├── .travis.yml ├── siphash ├── siphash_amd64.go ├── sum_amd64.go ├── vectors_test.go ├── siphash_amd64.s ├── sum_ref.go ├── siphash_ref.go ├── siphash.go └── siphash_test.go ├── poly1305 ├── sum.go ├── vectors_test.go ├── poly1305_amd64.go ├── poly1305_ref.go ├── poly1305_test.go └── poly1305.go ├── xor.go ├── skein ├── skein256 │ ├── skein256_amd64.go │ ├── skein256_ref.go │ ├── skein.go │ └── skein256.go ├── skein512_ref.go ├── skein512_amd64.go ├── skein1024 │ ├── skein1024_ref.go │ ├── skein1024_amd64.go │ ├── skein.go │ └── skein1024.go ├── constants.go ├── threefish │ ├── threefish_ref.go │ ├── threefish_amd64.go │ ├── threefish.go │ └── threefish_test.go ├── skein512.go └── skein_test.go ├── chacha20 ├── chacha │ ├── chacha.go │ ├── chacha_test.go │ └── chacha_amd64.go ├── chacha20.go ├── chacha20_test.go ├── chachaPoly1305.go └── chachaPoly1305_test.go ├── xor_amd64.go ├── crypto.go ├── camellia ├── camellia_ref.go ├── vectors_test.go └── camellia_test.go ├── hc256 ├── hc256_ref.go ├── hc256_test.go ├── vectors_test.go └── hc256.go ├── hc128 ├── hc128_ref.go ├── hc128_test.go ├── vectors_test.go └── hc128.go ├── blake2 ├── blake2s │ ├── constants.go │ ├── blake2s_ref.go │ ├── blake2s_test.go │ └── vectors_test.go ├── blake2b │ ├── constants.go │ ├── blake2b_ref.go │ └── blake2b_test.go └── blake2_test.go ├── pad ├── x923.go ├── pkcs7.go ├── iso10126.go └── pad.go ├── dh ├── ecdh │ ├── ecdh.go │ ├── curve25519.go │ ├── generic.go │ └── ecdh_test.go ├── dh_test.go ├── dh.go └── groups.go ├── xor_test.go ├── cipher ├── eax_test.go ├── vectors_test.go └── eax.go ├── cmac ├── vectors_test.go └── cmac.go ├── README.md └── serpent ├── vectors_test.go └── serpent.go /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.6 5 | -------------------------------------------------------------------------------- /siphash/siphash_amd64.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // +build amd64, !appengine, !gccgo 5 | 6 | package siphash 7 | 8 | //go:noescape 9 | func core(hVal *[4]uint64, msg []byte) 10 | 11 | //go:noescape 12 | func finalize(hVal *[4]uint64, block *[TagSize]byte) uint64 13 | -------------------------------------------------------------------------------- /poly1305/sum.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package poly1305 5 | 6 | import poly "golang.org/x/crypto/poly1305" 7 | 8 | // Sum generates an authenticator for msg using a one-time key and puts the 9 | // 16-byte result into out. Authenticating two different messages with the same 10 | // key allows an attacker to forge messages at will. 11 | func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) { 12 | poly.Sum(out, msg, key) 13 | } 14 | -------------------------------------------------------------------------------- /xor.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // +build !amd64 5 | 6 | package crypto 7 | 8 | // XOR xors the bytes in src and with and writes the result to dst. 9 | // The destination is assumed to have enough space. Returns the 10 | // number of bytes xor'd. 11 | func XOR(dst, src, with []byte) int { 12 | var a, b []byte 13 | if len(src) <= len(with) { 14 | a = src 15 | b = with 16 | } else { 17 | b = src 18 | a = with 19 | } 20 | 21 | for i, v := range a { 22 | dst[i] = b[i] ^ v 23 | } 24 | return len(a) 25 | } 26 | -------------------------------------------------------------------------------- /skein/skein256/skein256_amd64.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // +build amd64 5 | 6 | package skein256 7 | 8 | import "unsafe" 9 | 10 | func bytesToBlock(block *[4]uint64, src []byte) { 11 | srcPtr := (*[4]uint64)(unsafe.Pointer(&src[0])) 12 | 13 | block[0] = srcPtr[0] 14 | block[1] = srcPtr[1] 15 | block[2] = srcPtr[2] 16 | block[3] = srcPtr[3] 17 | } 18 | 19 | func blockToBytes(dst []byte, block *[4]uint64) { 20 | dstPtr := (*[4]uint64)(unsafe.Pointer(&dst[0])) 21 | 22 | dstPtr[0] = block[0] 23 | dstPtr[1] = block[1] 24 | dstPtr[2] = block[2] 25 | dstPtr[3] = block[3] 26 | } 27 | -------------------------------------------------------------------------------- /skein/skein512_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // +build !amd64 5 | 6 | package skein 7 | 8 | func bytesToBlock(block *[8]uint64, src []byte) { 9 | for i := range block { 10 | j := i * 8 11 | block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | 12 | uint64(src[j+3])<<24 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | 13 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 14 | } 15 | } 16 | 17 | func blockToBytes(dst []byte, block *[8]uint64) { 18 | i := 0 19 | for _, v := range block { 20 | dst[i] = byte(v) 21 | dst[i+1] = byte(v >> 8) 22 | dst[i+2] = byte(v >> 16) 23 | dst[i+3] = byte(v >> 24) 24 | dst[i+4] = byte(v >> 32) 25 | dst[i+5] = byte(v >> 40) 26 | dst[i+6] = byte(v >> 48) 27 | dst[i+7] = byte(v >> 56) 28 | i += 8 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /skein/skein512_amd64.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // +build amd64 5 | 6 | package skein 7 | 8 | import "unsafe" 9 | 10 | func bytesToBlock(block *[8]uint64, src []byte) { 11 | srcPtr := (*[8]uint64)(unsafe.Pointer(&src[0])) 12 | 13 | block[0] = srcPtr[0] 14 | block[1] = srcPtr[1] 15 | block[2] = srcPtr[2] 16 | block[3] = srcPtr[3] 17 | block[4] = srcPtr[4] 18 | block[5] = srcPtr[5] 19 | block[6] = srcPtr[6] 20 | block[7] = srcPtr[7] 21 | } 22 | 23 | func blockToBytes(dst []byte, block *[8]uint64) { 24 | dstPtr := (*[8]uint64)(unsafe.Pointer(&dst[0])) 25 | 26 | dstPtr[0] = block[0] 27 | dstPtr[1] = block[1] 28 | dstPtr[2] = block[2] 29 | dstPtr[3] = block[3] 30 | dstPtr[4] = block[4] 31 | dstPtr[5] = block[5] 32 | dstPtr[6] = block[6] 33 | dstPtr[7] = block[7] 34 | } 35 | -------------------------------------------------------------------------------- /skein/skein256/skein256_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // +build !amd64 5 | 6 | package skein256 7 | 8 | func bytesToBlock(block *[4]uint64, src []byte) { 9 | for i := range block { 10 | j := i * 8 11 | block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | 12 | uint64(src[j+3])<<24 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | 13 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 14 | } 15 | } 16 | 17 | func blockToBytes(dst []byte, block *[4]uint64) { 18 | i := 0 19 | for _, v := range block { 20 | dst[i] = byte(v) 21 | dst[i+1] = byte(v >> 8) 22 | dst[i+2] = byte(v >> 16) 23 | dst[i+3] = byte(v >> 24) 24 | dst[i+4] = byte(v >> 32) 25 | dst[i+5] = byte(v >> 40) 26 | dst[i+6] = byte(v >> 48) 27 | dst[i+7] = byte(v >> 56) 28 | i += 8 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /skein/skein1024/skein1024_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // +build !amd64 5 | 6 | package skein1024 7 | 8 | func bytesToBlock(block *[16]uint64, src []byte) { 9 | for i := range block { 10 | j := i * 8 11 | block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | 12 | uint64(src[j+3])<<24 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | 13 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 14 | } 15 | } 16 | 17 | func blockToBytes(dst []byte, block *[16]uint64) { 18 | i := 0 19 | for _, v := range block { 20 | dst[i] = byte(v) 21 | dst[i+1] = byte(v >> 8) 22 | dst[i+2] = byte(v >> 16) 23 | dst[i+3] = byte(v >> 24) 24 | dst[i+4] = byte(v >> 32) 25 | dst[i+5] = byte(v >> 40) 26 | dst[i+6] = byte(v >> 48) 27 | dst[i+7] = byte(v >> 56) 28 | i += 8 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /chacha20/chacha/chacha.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package chacha implements some low level functions of the 5 | // ChaCha cipher family. 6 | package chacha 7 | 8 | var constants = [16]byte{ 9 | 0x65, 0x78, 0x70, 0x61, 10 | 0x6e, 0x64, 0x20, 0x33, 11 | 0x32, 0x2d, 0x62, 0x79, 12 | 0x74, 0x65, 0x20, 0x6b, 13 | } 14 | 15 | // Cipher is the ChaCha/X struct. 16 | // X is the number of rounds (e.g. ChaCha20 for 20 rounds) 17 | type Cipher struct { 18 | state, block [64]byte 19 | off int 20 | rounds int 21 | } 22 | 23 | // Sets the counter of the cipher. 24 | // Notice that this function skips the unused 25 | // keystream of the current 64 byte block. 26 | func (c *Cipher) SetCounter(ctr uint32) { 27 | c.state[48] = byte(ctr) 28 | c.state[49] = byte(ctr >> 8) 29 | c.state[50] = byte(ctr >> 16) 30 | c.state[51] = byte(ctr >> 24) 31 | c.off = 0 32 | } 33 | -------------------------------------------------------------------------------- /xor_amd64.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // +build amd64, !cgo, !appengine 5 | 6 | package crypto 7 | 8 | import "unsafe" 9 | 10 | const wordSize = int(unsafe.Sizeof(uintptr(0))) 11 | 12 | // XOR xors the bytes in src and with and writes the result to dst. 13 | // The destination is assumed to have enough space. Returns the 14 | // number of bytes xor'd. 15 | func XOR(dst, src, with []byte) int { 16 | n := len(src) 17 | if len(with) < n { 18 | n = len(with) 19 | } 20 | 21 | w := n / wordSize 22 | if w > 0 { 23 | dstPtr := *(*[]uintptr)(unsafe.Pointer(&dst)) 24 | srcPtr := *(*[]uintptr)(unsafe.Pointer(&src)) 25 | withPtr := *(*[]uintptr)(unsafe.Pointer(&with)) 26 | for i, v := range srcPtr[:w] { 27 | dstPtr[i] = withPtr[i] ^ v 28 | } 29 | } 30 | 31 | for i := (n & (^(wordSize - 1))); i < n; i++ { 32 | dst[i] = src[i] ^ with[i] 33 | } 34 | 35 | return n 36 | } 37 | -------------------------------------------------------------------------------- /crypto.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package crypto contains commen and general useful 5 | // cryptographic functions and types. 6 | package crypto 7 | 8 | import "strconv" 9 | 10 | // A KeySizeError indicates, that the size of a given key 11 | // does not match the expected size. 12 | type KeySizeError int 13 | 14 | func (k KeySizeError) Error() string { 15 | return "invalid key size " + strconv.Itoa(int(k)) 16 | } 17 | 18 | // A NonceSizeError indicates, that the size of a given nonce 19 | // does not match the expected size. 20 | type NonceSizeError int 21 | 22 | func (n NonceSizeError) Error() string { 23 | return "invalid nonce size " + strconv.Itoa(int(n)) 24 | } 25 | 26 | // A AuthenticationError indicates, that an authentication 27 | // process failed. E.g. the message authentication of a AEAD 28 | // cipher. 29 | type AuthenticationError struct{} 30 | 31 | func (a AuthenticationError) Error() string { 32 | return "authentication failed" 33 | } 34 | -------------------------------------------------------------------------------- /camellia/camellia_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package camellia 5 | 6 | // The camellia non-linear feistel function. 7 | func f(r0, r1, r2, r3 *uint32, k0, k1 uint32) { 8 | k0 ^= *r0 9 | k1 ^= *r1 10 | 11 | t := sbox4_4404[byte(k0)] 12 | t ^= sbox3_3033[byte(k0>>8)] 13 | t ^= sbox2_0222[byte(k0>>16)] 14 | t ^= sbox1_1110[byte(k0>>24)] 15 | *r3 ^= (t >> 8) | (t << (32 - 8)) 16 | 17 | k0 = t 18 | k0 ^= sbox1_1110[byte(k1)] 19 | k0 ^= sbox4_4404[byte(k1>>8)] 20 | k0 ^= sbox3_3033[byte(k1>>16)] 21 | k0 ^= sbox2_0222[byte(k1>>24)] 22 | 23 | *r2 ^= k0 24 | *r3 ^= k0 25 | } 26 | 27 | // Note that n has to be less than 32. Rotations for larger amount 28 | // of bits are achieved by "rotating" order of registers and 29 | // adjusting n accordingly, e.g. RotLeft128(r1,r2,r3,r0,n-32). 30 | func rotl128(r0, r1, r2, r3 *uint32, n uint) { 31 | t := *r0 >> (32 - n) 32 | *r0 = (*r0 << n) | (*r1 >> (32 - n)) 33 | *r1 = (*r1 << n) | (*r2 >> (32 - n)) 34 | *r2 = (*r2 << n) | (*r3 >> (32 - n)) 35 | *r3 = (*r3 << n) | t 36 | } 37 | -------------------------------------------------------------------------------- /hc256/hc256_ref.go: -------------------------------------------------------------------------------- 1 | package hc256 2 | 3 | import "github.com/enceve/crypto" 4 | 5 | func (c *streamCipher) XORKeyStream(dst, src []byte) { 6 | length := len(src) 7 | if len(dst) < length { 8 | panic("dst buffer is to small") 9 | } 10 | 11 | if c.off > 0 { 12 | left := 4 - c.off 13 | if left > length { 14 | left = length 15 | } 16 | for i, v := range c.keyStream[c.off : c.off+left] { 17 | dst[i] = src[i] ^ v 18 | } 19 | src = src[left:] 20 | dst = dst[left:] 21 | length -= left 22 | c.off += left 23 | if c.off == 4 { 24 | c.off = 0 25 | } 26 | } 27 | 28 | n := length - (length % 4) 29 | for i := 0; i < n; i += 4 { 30 | k := genKeyStream(&(c.ctr), &(c.p), &(c.q)) 31 | dst[i] = src[i] ^ byte(k) 32 | dst[i+1] = src[i+1] ^ byte(k>>8) 33 | dst[i+2] = src[i+2] ^ byte(k>>16) 34 | dst[i+3] = src[i+3] ^ byte(k>>24) 35 | } 36 | 37 | length -= n 38 | if length > 0 { 39 | k := genKeyStream(&(c.ctr), &(c.p), &(c.q)) 40 | c.keyStream[0] = byte(k) 41 | c.keyStream[1] = byte(k >> 8) 42 | c.keyStream[2] = byte(k >> 16) 43 | c.keyStream[3] = byte(k >> 24) 44 | c.off += crypto.XOR(dst[n:], src[n:], c.keyStream[:]) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /hc128/hc128_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package hc128 5 | 6 | import "github.com/enceve/crypto" 7 | 8 | func (c *streamCipher) XORKeyStream(dst, src []byte) { 9 | length := len(src) 10 | if len(dst) < length { 11 | panic("dst buffer is to small") 12 | } 13 | 14 | if c.off > 0 { 15 | left := 4 - c.off 16 | if left > length { 17 | left = length 18 | } 19 | for i, v := range c.keyStream[c.off : c.off+left] { 20 | dst[i] = src[i] ^ v 21 | } 22 | src = src[left:] 23 | dst = dst[left:] 24 | length -= left 25 | c.off += left 26 | if c.off == 4 { 27 | c.off = 0 28 | } 29 | } 30 | 31 | n := length - (length % 4) 32 | for i := 0; i < n; i += 4 { 33 | k := genKeyStream(&(c.ctr), &(c.p), &(c.q)) 34 | dst[i] = src[i] ^ byte(k) 35 | dst[i+1] = src[i+1] ^ byte(k>>8) 36 | dst[i+2] = src[i+2] ^ byte(k>>16) 37 | dst[i+3] = src[i+3] ^ byte(k>>24) 38 | } 39 | 40 | length -= n 41 | if length > 0 { 42 | k := genKeyStream(&(c.ctr), &(c.p), &(c.q)) 43 | c.keyStream[0] = byte(k) 44 | c.keyStream[1] = byte(k >> 8) 45 | c.keyStream[2] = byte(k >> 16) 46 | c.keyStream[3] = byte(k >> 24) 47 | c.off += crypto.XOR(dst[n:], src[n:], c.keyStream[:]) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /blake2/blake2s/constants.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package blake2s 5 | 6 | const ( 7 | // The block flag for message blocks 8 | MsgFlag uint32 = 0 9 | // The block flag for the last block 10 | FinalFlag uint32 = 0xffffffff 11 | ) 12 | 13 | // the BLAKE2s iv constants 14 | var iv = [8]uint32{ 15 | 0x6a09e667, 0xbb67ae85, 16 | 0x3c6ef372, 0xa54ff53a, 17 | 0x510e527f, 0x9b05688c, 18 | 0x1f83d9ab, 0x5be0cd19, 19 | } 20 | 21 | // the precomputed values for BLAKE2s 22 | // there are 12 16-byte arrays - one for each round 23 | // the entries are calculated from the sigma constants. 24 | var precomputed [10][16]byte = [10][16]byte{ 25 | {0, 2, 4, 6, 5, 7, 3, 1, 8, 10, 12, 14, 13, 15, 11, 9}, 26 | {14, 4, 9, 13, 15, 6, 8, 10, 1, 0, 11, 5, 7, 3, 2, 12}, 27 | {11, 12, 5, 15, 2, 13, 0, 8, 10, 3, 7, 9, 1, 4, 6, 14}, 28 | {7, 3, 13, 11, 12, 14, 1, 9, 2, 5, 4, 15, 0, 8, 10, 6}, 29 | {9, 5, 2, 10, 4, 15, 7, 0, 14, 11, 6, 3, 8, 13, 12, 1}, 30 | {2, 6, 0, 8, 11, 3, 10, 12, 4, 7, 15, 1, 14, 9, 5, 13}, 31 | {12, 1, 14, 4, 13, 10, 15, 5, 0, 6, 9, 8, 2, 11, 3, 7}, 32 | {13, 7, 12, 3, 1, 9, 14, 11, 5, 15, 8, 2, 6, 10, 4, 0}, 33 | {6, 14, 11, 0, 3, 8, 9, 15, 12, 13, 1, 10, 4, 5, 7, 2}, 34 | {10, 8, 7, 1, 6, 5, 4, 2, 15, 9, 3, 13, 12, 0, 14, 11}, 35 | } 36 | -------------------------------------------------------------------------------- /skein/skein1024/skein1024_amd64.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // +build amd64 5 | 6 | package skein1024 7 | 8 | import "unsafe" 9 | 10 | func bytesToBlock(block *[16]uint64, src []byte) { 11 | srcPtr := (*[16]uint64)(unsafe.Pointer(&src[0])) 12 | 13 | block[0] = srcPtr[0] 14 | block[1] = srcPtr[1] 15 | block[2] = srcPtr[2] 16 | block[3] = srcPtr[3] 17 | block[4] = srcPtr[4] 18 | block[5] = srcPtr[5] 19 | block[6] = srcPtr[6] 20 | block[7] = srcPtr[7] 21 | block[8] = srcPtr[8] 22 | block[9] = srcPtr[9] 23 | block[10] = srcPtr[10] 24 | block[11] = srcPtr[11] 25 | block[12] = srcPtr[12] 26 | block[13] = srcPtr[13] 27 | block[14] = srcPtr[14] 28 | block[15] = srcPtr[15] 29 | } 30 | 31 | func blockToBytes(dst []byte, block *[16]uint64) { 32 | dstPtr := (*[16]uint64)(unsafe.Pointer(&dst[0])) 33 | 34 | dstPtr[0] = block[0] 35 | dstPtr[1] = block[1] 36 | dstPtr[2] = block[2] 37 | dstPtr[3] = block[3] 38 | dstPtr[4] = block[4] 39 | dstPtr[5] = block[5] 40 | dstPtr[6] = block[6] 41 | dstPtr[7] = block[7] 42 | dstPtr[8] = block[8] 43 | dstPtr[9] = block[9] 44 | dstPtr[10] = block[10] 45 | dstPtr[11] = block[11] 46 | dstPtr[12] = block[12] 47 | dstPtr[13] = block[13] 48 | dstPtr[14] = block[14] 49 | dstPtr[15] = block[15] 50 | } 51 | -------------------------------------------------------------------------------- /pad/x923.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package pad 5 | 6 | type x923Padding int 7 | 8 | func (p x923Padding) BlockSize() int { 9 | return int(p) 10 | } 11 | 12 | func (p x923Padding) Overhead(src []byte) int { 13 | return overhead(p.BlockSize(), src) 14 | } 15 | 16 | func (p x923Padding) Pad(src []byte) []byte { 17 | overhead := p.Overhead(src) 18 | 19 | dst := make([]byte, overhead) 20 | dst[overhead-1] = byte(overhead) 21 | return append(src, dst...) 22 | } 23 | 24 | func (p x923Padding) Unpad(src []byte) ([]byte, error) { 25 | length := len(src) 26 | if length == 0 || length%p.BlockSize() != 0 { 27 | return nil, notMulOfBlockErr 28 | } 29 | 30 | block := src[length-p.BlockSize():] 31 | unLen, err := verifyX923(block, p.BlockSize()) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return src[:(length - p.BlockSize() + unLen)], nil 36 | 37 | } 38 | 39 | // Verify the X923 padding - NOTICE: not constant time! 40 | func verifyX923(block []byte, blocksize int) (p int, err error) { 41 | padLen := int(block[blocksize-1]) 42 | if padLen == 0 || int(padLen) > blocksize { 43 | err = badPadErr 44 | return 45 | } 46 | 47 | p = blocksize - int(padLen) 48 | for _, b := range block[p : blocksize-1] { 49 | if b != 0 { 50 | err = badPadErr 51 | } 52 | } 53 | return 54 | } 55 | -------------------------------------------------------------------------------- /chacha20/chacha20.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package chacha20 implements the ChaCha stream cipher and 5 | // the ChaCha20Poly1305 AEAD construction described in RFC 7539. 6 | // 7 | // ChaCha20 uses a 32 bit counter and produces 64 byte keystream per 8 | // iteration. Following ChaCha20 can en/decrypt up to 2^32 * 64 byte 9 | // for one key-nonce combination. Notice that one specific key-nonce 10 | // combination must be unique for all time. 11 | package chacha20 12 | 13 | import ( 14 | "crypto/cipher" 15 | 16 | "github.com/enceve/crypto/chacha20/chacha" 17 | ) 18 | 19 | // The size of the ChaCha20 nonce in bytes. 20 | const NonceSize = 12 21 | 22 | // XORKeyStream crypts bytes from src to dst using the given key, nonce and counter. Src 23 | // and dst may be the same slice but otherwise should not overlap. If len(dst) < len(src) 24 | // this function panics. 25 | func XORKeyStream(dst, src []byte, nonce *[NonceSize]byte, key *[32]byte, counter uint32) { 26 | chacha.XORKeyStream(dst, src, nonce, key, counter, 20) 27 | } 28 | 29 | // NewCipher returns a new cipher.Stream implementing the ChaCha20 30 | // stream cipher. The nonce must be unique for one 31 | // key for all time. 32 | func NewCipher(nonce *[NonceSize]byte, key *[32]byte) cipher.Stream { 33 | return chacha.NewCipher(nonce, key, 20) 34 | } 35 | -------------------------------------------------------------------------------- /pad/pkcs7.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package pad 5 | 6 | type pkcs7Padding int 7 | 8 | func (p pkcs7Padding) BlockSize() int { 9 | return int(p) 10 | } 11 | 12 | func (p pkcs7Padding) Overhead(src []byte) int { 13 | return overhead(p.BlockSize(), src) 14 | } 15 | 16 | func (p pkcs7Padding) Pad(src []byte) []byte { 17 | overhead := p.Overhead(src) 18 | 19 | dst := make([]byte, overhead) 20 | for i := range dst { 21 | dst[i] = byte(overhead) 22 | } 23 | return append(src, dst...) 24 | } 25 | 26 | func (p pkcs7Padding) Unpad(src []byte) ([]byte, error) { 27 | length := len(src) 28 | if length == 0 || length%p.BlockSize() != 0 { 29 | return nil, notMulOfBlockErr 30 | } 31 | 32 | block := src[(length - p.BlockSize()):] 33 | unLen, err := verifyPkcs7(block, p.BlockSize()) 34 | if err != nil { 35 | return nil, err 36 | } 37 | return src[:(length - p.BlockSize() + unLen)], nil 38 | } 39 | 40 | // Verify the PKCS7 padding - NOTICE: not constant time! 41 | func verifyPkcs7(block []byte, blocksize int) (p int, err error) { 42 | padLen := block[blocksize-1] 43 | if padLen == 0 || int(padLen) > blocksize { 44 | err = badPadErr 45 | return 46 | } 47 | 48 | p = blocksize - int(padLen) 49 | for _, b := range block[p:] { 50 | if b != padLen { 51 | err = badPadErr 52 | } 53 | } 54 | return 55 | } 56 | -------------------------------------------------------------------------------- /siphash/sum_amd64.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // +build amd64, !cgo, !appengine 5 | 6 | package siphash 7 | 8 | import ( 9 | "hash" 10 | "unsafe" 11 | ) 12 | 13 | // New returns a hash.Hash64 computing the SipHash checksum with a 128 bit key. 14 | func New(key *[16]byte) hash.Hash64 { 15 | h := new(hashFunc) 16 | h.key[0] = *(*uint64)(unsafe.Pointer(&key[0])) 17 | h.key[1] = *(*uint64)(unsafe.Pointer(&key[8])) 18 | h.Reset() 19 | return h 20 | } 21 | 22 | // Sum generates an authenticator for msg with a 128 bit key 23 | // and puts the 64 bit result into out. 24 | func Sum(out *[TagSize]byte, msg []byte, key *[16]byte) { 25 | (*[1]uint64)(unsafe.Pointer(&out[0]))[0] = Sum64(msg, key) 26 | } 27 | 28 | // Sum64 generates and returns the 64 bit authenticator 29 | // for msg with a 128 bit key. 30 | func Sum64(msg []byte, key *[16]byte) uint64 { 31 | k0 := *(*uint64)(unsafe.Pointer(&key[0])) 32 | k1 := *(*uint64)(unsafe.Pointer(&key[8])) 33 | 34 | var hVal [4]uint64 35 | hVal[0] = k0 ^ c0 36 | hVal[1] = k1 ^ c1 37 | hVal[2] = k0 ^ c2 38 | hVal[3] = k1 ^ c3 39 | 40 | n := len(msg) 41 | ctr := byte(n) 42 | 43 | if n >= TagSize { 44 | n &= (^(TagSize - 1)) 45 | core(&hVal, msg[:n]) 46 | msg = msg[n:] 47 | } 48 | 49 | var block [TagSize]byte 50 | for i, v := range msg { 51 | block[i] = v 52 | } 53 | block[7] = ctr 54 | 55 | return finalize(&hVal, &block) 56 | } 57 | -------------------------------------------------------------------------------- /pad/iso10126.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package pad 5 | 6 | import ( 7 | "io" 8 | ) 9 | 10 | type isoPadding struct { 11 | blocksize int 12 | random io.Reader 13 | } 14 | 15 | func (p *isoPadding) BlockSize() int { 16 | return p.blocksize 17 | } 18 | 19 | func (p *isoPadding) Overhead(src []byte) int { 20 | return overhead(p.blocksize, src) 21 | } 22 | 23 | func (p *isoPadding) Pad(src []byte) []byte { 24 | overhead := p.Overhead(src) 25 | 26 | dst := make([]byte, overhead) 27 | n, e := io.ReadFull(p.random, dst) 28 | if e != nil || n != overhead { 29 | // if random fails, do a pkcs7 padding 30 | for i := range dst { 31 | dst[i] = byte(overhead) 32 | } 33 | } 34 | 35 | dst[overhead-1] = byte(overhead) 36 | return append(src, dst...) 37 | } 38 | 39 | func (p *isoPadding) Unpad(src []byte) ([]byte, error) { 40 | length := len(src) 41 | if length == 0 || length%p.blocksize != 0 { 42 | return nil, notMulOfBlockErr 43 | } 44 | 45 | block := src[length-p.blocksize:] 46 | unLen, err := verifyISO(block, p.blocksize) 47 | if err != nil { 48 | return nil, err 49 | } 50 | 51 | return src[:(length - p.BlockSize() + unLen)], nil 52 | } 53 | 54 | func verifyISO(block []byte, length int) (p int, err error) { 55 | padLen := block[length-1] 56 | if padLen == 0 || int(padLen) > length { 57 | err = badPadErr 58 | } 59 | p = length - int(padLen) 60 | return 61 | } 62 | -------------------------------------------------------------------------------- /blake2/blake2b/constants.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package blake2b 5 | 6 | const ( 7 | // The block flag for message blocks 8 | MsgFlag uint64 = 0 9 | // The block flag for the last block 10 | FinalFlag uint64 = 0xffffffffffffffff 11 | ) 12 | 13 | // the blake2b iv constants 14 | var iv = [8]uint64{ 15 | 0x6a09e667f3bcc908, 16 | 0xbb67ae8584caa73b, 17 | 0x3c6ef372fe94f82b, 18 | 0xa54ff53a5f1d36f1, 19 | 0x510e527fade682d1, 20 | 0x9b05688c2b3e6c1f, 21 | 0x1f83d9abfb41bd6b, 22 | 0x5be0cd19137e2179, 23 | } 24 | 25 | // the precomputed values for blake2b 26 | // there are 12 16-byte arrays - one for each round 27 | // the entries are calculated from the sigma constants. 28 | var precomputed [12][16]byte = [12][16]byte{ 29 | {0, 2, 4, 6, 5, 7, 3, 1, 8, 10, 12, 14, 13, 15, 11, 9}, 30 | {14, 4, 9, 13, 15, 6, 8, 10, 1, 0, 11, 5, 7, 3, 2, 12}, 31 | {11, 12, 5, 15, 2, 13, 0, 8, 10, 3, 7, 9, 1, 4, 6, 14}, 32 | {7, 3, 13, 11, 12, 14, 1, 9, 2, 5, 4, 15, 0, 8, 10, 6}, 33 | {9, 5, 2, 10, 4, 15, 7, 0, 14, 11, 6, 3, 8, 13, 12, 1}, 34 | {2, 6, 0, 8, 11, 3, 10, 12, 4, 7, 15, 1, 14, 9, 5, 13}, 35 | {12, 1, 14, 4, 13, 10, 15, 5, 0, 6, 9, 8, 2, 11, 3, 7}, 36 | {13, 7, 12, 3, 1, 9, 14, 11, 5, 15, 8, 2, 6, 10, 4, 0}, 37 | {6, 14, 11, 0, 3, 8, 9, 15, 12, 13, 1, 10, 4, 5, 7, 2}, 38 | {10, 8, 7, 1, 6, 5, 4, 2, 15, 9, 3, 13, 12, 0, 14, 11}, 39 | {0, 2, 4, 6, 5, 7, 3, 1, 8, 10, 12, 14, 13, 15, 11, 9}, // equal to the first 40 | {14, 4, 9, 13, 15, 6, 8, 10, 1, 0, 11, 5, 7, 3, 2, 12}, // equal to the secound 41 | } 42 | -------------------------------------------------------------------------------- /siphash/vectors_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package siphash 5 | 6 | import ( 7 | "encoding/hex" 8 | "testing" 9 | ) 10 | 11 | type testVector struct { 12 | key, msg string 13 | hash uint64 14 | } 15 | 16 | var vectors []testVector = []testVector{ 17 | // Test vector from https://131002.net/siphash/siphash.pdf 18 | testVector{ 19 | key: "000102030405060708090a0b0c0d0e0f", 20 | msg: "000102030405060708090a0b0c0d0e", 21 | hash: uint64(0xa129ca6149be45e5), 22 | }, 23 | } 24 | 25 | // Tests the SipHash implementation 26 | func TestVectors(t *testing.T) { 27 | for i, v := range vectors { 28 | var key [16]byte 29 | k, err := hex.DecodeString(v.key) 30 | if err != nil { 31 | t.Fatalf("Test vector %d: Failed to decode hex key: %s", i, err) 32 | } 33 | copy(key[:], k) 34 | 35 | msg, err := hex.DecodeString(v.msg) 36 | if err != nil { 37 | t.Fatalf("Test vector %d: Failed to decode hex msg: %s", i, err) 38 | } 39 | 40 | h := New(&key) 41 | _, err = h.Write(msg) 42 | if err != nil { 43 | t.Fatalf("Test vector %d: Spihash write failed: %s", i, err) 44 | } 45 | 46 | sum := h.Sum64() 47 | if sum != v.hash { 48 | t.Fatalf("Test vector %d: Hash values don't match - found %x expected %x", i, sum, v.hash) 49 | } 50 | sum = Sum64(msg, &key) 51 | if err != nil { 52 | t.Fatalf("Test vector %d: Failed to calculate MAC: %s", i, err) 53 | } 54 | if sum != v.hash { 55 | t.Fatalf("Hash values don't match - found %x expected %x", sum, v.hash) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /poly1305/vectors_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | package poly1305 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | type testVector struct { 13 | key, msg, tag string 14 | } 15 | 16 | var vectors = []testVector{ 17 | // From: https://tools.ietf.org/html/rfc7539#section-2.5.2 18 | testVector{ 19 | key: "85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b", 20 | msg: "43727970746f6772617068696320466f72756d2052657365617263682047726f7570", 21 | tag: "a8061dc1305136c6c22b8baf0c0127a9", 22 | }, 23 | } 24 | 25 | func TestVectors(t *testing.T) { 26 | for i, v := range vectors { 27 | key, err := hex.DecodeString(v.key) 28 | if err != nil { 29 | t.Fatalf("Test vector %d : Failed to decode key: %s", i, err) 30 | } 31 | msg, err := hex.DecodeString(v.msg) 32 | if err != nil { 33 | t.Fatalf("Test vector %d : Failed to decode msg: %s", i, err) 34 | } 35 | tag, err := hex.DecodeString(v.tag) 36 | if err != nil { 37 | t.Fatalf("Test vector %d : Failed to decode tag: %s", i, err) 38 | } 39 | 40 | var sum [TagSize]byte 41 | var k [32]byte 42 | 43 | copy(k[:], key) 44 | Sum(&sum, msg, &k) 45 | if !bytes.Equal(sum[:], tag) { 46 | t.Fatalf("Test vector %d : Poly1305 Tags are not equal:\nFound: %v\nExpected: %v", i, sum, tag) 47 | } 48 | 49 | p := New(&k) 50 | p.Write(msg) 51 | p.Sum(&sum) 52 | if !bytes.Equal(sum[:], tag) { 53 | t.Fatalf("Test vector %d : Poly1305 Tags are not equal:\nFound: %v\nExpected: %v", i, sum[:], tag) 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /siphash/siphash_amd64.s: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | // +build amd64,!appengine,!gccgo 4 | 5 | #define ROUND(v0, v1, v2, v3) \ 6 | ADDQ v1, v0; \ 7 | RORQ $51, v1; \ 8 | ADDQ v3, v2; \ 9 | XORQ v0, v1; \ 10 | RORQ $48, v3; \ 11 | RORQ $32, v0; \ 12 | XORQ v2, v3; \ 13 | ADDQ v1, v2; \ 14 | ADDQ v3, v0; \ 15 | RORQ $43, v3; \ 16 | RORQ $47, v1; \ 17 | XORQ v0, v3; \ 18 | XORQ v2, v1; \ 19 | RORQ $32, v2 20 | 21 | // core(hVal *[4]uint64, msg []byte) 22 | TEXT ·core(SB),4,$0-32 23 | MOVQ hVal+0(FP), AX 24 | MOVQ msg+16(FP), BX 25 | MOVQ msg+8(FP), CX 26 | MOVQ 0(AX), R9 27 | MOVQ 8(AX), R10 28 | MOVQ 16(AX), R11 29 | MOVQ 24(AX), R12 30 | ANDQ $0XFFFFFFFFFFFFFFF8, BX // BX & (^7) 31 | loop: 32 | MOVQ 0(CX), DX 33 | XORQ DX, R12 34 | ROUND(R9, R10, R11, R12) 35 | ROUND(R9, R10, R11, R12) 36 | XORQ DX, R9 37 | ADDQ $8, CX 38 | SUBQ $8, BX 39 | JNZ loop 40 | MOVQ R9, 0(AX) 41 | MOVQ R10, 8(AX) 42 | MOVQ R11, 16(AX) 43 | MOVQ R12, 24(AX) 44 | RET 45 | 46 | // finalize(hVal *[4]uint64, block *[8]byte) uint64 47 | TEXT ·finalize(SB),4,$0-24 48 | MOVQ hVal+0(FP), AX 49 | MOVQ block+8(FP), BX 50 | MOVQ 0(BX), CX 51 | MOVQ 0(AX), R9 52 | MOVQ 8(AX), R10 53 | MOVQ 16(AX), R11 54 | MOVQ 24(AX), R12 55 | XORQ CX, R12 56 | ROUND(R9, R10, R11, R12) 57 | ROUND(R9, R10, R11, R12) 58 | XORQ CX, R9 59 | NOTB R11 60 | ROUND(R9, R10, R11, R12) 61 | ROUND(R9, R10, R11, R12) 62 | ROUND(R9, R10, R11, R12) 63 | ROUND(R9, R10, R11, R12) 64 | XORQ R12, R11 65 | XORQ R10, R9 66 | XORQ R11, R9 67 | MOVQ R9, ret+16(FP) 68 | RET 69 | -------------------------------------------------------------------------------- /dh/ecdh/ecdh.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package ecdh implements the Diffie-Hellman key exchange 5 | // with elliptic curves. This package directly implements 6 | // generic curves imlementing elliptic.Curve 7 | // (the NIST curves P224, P256, P384 and P521) 8 | // and Bernstein's Curve25519. Other curves can be used 9 | // by implementing the KeyExchange interface. 10 | // 11 | // For generic curves this implementation of ECDH 12 | // only uses the x-coordinate as the computed secret. 13 | package ecdh 14 | 15 | import "io" 16 | 17 | // PublicKey is the type of ECDH public keys. 18 | type PublicKey []byte 19 | 20 | // PrivateKey is the type of ECDH private keys. 21 | type PrivateKey []byte 22 | 23 | // KeyExchange is the interface defining all functions 24 | // necessary for ECDH. 25 | type KeyExchange interface { 26 | // GenerateKey generates a private/public key pair using entropy from rand. 27 | // If rand is nil, crypto/rand.Reader will be used. 28 | GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) 29 | 30 | // PublicKey returns the public key corresponding to the given private one. 31 | PublicKey(private PrivateKey) (public PublicKey) 32 | 33 | // Check returns a non-nil error if the peers public key cannot used for the 34 | // key exchange (e.g. the public key isn't a point of the elliptic curve) 35 | // It's recommended to check peer's public key before computing the secret. 36 | Check(peersPublic PublicKey) (err error) 37 | 38 | // ComputeSecret returns the secret value computed from the given private key 39 | // and the peers public key. 40 | ComputeSecret(private PrivateKey, peersPublic PublicKey) (secret []byte) 41 | } 42 | -------------------------------------------------------------------------------- /chacha20/chacha20_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package chacha20 5 | 6 | import ( 7 | "testing" 8 | ) 9 | 10 | func BenchmarkCipher64B(b *testing.B) { 11 | var ( 12 | key [32]byte 13 | nonce [NonceSize]byte 14 | ) 15 | c := NewCipher(&nonce, &key) 16 | buf := make([]byte, 64) 17 | b.SetBytes(64) 18 | for i := 0; i < b.N; i++ { 19 | c.XORKeyStream(buf, buf) 20 | } 21 | } 22 | 23 | func BenchmarkCipher1K(b *testing.B) { 24 | var ( 25 | key [32]byte 26 | nonce [NonceSize]byte 27 | ) 28 | c := NewCipher(&nonce, &key) 29 | buf := make([]byte, 1024) 30 | b.SetBytes(1024) 31 | for i := 0; i < b.N; i++ { 32 | c.XORKeyStream(buf, buf) 33 | } 34 | } 35 | 36 | func BenchmarkCipher64K(b *testing.B) { 37 | var ( 38 | key [32]byte 39 | nonce [NonceSize]byte 40 | ) 41 | c := NewCipher(&nonce, &key) 42 | buf := make([]byte, 64*1024) 43 | b.SetBytes(64 * 1024) 44 | for i := 0; i < b.N; i++ { 45 | c.XORKeyStream(buf, buf) 46 | } 47 | } 48 | 49 | func BenchmarkXORKeyStream64B(b *testing.B) { 50 | var ( 51 | key [32]byte 52 | nonce [NonceSize]byte 53 | ) 54 | buf := make([]byte, 64) 55 | b.SetBytes(64) 56 | for i := 0; i < b.N; i++ { 57 | XORKeyStream(buf, buf, &nonce, &key, 0) 58 | } 59 | } 60 | 61 | func BenchmarkXORKeyStream1K(b *testing.B) { 62 | var ( 63 | key [32]byte 64 | nonce [NonceSize]byte 65 | ) 66 | buf := make([]byte, 1024) 67 | b.SetBytes(1024) 68 | for i := 0; i < b.N; i++ { 69 | XORKeyStream(buf, buf, &nonce, &key, 0) 70 | } 71 | } 72 | 73 | func BenchmarkXORKeyStream64K(b *testing.B) { 74 | var ( 75 | key [32]byte 76 | nonce [NonceSize]byte 77 | ) 78 | buf := make([]byte, 64*1024) 79 | b.SetBytes(64 * 1024) 80 | for i := 0; i < b.N; i++ { 81 | XORKeyStream(buf, buf, &nonce, &key, 0) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /hc128/hc128_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package hc128 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | func TestXORKeyStream(t *testing.T) { 13 | var nonce, key [16]byte 14 | c := NewCipher(&nonce, &key) 15 | ref := NewCipher(&nonce, &key) 16 | 17 | dst, src := make([]byte, 32), make([]byte, 16) 18 | cmp := make([]byte, 32) 19 | c.XORKeyStream(dst, src[:2]) 20 | c.XORKeyStream(dst[2:], src[:1]) 21 | c.XORKeyStream(dst[3:], src) 22 | c.XORKeyStream(dst[19:], src[:13]) 23 | 24 | ref.XORKeyStream(cmp, cmp) 25 | if !bytes.Equal(dst, cmp) { 26 | t.Fatalf("XORKeyStream failed:\nFound: %s\nExpected: %s", hex.EncodeToString(dst), hex.EncodeToString(cmp)) 27 | } 28 | 29 | dst, src = make([]byte, 15), make([]byte, 16) 30 | func() { 31 | defer func() { 32 | if err := recover(); err == nil { 33 | t.Fatal("Recover expected error, but no one occured") 34 | } 35 | }() 36 | c.XORKeyStream(dst, src) 37 | }() 38 | } 39 | 40 | // Benchmarks 41 | 42 | func BenchmarkXORKeyStream_64B(b *testing.B) { 43 | var nonce, key [16]byte 44 | c := NewCipher(&nonce, &key) 45 | 46 | buf := make([]byte, 64) 47 | 48 | b.SetBytes(int64(len(buf))) 49 | for i := 0; i < b.N; i++ { 50 | c.XORKeyStream(buf, buf) 51 | } 52 | } 53 | 54 | func BenchmarkXORKeyStream_1K(b *testing.B) { 55 | var nonce, key [16]byte 56 | c := NewCipher(&nonce, &key) 57 | 58 | buf := make([]byte, 1024) 59 | 60 | b.SetBytes(int64(len(buf))) 61 | for i := 0; i < b.N; i++ { 62 | c.XORKeyStream(buf, buf) 63 | } 64 | } 65 | 66 | func BenchmarkXORKeyStream_64K(b *testing.B) { 67 | var nonce, key [16]byte 68 | c := NewCipher(&nonce, &key) 69 | 70 | buf := make([]byte, 64*1024) 71 | 72 | b.SetBytes(int64(len(buf))) 73 | for i := 0; i < b.N; i++ { 74 | c.XORKeyStream(buf, buf) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /hc256/hc256_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package hc256 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | func TestXORKeyStream(t *testing.T) { 13 | var nonce, key [32]byte 14 | c := NewCipher(&nonce, &key) 15 | ref := NewCipher(&nonce, &key) 16 | 17 | dst, src := make([]byte, 32), make([]byte, 16) 18 | cmp := make([]byte, 32) 19 | c.XORKeyStream(dst, src[:2]) 20 | c.XORKeyStream(dst[2:], src[:1]) 21 | c.XORKeyStream(dst[3:], src) 22 | c.XORKeyStream(dst[19:], src[:13]) 23 | 24 | ref.XORKeyStream(cmp, cmp) 25 | if !bytes.Equal(dst, cmp) { 26 | t.Fatalf("XORKeyStream failed:\nFound: %s\nExpected: %s", hex.EncodeToString(dst), hex.EncodeToString(cmp)) 27 | } 28 | 29 | dst, src = make([]byte, 15), make([]byte, 16) 30 | func() { 31 | defer func() { 32 | if err := recover(); err == nil { 33 | t.Fatal("Recover expected error, but no one occured") 34 | } 35 | }() 36 | c.XORKeyStream(dst, src) 37 | }() 38 | } 39 | 40 | // Benchmarks 41 | 42 | func BenchmarkXORKeyStream_64B(b *testing.B) { 43 | var nonce, key [32]byte 44 | c := NewCipher(&nonce, &key) 45 | 46 | buf := make([]byte, 64) 47 | 48 | b.SetBytes(int64(len(buf))) 49 | for i := 0; i < b.N; i++ { 50 | c.XORKeyStream(buf, buf) 51 | } 52 | } 53 | 54 | func BenchmarkXORKeyStream_1K(b *testing.B) { 55 | var nonce, key [32]byte 56 | c := NewCipher(&nonce, &key) 57 | 58 | buf := make([]byte, 1024) 59 | 60 | b.SetBytes(int64(len(buf))) 61 | for i := 0; i < b.N; i++ { 62 | c.XORKeyStream(buf, buf) 63 | } 64 | } 65 | 66 | func BenchmarkXORKeyStream_64K(b *testing.B) { 67 | var nonce, key [32]byte 68 | c := NewCipher(&nonce, &key) 69 | 70 | buf := make([]byte, 64*1024) 71 | 72 | b.SetBytes(int64(len(buf))) 73 | for i := 0; i < b.N; i++ { 74 | c.XORKeyStream(buf, buf) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /dh/ecdh/curve25519.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package ecdh 5 | 6 | import ( 7 | cryptorand "crypto/rand" 8 | "errors" 9 | "io" 10 | 11 | "golang.org/x/crypto/curve25519" 12 | ) 13 | 14 | type ecdh25519 struct{} 15 | 16 | // Curve25519 creates a new ecdh.KeyExchange with 17 | // the elliptic curve Curve25519. 18 | func Curve25519() KeyExchange { 19 | return ecdh25519{} 20 | } 21 | 22 | func (c ecdh25519) GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) { 23 | if rand == nil { 24 | rand = cryptorand.Reader 25 | } 26 | 27 | var pri, pub [32]byte 28 | _, err = io.ReadFull(rand, pri[:]) 29 | if err != nil { 30 | return 31 | } 32 | 33 | // From https://cr.yp.to/ecdh.html 34 | pri[0] &= 248 35 | pri[31] &= 127 36 | pri[31] |= 64 37 | 38 | curve25519.ScalarBaseMult(&pub, &pri) 39 | 40 | private = pri[:] 41 | public = pub[:] 42 | return 43 | } 44 | 45 | func (c ecdh25519) PublicKey(private PrivateKey) (public PublicKey) { 46 | if len(private) != 32 { 47 | panic("ecdh: private key is not 32 byte") 48 | } 49 | 50 | var pri, pub [32]byte 51 | copy(pri[:], private) 52 | 53 | curve25519.ScalarBaseMult(&pub, &pri) 54 | 55 | public = pub[:] 56 | return 57 | } 58 | 59 | func (c ecdh25519) Check(peersPublic PublicKey) (err error) { 60 | if len(peersPublic) != 32 { 61 | err = errors.New("peers public key is not 32 byte") 62 | } 63 | return 64 | } 65 | 66 | func (c ecdh25519) ComputeSecret(private PrivateKey, peersPublic PublicKey) (secret []byte) { 67 | if len(private) != 32 { 68 | panic("ecdh: private key is not 32 byte") 69 | } 70 | if len(peersPublic) != 32 { 71 | panic("ecdh: peers public key is not 32 byte") 72 | } 73 | 74 | var sec, pri, pub [32]byte 75 | copy(pri[:], private) 76 | copy(pub[:], peersPublic) 77 | 78 | curve25519.ScalarMult(&sec, &pri, &pub) 79 | 80 | secret = sec[:] 81 | return 82 | } 83 | -------------------------------------------------------------------------------- /camellia/vectors_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package camellia 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | type testVector struct { 13 | key, plaintext, ciphertext string 14 | } 15 | 16 | func fromHex(s string) []byte { 17 | b, err := hex.DecodeString(s) 18 | if err != nil { 19 | panic(err) 20 | } 21 | return b 22 | } 23 | 24 | // Test vectors from RFC3713 - https://www.ietf.org/rfc/rfc3713.txt 25 | var vectors = []struct { 26 | key, plaintext, ciphertext string 27 | }{ 28 | { 29 | key: "0123456789abcdeffedcba9876543210", 30 | plaintext: "0123456789abcdeffedcba9876543210", 31 | ciphertext: "67673138549669730857065648eabe43", 32 | }, 33 | { 34 | key: "0123456789abcdeffedcba98765432100011223344556677", 35 | plaintext: "0123456789abcdeffedcba9876543210", 36 | ciphertext: "b4993401b3e996f84ee5cee7d79b09b9", 37 | }, 38 | { 39 | key: "0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff", 40 | plaintext: "0123456789abcdeffedcba9876543210", 41 | ciphertext: "9acc237dff16d76c20ef7c919e3a7509", 42 | }, 43 | } 44 | 45 | func TestVectors(t *testing.T) { 46 | for i, v := range vectors { 47 | key := fromHex(v.key) 48 | plaintext := fromHex(v.plaintext) 49 | ciphertext := fromHex(v.ciphertext) 50 | buf := make([]byte, BlockSize) 51 | 52 | c, err := NewCipher(key) 53 | if err != nil { 54 | t.Fatalf("Test vector %d: Failed to create Camellia instance: %s", i, err) 55 | } 56 | 57 | c.Encrypt(buf, plaintext) 58 | if !bytes.Equal(ciphertext, buf) { 59 | t.Fatalf("Test vector %d:\nEncryption failed\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(ciphertext)) 60 | } 61 | c.Decrypt(buf, buf) 62 | if !bytes.Equal(plaintext, buf) { 63 | t.Fatalf("Test vector %d:\nDecryption failed\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(plaintext)) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /siphash/sum_ref.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 2 | 3 | package siphash 4 | 5 | import "hash" 6 | 7 | // New returns a hash.Hash64 computing the SipHash checksum with a 128 bit key. 8 | func New(key *[16]byte) hash.Hash64 { 9 | h := new(hashFunc) 10 | h.key[0] = uint64(key[0]) | uint64(key[1])<<8 | uint64(key[2])<<16 | uint64(key[3])<<24 | 11 | uint64(key[4])<<32 | uint64(key[5])<<40 | uint64(key[6])<<48 | uint64(key[7])<<56 12 | h.key[1] = uint64(key[8]) | uint64(key[9])<<8 | uint64(key[10])<<16 | uint64(key[11])<<24 | 13 | uint64(key[12])<<32 | uint64(key[13])<<40 | uint64(key[14])<<48 | uint64(key[15])<<56 14 | h.Reset() 15 | return h 16 | } 17 | 18 | // Sum generates an authenticator for msg with a 128 bit key 19 | // and puts the 64 bit result into out. 20 | func Sum(out *[TagSize]byte, msg []byte, key *[16]byte) { 21 | r := Sum64(msg, key) 22 | 23 | out[0] = byte(r) 24 | out[1] = byte(r >> 8) 25 | out[2] = byte(r >> 16) 26 | out[3] = byte(r >> 24) 27 | out[4] = byte(r >> 32) 28 | out[5] = byte(r >> 40) 29 | out[6] = byte(r >> 48) 30 | out[7] = byte(r >> 56) 31 | } 32 | 33 | // Sum64 generates and returns the 64 bit authenticator 34 | // for msg with a 128 bit key. 35 | func Sum64(msg []byte, key *[16]byte) uint64 { 36 | k0 := uint64(key[0]) | uint64(key[1])<<8 | uint64(key[2])<<16 | uint64(key[3])<<24 | 37 | uint64(key[4])<<32 | uint64(key[5])<<40 | uint64(key[6])<<48 | uint64(key[7])<<56 38 | k1 := uint64(key[8]) | uint64(key[9])<<8 | uint64(key[10])<<16 | uint64(key[11])<<24 | 39 | uint64(key[12])<<32 | uint64(key[13])<<40 | uint64(key[14])<<48 | uint64(key[15])<<56 40 | 41 | var hVal [4]uint64 42 | hVal[0] = k0 ^ c0 43 | hVal[1] = k1 ^ c1 44 | hVal[2] = k0 ^ c2 45 | hVal[3] = k1 ^ c3 46 | 47 | n := len(msg) 48 | ctr := byte(n) 49 | 50 | if n >= TagSize { 51 | n &= (^(TagSize - 1)) 52 | core(&hVal, msg[:n]) 53 | msg = msg[n:] 54 | } 55 | 56 | var block [TagSize]byte 57 | for i, v := range msg { 58 | block[i] = v 59 | } 60 | block[7] = ctr 61 | 62 | return finalize(&hVal, &block) 63 | } 64 | -------------------------------------------------------------------------------- /xor_test.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "bytes" 5 | "encoding/hex" 6 | "testing" 7 | "unsafe" 8 | ) 9 | 10 | func unalignBytes(in []byte) []byte { 11 | out := make([]byte, len(in)+1) 12 | if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { 13 | out = out[1:] 14 | } else { 15 | out = out[:len(in)] 16 | } 17 | copy(out, in) 18 | return out 19 | } 20 | 21 | func testXOR(t *testing.T, dSize, sSize, wSize int, unalign bool) { 22 | dst0, src, with := make([]byte, dSize), make([]byte, sSize), make([]byte, wSize) 23 | dst1 := make([]byte, dSize) 24 | 25 | if unalign { 26 | with = unalignBytes(with) 27 | } 28 | 29 | var n int 30 | if len(src) < len(with) { 31 | n = len(src) 32 | } else { 33 | n = len(with) 34 | } 35 | 36 | for i := 0; i < n; i++ { 37 | src[i] = byte(i) 38 | with[i] = byte(i + 1) 39 | dst0[i] = src[i] ^ with[i] 40 | } 41 | XOR(dst1, src, with) 42 | 43 | if !bytes.Equal(dst0, dst1) { 44 | t.Fatalf("xor failed:\nexpected: %s\ngot: %s", hex.EncodeToString(dst0), hex.EncodeToString(dst1)) 45 | } 46 | } 47 | 48 | func TestXOR(t *testing.T) { 49 | testXOR(t, 0, 0, 0, true) 50 | testXOR(t, 0, 0, 0, false) 51 | testXOR(t, 64, 64, 64, true) 52 | testXOR(t, 64, 64, 64, false) 53 | testXOR(t, 65, 64, 63, true) 54 | testXOR(t, 65, 64, 63, false) 55 | testXOR(t, 16, 16, 64, true) 56 | testXOR(t, 16, 16, 64, false) 57 | } 58 | 59 | func benchmarkXOR(b *testing.B, size int, unalign bool) { 60 | dst, src, with := make([]byte, size), make([]byte, size), make([]byte, size) 61 | if unalign { 62 | with = unalignBytes(with) 63 | } 64 | 65 | b.SetBytes(int64(size)) 66 | b.ResetTimer() 67 | for i := 0; i < b.N; i++ { 68 | XOR(dst, src, with) 69 | } 70 | } 71 | 72 | func BenchmarkXOR_64(b *testing.B) { benchmarkXOR(b, 64, false) } 73 | func BenchmarkXOR_1K(b *testing.B) { benchmarkXOR(b, 1024, false) } 74 | func BenchmarkXORUnaligned_64(b *testing.B) { benchmarkXOR(b, 64, true) } 75 | func BenchmarkXORUnaligned_1K(b *testing.B) { benchmarkXOR(b, 1024, true) } 76 | -------------------------------------------------------------------------------- /hc128/vectors_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package hc128 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | // Test vectors from the HC128 description by Hongjun Wu. 13 | // http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf 14 | // The byte order was changed: 0x73150082 -> 0x82001573 15 | var vectors128 = []struct { 16 | key, nonce, keystream string 17 | }{ 18 | { 19 | key: "00000000000000000000000000000000", 20 | nonce: "00000000000000000000000000000000", 21 | keystream: "82001573a003fd3b7fd72ffb0eaf63aac62f12deb629dca72785a66268ec758b", 22 | }, 23 | { 24 | key: "00000000000000000000000000000000", 25 | nonce: "01000000000000000000000000000000", 26 | keystream: "d59318c058e9dbb798ec658f046617642467fc36ec6e2cc8a7381c1b952ab4c9", 27 | }, 28 | { 29 | key: "55000000000000000000000000000000", 30 | nonce: "00000000000000000000000000000000", 31 | keystream: "a45182510a93b40431f92ab032f039067aa4b4bc0b482257729ff92b66e5c0cd", 32 | }, 33 | } 34 | 35 | func TestVectors(t *testing.T) { 36 | for i, v := range vectors128 { 37 | key, err := hex.DecodeString(v.key) 38 | if err != nil { 39 | t.Fatalf("Test vector %d: Failed to decode hex key: %s", i, err) 40 | } 41 | nonce, err := hex.DecodeString(v.nonce) 42 | if err != nil { 43 | t.Fatalf("Test vector %d: Failed to decode hex nonce: %s", i, err) 44 | } 45 | keystream, err := hex.DecodeString(v.keystream) 46 | if err != nil { 47 | t.Fatalf("Test vector %d: Failed to decode hex keystream: %s", i, err) 48 | } 49 | var Key, Nonce [16]byte 50 | copy(Key[:], key) 51 | copy(Nonce[:], nonce) 52 | 53 | c := NewCipher(&Nonce, &Key) 54 | 55 | buf := make([]byte, len(keystream)) 56 | 57 | c.XORKeyStream(buf, buf) 58 | if !bytes.Equal(buf, keystream) { 59 | t.Fatalf("Test vector %d: Unexpected keystream:\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(keystream)) 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /hc256/vectors_test.go: -------------------------------------------------------------------------------- 1 | package hc256 2 | 3 | import ( 4 | "bytes" 5 | "encoding/hex" 6 | "testing" 7 | ) 8 | 9 | // Test vectors taken from the HC256 description by Hongjun Wu 10 | // https://eprint.iacr.org/2004/092.pdf 11 | // The byte order was changed: 12 | // 0x8589075b -> 0x5b078985 13 | var vectors256 = []struct { 14 | key, nonce, keystream string 15 | }{ 16 | { 17 | key: "0000000000000000000000000000000000000000000000000000000000000000", 18 | nonce: "0000000000000000000000000000000000000000000000000000000000000000", 19 | keystream: "5b078985d8f6f30d42c5c02fa6b6795153f06534801f89f24e74248b720b4818", 20 | }, 21 | { 22 | key: "0000000000000000000000000000000000000000000000000000000000000000", 23 | nonce: "0100000000000000000000000000000000000000000000000000000000000000", 24 | keystream: "afe2a2bf4f17cee9fec2058bd1b18bb15fc042ee712b3101dd501fc60b082a50", 25 | }, 26 | { 27 | key: "5500000000000000000000000000000000000000000000000000000000000000", 28 | nonce: "0000000000000000000000000000000000000000000000000000000000000000", 29 | keystream: "1c404afe4fe25fed958f9ad1ae36c06f88a65a3cc0abe223aeb3902f420ed3a8", 30 | }, 31 | } 32 | 33 | func TestVectors(t *testing.T) { 34 | for i, v := range vectors256 { 35 | key, err := hex.DecodeString(v.key) 36 | if err != nil { 37 | t.Fatalf("Test vector %d: Failed to decode hex key: %s", i, err) 38 | } 39 | nonce, err := hex.DecodeString(v.nonce) 40 | if err != nil { 41 | t.Fatalf("Test vector %d: Failed to decode hex nonce: %s", i, err) 42 | } 43 | keystream, err := hex.DecodeString(v.keystream) 44 | if err != nil { 45 | t.Fatalf("Test vector %d: Failed to decode hex keystream: %s", i, err) 46 | } 47 | var Key, Nonce [32]byte 48 | copy(Key[:], key) 49 | copy(Nonce[:], nonce) 50 | 51 | c := NewCipher(&Nonce, &Key) 52 | 53 | buf := make([]byte, len(keystream)) 54 | 55 | c.XORKeyStream(buf, buf) 56 | if !bytes.Equal(buf, keystream) { 57 | t.Fatalf("Test vector %d: Unexpected keystream:\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(keystream)) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /skein/constants.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | package skein 5 | 6 | import "github.com/enceve/crypto/skein/threefish" 7 | 8 | const ( 9 | // The blocksize of Skein-512 in bytes. 10 | BlockSize = threefish.BlockSize512 11 | ) 12 | 13 | // The different parameter types 14 | const ( 15 | // CfgKey is the config type for the Key. 16 | CfgKey uint64 = 0 17 | 18 | // CfgConfig is the config type for the configuration. 19 | CfgConfig uint64 = 4 20 | 21 | // CfgPersonal is the config type for the personalization. 22 | CfgPersonal uint64 = 8 23 | 24 | // CfgPublicKey is the config type for the public key. 25 | CfgPublicKey uint64 = 12 26 | 27 | // CfgKeyID is the config type for the key id. 28 | CfgKeyID uint64 = 16 29 | 30 | // CfgNonce is the config type for the nonce. 31 | CfgNonce uint64 = 20 32 | 33 | // CfgMessage is the config type for the message. 34 | CfgMessage uint64 = 48 35 | 36 | // CfgOutput is the config type for the output. 37 | CfgOutput uint64 = 63 38 | 39 | // FirstBlock is the first block flag 40 | FirstBlock uint64 = 1 << 62 41 | 42 | // FinalBlock is the final block flag 43 | FinalBlock uint64 = 1 << 63 44 | 45 | // The skein schema ID = S H A 3 1 0 0 0 46 | SchemaID uint64 = 0x133414853 47 | ) 48 | 49 | // Precomputed chain values for Skein-512 50 | var iv160 = [9]uint64{ 51 | 0x28B81A2AE013BD91, 0xC2F11668B5BDF78F, 0x1760D8F3F6A56F12, 0x4FB747588239904F, 52 | 0x21EDE07F7EAF5056, 0xD908922E63ED70B8, 0xB8EC76FFECCB52FA, 0x01A47BB8A3F27A6E, 53 | 0, 54 | } 55 | 56 | var iv256 = [9]uint64{ 57 | 0xCCD044A12FDB3E13, 0xE83590301A79A9EB, 0x55AEA0614F816E6F, 0x2A2767A4AE9B94DB, 58 | 0xEC06025E74DD7683, 0xE7A436CDC4746251, 0xC36FBAF9393AD185, 0x3EEDBA1833EDFC13, 59 | 0, 60 | } 61 | 62 | var iv384 = [9]uint64{ 63 | 0xA3F6C6BF3A75EF5F, 0xB0FEF9CCFD84FAA4, 0x9D77DD663D770CFE, 0xD798CBF3B468FDDA, 64 | 0x1BC4A6668A0E4465, 0x7ED7D434E5807407, 0x548FC1ACD4EC44D6, 0x266E17546AA18FF8, 65 | 0, 66 | } 67 | 68 | var iv512 = [9]uint64{ 69 | 0x4903ADFF749C51CE, 0x0D95DE399746DF03, 0x8FD1934127C79BCE, 0x9A255629FF352CB1, 70 | 0x5DB62599DF6CA7B0, 0xEABE394CA9D5C3F4, 0x991112C71A75B523, 0xAE18A40B660FCC33, 71 | 0, 72 | } 73 | -------------------------------------------------------------------------------- /skein/threefish/threefish_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // +build !amd64 5 | 6 | package threefish 7 | 8 | func bytesToBlock256(block *[4]uint64, src []byte) { 9 | for i := range block { 10 | j := i * 8 11 | block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | uint64(src[j+3])<<24 | 12 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 13 | } 14 | } 15 | 16 | func block256ToBytes(dst []byte, block *[4]uint64) { 17 | for i, v := range block { 18 | j := i * 8 19 | dst[j] = byte(v) 20 | dst[j+1] = byte(v >> 8) 21 | dst[j+2] = byte(v >> 16) 22 | dst[j+3] = byte(v >> 24) 23 | dst[j+4] = byte(v >> 32) 24 | dst[j+5] = byte(v >> 40) 25 | dst[j+6] = byte(v >> 48) 26 | dst[j+7] = byte(v >> 56) 27 | } 28 | } 29 | 30 | func bytesToBlock512(block *[8]uint64, src []byte) { 31 | for i := range block { 32 | j := i * 8 33 | block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | uint64(src[j+3])<<24 | 34 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 35 | } 36 | } 37 | 38 | func block512ToBytes(dst []byte, block *[8]uint64) { 39 | for i, v := range block { 40 | j := i * 8 41 | dst[j] = byte(v) 42 | dst[j+1] = byte(v >> 8) 43 | dst[j+2] = byte(v >> 16) 44 | dst[j+3] = byte(v >> 24) 45 | dst[j+4] = byte(v >> 32) 46 | dst[j+5] = byte(v >> 40) 47 | dst[j+6] = byte(v >> 48) 48 | dst[j+7] = byte(v >> 56) 49 | } 50 | } 51 | 52 | func bytesToBlock1024(block *[16]uint64, src []byte) { 53 | for i := range block { 54 | j := i * 8 55 | block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | uint64(src[j+3])<<24 | 56 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 57 | } 58 | } 59 | 60 | func block1024ToBytes(dst []byte, block *[16]uint64) { 61 | for i, v := range block { 62 | j := i * 8 63 | dst[j] = byte(v) 64 | dst[j+1] = byte(v >> 8) 65 | dst[j+2] = byte(v >> 16) 66 | dst[j+3] = byte(v >> 24) 67 | dst[j+4] = byte(v >> 32) 68 | dst[j+5] = byte(v >> 40) 69 | dst[j+6] = byte(v >> 48) 70 | dst[j+7] = byte(v >> 56) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dh/ecdh/generic.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package ecdh 5 | 6 | import ( 7 | "crypto/elliptic" 8 | cryptorand "crypto/rand" 9 | "errors" 10 | "io" 11 | "math/big" 12 | ) 13 | 14 | // The same unmarshal as elliptic.Unmarshal but without 15 | // point checking (see Check method) 16 | func unmarshal(curve elliptic.Curve, data []byte) (x, y *big.Int) { 17 | byteLen := (curve.Params().BitSize + 7) >> 3 18 | if len(data) != 1+2*byteLen { 19 | return 20 | } 21 | if data[0] != 4 { // uncompressed form 22 | return 23 | } 24 | x = new(big.Int).SetBytes(data[1 : 1+byteLen]) 25 | y = new(big.Int).SetBytes(data[1+byteLen:]) 26 | return 27 | } 28 | 29 | // GenericCurve creates a new ecdh.KeyExchange with 30 | // generic elliptic.Curve implementations. 31 | func GenericCurve(c elliptic.Curve) KeyExchange { 32 | if c == nil { 33 | panic("ecdh: curve is nil") 34 | } 35 | return genericCurve{curve: c} 36 | } 37 | 38 | type genericCurve struct { 39 | curve elliptic.Curve 40 | } 41 | 42 | func (g genericCurve) GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) { 43 | if rand == nil { 44 | rand = cryptorand.Reader 45 | } 46 | private, x, y, err := elliptic.GenerateKey(g.curve, rand) 47 | if err != nil { 48 | private = nil 49 | return 50 | } 51 | public = elliptic.Marshal(g.curve, x, y) 52 | return 53 | } 54 | 55 | func (g genericCurve) PublicKey(private PrivateKey) (public PublicKey) { 56 | N := g.curve.Params().N 57 | 58 | if new(big.Int).SetBytes(private).Cmp(N) >= 0 { 59 | panic("ecdh: private key cannot used with given curve") 60 | } 61 | 62 | x, y := g.curve.ScalarBaseMult(private) 63 | public = elliptic.Marshal(g.curve, x, y) 64 | return 65 | } 66 | 67 | func (g genericCurve) Check(peersPublic PublicKey) (err error) { 68 | x, y := unmarshal(g.curve, peersPublic) 69 | if !g.curve.IsOnCurve(x, y) { 70 | err = errors.New("peer's public key is not on curve") 71 | } 72 | return 73 | } 74 | 75 | func (g genericCurve) ComputeSecret(private PrivateKey, peersPublic PublicKey) (secret []byte) { 76 | x, y := unmarshal(g.curve, peersPublic) 77 | 78 | sX, _ := g.curve.ScalarMult(x, y, private) 79 | 80 | secret = sX.Bytes() 81 | return 82 | } 83 | -------------------------------------------------------------------------------- /dh/dh_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package dh 5 | 6 | import ( 7 | "crypto/rand" 8 | "fmt" 9 | "testing" 10 | ) 11 | 12 | // A Diffie-Hellman exchange example. 13 | func ExampleKeyExchange() { 14 | // using 2048 bit group 15 | group := RFC3526_2048() 16 | 17 | // Alice 18 | alicePrivate, alicePublic, err := group.GenerateKey(rand.Reader) 19 | if err != nil { 20 | fmt.Printf("Failed to generate alice's private / public key pair: %s", err) 21 | } 22 | 23 | // Bob 24 | bobPrivate, bobPublic, err := group.GenerateKey(rand.Reader) 25 | if err != nil { 26 | fmt.Printf("Failed to generate bob's private / public key pair: %s", err) 27 | } 28 | 29 | secretAlice := group.ComputeSecret(alicePrivate, bobPublic) 30 | secretBob := group.ComputeSecret(bobPrivate, alicePublic) 31 | 32 | if secretAlice.Cmp(secretBob) != 0 { 33 | fmt.Printf("key exchange failed - secrets not equal\nAlice: %v\nBob : %v", secretAlice, secretBob) 34 | } 35 | 36 | fmt.Println("key exchange succeed") 37 | // Output: 38 | // key exchange succeed 39 | } 40 | 41 | func BenchmarkGenerateKey2048(b *testing.B) { 42 | group := RFC3526_2048() 43 | for i := 0; i < b.N; i++ { 44 | _, _, err := group.GenerateKey(rand.Reader) 45 | if err != nil { 46 | b.Fatal("Failed to generate private / public key pair") 47 | } 48 | } 49 | } 50 | 51 | func Benchmark2048(b *testing.B) { 52 | group := RFC3526_2048() 53 | alicePrivate, _, err := group.GenerateKey(rand.Reader) 54 | if err != nil { 55 | b.Fatalf("Failed to generate alice's private / public key: %s", err) 56 | } 57 | _, bobPublic, err := group.GenerateKey(rand.Reader) 58 | if err != nil { 59 | b.Fatalf("Failed to generate bob's private / public key: %s", err) 60 | } 61 | for i := 0; i < b.N; i++ { 62 | group.ComputeSecret(alicePrivate, bobPublic) 63 | } 64 | } 65 | 66 | func Benchmark4096(b *testing.B) { 67 | group := RFC3526_4096() 68 | alicePrivate, _, err := group.GenerateKey(rand.Reader) 69 | if err != nil { 70 | b.Fatalf("Failed to generate alice's private / public key: %s", err) 71 | } 72 | _, bobPublic, err := group.GenerateKey(rand.Reader) 73 | if err != nil { 74 | b.Fatalf("Failed to generate bob's private / public key: %s", err) 75 | } 76 | for i := 0; i < b.N; i++ { 77 | group.ComputeSecret(alicePrivate, bobPublic) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /skein/threefish/threefish_amd64.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // +build amd64 5 | 6 | package threefish 7 | 8 | import "unsafe" 9 | 10 | func bytesToBlock256(block *[4]uint64, src []byte) { 11 | srcPtr := (*[4]uint64)(unsafe.Pointer(&src[0])) 12 | 13 | block[0] = srcPtr[0] 14 | block[1] = srcPtr[1] 15 | block[2] = srcPtr[2] 16 | block[3] = srcPtr[3] 17 | } 18 | 19 | func block256ToBytes(dst []byte, block *[4]uint64) { 20 | dstPtr := (*[4]uint64)(unsafe.Pointer(&dst[0])) 21 | 22 | dstPtr[0] = block[0] 23 | dstPtr[1] = block[1] 24 | dstPtr[2] = block[2] 25 | dstPtr[3] = block[3] 26 | } 27 | 28 | func bytesToBlock512(block *[8]uint64, src []byte) { 29 | srcPtr := (*[8]uint64)(unsafe.Pointer(&src[0])) 30 | 31 | block[0] = srcPtr[0] 32 | block[1] = srcPtr[1] 33 | block[2] = srcPtr[2] 34 | block[3] = srcPtr[3] 35 | block[4] = srcPtr[4] 36 | block[5] = srcPtr[5] 37 | block[6] = srcPtr[6] 38 | block[7] = srcPtr[7] 39 | } 40 | 41 | func block512ToBytes(dst []byte, block *[8]uint64) { 42 | dstPtr := (*[8]uint64)(unsafe.Pointer(&dst[0])) 43 | 44 | dstPtr[0] = block[0] 45 | dstPtr[1] = block[1] 46 | dstPtr[2] = block[2] 47 | dstPtr[3] = block[3] 48 | dstPtr[4] = block[4] 49 | dstPtr[5] = block[5] 50 | dstPtr[6] = block[6] 51 | dstPtr[7] = block[7] 52 | } 53 | 54 | func bytesToBlock1024(block *[16]uint64, src []byte) { 55 | srcPtr := (*[16]uint64)(unsafe.Pointer(&src[0])) 56 | 57 | block[0] = srcPtr[0] 58 | block[1] = srcPtr[1] 59 | block[2] = srcPtr[2] 60 | block[3] = srcPtr[3] 61 | block[4] = srcPtr[4] 62 | block[5] = srcPtr[5] 63 | block[6] = srcPtr[6] 64 | block[7] = srcPtr[7] 65 | block[8] = srcPtr[8] 66 | block[9] = srcPtr[9] 67 | block[10] = srcPtr[10] 68 | block[11] = srcPtr[11] 69 | block[12] = srcPtr[12] 70 | block[13] = srcPtr[13] 71 | block[14] = srcPtr[14] 72 | block[15] = srcPtr[15] 73 | } 74 | 75 | func block1024ToBytes(dst []byte, block *[16]uint64) { 76 | dstPtr := (*[16]uint64)(unsafe.Pointer(&dst[0])) 77 | 78 | dstPtr[0] = block[0] 79 | dstPtr[1] = block[1] 80 | dstPtr[2] = block[2] 81 | dstPtr[3] = block[3] 82 | dstPtr[4] = block[4] 83 | dstPtr[5] = block[5] 84 | dstPtr[6] = block[6] 85 | dstPtr[7] = block[7] 86 | dstPtr[8] = block[8] 87 | dstPtr[9] = block[9] 88 | dstPtr[10] = block[10] 89 | dstPtr[11] = block[11] 90 | dstPtr[12] = block[12] 91 | dstPtr[13] = block[13] 92 | dstPtr[14] = block[14] 93 | dstPtr[15] = block[15] 94 | } 95 | -------------------------------------------------------------------------------- /skein/threefish/threefish.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // Package threefish implements the Threefish tweakable block cipher. 5 | // Threefish is designed to be the core function of the Skein hash function 6 | // family. 7 | // There are three versions of Threefish 8 | // - Threefish256 processes 256 bit blocks 9 | // - Threefish512 processes 512 bit blocks 10 | // - Threefish1024 processes 1024 bit blocks 11 | package threefish 12 | 13 | import ( 14 | "crypto/cipher" 15 | 16 | "github.com/enceve/crypto" 17 | ) 18 | 19 | const ( 20 | // The size of the tweak in bytes. 21 | TweakSize = 16 22 | // C240 is the key schedule constant 23 | C240 = 0x1bd11bdaa9fc1a22 24 | // The block size of Threefish-256 in bytes. 25 | BlockSize256 = 32 26 | // The block size of Threefish-512 in bytes. 27 | BlockSize512 = 64 28 | // The block size of Threefish-1024 in bytes. 29 | BlockSize1024 = 128 30 | ) 31 | 32 | // NewCipher returns a cipher.Block implementing the Threefish cipher. 33 | // The length of the key must be 32, 64 or 128 byte. 34 | // The length of the tweak must be TweakSize. 35 | // The returned cipher implements: 36 | // - Threefish-256 - if len(key) = 32 37 | // - Threefish-512 - if len(key) = 64 38 | // - Threefish-1024 - if len(key) = 128 39 | func NewCipher(tweak *[TweakSize]byte, key []byte) (cipher.Block, error) { 40 | switch k := len(key); k { 41 | default: 42 | return nil, crypto.KeySizeError(k) 43 | case BlockSize256: 44 | return newCipher256(tweak, key), nil 45 | case BlockSize512: 46 | return newCipher512(tweak, key), nil 47 | case BlockSize1024: 48 | return newCipher1024(tweak, key), nil 49 | } 50 | } 51 | 52 | // Increment the tweak by the ctr argument. 53 | // Skein can consume messages up to 2^96 -1 bytes. 54 | func IncrementTweak(tweak *[3]uint64, ctr uint64) { 55 | t0 := tweak[0] 56 | tweak[0] += ctr 57 | if tweak[0] < t0 { 58 | t1 := tweak[1] 59 | tweak[1] = (t1 + 1) & 0x00000000FFFFFFFF 60 | } 61 | } 62 | 63 | // The threefish-256 tweakable blockcipher 64 | type threefish256 struct { 65 | keys [5]uint64 66 | tweak [3]uint64 67 | } 68 | 69 | func (t *threefish256) BlockSize() int { return BlockSize256 } 70 | 71 | // The threefish-512 tweakable blockcipher 72 | type threefish512 struct { 73 | keys [9]uint64 74 | tweak [3]uint64 75 | } 76 | 77 | func (t *threefish512) BlockSize() int { return BlockSize512 } 78 | 79 | // The threefish-1024 tweakable blockcipher 80 | type threefish1024 struct { 81 | keys [17]uint64 82 | tweak [3]uint64 83 | } 84 | 85 | func (t *threefish1024) BlockSize() int { return BlockSize1024 } 86 | -------------------------------------------------------------------------------- /poly1305/poly1305_amd64.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // +build amd64,!gccgo,!appengine 5 | 6 | package poly1305 7 | 8 | import "unsafe" 9 | 10 | func initialize(r *[5]uint32, pad *[4]uint32, key *[32]byte) { 11 | k0 := *(*uint64)(unsafe.Pointer(&key[0])) 12 | k1 := *(*uint64)(unsafe.Pointer(&key[8])) 13 | 14 | r[0] = uint32(k0) & 0x3ffffff 15 | r[1] = uint32(k0>>26) & 0x3ffff03 16 | r[2] = (uint32((k0>>48)|(k1<<16)) >> 4) & 0x3ffc0ff 17 | r[3] = uint32(k1>>14) & 0x3f03fff 18 | r[4] = uint32(k1>>40) & 0x00fffff 19 | 20 | pad[0] = *(*uint32)(unsafe.Pointer(&key[16])) 21 | pad[1] = *(*uint32)(unsafe.Pointer(&key[20])) 22 | pad[2] = *(*uint32)(unsafe.Pointer(&key[24])) 23 | pad[3] = *(*uint32)(unsafe.Pointer(&key[28])) 24 | } 25 | 26 | func core(msg []byte, flag uint32, h, r *[5]uint32) { 27 | h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] 28 | r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4]) 29 | s1, s2, s3, s4 := uint64(r[1]*5), uint64(r[2]*5), uint64(r[3]*5), uint64(r[4]*5) 30 | 31 | var d0, d1, d2, d3, d4 uint64 32 | var m0, m1 uint64 33 | for i := 0; i < len(msg); i += TagSize { 34 | m0 = *(*uint64)(unsafe.Pointer(&msg[i])) 35 | m1 = *(*uint64)(unsafe.Pointer(&msg[i+8])) 36 | 37 | // h += m 38 | h0 += uint32(m0) & 0x3ffffff 39 | h1 += uint32(m0>>26) & 0x3ffffff 40 | h2 += (uint32((m0>>48)|(m1<<16)) >> 4) & 0x3ffffff 41 | h3 += uint32(m1>>14) & 0x3ffffff 42 | h4 += uint32(m1>>40) | flag 43 | 44 | // h *= r 45 | d0 = (uint64(h0) * r0) + (uint64(h1) * s4) + (uint64(h2) * s3) + (uint64(h3) * s2) + (uint64(h4) * s1) 46 | d1 = (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * s4) + (uint64(h3) * s3) + (uint64(h4) * s2) 47 | d2 = (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * s4) + (uint64(h4) * s3) 48 | d3 = (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * s4) 49 | d4 = (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0) 50 | 51 | // h %= p 52 | h0 = uint32(d0) & 0x3ffffff 53 | h1 = uint32(d1) & 0x3ffffff 54 | h2 = uint32(d2) & 0x3ffffff 55 | h3 = uint32(d3) & 0x3ffffff 56 | h4 = uint32(d4) & 0x3ffffff 57 | 58 | h0 += uint32(d4>>26) * 5 59 | h1 += h0 >> 26 60 | h0 = h0 & 0x3ffffff 61 | } 62 | h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4 63 | } 64 | 65 | func extractHash(tag *[16]byte, h0, h1, h2, h3 uint32) { 66 | tagPtr := (*[2]uint64)(unsafe.Pointer(&tag[0])) 67 | tagPtr[0] = uint64(h0) | (uint64(h1) << 32) 68 | tagPtr[1] = uint64(h2) | (uint64(h3) << 32) 69 | } 70 | -------------------------------------------------------------------------------- /cipher/eax_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package cipher 5 | 6 | import ( 7 | "crypto/aes" 8 | "testing" 9 | ) 10 | 11 | // Benchmarks 12 | 13 | func BenchmarkSeal_64B(b *testing.B) { 14 | block, err := aes.NewCipher(make([]byte, 16)) 15 | if err != nil { 16 | b.Fatalf("Failed to create AES-128 instance: %s", err) 17 | } 18 | nonce := make([]byte, aes.BlockSize) 19 | c, err := NewEAX(block, block.BlockSize()) 20 | if err != nil { 21 | b.Fatalf("Failed to create AES-128-EAX instance: %s", err) 22 | } 23 | msg := make([]byte, 64) 24 | dst := make([]byte, len(msg)+aes.BlockSize) 25 | data := make([]byte, 8) 26 | b.SetBytes(64) 27 | for i := 0; i < b.N; i++ { 28 | dst = c.Seal(dst, nonce, msg, data) 29 | } 30 | } 31 | 32 | func BenchmarkSeal_1K(b *testing.B) { 33 | block, err := aes.NewCipher(make([]byte, 16)) 34 | if err != nil { 35 | b.Fatalf("Failed to create AES-128 instance: %s", err) 36 | } 37 | nonce := make([]byte, aes.BlockSize) 38 | c, err := NewEAX(block, block.BlockSize()) 39 | if err != nil { 40 | b.Fatalf("Failed to create AES-128-EAX instance: %s", err) 41 | } 42 | msg := make([]byte, 1024) 43 | dst := make([]byte, len(msg)+aes.BlockSize) 44 | data := make([]byte, 8) 45 | b.SetBytes(1024) 46 | for i := 0; i < b.N; i++ { 47 | dst = c.Seal(dst, nonce, msg, data) 48 | } 49 | } 50 | 51 | func BenchmarkOpen_64B(b *testing.B) { 52 | block, err := aes.NewCipher(make([]byte, 16)) 53 | if err != nil { 54 | b.Fatalf("Failed to create AES-128 instance: %s", err) 55 | } 56 | nonce := make([]byte, aes.BlockSize) 57 | c, err := NewEAX(block, block.BlockSize()) 58 | if err != nil { 59 | b.Fatalf("Failed to create AES-128-EAX instance: %s", err) 60 | } 61 | msg := make([]byte, 64) 62 | dst := make([]byte, len(msg)) 63 | ciphertext := make([]byte, len(msg)+aes.BlockSize) 64 | data := make([]byte, 8) 65 | ciphertext = c.Seal(ciphertext, nonce, msg, data) 66 | b.SetBytes(64) 67 | for i := 0; i < b.N; i++ { 68 | dst, _ = c.Open(dst, nonce, ciphertext, data) 69 | } 70 | } 71 | 72 | func BenchmarkOpen_1K(b *testing.B) { 73 | block, err := aes.NewCipher(make([]byte, 16)) 74 | if err != nil { 75 | b.Fatalf("Failed to create AES-128 instance: %s", err) 76 | } 77 | nonce := make([]byte, aes.BlockSize) 78 | c, err := NewEAX(block, block.BlockSize()) 79 | if err != nil { 80 | b.Fatalf("Failed to create AES-128-EAX instance: %s", err) 81 | } 82 | msg := make([]byte, 1024) 83 | dst := make([]byte, len(msg)) 84 | ciphertext := make([]byte, len(msg)+aes.BlockSize) 85 | data := make([]byte, 8) 86 | ciphertext = c.Seal(ciphertext, nonce, msg, data) 87 | b.SetBytes(1024) 88 | for i := 0; i < b.N; i++ { 89 | dst, _ = c.Open(dst, nonce, ciphertext, data) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /cmac/vectors_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package cmac 5 | 6 | import ( 7 | "bytes" 8 | "crypto/aes" 9 | "encoding/hex" 10 | "testing" 11 | ) 12 | 13 | // Test vectors for CMac-AES from NIST 14 | // http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf 15 | // Appendix D 16 | var testVectors = []struct { 17 | key, msg, hash string 18 | }{ 19 | // AES-128 vectors 20 | { 21 | key: "2b7e151628aed2a6abf7158809cf4f3c", 22 | msg: "", 23 | hash: "bb1d6929e95937287fa37d129b756746", 24 | }, 25 | { 26 | key: "2b7e151628aed2a6abf7158809cf4f3c", 27 | msg: "6bc1bee22e409f96e93d7e117393172a", 28 | hash: "070a16b46b4d4144f79bdd9dd04a287c", 29 | }, 30 | { 31 | key: "2b7e151628aed2a6abf7158809cf4f3c", 32 | msg: "6bc1bee22e409f96e93d7e117393172a" + 33 | "ae2d8a571e03ac9c9eb76fac45af8e51" + 34 | "30c81c46a35ce411", 35 | hash: "dfa66747de9ae63030ca32611497c827", 36 | }, 37 | // AES-256 vectors 38 | { 39 | key: "603deb1015ca71be2b73aef0857d7781" + 40 | "1f352c073b6108d72d9810a30914dff4", 41 | msg: "", 42 | hash: "028962f61b7bf89efc6b551f4667d983", 43 | }, 44 | { 45 | key: "603deb1015ca71be2b73aef0857d7781" + 46 | "1f352c073b6108d72d9810a30914dff4", 47 | msg: "6bc1bee22e409f96e93d7e117393172a", 48 | hash: "28a7023f452e8f82bd4bf28d8c37c35c", 49 | }, 50 | { 51 | key: "603deb1015ca71be2b73aef0857d7781" + 52 | "1f352c073b6108d72d9810a30914dff4", 53 | msg: "6bc1bee22e409f96e93d7e117393172a" + 54 | "ae2d8a571e03ac9c9eb76fac45af8e51" + 55 | "30c81c46a35ce411", 56 | hash: "aaf3d8f1de5640c232f5b169b9c911e6", 57 | }, 58 | } 59 | 60 | func TestVectors(t *testing.T) { 61 | for i, v := range testVectors { 62 | key, err := hex.DecodeString(v.key) 63 | if err != nil { 64 | t.Fatalf("Test vector %d: Failed to decode hex key: %s", i, err) 65 | } 66 | msg, err := hex.DecodeString(v.msg) 67 | if err != nil { 68 | t.Fatalf("Test vector %d: Failed to decode hex msg: %s", i, err) 69 | } 70 | hash, err := hex.DecodeString(v.hash) 71 | if err != nil { 72 | t.Fatalf("Test vector %d: Failed to decode hex hash: %s", i, err) 73 | } 74 | 75 | c, err := aes.NewCipher(key) 76 | if err != nil { 77 | t.Fatalf("Test vector %d: Failed to create AES instance: %s", i, err) 78 | } 79 | h, err := New(c) 80 | if err != nil { 81 | t.Fatalf("Test vector %d: Failed to create CMac instance: %s", i, err) 82 | } 83 | _, err = h.Write(msg) 84 | if err != nil { 85 | t.Fatalf("Test vector %d: CMac write failed: %s", i, err) 86 | } 87 | sum := h.Sum(nil) 88 | if !bytes.Equal(sum, hash) { 89 | t.Fatalf("Test vector %d : MAC does not match:\nFound: %v\nExpected: %v", i, hex.EncodeToString(sum), hex.EncodeToString(hash)) 90 | } 91 | if !Verify(hash, msg, c) { 92 | t.Fatalf("Test vector %d: verification of MAC failed", i) 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /pad/pad.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package pad implements some padding schemes 5 | // for block ciphers. 6 | package pad 7 | 8 | import ( 9 | cryptorand "crypto/rand" 10 | "errors" 11 | "io" 12 | ) 13 | 14 | var badPadErr = errors.New("bad padding bytes") 15 | var notMulOfBlockErr = errors.New("src is not a multiply of the padding blocksize") 16 | 17 | // The Padding interface represents a padding scheme. 18 | type Padding interface { 19 | 20 | // BlockSize returns the block size of the padding. 21 | BlockSize() int 22 | 23 | // Returns the overhead, the padding will cause 24 | // by padding the given byte slice. The overhead 25 | // will always be between 1 and BlockSize() inclusively. 26 | Overhead(src []byte) int 27 | 28 | // Pads the last (may incomplete) block of the src slice 29 | // to a padded and complete block, appends the padding bytes 30 | // to the src slice and returns this slice. 31 | // The length of the returned slice is len(src) + Overhead(src) 32 | Pad(src []byte) []byte 33 | 34 | // Takes a slice and tries to remove the padding bytes 35 | // form the last block. Therefore the length of the 36 | // src argument must be a multiply of the blocksize. 37 | // If the returned error is nil, the padding could be 38 | // removed successfully. The returned slice holds the 39 | // unpadded src bytes. 40 | Unpad(src []byte) ([]byte, error) 41 | } 42 | 43 | // NewX923 returns a new pad.Padding implementing the ANSI X.923 scheme. 44 | // Only block sizes between 1 and 255 are valid. 45 | func NewX923(blocksize int) Padding { 46 | if blocksize < 1 || blocksize > 255 { 47 | panic("illegal blocksize - size must between 0 and 256") 48 | } 49 | pad := x923Padding(blocksize) 50 | return pad 51 | } 52 | 53 | // NewPKCS7 returns a new pad.Padding implementing the PKCS 7 scheme. 54 | // Only block sizes between 1 and 255 are valid. 55 | func NewPKCS7(blocksize int) Padding { 56 | if blocksize < 1 || blocksize > 255 { 57 | panic("illegal blocksize - size must between 0 and 256") 58 | } 59 | pad := pkcs7Padding(blocksize) 60 | return pad 61 | } 62 | 63 | // NewISO10126 returns a new pad.Padding, which uses the padding scheme 64 | // described in ISO 10126. The padding bytes are taken 65 | // form the given rand argument. If rand is nil, crypto/rand will be used. 66 | // Only block sizes between 1 and 255 are valid. 67 | func NewISO10126(blocksize int, rand io.Reader) Padding { 68 | if blocksize < 1 || blocksize > 255 { 69 | panic("illegal blocksize - size must between 0 and 256") 70 | } 71 | pad := new(isoPadding) 72 | pad.blocksize = blocksize 73 | if rand == nil { 74 | pad.random = cryptorand.Reader 75 | } else { 76 | pad.random = rand 77 | } 78 | return pad 79 | } 80 | 81 | // Returns the overhead for a given slice with a 82 | // specific block size. 83 | func overhead(blocksize int, src []byte) int { 84 | return blocksize - (len(src) % blocksize) 85 | } 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://api.travis-ci.org/enceve/crypto.svg?branch=master)](https://api.travis-ci.org/enceve/crypto) 2 | [![Godoc Reference](https://godoc.org/github.com/enceve/crypto?status.svg)](https://godoc.org/github.com/enceve/crypto) 3 | [![Go Report](https://goreportcard.com/badge/github.com/enceve/crypto)](https://goreportcard.com/report/github.com/enceve/crypto) 4 | 5 | ## The *crypto* package 6 | 7 | **Notice**: 8 | The public API is not stable and backward compatibility is currently not guaranteed. 9 | This code should currently NOT used in productive environments! 10 | 11 | ### Introduction 12 | 13 | The `crypto` package implements some additional cryptographic functionality, currently not supported by the standard or additional [golang packages](https://golang.org/pkg/ "offical golang packages"). 14 | This repository should not replace or somehow compete with the [golang crypto packages](https://godoc.org/golang.org/x/crypto "Additional golang crypto packages"). Rather, this package should supplement the official and additional golang cryptographic. 15 | 16 | **Currently implemented**: 17 | - The [BLAKE2b and BLAKE2s](https://blake2.net/ "offical BLAKE2 site") hash functions. 18 | - The [Camellia](https://tools.ietf.org/html/rfc3713 "RFC 3713") block cipher. 19 | - The [ChaCha20](https://tools.ietf.org/html/rfc7539 "RFC 7539") stream cipher. 20 | - The [CMac](https://tools.ietf.org/html/rfc4493 "RFC 4493") message authentication code (OMAC1). 21 | - The [HC-128 and HC-256](https://en.wikipedia.org/wiki/HC-256 "Wikipedia") stream ciphers 22 | - The [Poly1305](https://tools.ietf.org/html/rfc7539 "RFC 7539") message authentication code. 23 | - The [Serpent](https://www.cl.cam.ac.uk/~rja14/serpent.html "offical Serpent site") block cipher. 24 | - The [SipHash](https://131002.net/siphash/ "offical SipHash site") message authentication code. 25 | - The [Skein](http://skein-hash.info/ "offical Skein site") hash function. 26 | - The [Threefish](http://skein-hash.info/ "offical Skein/Threefish site") tweakable block cipher. 27 | - The [Diffie-Hellman](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange "Wikipedia") and [ECDH](https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman "Wikipedia") key exchange. 28 | - The [EAX](https://en.wikipedia.org/wiki/EAX_mode "Wikipedia") AEAD block cipher mode. 29 | - Some [Padding](https://en.wikipedia.org/wiki/Padding_%28cryptography%29 "Wikipedia") schemes for block ciphers. 30 | 31 | ### Aim 32 | 33 | The aim of this project / repository is a powerful, flexible and easy to use cryptographic library, 34 | which can be easily integrated into Go applications. 35 | 36 | ### Installation 37 | 38 | Install in your GOPATH: `go get -u github.com/enceve/crypto` 39 | Install Dependencies: `go get -u golang.org/x/crypto` 40 | 41 | ### Contribute 42 | 43 | First of all: **Contributions are welcome!** 44 | 45 | If you have an idea or found a bug - please raise an issue. If you want to add functionality - as usual on github send a pull request. 46 | -------------------------------------------------------------------------------- /serpent/vectors_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package serpent 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | func fromHex(s string) []byte { 13 | b, err := hex.DecodeString(s) 14 | if err != nil { 15 | panic(err) 16 | } 17 | return b 18 | } 19 | 20 | // Test vectors for serpent 21 | var vectors = []struct { 22 | key, plaintext, ciphertext string 23 | }{ 24 | // test vectors for 128 bit key from 25 | // http://www.cs.technion.ac.il/~biham/Reports/Serpent/Serpent-128-128.verified.test-vectors 26 | { // Set 1, vector# 0 27 | key: "80000000000000000000000000000000", 28 | plaintext: "00000000000000000000000000000000", 29 | ciphertext: "264E5481EFF42A4606ABDA06C0BFDA3D", 30 | }, 31 | { // Set 1, vector# 1 32 | key: "40000000000000000000000000000000", 33 | plaintext: "00000000000000000000000000000000", 34 | ciphertext: "4A231B3BC727993407AC6EC8350E8524", 35 | }, 36 | // test vectors for 192 bit key from 37 | // http://www.cs.technion.ac.il/~biham/Reports/Serpent/Serpent-192-128.verified.test-vectors 38 | { // Set 1, vector# 0 39 | key: "800000000000000000000000000000000000000000000000", 40 | plaintext: "00000000000000000000000000000000", 41 | ciphertext: "9E274EAD9B737BB21EFCFCA548602689", 42 | }, 43 | { // Set 1, vector# 3 44 | key: "100000000000000000000000000000000000000000000000", 45 | plaintext: "00000000000000000000000000000000", 46 | ciphertext: "BEC1E37824CF721E5D87F6CB4EBFB9BE", 47 | }, 48 | // test vectors for 256 bit key from 49 | // http://www.cs.technion.ac.il/~biham/Reports/Serpent/Serpent-256-128.verified.test-vectors 50 | { // Set 3, vector# 1 51 | key: "0101010101010101010101010101010101010101010101010101010101010101", 52 | plaintext: "01010101010101010101010101010101", 53 | ciphertext: "EC9723B15B2A6489F84C4524FFFC2748", 54 | }, 55 | { // Set 3, vector# 2 56 | key: "0202020202020202020202020202020202020202020202020202020202020202", 57 | plaintext: "02020202020202020202020202020202", 58 | ciphertext: "1187F485538514476184E567DA0421C7", 59 | }, 60 | } 61 | 62 | // Tests all serpent test vectors. 63 | func TestVectors(t *testing.T) { 64 | for i, v := range vectors { 65 | key := fromHex(v.key) 66 | plaintext := fromHex(v.plaintext) 67 | ciphertext := fromHex(v.ciphertext) 68 | c, err := NewCipher(key) 69 | if err != nil { 70 | t.Fatalf("Test vector %d: Failed to create cipher instance: %s", i, err) 71 | } 72 | 73 | buf := make([]byte, BlockSize) 74 | 75 | c.Encrypt(buf, plaintext) 76 | if !bytes.Equal(ciphertext, buf) { 77 | t.Fatalf("Test vector %d:\nEncryption failed\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(ciphertext)) 78 | } 79 | c.Decrypt(buf, buf) 80 | if !bytes.Equal(plaintext, buf) { 81 | t.Fatalf("Test vector %d:\nDecryption failed\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(plaintext)) 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /siphash/siphash_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | // +build !amd64 appengine gccgo 4 | 5 | package siphash 6 | 7 | func finalize(hVal *[4]uint64, block *[TagSize]byte) uint64 { 8 | core(hVal, block[:]) 9 | 10 | v0, v1, v2, v3 := hVal[0], hVal[1], hVal[2], hVal[3] 11 | v2 ^= 0xff 12 | 13 | // Round 1. 14 | v0 += v1 15 | v1 = v1<<13 | v1>>(64-13) 16 | v1 ^= v0 17 | v0 = v0<<32 | v0>>(64-32) 18 | 19 | v2 += v3 20 | v3 = v3<<16 | v3>>(64-16) 21 | v3 ^= v2 22 | 23 | v0 += v3 24 | v3 = v3<<21 | v3>>(64-21) 25 | v3 ^= v0 26 | 27 | v2 += v1 28 | v1 = v1<<17 | v1>>(64-17) 29 | v1 ^= v2 30 | v2 = v2<<32 | v2>>(64-32) 31 | 32 | // Round 2. 33 | v0 += v1 34 | v1 = v1<<13 | v1>>(64-13) 35 | v1 ^= v0 36 | v0 = v0<<32 | v0>>(64-32) 37 | 38 | v2 += v3 39 | v3 = v3<<16 | v3>>(64-16) 40 | v3 ^= v2 41 | 42 | v0 += v3 43 | v3 = v3<<21 | v3>>(64-21) 44 | v3 ^= v0 45 | 46 | v2 += v1 47 | v1 = v1<<17 | v1>>(64-17) 48 | v1 ^= v2 49 | v2 = v2<<32 | v2>>(64-32) 50 | 51 | // Round 3. 52 | v0 += v1 53 | v1 = v1<<13 | v1>>(64-13) 54 | v1 ^= v0 55 | v0 = v0<<32 | v0>>(64-32) 56 | 57 | v2 += v3 58 | v3 = v3<<16 | v3>>(64-16) 59 | v3 ^= v2 60 | 61 | v0 += v3 62 | v3 = v3<<21 | v3>>(64-21) 63 | v3 ^= v0 64 | 65 | v2 += v1 66 | v1 = v1<<17 | v1>>(64-17) 67 | v1 ^= v2 68 | v2 = v2<<32 | v2>>(64-32) 69 | 70 | // Round 4. 71 | v0 += v1 72 | v1 = v1<<13 | v1>>(64-13) 73 | v1 ^= v0 74 | v0 = v0<<32 | v0>>(64-32) 75 | 76 | v2 += v3 77 | v3 = v3<<16 | v3>>(64-16) 78 | v3 ^= v2 79 | 80 | v0 += v3 81 | v3 = v3<<21 | v3>>(64-21) 82 | v3 ^= v0 83 | 84 | v2 += v1 85 | v1 = v1<<17 | v1>>(64-17) 86 | v1 ^= v2 87 | v2 = v2<<32 | v2>>(64-32) 88 | 89 | return v0 ^ v1 ^ v2 ^ v3 90 | } 91 | 92 | func core(hVal *[4]uint64, msg []byte) { 93 | v0, v1, v2, v3 := hVal[0], hVal[1], hVal[2], hVal[3] 94 | 95 | for i := 0; i < len(msg); i += TagSize { 96 | m := uint64(msg[i]) | uint64(msg[i+1])<<8 | uint64(msg[i+2])<<16 | uint64(msg[i+3])<<24 | 97 | uint64(msg[i+4])<<32 | uint64(msg[i+5])<<40 | uint64(msg[i+6])<<48 | uint64(msg[i+7])<<56 98 | 99 | v3 ^= m 100 | 101 | // Round 1. 102 | v0 += v1 103 | v1 = v1<<13 | v1>>(64-13) 104 | v1 ^= v0 105 | v0 = v0<<32 | v0>>(64-32) 106 | 107 | v2 += v3 108 | v3 = v3<<16 | v3>>(64-16) 109 | v3 ^= v2 110 | 111 | v0 += v3 112 | v3 = v3<<21 | v3>>(64-21) 113 | v3 ^= v0 114 | 115 | v2 += v1 116 | v1 = v1<<17 | v1>>(64-17) 117 | v1 ^= v2 118 | v2 = v2<<32 | v2>>(64-32) 119 | 120 | // Round 2. 121 | v0 += v1 122 | v1 = v1<<13 | v1>>(64-13) 123 | v1 ^= v0 124 | v0 = v0<<32 | v0>>(64-32) 125 | 126 | v2 += v3 127 | v3 = v3<<16 | v3>>(64-16) 128 | v3 ^= v2 129 | 130 | v0 += v3 131 | v3 = v3<<21 | v3>>(64-21) 132 | v3 ^= v0 133 | 134 | v2 += v1 135 | v1 = v1<<17 | v1>>(64-17) 136 | v1 ^= v2 137 | v2 = v2<<32 | v2>>(64-32) 138 | 139 | v0 ^= m 140 | } 141 | 142 | hVal[0], hVal[1], hVal[2], hVal[3] = v0, v1, v2, v3 143 | } 144 | -------------------------------------------------------------------------------- /chacha20/chacha/chacha_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package chacha 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | var recFail = func(t *testing.T, msg string) { 13 | if err := recover(); err == nil { 14 | t.Fatalf("Expected error: %s", msg) 15 | } 16 | } 17 | 18 | func TestNewCipher(t *testing.T) { 19 | mustFail := func(t *testing.T, msg string, nonce *[12]byte, key *[32]byte, rounds int) { 20 | defer recFail(t, msg) 21 | NewCipher(nonce, key, rounds) 22 | } 23 | 24 | key := new([32]byte) 25 | nonce := new([12]byte) 26 | 27 | mustFail(t, "rounds is 0", nonce, key, 0) 28 | 29 | mustFail(t, "rounds is not even", nonce, key, 21) 30 | } 31 | 32 | func TestSetCounter(t *testing.T) { 33 | var key [32]byte 34 | var nonce [12]byte 35 | for i := range key { 36 | key[i] = byte(i) 37 | } 38 | buf0, buf1 := make([]byte, 128), make([]byte, 128) 39 | 40 | c := NewCipher(&nonce, &key, 20) 41 | c.XORKeyStream(buf0[:1], buf0[:1]) 42 | c.SetCounter(20) 43 | c.XORKeyStream(buf0[1:], buf0[1:]) 44 | 45 | XORKeyStream(buf1[:1], buf1[:1], &nonce, &key, 0, 20) 46 | XORKeyStream(buf1[1:], buf1[1:], &nonce, &key, 20, 20) 47 | 48 | if !bytes.Equal(buf0, buf1) { 49 | t.Fatalf("XORKeyStream differ from chacha.XORKeyStream\n XORKeyStream: %s \n chacha.XORKeyStream: %s", hex.EncodeToString(buf1), hex.EncodeToString(buf0)) 50 | } 51 | } 52 | 53 | func TestXORKeyStream(t *testing.T) { 54 | var key [32]byte 55 | var nonce [12]byte 56 | for i := range key { 57 | key[i] = byte(i) 58 | } 59 | buf0, buf1 := make([]byte, 256), make([]byte, 256) 60 | 61 | c := NewCipher(&nonce, &key, 20) 62 | c.XORKeyStream(buf0[:1], buf0[:1]) 63 | c.XORKeyStream(buf0[1:65], buf0[1:65]) 64 | c.XORKeyStream(buf0[65:193], buf0[65:193]) 65 | c.XORKeyStream(buf0[193:200], buf0[193:200]) 66 | c.XORKeyStream(buf0[200:], buf0[200:]) 67 | 68 | XORKeyStream(buf1, buf1, &nonce, &key, 0, 20) 69 | 70 | if !bytes.Equal(buf0, buf1) { 71 | t.Fatalf("XORKeyStream differ from chacha.XORKeyStream\n XORKeyStream: %s \n chacha.XORKeyStream: %s", hex.EncodeToString(buf1), hex.EncodeToString(buf0)) 72 | } 73 | } 74 | 75 | func TestXORKeyStreamPanic(t *testing.T) { 76 | mustFail := func(t *testing.T, msg string, dst, src []byte, nonce *[12]byte, key *[32]byte, counter uint32, rounds int) { 77 | defer recFail(t, msg) 78 | XORKeyStream(dst, src, nonce, key, counter, rounds) 79 | } 80 | 81 | key := new([32]byte) 82 | nonce := new([12]byte) 83 | src, dst := make([]byte, 65), make([]byte, 65) 84 | 85 | mustFail(t, "rounds is 0", dst, src, nonce, key, 0, 0) 86 | 87 | mustFail(t, "rounds is not even", dst, src, nonce, key, 0, 21) 88 | 89 | mustFail(t, "len(dst) < len(src)", dst[:len(src)-1], src, nonce, key, 0, 20) 90 | 91 | c := NewCipher(nonce, key, 20) 92 | 93 | mustFail2 := func(t *testing.T, msg string, dst, src []byte) { 94 | defer recFail(t, msg) 95 | c.XORKeyStream(dst, src) 96 | } 97 | 98 | mustFail2(t, "len(dst) < len(src)", dst[:len(src)-1], src) 99 | 100 | } 101 | -------------------------------------------------------------------------------- /siphash/siphash.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package siphash implements a hash / MAC function 5 | // developed Jean-Philippe Aumasson and Daniel J Bernstein 6 | // in 2012. SipHash computes 64-bit message authentication 7 | // code from a variable-length message and a 128-bit secret 8 | // key. It was designed to be efficient even for short inputs, 9 | // with performance comparable to non-cryptographic hash 10 | // functions. This package implements SipHash with the 11 | // recommended parameters: c = 2 and d = 4. 12 | package siphash 13 | 14 | import "crypto/subtle" 15 | 16 | // The size of the SipHash authentication tag in bytes. 17 | const TagSize = 8 18 | 19 | // The four initialization constants 20 | const ( 21 | c0 = uint64(0x736f6d6570736575) 22 | c1 = uint64(0x646f72616e646f6d) 23 | c2 = uint64(0x6c7967656e657261) 24 | c3 = uint64(0x7465646279746573) 25 | ) 26 | 27 | // Verify checks whether the given sum is equal to the 28 | // computed checksum of msg. This function returns true 29 | // if and only if the computed checksum is equal to the 30 | // given sum. 31 | func Verify(sum *[TagSize]byte, msg []byte, key *[16]byte) bool { 32 | var out [TagSize]byte 33 | Sum(&out, msg, key) 34 | return subtle.ConstantTimeCompare(sum[:], out[:]) == 1 35 | } 36 | 37 | // The siphash hash struct implementing hash.Hash 38 | type hashFunc struct { 39 | hVal [4]uint64 40 | key [2]uint64 41 | block [TagSize]byte 42 | off int 43 | ctr byte 44 | } 45 | 46 | func (h *hashFunc) BlockSize() int { return TagSize } 47 | 48 | func (h *hashFunc) Size() int { return TagSize } 49 | 50 | func (h *hashFunc) Reset() { 51 | h.hVal[0] = h.key[0] ^ c0 52 | h.hVal[1] = h.key[1] ^ c1 53 | h.hVal[2] = h.key[0] ^ c2 54 | h.hVal[3] = h.key[1] ^ c3 55 | 56 | h.off = 0 57 | h.ctr = 0 58 | } 59 | 60 | func (h *hashFunc) Write(p []byte) (int, error) { 61 | n := len(p) 62 | h.ctr += byte(n) 63 | 64 | if h.off > 0 { 65 | dif := TagSize - h.off 66 | if n > dif { 67 | h.off += copy(h.block[h.off:], p[:dif]) 68 | p = p[dif:] 69 | core(&(h.hVal), h.block[:]) 70 | h.off = 0 71 | } else { 72 | h.off += copy(h.block[h.off:], p) 73 | return n, nil 74 | } 75 | } 76 | 77 | if nn := len(p); nn >= TagSize { 78 | nn &= (^(TagSize - 1)) 79 | core(&(h.hVal), p[:nn]) 80 | p = p[nn:] 81 | } 82 | 83 | if len(p) > 0 { 84 | h.off = copy(h.block[:], p) 85 | } 86 | return n, nil 87 | } 88 | 89 | func (h *hashFunc) Sum64() uint64 { 90 | hVal := h.hVal 91 | block := h.block 92 | for i := h.off; i < TagSize-1; i++ { 93 | block[i] = 0 94 | } 95 | block[7] = h.ctr 96 | return finalize(&hVal, &block) 97 | } 98 | 99 | func (h *hashFunc) Sum(b []byte) []byte { 100 | r := h.Sum64() 101 | 102 | var out [TagSize]byte 103 | out[0] = byte(r) 104 | out[1] = byte(r >> 8) 105 | out[2] = byte(r >> 16) 106 | out[3] = byte(r >> 24) 107 | out[4] = byte(r >> 32) 108 | out[5] = byte(r >> 40) 109 | out[6] = byte(r >> 48) 110 | out[7] = byte(r >> 56) 111 | return append(b, out[:]...) 112 | } 113 | -------------------------------------------------------------------------------- /skein/skein1024/skein.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // Package skein1024 implements the Skein1024 hash function 5 | // based on the Threefish1024 tweakable block cipher. 6 | package skein1024 7 | 8 | import ( 9 | "hash" 10 | 11 | "github.com/enceve/crypto/skein" 12 | ) 13 | 14 | // Sum512 computes the 512 bit Skein1024 checksum (or MAC if key is set) of msg 15 | // and writes it to out. The key is optional and can be nil. 16 | func Sum512(out *[64]byte, msg, key []byte) { 17 | var out1024 [128]byte 18 | 19 | s := new(hashFunc) 20 | s.initialize(64, &skein.Config{Key: key}) 21 | 22 | s.Write(msg) 23 | 24 | s.finalizeHash() 25 | 26 | s.output(&out1024, 0) 27 | copy(out[:], out1024[:64]) 28 | } 29 | 30 | // Sum384 computes the 384 bit Skein1024 checksum (or MAC if key is set) of msg 31 | // and writes it to out. The key is optional and can be nil. 32 | func Sum384(out *[48]byte, msg, key []byte) { 33 | var out1024 [128]byte 34 | 35 | s := new(hashFunc) 36 | s.initialize(48, &skein.Config{Key: key}) 37 | 38 | s.Write(msg) 39 | 40 | s.finalizeHash() 41 | 42 | s.output(&out1024, 0) 43 | copy(out[:], out1024[:48]) 44 | } 45 | 46 | // Sum256 computes the 256 bit Skein1024 checksum (or MAC if key is set) of msg 47 | // and writes it to out. The key is optional and can be nil. 48 | func Sum256(out *[32]byte, msg, key []byte) { 49 | var out1024 [128]byte 50 | 51 | s := new(hashFunc) 52 | s.initialize(32, &skein.Config{Key: key}) 53 | 54 | s.Write(msg) 55 | 56 | s.finalizeHash() 57 | 58 | s.output(&out1024, 0) 59 | copy(out[:], out1024[:32]) 60 | } 61 | 62 | // Sum160 computes the 160 bit Skein1024 checksum (or MAC if key is set) of msg 63 | // and writes it to out. The key is optional and can be nil. 64 | func Sum160(out *[20]byte, msg, key []byte) { 65 | var out1024 [128]byte 66 | 67 | s := new(hashFunc) 68 | s.initialize(20, &skein.Config{Key: key}) 69 | 70 | s.Write(msg) 71 | 72 | s.finalizeHash() 73 | 74 | s.output(&out1024, 0) 75 | copy(out[:], out1024[:20]) 76 | } 77 | 78 | // Sum returns the Skein1024 checksum with the given hash size of msg using the (optional) 79 | // conf for configuration. The hashsize must be > 0. 80 | func Sum(msg []byte, hashsize int, conf *skein.Config) []byte { 81 | s := New(hashsize, conf) 82 | s.Write(msg) 83 | return s.Sum(nil) 84 | } 85 | 86 | // New512 returns a hash.Hash computing the Skein1024 512 bit checksum. 87 | // The key is optional and turns the hash into a MAC. 88 | func New512(key []byte) hash.Hash { 89 | s := new(hashFunc) 90 | 91 | s.initialize(64, &skein.Config{Key: key}) 92 | 93 | return s 94 | } 95 | 96 | // New256 returns a hash.Hash computing the Skein1024 256 bit checksum. 97 | // The key is optional and turns the hash into a MAC. 98 | func New256(key []byte) hash.Hash { 99 | s := new(hashFunc) 100 | 101 | s.initialize(32, &skein.Config{Key: key}) 102 | 103 | return s 104 | } 105 | 106 | // New returns a hash.Hash computing the Skein1024 checksum with the given hash size. 107 | // The conf is optional and configurates the hash.Hash 108 | func New(hashsize int, conf *skein.Config) hash.Hash { 109 | s := new(hashFunc) 110 | s.initialize(hashsize, conf) 111 | return s 112 | } 113 | -------------------------------------------------------------------------------- /skein/skein256/skein.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | // Package skein256 implements the Skein256 hash function 5 | // based on the Threefish256 tweakable block cipher. 6 | package skein256 7 | 8 | import ( 9 | "hash" 10 | 11 | "github.com/enceve/crypto/skein" 12 | ) 13 | 14 | // Sum512 computes the 512 bit Skein256 checksum (or MAC if key is set) of msg 15 | // and writes it to out. The key is optional and can be nil. 16 | func Sum512(out *[64]byte, msg, key []byte) { 17 | var out256 [32]byte 18 | 19 | s := new(hashFunc) 20 | s.initialize(64, &skein.Config{Key: key}) 21 | 22 | s.Write(msg) 23 | 24 | s.finalizeHash() 25 | 26 | s.output(&out256, 0) 27 | copy(out[:], out256[:]) 28 | s.output(&out256, 1) 29 | copy(out[32:], out256[:]) 30 | } 31 | 32 | // Sum384 computes the 384 bit Skein256 checksum (or MAC if key is set) of msg 33 | // and writes it to out. The key is optional and can be nil. 34 | func Sum384(out *[48]byte, msg, key []byte) { 35 | var out256 [32]byte 36 | 37 | s := new(hashFunc) 38 | s.initialize(48, &skein.Config{Key: key}) 39 | 40 | s.Write(msg) 41 | 42 | s.finalizeHash() 43 | 44 | s.output(&out256, 0) 45 | copy(out[:], out256[:]) 46 | s.output(&out256, 1) 47 | copy(out[32:], out256[:16]) 48 | } 49 | 50 | // Sum256 computes the 256 bit Skein256 checksum (or MAC if key is set) of msg 51 | // and writes it to out. The key is optional and can be nil. 52 | func Sum256(out *[32]byte, msg, key []byte) { 53 | s := new(hashFunc) 54 | s.initialize(32, &skein.Config{Key: key}) 55 | 56 | s.Write(msg) 57 | 58 | s.finalizeHash() 59 | s.output(out, 0) 60 | } 61 | 62 | // Sum160 computes the 160 bit Skein256 checksum (or MAC if key is set) of msg 63 | // and writes it to out. The key is optional and can be nil. 64 | func Sum160(out *[20]byte, msg, key []byte) { 65 | var out256 [32]byte 66 | s := new(hashFunc) 67 | s.initialize(20, &skein.Config{Key: key}) 68 | 69 | s.Write(msg) 70 | 71 | s.finalizeHash() 72 | s.output(&out256, 0) 73 | 74 | copy(out[:], out256[:20]) 75 | } 76 | 77 | // Sum returns the Skein256 checksum with the given hash size of msg using the (optional) 78 | // conf for configuration. The hashsize must be > 0. 79 | func Sum(msg []byte, hashsize int, conf *skein.Config) []byte { 80 | s := New(hashsize, conf) 81 | s.Write(msg) 82 | return s.Sum(nil) 83 | } 84 | 85 | // New512 returns a hash.Hash computing the Skein256 512 bit checksum. 86 | // The key is optional and turns the hash into a MAC. 87 | func New512(key []byte) hash.Hash { 88 | s := new(hashFunc) 89 | 90 | s.initialize(64, &skein.Config{Key: key}) 91 | 92 | return s 93 | } 94 | 95 | // New256 returns a hash.Hash computing the Skein256 256 bit checksum. 96 | // The key is optional and turns the hash into a MAC. 97 | func New256(key []byte) hash.Hash { 98 | s := new(hashFunc) 99 | 100 | s.initialize(32, &skein.Config{Key: key}) 101 | 102 | return s 103 | } 104 | 105 | // New returns a hash.Hash computing the Skein256 checksum with the given hash size. 106 | // The conf is optional and configurates the hash.Hash 107 | func New(hashsize int, conf *skein.Config) hash.Hash { 108 | s := new(hashFunc) 109 | s.initialize(hashsize, conf) 110 | return s 111 | } 112 | -------------------------------------------------------------------------------- /poly1305/poly1305_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // +build !amd64 5 | 6 | package poly1305 7 | 8 | func initialize(r *[5]uint32, pad *[4]uint32, key *[32]byte) { 9 | r[0] = (uint32(key[0]) | uint32(key[1])<<8 | uint32(key[2])<<16 | uint32(key[3])<<24) & 0x3ffffff 10 | r[1] = ((uint32(key[3]) | uint32(key[4])<<8 | uint32(key[5])<<16 | uint32(key[6])<<24) >> 2) & 0x3ffff03 11 | r[2] = ((uint32(key[6]) | uint32(key[7])<<8 | uint32(key[8])<<16 | uint32(key[9])<<24) >> 4) & 0x3ffc0ff 12 | r[3] = ((uint32(key[9]) | uint32(key[10])<<8 | uint32(key[11])<<16 | uint32(key[12])<<24) >> 6) & 0x3f03fff 13 | r[4] = ((uint32(key[12]) | uint32(key[13])<<8 | uint32(key[14])<<16 | uint32(key[15])<<24) >> 8) & 0x00fffff 14 | 15 | pad[0] = (uint32(key[16]) | uint32(key[17])<<8 | uint32(key[18])<<16 | uint32(key[19])<<24) 16 | pad[1] = (uint32(key[20]) | uint32(key[21])<<8 | uint32(key[22])<<16 | uint32(key[23])<<24) 17 | pad[2] = (uint32(key[24]) | uint32(key[25])<<8 | uint32(key[26])<<16 | uint32(key[27])<<24) 18 | pad[3] = (uint32(key[28]) | uint32(key[29])<<8 | uint32(key[30])<<16 | uint32(key[31])<<24) 19 | } 20 | 21 | func core(msg []byte, flag uint32, h, r *[5]uint32) { 22 | h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] 23 | r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4]) 24 | s1, s2, s3, s4 := uint64(r[1]*5), uint64(r[2]*5), uint64(r[3]*5), uint64(r[4]*5) 25 | 26 | var d0, d1, d2, d3, d4 uint64 27 | for i := 0; i < len(msg); i += TagSize { 28 | // h += m 29 | h0 += (uint32(msg[i+0]) | uint32(msg[i+1])<<8 | uint32(msg[i+2])<<16 | uint32(msg[i+3])<<24) & 0x3ffffff 30 | h1 += ((uint32(msg[i+3]) | uint32(msg[i+4])<<8 | uint32(msg[i+5])<<16 | uint32(msg[i+6])<<24) >> 2) & 0x3ffffff 31 | h2 += ((uint32(msg[i+6]) | uint32(msg[i+7])<<8 | uint32(msg[i+8])<<16 | uint32(msg[i+9])<<24) >> 4) & 0x3ffffff 32 | h3 += ((uint32(msg[i+9]) | uint32(msg[i+10])<<8 | uint32(msg[i+11])<<16 | uint32(msg[i+12])<<24) >> 6) & 0x3ffffff 33 | h4 += ((uint32(msg[i+12]) | uint32(msg[i+13])<<8 | uint32(msg[i+14])<<16 | uint32(msg[i+15])<<24) >> 8) | flag 34 | 35 | // h *= r 36 | d0 = (uint64(h0) * r0) + (uint64(h1) * s4) + (uint64(h2) * s3) + (uint64(h3) * s2) + (uint64(h4) * s1) 37 | d1 = (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * s4) + (uint64(h3) * s3) + (uint64(h4) * s2) 38 | d2 = (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * s4) + (uint64(h4) * s3) 39 | d3 = (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * s4) 40 | d4 = (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0) 41 | 42 | // h %= p 43 | h0 = uint32(d0) & 0x3ffffff 44 | h1 = uint32(d1) & 0x3ffffff 45 | h2 = uint32(d2) & 0x3ffffff 46 | h3 = uint32(d3) & 0x3ffffff 47 | h4 = uint32(d4) & 0x3ffffff 48 | 49 | h0 += uint32(d4>>26) * 5 50 | h1 += h0 >> 26 51 | h0 = h0 & 0x3ffffff 52 | } 53 | h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4 54 | } 55 | 56 | func extractHash(tag *[16]byte, h0, h1, h2, h3 uint32) { 57 | tag[0] = byte(h0) 58 | tag[1] = byte(h0 >> 8) 59 | tag[2] = byte(h0 >> 16) 60 | tag[3] = byte(h0 >> 24) 61 | tag[4] = byte(h1) 62 | tag[5] = byte(h1 >> 8) 63 | tag[6] = byte(h1 >> 16) 64 | tag[7] = byte(h1 >> 24) 65 | tag[8] = byte(h2) 66 | tag[9] = byte(h2 >> 8) 67 | tag[10] = byte(h2 >> 16) 68 | tag[11] = byte(h2 >> 24) 69 | tag[12] = byte(h3) 70 | tag[13] = byte(h3 >> 8) 71 | tag[14] = byte(h3 >> 16) 72 | tag[15] = byte(h3 >> 24) 73 | } 74 | -------------------------------------------------------------------------------- /hc128/hc128.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package hc128 implements the stream cipher 5 | // HC-128 from the eSTREAM portfolio (software) 6 | // designed by Hongjun Wu. 7 | package hc128 // import "github.com/enceve/crypto/hc128" 8 | 9 | import "crypto/cipher" 10 | 11 | const ( 12 | mod512 uint32 = 0x1FF 13 | mod1024 uint32 = 0x3FF 14 | ) 15 | 16 | // NewCipher returns a new cipher.Stream implementing the 17 | // HC-128 cipher with the given key and nonce. 18 | func NewCipher(nonce, key *[16]byte) cipher.Stream { 19 | c := new(streamCipher) 20 | initialize(nonce, key, &(c.p), &(c.q)) 21 | return c 22 | } 23 | 24 | type streamCipher struct { 25 | p, q [512]uint32 26 | ctr uint32 27 | keyStream [4]byte 28 | off int 29 | } 30 | 31 | func initialize(nonce, key *[16]byte, p, q *[512]uint32) { 32 | var tmp [1280]uint32 33 | 34 | tmp[0] = uint32(key[0]) | (uint32(key[1]) << 8) | (uint32(key[2]) << 16) | (uint32(key[3]) << 24) 35 | tmp[1] = uint32(key[4]) | (uint32(key[5]) << 8) | (uint32(key[6]) << 16) | (uint32(key[7]) << 24) 36 | tmp[2] = uint32(key[8]) | (uint32(key[9]) << 8) | (uint32(key[10]) << 16) | (uint32(key[11]) << 24) 37 | tmp[3] = uint32(key[12]) | (uint32(key[13]) << 8) | (uint32(key[14]) << 16) | (uint32(key[15]) << 24) 38 | copy(tmp[4:8], tmp[0:4]) 39 | 40 | tmp[8] = uint32(nonce[0]) | (uint32(nonce[1]) << 8) | (uint32(nonce[2]) << 16) | (uint32(nonce[3]) << 24) 41 | tmp[9] = uint32(nonce[4]) | (uint32(nonce[5]) << 8) | (uint32(nonce[6]) << 16) | (uint32(nonce[7]) << 24) 42 | tmp[10] = uint32(nonce[8]) | (uint32(nonce[9]) << 8) | (uint32(nonce[10]) << 16) | (uint32(nonce[11]) << 24) 43 | tmp[11] = uint32(nonce[12]) | (uint32(nonce[13]) << 8) | (uint32(nonce[14]) << 16) | (uint32(nonce[15]) << 24) 44 | copy(tmp[12:16], tmp[8:12]) 45 | 46 | // expand key and nonce with the f1 and f2 functions 47 | // (2.2 http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf) 48 | var f2, f1 uint32 49 | for i := 16; i < 1280; i++ { 50 | f1, f2 = tmp[i-15], tmp[i-2] 51 | f1 = ((f1 >> 7) | (f1 << 25)) ^ ((f1 >> 18) | (f1 << 14)) ^ (f1 >> 3) 52 | f2 = ((f2 >> 17) | (f2 << 15)) ^ ((f2 >> 19) | (f2 << 13)) ^ (f2 >> 10) 53 | tmp[i] = f1 + f2 + tmp[i-7] + tmp[i-16] + uint32(i) 54 | } 55 | copy(p[:], tmp[256:(256+512)]) 56 | copy(q[:], tmp[768:(768+512)]) 57 | 58 | // do 1024 iterations for initialization 59 | var ctr uint32 60 | for i := range p { 61 | p[i] = genKeyStream(&ctr, p, q) 62 | } 63 | for i := range q { 64 | q[i] = genKeyStream(&ctr, p, q) 65 | } 66 | } 67 | 68 | func genKeyStream(counter *uint32, p, q *[512]uint32) uint32 { 69 | var r, t0, t1, t2, t3 uint32 70 | ctr := *counter 71 | 72 | j := ctr & mod512 73 | if ctr < 512 { 74 | t0 = p[(j-3)&mod512] 75 | t1 = p[(j-10)&mod512] 76 | t2 = p[(j-511)&mod512] 77 | t3 = p[(j-12)&mod512] 78 | 79 | t0 = ((t0 >> 10) | (t0 << 22)) 80 | t1 = ((t1 >> 8) | (t1 << 24)) 81 | t2 = ((t2 >> 23) | (t2 << 9)) 82 | p[j] += (t0 ^ t2) + t1 83 | 84 | t0 = t3 & 0xff 85 | t1 = 256 + (t3>>16)&0xff 86 | r = (q[t0] + q[t1]) ^ p[j] 87 | } else { 88 | t0 = q[(j-3)&mod512] 89 | t1 = q[(j-10)&mod512] 90 | t2 = q[(j-511)&mod512] 91 | t3 = q[(j-12)&mod512] 92 | 93 | t0 = ((t0 << 10) | (t0 >> 22)) 94 | t1 = ((t1 << 8) | (t1 >> 24)) 95 | t2 = ((t2 << 23) | (t2 >> 9)) 96 | q[j] += (t0 ^ t2) + t1 97 | 98 | t0 = t3 & 0xff 99 | t1 = 256 + (t3>>16)&0xff 100 | r = p[t0] + p[t1] ^ q[j] 101 | } 102 | 103 | *counter = (ctr + 1) & mod1024 104 | return r 105 | } 106 | -------------------------------------------------------------------------------- /dh/dh.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package dh implements the Diffie-Hellman key exchange over 5 | // multiplicative groups of integers modulo a prime. 6 | // This also defines some commen groups described in RFC 3526. 7 | package dh 8 | 9 | import ( 10 | cryptorand "crypto/rand" 11 | "errors" 12 | "io" 13 | "math/big" 14 | ) 15 | 16 | var zero *big.Int = big.NewInt(0) 17 | var one *big.Int = big.NewInt(1) 18 | var two *big.Int = big.NewInt(2) 19 | 20 | // IsSafePrime returns true, if the prime of the group is 21 | // a so called safe-prime. For a group with a safe-prime prime 22 | // number the Decisional-Diffie-Hellman-Problem (DDH) is a 23 | // 'hard' problem. The n argument is the number of iterations 24 | // for the probabilistic prime test. 25 | // It's recommend to use DDH-safe groups for DH-exchanges. 26 | func IsSafePrimeGroup(g *Group, n int) bool { 27 | q := new(big.Int).Sub(g.P, one) 28 | q = q.Div(q, two) 29 | return q.ProbablyPrime(n) 30 | } 31 | 32 | // PublicKey is the type of DH public keys. 33 | type PublicKey *big.Int 34 | 35 | // PrivateKey is the type of DH private keys. 36 | type PrivateKey *big.Int 37 | 38 | // Group represents a mathematical group defined 39 | // by a large prime and a generator. 40 | type Group struct { 41 | P *big.Int // The prime 42 | G *big.Int // The generator 43 | } 44 | 45 | // GenerateKey generates a public/private key pair using entropy from rand. 46 | // If rand is nil, crypto/rand.Reader will be used. 47 | func (g *Group) GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) { 48 | if g.P == nil { 49 | panic("crypto/dh: group prime is nil") 50 | } 51 | if g.G == nil { 52 | panic("crypto/dh: group generator is nil") 53 | } 54 | if rand == nil { 55 | rand = cryptorand.Reader 56 | } 57 | 58 | // Ensure, that p.G ^ privateKey > than g.P 59 | // (only modulo calculations are safe) 60 | // The minimal (and common) value for p.G is 2 61 | // So 2 ^ (1 + 'bitsize of p.G') > than g.P 62 | min := big.NewInt(int64(g.P.BitLen() + 1)) 63 | bytes := make([]byte, (g.P.BitLen()+7)/8) 64 | 65 | for private == nil { 66 | _, err = io.ReadFull(rand, bytes) 67 | if err != nil { 68 | private = nil 69 | return 70 | } 71 | // Clear bits in the first byte to increase 72 | // the probability that the candidate is < g.P. 73 | bytes[0] = 0 74 | if private == nil { 75 | private = new(big.Int) 76 | } 77 | (*private).SetBytes(bytes) 78 | if (*private).Cmp(min) < 0 { 79 | private = nil 80 | } 81 | } 82 | 83 | public = new(big.Int).Exp(g.G, private, g.P) 84 | return 85 | } 86 | 87 | // PublicKey returns the public key corresponding to the given private one. 88 | func (g *Group) PublicKey(private PrivateKey) (public PublicKey) { 89 | public = new(big.Int).Exp(g.G, private, g.P) 90 | return 91 | } 92 | 93 | //private returns a non-nil error if the given public key is 94 | // not a possible element of the group. This means, that the 95 | // public key is < 0 or > g.P. 96 | func (g *Group) Check(peersPublic PublicKey) (err error) { 97 | if !((*peersPublic).Cmp(zero) >= 0 && (*peersPublic).Cmp(g.P) == -1) { 98 | err = errors.New("peer's public is not a possible group element") 99 | } 100 | return 101 | } 102 | 103 | // ComputeSecret returns the secret computed from 104 | // the own private and the peer's public key. 105 | func (g *Group) ComputeSecret(private PrivateKey, peersPublic PublicKey) (secret *big.Int) { 106 | secret = new(big.Int).Exp(peersPublic, private, g.P) 107 | return 108 | } 109 | -------------------------------------------------------------------------------- /serpent/serpent.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package serpent implements the Serpent block cipher 5 | // submitted to the AES challenge. Serpent was designed by 6 | // Ross Anderson, Eli Biham und Lars Knudsen. 7 | // The block cipher takes a 128, 192 or 256 bit key and 8 | // has a block size of 128 bit. 9 | package serpent 10 | 11 | import ( 12 | "crypto/cipher" 13 | 14 | "github.com/enceve/crypto" 15 | ) 16 | 17 | // The Serpent block size in bytes. 18 | const BlockSize = 16 19 | 20 | // NewCipher returns a new cipher.Block implementing the serpent block cipher. 21 | // The key argument must be 128, 192 or 256 bit (16, 24, 32 byte). 22 | func NewCipher(key []byte) (cipher.Block, error) { 23 | if k := len(key); k != 16 && k != 24 && k != 32 { 24 | return nil, crypto.KeySizeError(k) 25 | } 26 | s := &subkeys{} 27 | s.keySchedule(key) 28 | return s, nil 29 | } 30 | 31 | // The 132 32 bit subkeys of serpent 32 | type subkeys [132]uint32 33 | 34 | func (s *subkeys) BlockSize() int { return BlockSize } 35 | 36 | func (s *subkeys) Encrypt(dst, src []byte) { 37 | if len(src) < BlockSize { 38 | panic("src buffer to small") 39 | } 40 | if len(dst) < BlockSize { 41 | panic("dst buffer to small") 42 | } 43 | encryptBlock(dst, src, s) 44 | } 45 | 46 | func (s *subkeys) Decrypt(dst, src []byte) { 47 | if len(src) < BlockSize { 48 | panic("src buffer to small") 49 | } 50 | if len(dst) < BlockSize { 51 | panic("dst buffer to small") 52 | } 53 | decryptBlock(dst, src, s) 54 | } 55 | 56 | const phi = 0x9e3779b9 // The Serpent phi constant (sqrt(5) - 1) * 2**31 57 | 58 | // The key schedule of serpent. 59 | func (s *subkeys) keySchedule(key []byte) { 60 | var k [16]uint32 61 | j := 0 62 | for i := 0; i+4 <= len(key); i += 4 { 63 | k[j] = uint32(key[i]) | uint32(key[i+1])<<8 | uint32(key[i+2])<<16 | uint32(key[i+3])<<24 64 | j++ 65 | } 66 | if j < 8 { 67 | k[j] = 1 68 | } 69 | 70 | for i := 8; i < 16; i++ { 71 | x := k[i-8] ^ k[i-5] ^ k[i-3] ^ k[i-1] ^ phi ^ uint32(i-8) 72 | k[i] = (x << 11) | (x >> 21) 73 | s[i-8] = k[i] 74 | } 75 | for i := 8; i < 132; i++ { 76 | x := s[i-8] ^ s[i-5] ^ s[i-3] ^ s[i-1] ^ phi ^ uint32(i) 77 | s[i] = (x << 11) | (x >> 21) 78 | } 79 | 80 | sb3(&s[0], &s[1], &s[2], &s[3]) 81 | sb2(&s[4], &s[5], &s[6], &s[7]) 82 | sb1(&s[8], &s[9], &s[10], &s[11]) 83 | sb0(&s[12], &s[13], &s[14], &s[15]) 84 | sb7(&s[16], &s[17], &s[18], &s[19]) 85 | sb6(&s[20], &s[21], &s[22], &s[23]) 86 | sb5(&s[24], &s[25], &s[26], &s[27]) 87 | sb4(&s[28], &s[29], &s[30], &s[31]) 88 | 89 | sb3(&s[32], &s[33], &s[34], &s[35]) 90 | sb2(&s[36], &s[37], &s[38], &s[39]) 91 | sb1(&s[40], &s[41], &s[42], &s[43]) 92 | sb0(&s[44], &s[45], &s[46], &s[47]) 93 | sb7(&s[48], &s[49], &s[50], &s[51]) 94 | sb6(&s[52], &s[53], &s[54], &s[55]) 95 | sb5(&s[56], &s[57], &s[58], &s[59]) 96 | sb4(&s[60], &s[61], &s[62], &s[63]) 97 | 98 | sb3(&s[64], &s[65], &s[66], &s[67]) 99 | sb2(&s[68], &s[69], &s[70], &s[71]) 100 | sb1(&s[72], &s[73], &s[74], &s[75]) 101 | sb0(&s[76], &s[77], &s[78], &s[79]) 102 | sb7(&s[80], &s[81], &s[82], &s[83]) 103 | sb6(&s[84], &s[85], &s[86], &s[87]) 104 | sb5(&s[88], &s[89], &s[90], &s[91]) 105 | sb4(&s[92], &s[93], &s[94], &s[95]) 106 | 107 | sb3(&s[96], &s[97], &s[98], &s[99]) 108 | sb2(&s[100], &s[101], &s[102], &s[103]) 109 | sb1(&s[104], &s[105], &s[106], &s[107]) 110 | sb0(&s[108], &s[109], &s[110], &s[111]) 111 | sb7(&s[112], &s[113], &s[114], &s[115]) 112 | sb6(&s[116], &s[117], &s[118], &s[119]) 113 | sb5(&s[120], &s[121], &s[122], &s[123]) 114 | sb4(&s[124], &s[125], &s[126], &s[127]) 115 | 116 | sb3(&s[128], &s[129], &s[130], &s[131]) 117 | } 118 | -------------------------------------------------------------------------------- /chacha20/chacha/chacha_amd64.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // +build amd64,!gccgo,!appengine 5 | 6 | package chacha 7 | 8 | import ( 9 | "unsafe" 10 | 11 | "github.com/enceve/crypto" 12 | ) 13 | 14 | // XORKeyStream crypts bytes from src to dst using the given key, nonce and counter. 15 | // The rounds argument specifies the number of rounds (must be even) performed for 16 | // keystream generation. (Common values are 20, 12 or 8) Src and dst may be the same 17 | // slice but otherwise should not overlap. If len(dst) < len(src) this function panics. 18 | func XORKeyStream(dst, src []byte, nonce *[12]byte, key *[32]byte, counter uint32, rounds int) { 19 | length := len(src) 20 | if len(dst) < length { 21 | panic("chacha20/chacha: dst buffer is to small") 22 | } 23 | if rounds <= 0 || rounds%2 != 0 { 24 | panic("chacha20/chacha: rounds must be a multiple of 2") 25 | } 26 | 27 | var state [64]byte 28 | 29 | copy(state[:], constants[:]) 30 | 31 | statePtr := (*[8]uint64)(unsafe.Pointer(&state[0])) 32 | keyPtr := (*[4]uint64)(unsafe.Pointer(&key[0])) 33 | 34 | statePtr[2] = keyPtr[0] 35 | statePtr[3] = keyPtr[1] 36 | statePtr[4] = keyPtr[2] 37 | statePtr[5] = keyPtr[3] 38 | 39 | statePtr[6] = (*(*uint64)(unsafe.Pointer(&nonce[0])) << 32) | uint64(counter) 40 | 41 | statePtr[7] = *(*uint64)(unsafe.Pointer(&nonce[4])) 42 | 43 | if length >= 64 { 44 | XORBlocks(dst, src, &state, rounds) 45 | } 46 | 47 | if n := length & (^(64 - 1)); length-n > 0 { 48 | var block [64]byte 49 | Core(&block, &state, rounds) 50 | 51 | crypto.XOR(dst[n:], src[n:], block[:]) 52 | } 53 | } 54 | 55 | // NewCipher returns a new *chacha.Cipher implementing the ChaCha/X (X = even number of rounds) 56 | // stream cipher. The nonce must be unique for one key for all time. 57 | func NewCipher(nonce *[12]byte, key *[32]byte, rounds int) *Cipher { 58 | if rounds <= 0 || rounds%2 != 0 { 59 | panic("chacha20/chacha: rounds must be a multiply of 2") 60 | } 61 | c := new(Cipher) 62 | c.rounds = rounds 63 | 64 | copy(c.state[:], constants[:]) 65 | 66 | statePtr := (*[8]uint64)(unsafe.Pointer(&(c.state[0]))) 67 | keyPtr := (*[4]uint64)(unsafe.Pointer(&key[0])) 68 | 69 | statePtr[2] = keyPtr[0] 70 | statePtr[3] = keyPtr[1] 71 | statePtr[4] = keyPtr[2] 72 | statePtr[5] = keyPtr[3] 73 | 74 | statePtr[6] = (*(*uint64)(unsafe.Pointer(&nonce[0])) << 32) 75 | 76 | statePtr[7] = *(*uint64)(unsafe.Pointer(&nonce[4])) 77 | 78 | return c 79 | } 80 | 81 | // XORKeyStream crypts bytes from src to dst. Src and dst may be the same slice 82 | // but otherwise should not overlap. If len(dst) < len(src) the function panics. 83 | func (c *Cipher) XORKeyStream(dst, src []byte) { 84 | length := len(src) 85 | if len(dst) < length { 86 | panic("chacha20/chacha: dst buffer is to small") 87 | } 88 | 89 | if c.off > 0 { 90 | n := crypto.XOR(dst, src, c.block[c.off:]) 91 | if n == length { 92 | c.off += n 93 | return 94 | } 95 | src = src[n:] 96 | dst = dst[n:] 97 | length -= n 98 | c.off = 0 99 | } 100 | 101 | if length >= 64 { 102 | XORBlocks(dst, src, &(c.state), c.rounds) 103 | } 104 | 105 | if n := length & (^(64 - 1)); length-n > 0 { 106 | Core(&(c.block), &(c.state), c.rounds) 107 | 108 | c.off += crypto.XOR(dst[n:], src[n:], c.block[:]) 109 | } 110 | } 111 | 112 | // XORBlocks crypts full block ( len(src) - (len(src) mod 64) bytes ) from src to 113 | // dst using the state. Src and dst may be the same slice but otherwise should not 114 | // overlap. This function increments the counter of state. 115 | // If len(src) > len(dst), XORBlocks does nothing. 116 | func XORBlocks(dst, src []byte, state *[64]byte, rounds int) 117 | 118 | // Core generates 64 byte keystream from the given state performing 'rounds' rounds 119 | // and writes them to dst. This function expects valid values. (no nil ptr etc.) 120 | // Core increments the counter of state. 121 | func Core(dst *[64]byte, state *[64]byte, rounds int) 122 | -------------------------------------------------------------------------------- /cipher/vectors_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package cipher 5 | 6 | import ( 7 | "bytes" 8 | "crypto/aes" 9 | "encoding/hex" 10 | "testing" 11 | ) 12 | 13 | type testVector struct { 14 | msg, key, nonce, data string 15 | ciphertext string 16 | macSize int 17 | } 18 | 19 | // EAX-AES test vectors from 20 | // http://web.cs.ucdavis.edu/~rogaway/papers/eax.pdf 21 | var vectors = []testVector{ 22 | testVector{ 23 | msg: "", 24 | key: "233952DEE4D5ED5F9B9C6D6FF80FF478", 25 | nonce: "62EC67F9C3A4A407FCB2A8C49031A8B3", 26 | data: "6BFB914FD07EAE6B", 27 | ciphertext: "E037830E8389F27B025A2D6527E79D01", 28 | macSize: 16, 29 | }, 30 | testVector{ 31 | msg: "F7FB", 32 | key: "91945D3F4DCBEE0BF45EF52255F095A4", 33 | nonce: "BECAF043B0A23D843194BA972C66DEBD", 34 | data: "FA3BFD4806EB53FA", 35 | ciphertext: "19DD5C4C9331049D0BDAB0277408F67967E5", 36 | macSize: 16, 37 | }, 38 | testVector{ 39 | msg: "1A47CB4933", 40 | key: "01F74AD64077F2E704C0F60ADA3DD523", 41 | nonce: "70C3DB4F0D26368400A10ED05D2BFF5E", 42 | data: "234A3463C1264AC6", 43 | ciphertext: "D851D5BAE03A59F238A23E39199DC9266626C40F80", 44 | macSize: 16, 45 | }, 46 | testVector{ 47 | msg: "1A47CB4933", 48 | key: "01F74AD64077F2E704C0F60ADA3DD523", 49 | nonce: "70C3DB4F0D26368400A10ED05D2BFF5E", 50 | data: "234A3463C1264AC6", 51 | ciphertext: "D851D5BAE03A59F238A23E39199DC9266626C4", 52 | macSize: 14, 53 | }, 54 | testVector{ 55 | msg: "8B0A79306C9CE7ED99DAE4F87F8DD61636", 56 | key: "7C77D6E813BED5AC98BAA417477A2E7D", 57 | nonce: "1A8C98DCD73D38393B2BF1569DEEFC19", 58 | data: "65D2017990D62528", 59 | ciphertext: "02083E3979DA014812F59F11D52630DA30137327D10" + 60 | "649B0AA6E1C181DB617D7F2", 61 | macSize: 16, 62 | }, 63 | testVector{ 64 | msg: "8B0A79306C9CE7ED99DAE4F87F8DD61636", 65 | key: "7C77D6E813BED5AC98BAA417477A2E7D", 66 | nonce: "1A8C98DCD73D38393B2BF1569DEEFC19", 67 | data: "65D2017990D62528", 68 | ciphertext: "02083E3979DA014812F59F11D52630DA30137327D10" + 69 | "649B0AA6E1C181D", 70 | macSize: 12, 71 | }, 72 | } 73 | 74 | func TestVectors(t *testing.T) { 75 | for i, v := range vectors { 76 | msg, err := hex.DecodeString(v.msg) 77 | if err != nil { 78 | t.Fatalf("TestVector %d: Failed to decode hex msg: %s", i, err) 79 | } 80 | key, err := hex.DecodeString(v.key) 81 | if err != nil { 82 | t.Fatalf("TestVector %d: Failed to decode hex key: %s", i, err) 83 | } 84 | nonce, err := hex.DecodeString(v.nonce) 85 | if err != nil { 86 | t.Fatalf("TestVector %d: Failed to decode hex nonce: %s", i, err) 87 | } 88 | data, err := hex.DecodeString(v.data) 89 | if err != nil { 90 | t.Fatalf("TestVector %d: Failed to decode hex data: %s", i, err) 91 | } 92 | ciphertext, err := hex.DecodeString(v.ciphertext) 93 | if err != nil { 94 | t.Fatalf("TestVector %d: Failed to decode hex ciphertext: %s", i, err) 95 | } 96 | cAES, err := aes.NewCipher(key) 97 | if err != nil { 98 | t.Fatalf("TestVector %d: Failed to create AES instance: %s", i, err) 99 | } 100 | eax, err := NewEAX(cAES, v.macSize) 101 | if err != nil { 102 | t.Fatalf("TestVector %d: Failed to create EAX instance: %s", i, err) 103 | } 104 | 105 | buf := make([]byte, len(ciphertext)) 106 | buf = eax.Seal(buf, nonce, msg, data) 107 | 108 | if !bytes.Equal(buf, ciphertext) { 109 | t.Fatalf("TestVector %d Seal failed:\nFound : %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(ciphertext)) 110 | } 111 | 112 | buf, err = eax.Open(buf, nonce, buf, data) 113 | 114 | if err != nil { 115 | t.Fatalf("TestVector %d: Open failed: %s", i, err) 116 | } 117 | if !bytes.Equal(buf, msg) { 118 | t.Fatalf("TestVector %d Open failed:\nFound : %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(msg)) 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /blake2/blake2s/blake2s_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package blake2s 5 | 6 | func Core(hVal *[8]uint32, counter *[2]uint32, flag uint32, msg []byte) { 7 | h0, h1, h2, h3 := hVal[0], hVal[1], hVal[2], hVal[3] 8 | h4, h5, h6, h7 := hVal[4], hVal[5], hVal[6], hVal[7] 9 | ctr0 := counter[0] 10 | ctr1 := counter[1] 11 | 12 | var m [16]uint32 13 | 14 | length := len(msg) 15 | for i := 0; i < length; i += BlockSize { 16 | ctr0 += BlockSize 17 | if ctr0 < BlockSize { 18 | ctr1++ 19 | } 20 | 21 | v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7 22 | v8, v9, v10, v11 := iv[0], iv[1], iv[2], iv[3] 23 | v12, v13, v14, v15 := iv[4], iv[5], iv[6], iv[7] 24 | v12 ^= ctr0 25 | v13 ^= ctr1 26 | v14 ^= flag 27 | 28 | j := i 29 | for k := range m { 30 | m[k] = uint32(msg[j]) | uint32(msg[j+1])<<8 | uint32(msg[j+2])<<16 | uint32(msg[j+3])<<24 31 | j += 4 32 | } 33 | 34 | for k := range precomputed { 35 | s := &(precomputed[k]) 36 | 37 | v0 += m[s[0]] 38 | v0 += v4 39 | v12 ^= v0 40 | v12 = v12<<(32-16) | v12>>16 41 | v8 += v12 42 | v4 ^= v8 43 | v4 = v4<<(32-12) | v4>>12 44 | v1 += m[s[1]] 45 | v1 += v5 46 | v13 ^= v1 47 | v13 = v13<<(32-16) | v13>>16 48 | v9 += v13 49 | v5 ^= v9 50 | v5 = v5<<(32-12) | v5>>12 51 | v2 += m[s[2]] 52 | v2 += v6 53 | v14 ^= v2 54 | v14 = v14<<(32-16) | v14>>16 55 | v10 += v14 56 | v6 ^= v10 57 | v6 = v6<<(32-12) | v6>>12 58 | v3 += m[s[3]] 59 | v3 += v7 60 | v15 ^= v3 61 | v15 = v15<<(32-16) | v15>>16 62 | v11 += v15 63 | v7 ^= v11 64 | v7 = v7<<(32-12) | v7>>12 65 | 66 | v0 += m[s[7]] 67 | v0 += v4 68 | v12 ^= v0 69 | v12 = v12<<(32-8) | v12>>8 70 | v8 += v12 71 | v4 ^= v8 72 | v4 = v4<<(32-7) | v4>>7 73 | v1 += m[s[6]] 74 | v1 += v5 75 | v13 ^= v1 76 | v13 = v13<<(32-8) | v13>>8 77 | v9 += v13 78 | v5 ^= v9 79 | v5 = v5<<(32-7) | v5>>7 80 | v2 += m[s[4]] 81 | v2 += v6 82 | v14 ^= v2 83 | v14 = v14<<(32-8) | v14>>8 84 | v10 += v14 85 | v6 ^= v10 86 | v6 = v6<<(32-7) | v6>>7 87 | v3 += m[s[5]] 88 | v3 += v7 89 | v15 ^= v3 90 | v15 = v15<<(32-8) | v15>>8 91 | v11 += v15 92 | v7 ^= v11 93 | v7 = v7<<(32-7) | v7>>7 94 | 95 | v0 += m[s[8]] 96 | v0 += v5 97 | v15 ^= v0 98 | v15 = v15<<(32-16) | v15>>16 99 | v10 += v15 100 | v5 ^= v10 101 | v5 = v5<<(32-12) | v5>>12 102 | v1 += m[s[9]] 103 | v1 += v6 104 | v12 ^= v1 105 | v12 = v12<<(32-16) | v12>>16 106 | v11 += v12 107 | v6 ^= v11 108 | v6 = v6<<(32-12) | v6>>12 109 | v2 += m[s[10]] 110 | v2 += v7 111 | v13 ^= v2 112 | v13 = v13<<(32-16) | v13>>16 113 | v8 += v13 114 | v7 ^= v8 115 | v7 = v7<<(32-12) | v7>>12 116 | v3 += m[s[11]] 117 | v3 += v4 118 | v14 ^= v3 119 | v14 = v14<<(32-16) | v14>>16 120 | v9 += v14 121 | v4 ^= v9 122 | v4 = v4<<(32-12) | v4>>12 123 | 124 | v0 += m[s[15]] 125 | v0 += v5 126 | v15 ^= v0 127 | v15 = v15<<(32-8) | v15>>8 128 | v10 += v15 129 | v5 ^= v10 130 | v5 = v5<<(32-7) | v5>>7 131 | v1 += m[s[14]] 132 | v1 += v6 133 | v12 ^= v1 134 | v12 = v12<<(32-8) | v12>>8 135 | v11 += v12 136 | v6 ^= v11 137 | v6 = v6<<(32-7) | v6>>7 138 | v2 += m[s[12]] 139 | v2 += v7 140 | v13 ^= v2 141 | v13 = v13<<(32-8) | v13>>8 142 | v8 += v13 143 | v7 ^= v8 144 | v7 = v7<<(32-7) | v7>>7 145 | v3 += m[s[13]] 146 | v3 += v4 147 | v14 ^= v3 148 | v14 = v14<<(32-8) | v14>>8 149 | v9 += v14 150 | v4 ^= v9 151 | v4 = v4<<(32-7) | v4>>7 152 | } 153 | 154 | h0 ^= v0 ^ v8 155 | h1 ^= v1 ^ v9 156 | h2 ^= v2 ^ v10 157 | h3 ^= v3 ^ v11 158 | h4 ^= v4 ^ v12 159 | h5 ^= v5 ^ v13 160 | h6 ^= v6 ^ v14 161 | h7 ^= v7 ^ v15 162 | } 163 | 164 | hVal[0], hVal[1], hVal[2], hVal[3] = h0, h1, h2, h3 165 | hVal[4], hVal[5], hVal[6], hVal[7] = h4, h5, h6, h7 166 | 167 | counter[0] = ctr0 168 | counter[1] = ctr1 169 | } 170 | -------------------------------------------------------------------------------- /skein/threefish/threefish_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | package threefish 5 | 6 | import "testing" 7 | 8 | // The UBI256, UBI512 and UBI1024 functions are tested within 9 | // the skein packages (skein, skein256 and skein1024) 10 | 11 | func testBlockSize(t *testing.T, blocksize int) { 12 | var tweak [TweakSize]byte 13 | c, err := NewCipher(&tweak, make([]byte, blocksize)) 14 | if err != nil { 15 | t.Fatalf("Failed to create Threefish-%d instance: %s", blocksize*8, err) 16 | } 17 | 18 | if bs := c.BlockSize(); bs != blocksize { 19 | t.Fatalf("BlockSize() returned unexpected value: %d - expected %d", bs, blocksize) 20 | } 21 | } 22 | 23 | func TestBlockSize(t *testing.T) { 24 | testBlockSize(t, BlockSize256) 25 | testBlockSize(t, BlockSize512) 26 | testBlockSize(t, BlockSize1024) 27 | } 28 | 29 | func TestNew(t *testing.T) { 30 | badKeyLengths := []int{ 31 | 0, 31, 33, 63, 65, 127, 129, 32 | } 33 | var tweak [TweakSize]byte 34 | for i, v := range badKeyLengths { 35 | _, err := NewCipher(&tweak, make([]byte, v)) 36 | if err == nil { 37 | t.Fatalf("BadKey %d: NewCipher accepted inavlid key length %d", i, v) 38 | } 39 | } 40 | } 41 | 42 | func TestIncrementTweak(t *testing.T) { 43 | var tweak [3]uint64 44 | 45 | IncrementTweak(&tweak, 1) 46 | if tweak[0] != 1 { 47 | t.Fatalf("IncrementTweak failed by increment of %d", 1) 48 | } 49 | 50 | tweak[0] = ^uint64(0) 51 | IncrementTweak(&tweak, 2) 52 | if tweak[0] != 1 && tweak[1] != 1 { 53 | t.Fatalf("IncrementTweak failed by increment of %d", 2) 54 | } 55 | 56 | tweak[0] = ^uint64(0) 57 | tweak[1] = uint64(0xFFFFFFFF) 58 | IncrementTweak(&tweak, 1) 59 | if tweak[0] != 0 && tweak[1] != 0 { 60 | t.Fatalf("IncrementTweak failed by increment of %d", 1) 61 | } 62 | } 63 | 64 | // Benchmarks 65 | 66 | func benchmarkEncrypt(b *testing.B, blocksize, size int) { 67 | key := make([]byte, blocksize) 68 | var tweak [TweakSize]byte 69 | 70 | c, err := NewCipher(&tweak, key) 71 | if err != nil { 72 | b.Fatalf("Failed to create Threefish-%d instance: %s", blocksize*8, err) 73 | } 74 | n := size / blocksize 75 | buf := make([]byte, blocksize) 76 | b.SetBytes(int64(blocksize * n)) 77 | 78 | b.ResetTimer() 79 | for i := 0; i < b.N; i++ { 80 | for j := 0; j < n; j++ { 81 | c.Encrypt(buf, buf) 82 | } 83 | } 84 | } 85 | 86 | func benchmarkDecrypt(b *testing.B, blocksize, size int) { 87 | key := make([]byte, blocksize) 88 | var tweak [TweakSize]byte 89 | 90 | c, err := NewCipher(&tweak, key) 91 | if err != nil { 92 | b.Fatalf("Failed to create Threefish-%d instance: %s", blocksize*8, err) 93 | } 94 | 95 | n := size / blocksize 96 | buf := make([]byte, blocksize) 97 | b.SetBytes(int64(blocksize * n)) 98 | 99 | b.ResetTimer() 100 | for i := 0; i < b.N; i++ { 101 | for j := 0; j < n; j++ { 102 | c.Decrypt(buf, buf) 103 | } 104 | } 105 | } 106 | 107 | func BenchmarkEncrypt256_32(b *testing.B) { benchmarkEncrypt(b, BlockSize256, 32) } 108 | func BenchmarkEncrypt256_1024(b *testing.B) { benchmarkEncrypt(b, BlockSize256, 1024) } 109 | func BenchmarkEncrypt512_64(b *testing.B) { benchmarkEncrypt(b, BlockSize512, 64) } 110 | func BenchmarkEncrypt512_1024(b *testing.B) { benchmarkEncrypt(b, BlockSize512, 1024) } 111 | func BenchmarkEncrypt1024_128(b *testing.B) { benchmarkEncrypt(b, BlockSize1024, 128) } 112 | func BenchmarkEncrypt1024_1024(b *testing.B) { benchmarkEncrypt(b, BlockSize1024, 1024) } 113 | 114 | func BenchmarkDecrypt256_32(b *testing.B) { benchmarkDecrypt(b, BlockSize256, 32) } 115 | func BenchmarkDecrypt256_1024(b *testing.B) { benchmarkDecrypt(b, BlockSize256, 1024) } 116 | func BenchmarkDecrypt512_64(b *testing.B) { benchmarkDecrypt(b, BlockSize512, 64) } 117 | func BenchmarkDecrypt512_1024(b *testing.B) { benchmarkDecrypt(b, BlockSize512, 1024) } 118 | func BenchmarkDecrypt1024_128(b *testing.B) { benchmarkDecrypt(b, BlockSize1024, 128) } 119 | func BenchmarkDecrypt1024_1024(b *testing.B) { benchmarkDecrypt(b, BlockSize1024, 1024) } 120 | -------------------------------------------------------------------------------- /blake2/blake2b/blake2b_ref.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package blake2b 5 | 6 | func Core(hVal *[8]uint64, counter *[2]uint64, flag uint64, msg []byte) { 7 | h0, h1, h2, h3 := hVal[0], hVal[1], hVal[2], hVal[3] 8 | h4, h5, h6, h7 := hVal[4], hVal[5], hVal[6], hVal[7] 9 | ctr0 := counter[0] 10 | ctr1 := counter[1] 11 | 12 | var m [16]uint64 13 | 14 | length := len(msg) 15 | for i := 0; i < length; i += BlockSize { 16 | ctr0 += BlockSize 17 | if ctr0 < BlockSize { 18 | ctr1++ 19 | } 20 | 21 | v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7 22 | v8, v9, v10, v11 := iv[0], iv[1], iv[2], iv[3] 23 | v12, v13, v14, v15 := iv[4], iv[5], iv[6], iv[7] 24 | v12 ^= ctr0 25 | v13 ^= ctr1 26 | v14 ^= flag 27 | 28 | j := i 29 | for k := range m { 30 | m[k] = uint64(msg[j]) | uint64(msg[j+1])<<8 | uint64(msg[j+2])<<16 | uint64(msg[j+3])<<24 | 31 | uint64(msg[j+4])<<32 | uint64(msg[j+5])<<40 | uint64(msg[j+6])<<48 | uint64(msg[j+7])<<56 32 | j += 8 33 | } 34 | 35 | for j := range precomputed { 36 | s := &(precomputed[j]) 37 | 38 | v0 += m[s[0]] 39 | v0 += v4 40 | v12 ^= v0 41 | v12 = v12<<(64-32) | v12>>32 42 | v8 += v12 43 | v4 ^= v8 44 | v4 = v4<<(64-24) | v4>>24 45 | v1 += m[s[1]] 46 | v1 += v5 47 | v13 ^= v1 48 | v13 = v13<<(64-32) | v13>>32 49 | v9 += v13 50 | v5 ^= v9 51 | v5 = v5<<(64-24) | v5>>24 52 | v2 += m[s[2]] 53 | v2 += v6 54 | v14 ^= v2 55 | v14 = v14<<(64-32) | v14>>32 56 | v10 += v14 57 | v6 ^= v10 58 | v6 = v6<<(64-24) | v6>>24 59 | v3 += m[s[3]] 60 | v3 += v7 61 | v15 ^= v3 62 | v15 = v15<<(64-32) | v15>>32 63 | v11 += v15 64 | v7 ^= v11 65 | v7 = v7<<(64-24) | v7>>24 66 | 67 | v0 += m[s[7]] 68 | v0 += v4 69 | v12 ^= v0 70 | v12 = v12<<(64-16) | v12>>16 71 | v8 += v12 72 | v4 ^= v8 73 | v4 = v4<<(64-63) | v4>>63 74 | v1 += m[s[6]] 75 | v1 += v5 76 | v13 ^= v1 77 | v13 = v13<<(64-16) | v13>>16 78 | v9 += v13 79 | v5 ^= v9 80 | v5 = v5<<(64-63) | v5>>63 81 | v2 += m[s[4]] 82 | v2 += v6 83 | v14 ^= v2 84 | v14 = v14<<(64-16) | v14>>16 85 | v10 += v14 86 | v6 ^= v10 87 | v6 = v6<<(64-63) | v6>>63 88 | v3 += m[s[5]] 89 | v3 += v7 90 | v15 ^= v3 91 | v15 = v15<<(64-16) | v15>>16 92 | v11 += v15 93 | v7 ^= v11 94 | v7 = v7<<(64-63) | v7>>63 95 | 96 | v0 += m[s[8]] 97 | v0 += v5 98 | v15 ^= v0 99 | v15 = v15<<(64-32) | v15>>32 100 | v10 += v15 101 | v5 ^= v10 102 | v5 = v5<<(64-24) | v5>>24 103 | v1 += m[s[9]] 104 | v1 += v6 105 | v12 ^= v1 106 | v12 = v12<<(64-32) | v12>>32 107 | v11 += v12 108 | v6 ^= v11 109 | v6 = v6<<(64-24) | v6>>24 110 | v2 += m[s[10]] 111 | v2 += v7 112 | v13 ^= v2 113 | v13 = v13<<(64-32) | v13>>32 114 | v8 += v13 115 | v7 ^= v8 116 | v7 = v7<<(64-24) | v7>>24 117 | v3 += m[s[11]] 118 | v3 += v4 119 | v14 ^= v3 120 | v14 = v14<<(64-32) | v14>>32 121 | v9 += v14 122 | v4 ^= v9 123 | v4 = v4<<(64-24) | v4>>24 124 | 125 | v0 += m[s[15]] 126 | v0 += v5 127 | v15 ^= v0 128 | v15 = v15<<(64-16) | v15>>16 129 | v10 += v15 130 | v5 ^= v10 131 | v5 = v5<<(64-63) | v5>>63 132 | v1 += m[s[14]] 133 | v1 += v6 134 | v12 ^= v1 135 | v12 = v12<<(64-16) | v12>>16 136 | v11 += v12 137 | v6 ^= v11 138 | v6 = v6<<(64-63) | v6>>63 139 | v2 += m[s[12]] 140 | v2 += v7 141 | v13 ^= v2 142 | v13 = v13<<(64-16) | v13>>16 143 | v8 += v13 144 | v7 ^= v8 145 | v7 = v7<<(64-63) | v7>>63 146 | v3 += m[s[13]] 147 | v3 += v4 148 | v14 ^= v3 149 | v14 = v14<<(64-16) | v14>>16 150 | v9 += v14 151 | v4 ^= v9 152 | v4 = v4<<(64-63) | v4>>63 153 | } 154 | 155 | h0 ^= v0 ^ v8 156 | h1 ^= v1 ^ v9 157 | h2 ^= v2 ^ v10 158 | h3 ^= v3 ^ v11 159 | h4 ^= v4 ^ v12 160 | h5 ^= v5 ^ v13 161 | h6 ^= v6 ^ v14 162 | h7 ^= v7 ^ v15 163 | } 164 | 165 | hVal[0], hVal[1], hVal[2], hVal[3] = h0, h1, h2, h3 166 | hVal[4], hVal[5], hVal[6], hVal[7] = h4, h5, h6, h7 167 | 168 | counter[0] = ctr0 169 | counter[1] = ctr1 170 | } 171 | -------------------------------------------------------------------------------- /poly1305/poly1305_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | package poly1305 5 | 6 | import ( 7 | "encoding/hex" 8 | "testing" 9 | "unsafe" 10 | ) 11 | 12 | func TestWriteAfterSum(t *testing.T) { 13 | var sum [TagSize]byte 14 | 15 | msg := make([]byte, 64) 16 | for i := range msg { 17 | h := New(new([32]byte)) 18 | 19 | if _, err := h.Write(msg[:i]); err != nil { 20 | t.Fatalf("Iteration %d: poly1305.Hash returned unexpected error: %s", i, err) 21 | } 22 | h.Sum(&sum) 23 | if _, err := h.Write(nil); err == nil { 24 | t.Fatalf("Iteration %d: poly1305.Hash returned no error for write after sum", i) 25 | } 26 | } 27 | } 28 | 29 | func TestWrite(t *testing.T) { 30 | var key [32]byte 31 | for i := range key { 32 | key[i] = byte(i) 33 | } 34 | 35 | h := New(&key) 36 | 37 | var msg1 []byte 38 | msg0 := make([]byte, 64) 39 | for i := range msg0 { 40 | h.Write(msg0[:i]) 41 | msg1 = append(msg1, msg0[:i]...) 42 | } 43 | 44 | var tag0, tag1 [TagSize]byte 45 | h.Sum(&tag0) 46 | Sum(&tag1, msg1, &key) 47 | 48 | if tag0 != tag1 { 49 | t.Fatalf("Sum differ from poly1305.Sum\n Sum: %s \n poly1305.Sum: %s", hex.EncodeToString(tag0[:]), hex.EncodeToString(tag1[:])) 50 | } 51 | } 52 | 53 | func TestSum(t *testing.T) { 54 | var key [32]byte 55 | for i := range key { 56 | key[i] = byte(i) 57 | } 58 | 59 | msg := make([]byte, 64) 60 | var tag, sum [TagSize]byte 61 | for i := range msg { 62 | h := New(&key) 63 | h.Write(msg[:i]) 64 | h.Sum(&sum) 65 | 66 | Sum(&tag, msg[:i], &key) 67 | 68 | if tag != sum { 69 | t.Fatalf("Iteration %d: Sum differ from poly1305.Sum\n Sum: %s \n poly1305.Sum %s", i, hex.EncodeToString(sum[:]), hex.EncodeToString(tag[:])) 70 | } 71 | } 72 | } 73 | 74 | func TestVerify(t *testing.T) { 75 | for i, v := range vectors { 76 | key, err := hex.DecodeString(v.key) 77 | if err != nil { 78 | t.Fatalf("Test vector %d : Failed to decode key: %s", i, err) 79 | } 80 | msg, err := hex.DecodeString(v.msg) 81 | if err != nil { 82 | t.Fatalf("Test vector %d : Failed to decode msg: %s", i, err) 83 | } 84 | tag, err := hex.DecodeString(v.tag) 85 | if err != nil { 86 | t.Fatalf("Test vector %d : Failed to decode tag: %s", i, err) 87 | } 88 | 89 | var sum [TagSize]byte 90 | var k [32]byte 91 | 92 | copy(k[:], key) 93 | copy(sum[:], tag) 94 | 95 | if !Verify(&sum, msg, &k) { 96 | t.Fatalf("Test vector %d : Poly1305 Verification failed", i) 97 | } 98 | } 99 | } 100 | 101 | // Benchmarks 102 | 103 | func BenchmarkSum_8(b *testing.B) { benchmarkSum(b, 8, false) } 104 | func BenchmarkSumUnaligned_8(b *testing.B) { benchmarkSum(b, 8, true) } 105 | func BenchmarkSum_4K(b *testing.B) { benchmarkSum(b, 4*1024, false) } 106 | func BenchmarkSumUnaligned_4K(b *testing.B) { benchmarkSum(b, 4*1024, true) } 107 | func BenchmarkWrite_8(b *testing.B) { benchmarkWrite(b, 8, false) } 108 | func BenchmarkWriteUnaligned_8(b *testing.B) { benchmarkWrite(b, 8, true) } 109 | func BenchmarkWrite_4K(b *testing.B) { benchmarkWrite(b, 4*1024, false) } 110 | func BenchmarkWriteUnaligned_4K(b *testing.B) { benchmarkWrite(b, 4*1024, true) } 111 | 112 | func benchmarkSum(b *testing.B, size int, unalign bool) { 113 | var key [32]byte 114 | var tag [16]byte 115 | 116 | msg := make([]byte, size) 117 | if unalign { 118 | msg = unalignBytes(msg) 119 | } 120 | 121 | b.SetBytes(int64(size)) 122 | b.ResetTimer() 123 | for i := 0; i < b.N; i++ { 124 | Sum(&tag, msg, &key) 125 | } 126 | } 127 | 128 | func benchmarkWrite(b *testing.B, size int, unalign bool) { 129 | var key [32]byte 130 | h := New(&key) 131 | 132 | msg := make([]byte, size) 133 | if unalign { 134 | msg = unalignBytes(msg) 135 | } 136 | 137 | b.SetBytes(int64(size)) 138 | b.ResetTimer() 139 | for i := 0; i < b.N; i++ { 140 | h.Write(msg) 141 | } 142 | } 143 | 144 | func unalignBytes(in []byte) []byte { 145 | out := make([]byte, len(in)+1) 146 | if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { 147 | out = out[1:] 148 | } else { 149 | out = out[:len(in)] 150 | } 151 | copy(out, in) 152 | return out 153 | } 154 | -------------------------------------------------------------------------------- /blake2/blake2s/blake2s_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package blake2s 5 | 6 | import ( 7 | "testing" 8 | ) 9 | 10 | func TestBlockSize(t *testing.T) { 11 | h, err := New(32, nil) 12 | if err != nil { 13 | t.Fatalf("Failed to create BLAKE2s instance: %s", err) 14 | } 15 | if bs := h.BlockSize(); bs != BlockSize { 16 | t.Fatalf("BlockSize() returned: %d - but expected: %d", bs, BlockSize) 17 | } 18 | } 19 | 20 | func TestSize(t *testing.T) { 21 | h, err := New(32, nil) 22 | if err != nil { 23 | t.Fatalf("Failed to create BLAKE2s instance: %s", err) 24 | } 25 | if s := h.Size(); s != 32 { 26 | t.Fatalf("Size() returned: %d - but expected: %d", s, 32) 27 | } 28 | 29 | h, err = New(20, nil) 30 | if err != nil { 31 | t.Fatalf("Failed to create BLAKE2s instance: %s", err) 32 | } 33 | if s := h.Size(); s != 20 { 34 | t.Fatalf("Size() returned: %d - but expected: %d", s, 20) 35 | } 36 | } 37 | 38 | func TestReset(t *testing.T) { 39 | h, err := New(32, &Config{ 40 | Key: make([]byte, 32), 41 | Salt: make([]byte, 8), 42 | Personal: make([]byte, 4), 43 | }) 44 | if err != nil { 45 | t.Fatalf("Failed to create BLAKE2s instance: %s", err) 46 | } 47 | 48 | s, ok := h.(*hashFunc) 49 | if !ok { 50 | t.Fatal("Impossible situation: New returns no blake2s struct") 51 | } 52 | orig := *s // copy 53 | 54 | s.Write(make([]byte, (2*BlockSize)+1)) 55 | s.Reset() 56 | 57 | if s.hVal != orig.hVal { 58 | t.Fatalf("Reseted hVal field: %v - but expected: %v", s.hVal, orig.hVal) 59 | } 60 | if s.hValCpy != orig.hValCpy { 61 | t.Fatalf("Reseted hValCpy field: %v - but expected: %v", s.hValCpy, orig.hValCpy) 62 | } 63 | if s.block != orig.block { 64 | t.Fatalf("Reseted block field: %v - but expected: %v", s.block, orig.block) 65 | } 66 | if s.ctr != orig.ctr { 67 | t.Fatalf("Reseted ctr field: %v - but expected: %v", s.ctr, orig.ctr) 68 | } 69 | if s.key != orig.key { 70 | t.Fatalf("Reseted key field: %v - but expected: %v", s.key, orig.key) 71 | } 72 | if s.off != orig.off { 73 | t.Fatalf("Reseted off field %d - but expected %d", s.off, orig.off) 74 | } 75 | if s.hasKey != orig.hasKey { 76 | t.Fatalf("Reseted hasKey field %v - but expected %v", s.hasKey, orig.hasKey) 77 | 78 | } 79 | } 80 | 81 | func TestNew(t *testing.T) { 82 | _, err := New(0, nil) 83 | if err == nil { 84 | t.Fatal("New allowed 0 for hash size") 85 | } 86 | } 87 | 88 | func TestSum(t *testing.T) { 89 | _, err := Sum(nil, 0, nil) 90 | if err == nil { 91 | t.Fatal("Sum allowed 0 for hash size") 92 | } 93 | } 94 | 95 | func TestConfigure(t *testing.T) { 96 | var hval [8]uint32 97 | 98 | err := Configure(&hval, 0, nil) 99 | if err == nil { 100 | t.Fatal("Configure allowed 0 for hash size") 101 | } 102 | err = Configure(&hval, Size+1, nil) 103 | if err == nil { 104 | t.Fatalf("Configure allowed %d for hash size", Size+1) 105 | } 106 | err = Configure(&hval, Size, &Config{Key: make([]byte, Size+1)}) 107 | if err == nil { 108 | t.Fatalf("Configure allowed key with length %d", Size+1) 109 | } 110 | err = Configure(&hval, Size, &Config{Salt: make([]byte, 9)}) 111 | if err == nil { 112 | t.Fatalf("Configure allowed salt with length %d", 9) 113 | } 114 | err = Configure(&hval, Size, &Config{Personal: make([]byte, 9)}) 115 | if err == nil { 116 | t.Fatalf("Configure allowed personal with length %d", 9) 117 | } 118 | } 119 | 120 | // Benchmarks 121 | 122 | func benchmarkWrite(b *testing.B, size int) { 123 | h, err := New(32, nil) 124 | if err != nil { 125 | b.Fatalf("Failed to create BLAKE2s instance: %s", err) 126 | } 127 | buf := make([]byte, size) 128 | b.SetBytes(int64(size)) 129 | b.ResetTimer() 130 | for i := 0; i < b.N; i++ { 131 | h.Write(buf) 132 | } 133 | } 134 | 135 | func benchmarkSum(b *testing.B, size int) { 136 | buf := make([]byte, size) 137 | b.SetBytes(int64(size)) 138 | b.ResetTimer() 139 | for i := 0; i < b.N; i++ { 140 | Sum(buf, 32, nil) 141 | } 142 | } 143 | 144 | func BenchmarkWrite_64(b *testing.B) { benchmarkWrite(b, 64) } 145 | func BenchmarkWrite_1K(b *testing.B) { benchmarkWrite(b, 1024) } 146 | func BenchmarkSum_64(b *testing.B) { benchmarkSum(b, 64) } 147 | func BenchmarkSum_1K(b *testing.B) { benchmarkSum(b, 1024) } 148 | -------------------------------------------------------------------------------- /blake2/blake2b/blake2b_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package blake2b 5 | 6 | import ( 7 | "testing" 8 | ) 9 | 10 | func TestBlockSize(t *testing.T) { 11 | h, err := New(64, nil) 12 | if err != nil { 13 | t.Fatalf("Failed to create BLAKE2b instance: %s", err) 14 | } 15 | if bs := h.BlockSize(); bs != BlockSize { 16 | t.Fatalf("BlockSize() returned: %d - but expected: %d", bs, BlockSize) 17 | } 18 | } 19 | 20 | func TestSize(t *testing.T) { 21 | h, err := New(64, nil) 22 | if err != nil { 23 | t.Fatalf("Failed to create BLAKE2b instance: %s", err) 24 | } 25 | if s := h.Size(); s != 64 { 26 | t.Fatalf("Size() returned: %d - but expected: %d", s, 64) 27 | } 28 | 29 | h, err = New(32, nil) 30 | if err != nil { 31 | t.Fatalf("Failed to create BLAKE2b instance: %s", err) 32 | } 33 | if s := h.Size(); s != 32 { 34 | t.Fatalf("Size() returned: %d - but expected: %d", s, 64) 35 | } 36 | } 37 | 38 | func TestReset(t *testing.T) { 39 | h, err := New(32, &Config{ 40 | Key: make([]byte, 64), 41 | Salt: make([]byte, 16), 42 | Personal: make([]byte, 8), 43 | }) 44 | if err != nil { 45 | t.Fatalf("Failed to create BLAKE2b instance: %s", err) 46 | } 47 | 48 | s, ok := h.(*hashFunc) 49 | if !ok { 50 | t.Fatal("Impossible situation: New returns no blake2b struct") 51 | } 52 | orig := *s // copy 53 | 54 | s.Write(make([]byte, (2*BlockSize)+1)) 55 | s.Reset() 56 | 57 | if s.hVal != orig.hVal { 58 | t.Fatalf("Reseted hVal field: %v - but expected: %v", s.hVal, orig.hVal) 59 | } 60 | if s.hValCpy != orig.hValCpy { 61 | t.Fatalf("Reseted hValCpy field: %v - but expected: %v", s.hValCpy, orig.hValCpy) 62 | } 63 | if s.block != orig.block { 64 | t.Fatalf("Reseted block field: %v - but expected: %v", s.block, orig.block) 65 | } 66 | if s.ctr != orig.ctr { 67 | t.Fatalf("Reseted ctr field: %v - but expected: %v", s.ctr, orig.ctr) 68 | } 69 | if s.key != orig.key { 70 | t.Fatalf("Reseted key field: %v - but expected: %v", s.key, orig.key) 71 | } 72 | if s.off != orig.off { 73 | t.Fatalf("Reseted off field %d - but expected %d", s.off, orig.off) 74 | } 75 | if s.hasKey != orig.hasKey { 76 | t.Fatalf("Reseted hasKey field %v - but expected %v", s.hasKey, orig.hasKey) 77 | 78 | } 79 | } 80 | 81 | func TestNew(t *testing.T) { 82 | _, err := New(0, nil) 83 | if err == nil { 84 | t.Fatal("New allowed 0 for hash size") 85 | } 86 | } 87 | 88 | func TestSum(t *testing.T) { 89 | _, err := Sum(nil, 0, nil) 90 | if err == nil { 91 | t.Fatal("Sum allowed 0 for hash size") 92 | } 93 | } 94 | 95 | func TestConfigure(t *testing.T) { 96 | var hval [8]uint64 97 | 98 | err := Configure(&hval, 0, nil) 99 | if err == nil { 100 | t.Fatal("Configure allowed 0 for hash size") 101 | } 102 | err = Configure(&hval, Size+1, nil) 103 | if err == nil { 104 | t.Fatalf("Configure allowed %d for hash size", Size+1) 105 | } 106 | err = Configure(&hval, Size, &Config{Key: make([]byte, Size+1)}) 107 | if err == nil { 108 | t.Fatalf("Configure allowed key with length %d", Size+1) 109 | } 110 | err = Configure(&hval, Size, &Config{Salt: make([]byte, 17)}) 111 | if err == nil { 112 | t.Fatalf("Configure allowed salt with length %d", 17) 113 | } 114 | err = Configure(&hval, Size, &Config{Personal: make([]byte, 17)}) 115 | if err == nil { 116 | t.Fatalf("Configure allowed personal with length %d", 17) 117 | } 118 | } 119 | 120 | // Benchmarks 121 | 122 | func benchmarkWrite(b *testing.B, size int) { 123 | h, err := New(64, nil) 124 | if err != nil { 125 | b.Fatalf("Failed to create BLAKE2s instance: %s", err) 126 | } 127 | buf := make([]byte, size) 128 | b.SetBytes(int64(size)) 129 | b.ResetTimer() 130 | for i := 0; i < b.N; i++ { 131 | h.Write(buf) 132 | } 133 | } 134 | 135 | func benchmarkSum(b *testing.B, size int) { 136 | buf := make([]byte, size) 137 | b.SetBytes(int64(size)) 138 | b.ResetTimer() 139 | for i := 0; i < b.N; i++ { 140 | Sum(buf, 64, nil) 141 | } 142 | } 143 | 144 | func BenchmarkWrite_64(b *testing.B) { benchmarkWrite(b, 64) } 145 | func BenchmarkWrite_1K(b *testing.B) { benchmarkWrite(b, 1024) } 146 | func BenchmarkSum_64(b *testing.B) { benchmarkSum(b, 64) } 147 | func BenchmarkSum_1K(b *testing.B) { benchmarkSum(b, 1024) } 148 | -------------------------------------------------------------------------------- /hc256/hc256.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package hc256 implements the stream cipher 5 | // HC-256 designed by Hongjun Wu. 6 | package hc256 // import "github.com/enceve/crypto/hc256" 7 | 8 | import "crypto/cipher" 9 | 10 | const ( 11 | mod1024 uint32 = 0x3FF 12 | mod2048 uint32 = 0x7FF 13 | ) 14 | 15 | // NewCipher returns a new cipher.Stream implementing the 16 | // HC-256 cipher with the given key and nonce. 17 | func NewCipher(nonce, key *[32]byte) cipher.Stream { 18 | c := new(streamCipher) 19 | initialize(nonce, key, &(c.p), &(c.q)) 20 | return c 21 | } 22 | 23 | type streamCipher struct { 24 | p, q [1024]uint32 25 | ctr uint32 26 | keyStream [4]byte 27 | off int 28 | } 29 | 30 | func initialize(nonce, key *[32]byte, p, q *[1024]uint32) { 31 | var tmp [2560]uint32 32 | 33 | tmp[0] = uint32(key[0]) | (uint32(key[1]) << 8) | (uint32(key[2]) << 16) | (uint32(key[3]) << 24) 34 | tmp[1] = uint32(key[4]) | (uint32(key[5]) << 8) | (uint32(key[6]) << 16) | (uint32(key[7]) << 24) 35 | tmp[2] = uint32(key[8]) | (uint32(key[9]) << 8) | (uint32(key[10]) << 16) | (uint32(key[11]) << 24) 36 | tmp[3] = uint32(key[12]) | (uint32(key[13]) << 8) | (uint32(key[14]) << 16) | (uint32(key[15]) << 24) 37 | tmp[4] = uint32(key[16]) | (uint32(key[17]) << 8) | (uint32(key[18]) << 16) | (uint32(key[19]) << 24) 38 | tmp[5] = uint32(key[20]) | (uint32(key[21]) << 8) | (uint32(key[22]) << 16) | (uint32(key[23]) << 24) 39 | tmp[6] = uint32(key[24]) | (uint32(key[25]) << 8) | (uint32(key[26]) << 16) | (uint32(key[27]) << 24) 40 | tmp[7] = uint32(key[28]) | (uint32(key[29]) << 8) | (uint32(key[30]) << 16) | (uint32(key[31]) << 24) 41 | 42 | tmp[8] = uint32(nonce[0]) | (uint32(nonce[1]) << 8) | (uint32(nonce[2]) << 16) | (uint32(nonce[3]) << 24) 43 | tmp[9] = uint32(nonce[4]) | (uint32(nonce[5]) << 8) | (uint32(nonce[6]) << 16) | (uint32(nonce[7]) << 24) 44 | tmp[10] = uint32(nonce[8]) | (uint32(nonce[9]) << 8) | (uint32(nonce[10]) << 16) | (uint32(nonce[11]) << 24) 45 | tmp[11] = uint32(nonce[12]) | (uint32(nonce[13]) << 8) | (uint32(nonce[14]) << 16) | (uint32(nonce[15]) << 24) 46 | tmp[12] = uint32(nonce[16]) | (uint32(nonce[17]) << 8) | (uint32(nonce[18]) << 16) | (uint32(nonce[19]) << 24) 47 | tmp[13] = uint32(nonce[20]) | (uint32(nonce[21]) << 8) | (uint32(nonce[22]) << 16) | (uint32(nonce[23]) << 24) 48 | tmp[14] = uint32(nonce[24]) | (uint32(nonce[25]) << 8) | (uint32(nonce[26]) << 16) | (uint32(nonce[27]) << 24) 49 | tmp[15] = uint32(nonce[28]) | (uint32(nonce[29]) << 8) | (uint32(nonce[30]) << 16) | (uint32(nonce[31]) << 24) 50 | 51 | // expand key and nonce with the f1 and f2 functions 52 | // (2.2 https://eprint.iacr.org/2004/092.pdf) 53 | var f2, f1 uint32 54 | for i := 16; i < 2560; i++ { 55 | f1, f2 = tmp[i-15], tmp[i-2] 56 | f1 = ((f1 >> 7) | (f1 << 25)) ^ ((f1 >> 18) | (f1 << 14)) ^ (f1 >> 3) 57 | f2 = ((f2 >> 17) | (f2 << 15)) ^ ((f2 >> 19) | (f2 << 13)) ^ (f2 >> 10) 58 | tmp[i] = f1 + f2 + tmp[i-7] + tmp[i-16] + uint32(i) 59 | } 60 | copy(p[:], tmp[512:(512+1024)]) 61 | copy(q[:], tmp[1536:(1536+1024)]) 62 | 63 | // do 4096 iterations for initialization 64 | var ctr uint32 65 | for i := 0; i < 4096; i++ { 66 | genKeyStream(&ctr, p, q) 67 | } 68 | } 69 | 70 | func genKeyStream(counter *uint32, p, q *[1024]uint32) uint32 { 71 | var r, t0, t1, t2, t3 uint32 72 | ctr := *counter 73 | 74 | j := ctr & mod1024 75 | if ctr < 1024 { 76 | t0 = p[(j-3)&mod1024] 77 | t1 = p[(j-1023)&mod1024] 78 | t2 = t0 ^ t1 79 | 80 | t0 = (t0 >> 10) | (t0 << 22) 81 | t1 = (t1 >> 23) | (t1 << 9) 82 | t3 = t0 ^ t1 83 | t0 = p[(j-10)&mod1024] 84 | t1 = q[t2&mod1024] 85 | 86 | p[j] += t0 + t1 + t3 87 | 88 | t3 = p[(j-12)&mod1024] 89 | t0 = 256 + ((t3 >> 8) & 0xff) 90 | t1 = 512 + ((t3 >> 16) & 0xff) 91 | t2 = 768 + ((t3 >> 24) & 0xff) 92 | t3 = t3 & 0xff 93 | 94 | r = q[t3] + q[t0] + q[t1] + q[t2] ^ p[j] 95 | } else { 96 | t0 = q[(j-3)&mod1024] 97 | t1 = q[(j-1023)&mod1024] 98 | t2 = t0 ^ t1 99 | 100 | t0 = (t0 >> 10) | (t0 << 22) 101 | t1 = (t1 >> 23) | (t1 << 9) 102 | t3 = t0 ^ t1 103 | t0 = q[(j-10)&mod1024] 104 | t1 = p[t2&mod1024] 105 | 106 | q[j] += t0 + t1 + t3 107 | 108 | t3 = q[(j-12)&mod1024] 109 | t0 = 256 + ((t3 >> 8) & 0xff) 110 | t1 = 512 + ((t3 >> 16) & 0xff) 111 | t2 = 768 + ((t3 >> 24) & 0xff) 112 | t3 = t3 & 0xff 113 | 114 | r = p[t3] + p[t0] + p[t1] + p[t2] ^ q[j] 115 | } 116 | 117 | *counter = (ctr + 1) & mod2048 118 | return r 119 | } 120 | -------------------------------------------------------------------------------- /chacha20/chachaPoly1305.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package chacha20 5 | 6 | import ( 7 | "crypto/cipher" 8 | "crypto/subtle" 9 | "errors" 10 | 11 | "github.com/enceve/crypto" 12 | "github.com/enceve/crypto/chacha20/chacha" 13 | "github.com/enceve/crypto/poly1305" 14 | ) 15 | 16 | // The max. size of the auth. tag for the ChaCha20Poly1305 AEAD cipher in bytes. 17 | const TagSize = poly1305.TagSize 18 | 19 | // NewChaCha20Poly1305 returns a cipher.AEAD implementing the 20 | // ChaCha20Poly1305 construction specified in RFC 7539 with a 21 | // 128 bit auth. tag. 22 | func NewChaCha20Poly1305(key *[32]byte) cipher.AEAD { 23 | c := &aead{tagsize: TagSize} 24 | c.key = *key 25 | return c 26 | } 27 | 28 | // NewChaCha20Poly1305WithTagSize returns a cipher.AEAD implementing the 29 | // ChaCha20Poly1305 construction specified in RFC 7539 with arbitrary tag size. 30 | // The tagsize must be between 1 and the TagSize constant. 31 | func NewChaCha20Poly1305WithTagSize(key *[32]byte, tagsize int) (cipher.AEAD, error) { 32 | if tagsize < 1 || tagsize > TagSize { 33 | return nil, errors.New("tag size must be between 1 and 16") 34 | } 35 | c := &aead{tagsize: tagsize} 36 | c.key = *key 37 | return c, nil 38 | } 39 | 40 | // The AEAD cipher ChaCha20-Poly1305 41 | type aead struct { 42 | key [32]byte 43 | tagsize int 44 | } 45 | 46 | func (c *aead) Overhead() int { return c.tagsize } 47 | 48 | func (c *aead) NonceSize() int { return NonceSize } 49 | 50 | func (c *aead) Seal(dst, nonce, plaintext, additionalData []byte) []byte { 51 | if n := len(nonce); n != NonceSize { 52 | panic(crypto.NonceSizeError(n)) 53 | } 54 | if len(dst) < len(plaintext)+c.tagsize { 55 | panic("dst buffer to small") 56 | } 57 | var Nonce [12]byte 58 | copy(Nonce[:], nonce) 59 | 60 | // create the poly1305 key 61 | var polyKey [32]byte 62 | chacha.XORKeyStream(polyKey[:], polyKey[:], &Nonce, &(c.key), 0, 20) 63 | 64 | // encrypt the plaintext 65 | n := len(plaintext) 66 | chacha.XORKeyStream(dst, plaintext, &Nonce, &(c.key), 1, 20) 67 | 68 | // authenticate the ciphertext 69 | var tag [poly1305.TagSize]byte 70 | authenticate(&tag, dst[:n], additionalData, &polyKey) 71 | return append(dst[:n], tag[:c.tagsize]...) 72 | } 73 | 74 | func (c *aead) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { 75 | if n := len(nonce); n != NonceSize { 76 | return nil, crypto.NonceSizeError(n) 77 | } 78 | if len(ciphertext) < c.tagsize { 79 | return nil, crypto.AuthenticationError{} 80 | } 81 | if len(dst) < len(ciphertext)-c.tagsize { 82 | panic("dst buffer to small") 83 | } 84 | var Nonce [12]byte 85 | 86 | copy(Nonce[:], nonce) 87 | 88 | hash := ciphertext[len(ciphertext)-c.tagsize:] 89 | ciphertext = ciphertext[:len(ciphertext)-c.tagsize] 90 | 91 | // create the poly1305 key 92 | var polyKey [32]byte 93 | chacha.XORKeyStream(polyKey[:], polyKey[:], &Nonce, &(c.key), 0, 20) 94 | 95 | // authenticate the ciphertext 96 | var tag [poly1305.TagSize]byte 97 | authenticate(&tag, ciphertext, additionalData, &polyKey) 98 | if subtle.ConstantTimeCompare(tag[:c.tagsize], hash[:c.tagsize]) != 1 { 99 | return nil, crypto.AuthenticationError{} 100 | } 101 | 102 | // decrypt ciphertext 103 | chacha.XORKeyStream(dst, ciphertext, &Nonce, &(c.key), 1, 20) 104 | return dst[:len(ciphertext)], nil 105 | } 106 | 107 | // authenticate calculates the poly1305 tag from 108 | // the given ciphertext and additional data. 109 | func authenticate(out *[TagSize]byte, ciphertext, additionalData []byte, key *[32]byte) { 110 | ctLen := uint64(len(ciphertext)) 111 | adLen := uint64(len(additionalData)) 112 | padAD, padCT := adLen%16, ctLen%16 113 | 114 | var buf [16]byte 115 | buf[0] = byte(adLen) 116 | buf[1] = byte(adLen >> 8) 117 | buf[2] = byte(adLen >> 16) 118 | buf[3] = byte(adLen >> 24) 119 | buf[4] = byte(adLen >> 32) 120 | buf[5] = byte(adLen >> 40) 121 | buf[6] = byte(adLen >> 48) 122 | buf[7] = byte(adLen >> 56) 123 | buf[8] = byte(ctLen) 124 | buf[9] = byte(ctLen >> 8) 125 | buf[10] = byte(ctLen >> 16) 126 | buf[11] = byte(ctLen >> 24) 127 | buf[12] = byte(ctLen >> 32) 128 | buf[13] = byte(ctLen >> 40) 129 | buf[14] = byte(ctLen >> 48) 130 | buf[15] = byte(ctLen >> 56) 131 | 132 | poly := poly1305.New(key) 133 | poly.Write(additionalData) 134 | if padAD > 0 { 135 | poly.Write(make([]byte, 16-padAD)) 136 | } 137 | poly.Write(ciphertext) 138 | if padCT > 0 { 139 | poly.Write(make([]byte, 16-padCT)) 140 | } 141 | poly.Write(buf[:]) 142 | poly.Sum(out) 143 | } 144 | -------------------------------------------------------------------------------- /siphash/siphash_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package siphash 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | "unsafe" 11 | ) 12 | 13 | func TestBlockSize(t *testing.T) { 14 | var key [16]byte 15 | h := New(&key) 16 | if bs := h.BlockSize(); bs != 8 { 17 | t.Fatalf("BlockSize() returned: %d - but expected: %d", bs, 8) 18 | } 19 | } 20 | 21 | func TestSize(t *testing.T) { 22 | var key [16]byte 23 | h := New(&key) 24 | if bs := h.Size(); bs != 8 { 25 | t.Fatalf("Size() returned: %d - but expected: %d", bs, 8) 26 | } 27 | } 28 | 29 | func TestReset(t *testing.T) { 30 | var key [16]byte 31 | h := New(&key) 32 | s, ok := h.(*hashFunc) 33 | if !ok { 34 | t.Fatal("Impossible situation: New returns no siphash struct") 35 | } 36 | orig := *s // copy 37 | 38 | s.Write(make([]byte, 18)) 39 | s.Reset() 40 | 41 | if s.hVal != orig.hVal { 42 | t.Fatalf("Reseted hVal field: %d - but expected: %d", s.block, orig.block) 43 | } 44 | if s.block != orig.block { 45 | t.Fatalf("Reseted block field: %d - but expected: %d", s.block, orig.block) 46 | } 47 | if s.ctr != orig.ctr { 48 | t.Fatalf("Reseted ctr field: %v - but expected: %v", s.ctr, orig.ctr) 49 | } 50 | if s.key != orig.key { 51 | t.Fatalf("Reseted key field: %v - but expected: %v", s.key, orig.key) 52 | } 53 | if s.off != orig.off { 54 | t.Fatalf("Reseted off field %v - but expected %v", s.off, orig.off) 55 | } 56 | } 57 | 58 | func TestWrite(t *testing.T) { 59 | var key [16]byte 60 | for i := range key { 61 | key[i] = byte(i) 62 | } 63 | 64 | h := New(&key) 65 | 66 | var msg1 []byte 67 | msg0 := make([]byte, 64) 68 | for i := range msg0 { 69 | h.Write(msg0[:i]) 70 | msg1 = append(msg1, msg0[:i]...) 71 | } 72 | 73 | if tag0, tag1 := h.Sum64(), Sum64(msg1, &key); tag0 != tag1 { 74 | t.Fatalf("Sum64 differ from siphash.Sum64\n Sum64: %x \n siphash.Sum64: %x", tag0, tag1) 75 | } 76 | } 77 | 78 | func TestSum(t *testing.T) { 79 | var key [16]byte 80 | for i := range key { 81 | key[i] = byte(i) 82 | } 83 | h := New(&key) 84 | 85 | msg := make([]byte, 64) 86 | var tag [8]byte 87 | for i := range msg { 88 | h.Write(msg[:i]) 89 | sum := h.Sum(nil) 90 | h.Reset() 91 | 92 | Sum(&tag, msg[:i], &key) 93 | 94 | if !bytes.Equal(sum, tag[:]) { 95 | t.Fatalf("Iteration %d: Sum differ from siphash.Sum\n Sum: %s \n sipash.Sum %s", i, hex.EncodeToString(sum), hex.EncodeToString(tag[:])) 96 | } 97 | } 98 | } 99 | 100 | func TestVerify(t *testing.T) { 101 | var key [16]byte 102 | for i := range key { 103 | key[i] = byte(i) 104 | } 105 | h := New(&key) 106 | 107 | msg := make([]byte, 64) 108 | var tag [8]byte 109 | for i := range msg { 110 | h.Write(msg[:i]) 111 | h.Sum(tag[:0]) 112 | h.Reset() 113 | 114 | if !Verify(&tag, msg[:i], &key) { 115 | t.Fatalf("Iteration %d: Verify failed: %s not accepted ", i, hex.EncodeToString(tag[:])) 116 | } 117 | } 118 | } 119 | 120 | // Benchmarks 121 | 122 | func BenchmarkWrite_8(b *testing.B) { benchmarkWrite(b, 8, false) } 123 | func BenchmarkWriteUnaligned_8(b *testing.B) { benchmarkWrite(b, 8, true) } 124 | func BenchmarkWrite_1K(b *testing.B) { benchmarkWrite(b, 1024, false) } 125 | func BenchmarkWriteUnaligned_1K(b *testing.B) { benchmarkWrite(b, 1024, true) } 126 | func BenchmarkSum_8(b *testing.B) { benchmarkWrite(b, 8, false) } 127 | func BenchmarkSumUnaligned_8(b *testing.B) { benchmarkWrite(b, 8, true) } 128 | func BenchmarkSum_1K(b *testing.B) { benchmarkWrite(b, 1024, false) } 129 | func BenchmarkSumUnaligned_1K(b *testing.B) { benchmarkWrite(b, 1024, true) } 130 | 131 | func unalignBytes(in []byte) []byte { 132 | out := make([]byte, len(in)+1) 133 | if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { 134 | out = out[1:] 135 | } else { 136 | out = out[:len(in)] 137 | } 138 | copy(out, in) 139 | return out 140 | } 141 | 142 | func benchmarkWrite(b *testing.B, size int, unalign bool) { 143 | var key [16]byte 144 | h := New(&key) 145 | msg := make([]byte, size) 146 | if unalign { 147 | msg = unalignBytes(msg) 148 | } 149 | 150 | b.SetBytes(int64(size)) 151 | b.ResetTimer() 152 | for i := 0; i < b.N; i++ { 153 | h.Write(msg) 154 | } 155 | } 156 | 157 | func benchmarkSum(b *testing.B, size int, unalign bool) { 158 | var out [TagSize]byte 159 | var key [16]byte 160 | msg := make([]byte, size) 161 | if unalign { 162 | msg = unalignBytes(msg) 163 | } 164 | 165 | b.SetBytes(int64(size)) 166 | b.ResetTimer() 167 | for i := 0; i < b.N; i++ { 168 | Sum(&out, msg, &key) 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /skein/skein512.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | package skein 5 | 6 | import ( 7 | "github.com/enceve/crypto/skein/threefish" 8 | ) 9 | 10 | type hashFunc struct { 11 | hashsize int 12 | hVal, hValCpy [9]uint64 13 | tweak [3]uint64 14 | block [BlockSize]byte 15 | off int 16 | hasMsg bool 17 | } 18 | 19 | func (s *hashFunc) BlockSize() int { return BlockSize } 20 | 21 | func (s *hashFunc) Size() int { return s.hashsize } 22 | 23 | func (s *hashFunc) Reset() { 24 | for i := range s.block { 25 | s.block[i] = 0 26 | } 27 | s.off = 0 28 | s.hasMsg = false 29 | 30 | s.hVal = s.hValCpy 31 | 32 | s.tweak[0] = 0 33 | s.tweak[1] = CfgMessage<<56 | FirstBlock 34 | } 35 | 36 | func (s *hashFunc) Write(p []byte) (n int, err error) { 37 | s.hasMsg = true 38 | 39 | n = len(p) 40 | var block [8]uint64 41 | 42 | dif := BlockSize - s.off 43 | if s.off > 0 && n > dif { 44 | s.off += copy(s.block[s.off:], p[:dif]) 45 | p = p[dif:] 46 | if s.off == BlockSize && len(p) > 0 { 47 | bytesToBlock(&block, s.block[:]) 48 | s.update(&block) 49 | s.off = 0 50 | } 51 | } 52 | 53 | if length := len(p); length > BlockSize { 54 | nn := length & (^(BlockSize - 1)) // length -= (length % BlockSize) 55 | if length == nn { 56 | nn -= BlockSize 57 | } 58 | for i := 0; i < len(p[:nn]); i += BlockSize { 59 | bytesToBlock(&block, p[i:]) 60 | s.update(&block) 61 | } 62 | p = p[nn:] 63 | } 64 | 65 | if len(p) > 0 { 66 | s.off += copy(s.block[s.off:], p) 67 | } 68 | return 69 | } 70 | 71 | func (s *hashFunc) Sum(b []byte) []byte { 72 | s0 := *s // copy 73 | 74 | if s0.hasMsg { 75 | s0.finalizeHash() 76 | } 77 | 78 | var out [BlockSize]byte 79 | var ctr uint64 80 | for i := s0.hashsize; i > 0; i -= BlockSize { 81 | s0.output(&out, ctr) 82 | ctr++ 83 | b = append(b, out[:]...) 84 | } 85 | return b[:s0.hashsize] 86 | } 87 | 88 | func (s *hashFunc) update(block *[8]uint64) { 89 | threefish.IncrementTweak(&(s.tweak), BlockSize) 90 | 91 | threefish.UBI512(block, &(s.hVal), &(s.tweak)) 92 | 93 | s.tweak[1] &^= FirstBlock 94 | } 95 | 96 | func (s *hashFunc) output(dst *[BlockSize]byte, counter uint64) { 97 | var block [8]uint64 98 | block[0] = counter 99 | 100 | hVal := s.hVal 101 | var outTweak = [3]uint64{8, CfgOutput<<56 | FirstBlock | FinalBlock, 0} 102 | 103 | threefish.UBI512(&block, &hVal, &outTweak) 104 | block[0] ^= counter 105 | 106 | blockToBytes(dst[:], &block) 107 | } 108 | 109 | func (s *hashFunc) initialize(hashsize int, conf *Config) { 110 | if hashsize < 1 { 111 | panic("skein: invalid hashsize for Skein-512") 112 | } 113 | 114 | s.hashsize = hashsize 115 | 116 | var key, pubKey, keyID, nonce, personal []byte 117 | if conf != nil { 118 | key = conf.Key 119 | pubKey = conf.PublicKey 120 | keyID = conf.KeyID 121 | nonce = conf.Nonce 122 | personal = conf.Personal 123 | } 124 | 125 | if len(key) > 0 { 126 | s.tweak[0] = 0 127 | s.tweak[1] = CfgKey<<56 | FirstBlock 128 | s.Write(key) 129 | s.finalizeHash() 130 | } 131 | 132 | var cfg [32]byte 133 | schemaId := SchemaID 134 | cfg[0] = byte(schemaId) 135 | cfg[1] = byte(schemaId >> 8) 136 | cfg[2] = byte(schemaId >> 16) 137 | cfg[3] = byte(schemaId >> 24) 138 | cfg[4] = byte(schemaId >> 32) 139 | cfg[5] = byte(schemaId >> 40) 140 | cfg[6] = byte(schemaId >> 48) 141 | cfg[7] = byte(schemaId >> 56) 142 | 143 | bits := uint64(s.hashsize * 8) 144 | cfg[8] = byte(bits) 145 | cfg[9] = byte(bits >> 8) 146 | cfg[10] = byte(bits >> 16) 147 | cfg[11] = byte(bits >> 24) 148 | cfg[12] = byte(bits >> 32) 149 | cfg[13] = byte(bits >> 40) 150 | cfg[14] = byte(bits >> 48) 151 | cfg[15] = byte(bits >> 56) 152 | 153 | s.tweak[0] = 0 154 | s.tweak[1] = CfgConfig<<56 | FirstBlock 155 | s.Write(cfg[:]) 156 | s.finalizeHash() 157 | 158 | if len(personal) > 0 { 159 | s.tweak[0] = 0 160 | s.tweak[1] = CfgPersonal<<56 | FirstBlock 161 | s.Write(personal) 162 | s.finalizeHash() 163 | } 164 | 165 | if len(pubKey) > 0 { 166 | s.tweak[0] = 0 167 | s.tweak[1] = CfgPublicKey<<56 | FirstBlock 168 | s.Write(pubKey) 169 | s.finalizeHash() 170 | } 171 | 172 | if len(keyID) > 0 { 173 | s.tweak[0] = 0 174 | s.tweak[1] = CfgKeyID<<56 | FirstBlock 175 | s.Write(keyID) 176 | s.finalizeHash() 177 | } 178 | 179 | if len(nonce) > 0 { 180 | s.tweak[0] = 0 181 | s.tweak[1] = CfgNonce<<56 | FirstBlock 182 | s.Write(nonce) 183 | s.finalizeHash() 184 | } 185 | 186 | s.hValCpy = s.hVal 187 | 188 | s.Reset() 189 | } 190 | 191 | func (s *hashFunc) finalizeHash() { 192 | threefish.IncrementTweak(&(s.tweak), uint64(s.off)) 193 | s.tweak[1] |= FinalBlock 194 | 195 | for i := s.off; i < len(s.block); i++ { 196 | s.block[i] = 0 197 | } 198 | s.off = 0 199 | 200 | var block [8]uint64 201 | bytesToBlock(&block, s.block[:]) 202 | 203 | threefish.UBI512(&block, &(s.hVal), &(s.tweak)) 204 | } 205 | -------------------------------------------------------------------------------- /skein/skein_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | package skein 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "hash" 10 | "testing" 11 | ) 12 | 13 | func testWrite(msg string, t *testing.T, h hash.Hash, c *Config) { 14 | var msg1 []byte 15 | msg0 := make([]byte, 64) 16 | for i := range msg0 { 17 | h.Write(msg0[:i]) 18 | msg1 = append(msg1, msg0[:i]...) 19 | } 20 | tag0 := h.Sum(nil) 21 | tag1 := Sum(msg1, h.Size(), c) 22 | 23 | if !bytes.Equal(tag0, tag1) { 24 | t.Fatalf("%s\nSum differ from Sum\n Sum: %s \n skein.Sum: %s", msg, hex.EncodeToString(tag0), hex.EncodeToString(tag1)) 25 | } 26 | } 27 | 28 | func TestWrite(t *testing.T) { 29 | testWrite("testWrite(t, New256(nil), nil)", t, New256(nil), nil) 30 | testWrite("testWrite(t, New256(make([]byte, 16)), &Config{Key: make([]byte, 16)})", t, New256(make([]byte, 16)), &Config{Key: make([]byte, 16)}) 31 | 32 | testWrite("testWrite(t, New512(nil), nil)", t, New512(nil), nil) 33 | testWrite("testWrite(t, New512(make([]byte, 16)), &Config{Key: make([]byte, 16)})", t, New512(make([]byte, 16)), &Config{Key: make([]byte, 16)}) 34 | 35 | testWrite("testWrite(t, New(128, nil), nil)", t, New(128, nil), nil) 36 | testWrite("testWrite(t, New(128, &Config{Key: make([]byte, 16)}), &Config{Key: make([]byte, 16)})", t, New(128, &Config{Key: make([]byte, 16)}), &Config{Key: make([]byte, 16)}) 37 | } 38 | 39 | func TestBlockSize(t *testing.T) { 40 | h := New(64, nil) 41 | if bs := h.BlockSize(); bs != BlockSize { 42 | t.Fatalf("BlockSize() returned: %d - but expected: %d", bs, BlockSize) 43 | } 44 | } 45 | 46 | func TestSum(t *testing.T) { 47 | sizes := []int{20, 32, 48, 64} 48 | key := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 49 | msg := make([]byte, 512) 50 | for i := range msg { 51 | msg[i] = byte(i) + key[i%len(key)] 52 | } 53 | c := &Config{Key: key} 54 | 55 | for _, hashsize := range sizes { 56 | switch hashsize { 57 | case 20: 58 | { 59 | var sum0 [20]byte 60 | Sum160(&sum0, msg, key) 61 | sum1 := Sum(msg, hashsize, c) 62 | if !bytes.Equal(sum0[:], sum1) { 63 | t.Fatalf("Sum160 differ from Sum: Sum160: %s\n Sum: %s", hex.EncodeToString(sum0[:]), hex.EncodeToString(sum1)) 64 | } 65 | } 66 | case 32: 67 | { 68 | var sum0 [32]byte 69 | Sum256(&sum0, msg, key) 70 | sum1 := Sum(msg, hashsize, c) 71 | if !bytes.Equal(sum0[:], sum1) { 72 | t.Fatalf("Sum256 differ from Sum: Sum256: %s\n Sum: %s", hex.EncodeToString(sum0[:]), hex.EncodeToString(sum1)) 73 | } 74 | } 75 | case 48: 76 | { 77 | var sum0 [48]byte 78 | Sum384(&sum0, msg, key) 79 | sum1 := Sum(msg, hashsize, c) 80 | if !bytes.Equal(sum0[:], sum1) { 81 | t.Fatalf("Sum384 differ from Sum: Sum384: %s\n Sum: %s", hex.EncodeToString(sum0[:]), hex.EncodeToString(sum1)) 82 | } 83 | } 84 | case 64: 85 | { 86 | var sum0 [64]byte 87 | Sum512(&sum0, msg, key) 88 | sum1 := Sum(msg, hashsize, c) 89 | if !bytes.Equal(sum0[:], sum1) { 90 | t.Fatalf("Sum512 differ from Sum: Sum512: %s\n Sum: %s", hex.EncodeToString(sum0[:]), hex.EncodeToString(sum1)) 91 | } 92 | } 93 | } 94 | } 95 | } 96 | 97 | func TestInitialize(t *testing.T) { 98 | rec := func() { 99 | if err := recover(); err == nil { 100 | t.Fatal("Recover expected error, but no one occured") 101 | } 102 | } 103 | mustFail := func() { 104 | defer rec() 105 | s := new(hashFunc) 106 | s.initialize(0, nil) 107 | } 108 | mustFail() 109 | 110 | c := &Config{ 111 | Key: make([]byte, 16), 112 | KeyID: make([]byte, 16), 113 | Personal: make([]byte, 8), 114 | Nonce: make([]byte, 12), 115 | PublicKey: make([]byte, 128), 116 | } 117 | testWrite("testWrite(t, New(64, c), c)", t, New(64, c), c) 118 | } 119 | 120 | // Benchmarks 121 | 122 | func benchmarkSum(b *testing.B, size int) { 123 | msg := make([]byte, size) 124 | b.SetBytes(int64(size)) 125 | b.ResetTimer() 126 | for i := 0; i < b.N; i++ { 127 | Sum(msg, 64, nil) 128 | } 129 | } 130 | 131 | func benchmarkSum512(b *testing.B, size int) { 132 | var sum [64]byte 133 | msg := make([]byte, size) 134 | b.SetBytes(int64(size)) 135 | b.ResetTimer() 136 | for i := 0; i < b.N; i++ { 137 | Sum512(&sum, msg, nil) 138 | } 139 | } 140 | 141 | func BenchmarkSum_64(b *testing.B) { benchmarkSum(b, 64) } 142 | func BenchmarkSum_1K(b *testing.B) { benchmarkSum(b, 1024) } 143 | func BenchmarkSum512_64(b *testing.B) { benchmarkSum512(b, 64) } 144 | func BenchmarkSum512_1K(b *testing.B) { benchmarkSum512(b, 1024) } 145 | 146 | func benchmarkWrite(b *testing.B, size int) { 147 | h := New512(nil) 148 | msg := make([]byte, size) 149 | b.SetBytes(int64(size)) 150 | b.ResetTimer() 151 | for i := 0; i < b.N; i++ { 152 | h.Write(msg) 153 | } 154 | } 155 | 156 | func BenchmarkWrite_64(b *testing.B) { benchmarkWrite(b, 64) } 157 | func BenchmarkWrite_1K(b *testing.B) { benchmarkWrite(b, 1024) } 158 | -------------------------------------------------------------------------------- /dh/ecdh/ecdh_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package ecdh 5 | 6 | import ( 7 | "bytes" 8 | "crypto/elliptic" 9 | "crypto/rand" 10 | "fmt" 11 | "testing" 12 | ) 13 | 14 | // An example for the ECDH key-exchange using the curve P256. 15 | func ExampleGenericKeyExchange() { 16 | p256 := GenericCurve(elliptic.P256()) 17 | 18 | privateAlice, publicAlice, err := p256.GenerateKey(rand.Reader) 19 | if err != nil { 20 | fmt.Printf("Failed to generate Alice's private/public key pair: %s\n", err) 21 | } 22 | privateBob, publicBob, err := p256.GenerateKey(rand.Reader) 23 | if err != nil { 24 | fmt.Printf("Failed to generate Bob's private/public key pair: %s\n", err) 25 | } 26 | 27 | if err := p256.Check(publicBob); err != nil { 28 | fmt.Printf("Bob's public key is not on the curve: %s\n", err) 29 | } 30 | secretAlice := p256.ComputeSecret(privateAlice, publicBob) 31 | 32 | if err := p256.Check(publicAlice); err != nil { 33 | fmt.Printf("Alice's public key is not on the curve: %s\n", err) 34 | } 35 | secretBob := p256.ComputeSecret(privateBob, publicAlice) 36 | 37 | if !bytes.Equal(secretAlice, secretBob) { 38 | fmt.Printf("key exchange failed - secret X coordinates not equal\n") 39 | } 40 | 41 | fmt.Println("\nkey exchange succeed\n") 42 | // Output: 43 | // key exchange succeed 44 | } 45 | 46 | // An example for the ECDH key-exchange using Curve25519. 47 | func ExampleCurve25519KeyExchange() { 48 | c25519 := Curve25519() 49 | 50 | privateAlice, publicAlice, err := c25519.GenerateKey(rand.Reader) 51 | if err != nil { 52 | fmt.Printf("Failed to generate Alice's private/public key pair: %s\n", err) 53 | } 54 | privateBob, publicBob, err := c25519.GenerateKey(rand.Reader) 55 | if err != nil { 56 | fmt.Printf("Failed to generate Bob's private/public key pair: %s\n", err) 57 | } 58 | 59 | if err := c25519.Check(publicBob); err != nil { 60 | fmt.Printf("Bob's public key is not on the curve: %s\n", err) 61 | } 62 | secretAlice := c25519.ComputeSecret(privateAlice, publicBob) 63 | 64 | if err := c25519.Check(publicAlice); err != nil { 65 | fmt.Printf("Alice's public key is not on the curve: %s\n", err) 66 | } 67 | secretBob := c25519.ComputeSecret(privateBob, publicAlice) 68 | 69 | if !bytes.Equal(secretAlice, secretBob) { 70 | fmt.Printf("key exchange failed - secret X coordinates not equal\n") 71 | } 72 | 73 | fmt.Println("\nkey exchange succeed\n") 74 | // Output: 75 | // key exchange succeed 76 | } 77 | 78 | func BenchmarkCurve25519(b *testing.B) { 79 | curve := Curve25519() 80 | privateAlice, _, err := curve.GenerateKey(rand.Reader) 81 | if err != nil { 82 | b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) 83 | } 84 | _, publicBob, err := curve.GenerateKey(rand.Reader) 85 | if err != nil { 86 | b.Fatalf("Failed to generate Bob's private/public key pair: %s", err) 87 | } 88 | for i := 0; i < b.N; i++ { 89 | curve.ComputeSecret(privateAlice, publicBob) 90 | } 91 | } 92 | 93 | func BenchmarkKeyGenerateCurve25519(b *testing.B) { 94 | curve := Curve25519() 95 | for i := 0; i < b.N; i++ { 96 | _, _, err := curve.GenerateKey(rand.Reader) 97 | if err != nil { 98 | b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) 99 | } 100 | } 101 | } 102 | 103 | func BenchmarkP256(b *testing.B) { 104 | p256 := GenericCurve(elliptic.P256()) 105 | privateAlice, _, err := p256.GenerateKey(rand.Reader) 106 | if err != nil { 107 | b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) 108 | } 109 | _, publicBob, err := p256.GenerateKey(rand.Reader) 110 | if err != nil { 111 | b.Fatalf("Failed to generate Bob's private/public key pair: %s", err) 112 | } 113 | b.ResetTimer() 114 | for i := 0; i < b.N; i++ { 115 | p256.ComputeSecret(privateAlice, publicBob) 116 | } 117 | } 118 | 119 | func BenchmarkKeyGenerateP256(b *testing.B) { 120 | p256 := GenericCurve(elliptic.P256()) 121 | for i := 0; i < b.N; i++ { 122 | _, _, err := p256.GenerateKey(rand.Reader) 123 | if err != nil { 124 | b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) 125 | } 126 | } 127 | } 128 | 129 | func BenchmarkP521(b *testing.B) { 130 | p521 := GenericCurve(elliptic.P256()) 131 | privateAlice, _, err := p521.GenerateKey(rand.Reader) 132 | if err != nil { 133 | b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) 134 | } 135 | _, publicBob, err := p521.GenerateKey(rand.Reader) 136 | if err != nil { 137 | b.Fatalf("Failed to generate Bob's private/public key pair: %s", err) 138 | } 139 | b.ResetTimer() 140 | for i := 0; i < b.N; i++ { 141 | p521.ComputeSecret(privateAlice, publicBob) 142 | } 143 | } 144 | 145 | func BenchmarkKeyGenerateP521(b *testing.B) { 146 | p521 := GenericCurve(elliptic.P256()) 147 | for i := 0; i < b.N; i++ { 148 | _, _, err := p521.GenerateKey(rand.Reader) 149 | if err != nil { 150 | b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /dh/groups.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package dh 5 | 6 | import ( 7 | "math/big" 8 | "sync" 9 | ) 10 | 11 | // DH groups defined in https://www.ietf.org/rfc/rfc3526.txt 12 | const ( 13 | // The 2048 bit prime form 3. 14 | rfc3526_2048G = "02" 15 | rfc3526_2048P = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3" + 16 | "404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BF" + 17 | "B5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C6" + 18 | "2F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28" + 19 | "FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF" 20 | 21 | // The 3072 bit prime form 4. 22 | rfc3526_3072G = "02" 23 | rfc3526_3072P = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3" + 24 | "404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BF" + 25 | "B5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C6" + 26 | "2F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28" + 27 | "FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1" + 28 | "CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA0" + 29 | "6D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B8" + 30 | "2D120A93AD2CAFFFFFFFFFFFFFFFF" 31 | 32 | // The 4096 bit prime form 5. 33 | rfc3526_4096G = "02" 34 | rfc3526_4096P = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3" + 35 | "404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BF" + 36 | "B5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C6" + 37 | "2F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28" + 38 | "FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1" + 39 | "CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA0" + 40 | "6D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B8" + 41 | "2D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF" + 42 | "92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B" + 43 | "05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF" 44 | ) 45 | 46 | var once sync.Once 47 | var rfc3526_2048 *Group 48 | var rfc3526_3072 *Group 49 | var rfc3526_4096 *Group 50 | 51 | func initRFC3526_2048() { 52 | rfc3526_2048 = &Group{} 53 | rfc3526_2048.G, _ = new(big.Int).SetString(rfc3526_2048G, 16) 54 | rfc3526_2048.P, _ = new(big.Int).SetString(rfc3526_2048P, 16) 55 | 56 | } 57 | 58 | func initRFC3526_3072() { 59 | rfc3526_3072 = &Group{} 60 | rfc3526_3072.G, _ = new(big.Int).SetString(rfc3526_3072G, 16) 61 | rfc3526_3072.P, _ = new(big.Int).SetString(rfc3526_3072P, 16) 62 | 63 | } 64 | 65 | func initRFC3526_4096() { 66 | rfc3526_4096 = &Group{} 67 | rfc3526_4096.G, _ = new(big.Int).SetString(rfc3526_4096G, 16) 68 | rfc3526_4096.P, _ = new(big.Int).SetString(rfc3526_4096P, 16) 69 | } 70 | 71 | // Initialize the primes and generators 72 | func initAll() { 73 | initRFC3526_2048() 74 | initRFC3526_3072() 75 | initRFC3526_4096() 76 | } 77 | 78 | // RFC3526_2048 creates a new dh.Group consisting of the prime 79 | // and the generator. The prime (and generator) are 80 | // described in RFC 3526 (3.). The prime is a 2048 bit value. 81 | func RFC3526_2048() *Group { 82 | once.Do(initAll) 83 | g := &Group{ 84 | P: new(big.Int).Set(rfc3526_2048.P), 85 | G: new(big.Int).Set(rfc3526_2048.G), 86 | } 87 | return g 88 | } 89 | 90 | // RFC3526_3072 creates a new dh.Group consisting of the prime 91 | // and the generator. The prime (and generator) are 92 | // described in RFC 3526 (4.). The prime is a 3072 bit value. 93 | func RFC3526_3072() *Group { 94 | once.Do(initAll) 95 | g := &Group{ 96 | P: new(big.Int).Set(rfc3526_3072.P), 97 | G: new(big.Int).Set(rfc3526_3072.G), 98 | } 99 | return g 100 | } 101 | 102 | // RFC3526_4096 creates a new dh.Group consisting of the prime 103 | // and the generator. The prime (and generator) are 104 | // described in RFC 3526 (5.). The prime is a 4096 bit value. 105 | func RFC3526_4096() *Group { 106 | once.Do(initAll) 107 | g := &Group{ 108 | P: new(big.Int).Set(rfc3526_4096.P), 109 | G: new(big.Int).Set(rfc3526_4096.G), 110 | } 111 | return g 112 | } 113 | -------------------------------------------------------------------------------- /camellia/camellia_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package camellia 5 | 6 | import ( 7 | "bytes" 8 | "crypto/cipher" 9 | "encoding/hex" 10 | "testing" 11 | ) 12 | 13 | var recoverFail = func(t *testing.T) { 14 | if err := recover(); err == nil { 15 | t.Fatal("Recover expected error, but no one occured") 16 | } 17 | } 18 | 19 | var badKeys = [][]byte{ 20 | make([]byte, 15), 21 | make([]byte, 17), 22 | make([]byte, 23), 23 | make([]byte, 25), 24 | make([]byte, 31), 25 | make([]byte, 33), 26 | } 27 | 28 | func TestBlockSize(t *testing.T) { 29 | c, err := NewCipher(make([]byte, 16)) 30 | if err != nil { 31 | t.Fatalf("Failed to create camellia cipher: %s", err) 32 | } 33 | if bs := c.BlockSize(); bs != BlockSize { 34 | t.Fatalf("BlockSize() returned unexpected value: %d", bs) 35 | } 36 | 37 | c, err = NewCipher(make([]byte, 32)) 38 | if err != nil { 39 | t.Fatalf("Failed to create camellia cipher: %s", err) 40 | } 41 | if bs := c.BlockSize(); bs != BlockSize { 42 | t.Fatalf("BlockSize() returned unexpected value: %d", bs) 43 | } 44 | } 45 | 46 | func TestEncrypt(t *testing.T) { 47 | encFail := func(t *testing.T, c cipher.Block, srcLen, dstLen int) { 48 | defer recoverFail(t) 49 | src := make([]byte, srcLen) 50 | dst := make([]byte, dstLen) 51 | c.Encrypt(dst, src) 52 | } 53 | 54 | c, err := NewCipher(make([]byte, 16)) 55 | if err != nil { 56 | t.Fatalf("Failed to create camellia cipher: %s", err) 57 | } 58 | encFail(t, c, BlockSize-1, BlockSize) 59 | encFail(t, c, BlockSize, BlockSize-1) 60 | 61 | c, err = NewCipher(make([]byte, 32)) 62 | if err != nil { 63 | t.Fatalf("Failed to create camellia cipher: %s", err) 64 | } 65 | encFail(t, c, BlockSize-1, BlockSize) 66 | encFail(t, c, BlockSize, BlockSize-1) 67 | } 68 | 69 | func TestDecrypt(t *testing.T) { 70 | decFail := func(t *testing.T, c cipher.Block, srcLen, dstLen int) { 71 | defer recoverFail(t) 72 | src := make([]byte, srcLen) 73 | dst := make([]byte, dstLen) 74 | c.Decrypt(dst, src) 75 | } 76 | 77 | c, err := NewCipher(make([]byte, 16)) 78 | if err != nil { 79 | t.Fatalf("Failed to create camellia cipher: %s", err) 80 | } 81 | decFail(t, c, BlockSize-1, BlockSize) 82 | decFail(t, c, BlockSize, BlockSize-1) 83 | 84 | c, err = NewCipher(make([]byte, 32)) 85 | if err != nil { 86 | t.Fatalf("Failed to create camellia cipher: %s", err) 87 | } 88 | decFail(t, c, BlockSize-1, BlockSize) 89 | decFail(t, c, BlockSize, BlockSize-1) 90 | } 91 | 92 | func TestEncryptDecrypt(t *testing.T) { 93 | c, err := NewCipher(make([]byte, 16)) 94 | if err != nil { 95 | t.Fatalf("Failed to create camellia cipher: %s", err) 96 | } 97 | 98 | src := make([]byte, 32) 99 | dst := make([]byte, 32) 100 | 101 | c.Encrypt(dst, src) 102 | c.Encrypt(dst[16:], src[:16]) 103 | c.Decrypt(dst, dst) 104 | c.Decrypt(dst[16:], dst[16:]) 105 | 106 | if !bytes.Equal(src, dst) { 107 | t.Fatalf("En / decryption sequence failed\nFound: %s\nExpected: %s", hex.EncodeToString(dst), hex.EncodeToString(src)) 108 | } 109 | } 110 | 111 | func TestNewCipher(t *testing.T) { 112 | var ( 113 | key128 [16]byte 114 | key192 [24]byte 115 | key256 [32]byte 116 | ) 117 | _, err := NewCipher(key128[:]) 118 | if err != nil { 119 | t.Fatalf("NewCipher rejected valid key with length: %d", len(key128)) 120 | } 121 | _, err = NewCipher(key192[:]) 122 | if err != nil { 123 | t.Fatalf("NewCipher rejected valid key with length: %d", len(key192)) 124 | } 125 | _, err = NewCipher(key256[:]) 126 | if err != nil { 127 | t.Fatalf("NewCipher rejected valid key with length: %d", len(key256)) 128 | } 129 | 130 | for i, v := range badKeys { 131 | _, err := NewCipher(v) 132 | if err == nil { 133 | t.Fatalf("NewCipher accpeted bad key %d with length: %d", i, len(v)) 134 | } 135 | } 136 | } 137 | 138 | // Benchmarks 139 | 140 | func BenchmarkEncrypt_16(b *testing.B) { benchmarkEncrypt(b, 16) } 141 | func BenchmarkDecrypt_16(b *testing.B) { benchmarkDecrypt(b, 16) } 142 | func BenchmarkEncrypt_1K(b *testing.B) { benchmarkEncrypt(b, 1024) } 143 | func BenchmarkDecrypt_1K(b *testing.B) { benchmarkDecrypt(b, 1024) } 144 | 145 | func benchmarkEncrypt(b *testing.B, size int) { 146 | c, err := NewCipher(make([]byte, 16)) 147 | if err != nil { 148 | b.Fatalf("Failed to create camellia instance: %s", err) 149 | } 150 | buf := make([]byte, c.BlockSize()) 151 | b.SetBytes(int64(size - (size % c.BlockSize()))) 152 | 153 | n := size / c.BlockSize() 154 | b.ResetTimer() 155 | for i := 0; i < b.N; i++ { 156 | for j := 0; j < n; j++ { 157 | c.Encrypt(buf, buf) 158 | } 159 | } 160 | } 161 | 162 | func benchmarkDecrypt(b *testing.B, size int) { 163 | c, err := NewCipher(make([]byte, 16)) 164 | if err != nil { 165 | b.Fatalf("Failed to create camelli instance: %s", err) 166 | } 167 | buf := make([]byte, c.BlockSize()) 168 | b.SetBytes(int64(size - (size % c.BlockSize()))) 169 | 170 | n := size / c.BlockSize() 171 | b.ResetTimer() 172 | for i := 0; i < b.N; i++ { 173 | for j := 0; j < n; j++ { 174 | c.Decrypt(buf, buf) 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /blake2/blake2s/vectors_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package blake2s 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | func fromHex(s string) []byte { 13 | b, err := hex.DecodeString(s) 14 | if err != nil { 15 | panic(err) 16 | } 17 | return b 18 | } 19 | 20 | var vectors = []struct { 21 | hashsize int 22 | conf *Config 23 | msg, hash string 24 | }{ 25 | // Test vectors from https://blake2.net/blake2s-test.txt 26 | { 27 | hashsize: 32, 28 | conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, 29 | msg: hex.EncodeToString([]byte("")), 30 | hash: "48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49", 31 | }, 32 | { 33 | hashsize: 32, 34 | conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, 35 | msg: "00", 36 | hash: "40d15fee7c328830166ac3f918650f807e7e01e177258cdc0a39b11f598066f1", 37 | }, 38 | { 39 | hashsize: 32, 40 | conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, 41 | msg: "000102030405060708090a", 42 | hash: "e33c4c9bd0cc7e45c80e65c77fa5997fec7002738541509e68a9423891e822a3", 43 | }, 44 | { 45 | hashsize: 32, 46 | conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, 47 | msg: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", 48 | hash: "c03bc642b20959cbe133a0303e0c1abff3e31ec8e1a328ec8565c36decff5265", 49 | }, 50 | { 51 | hashsize: 32, 52 | conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, 53 | msg: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + 54 | "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414" + 55 | "2434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364" + 56 | "65666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868" + 57 | "788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9" + 58 | "aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbc" + 59 | "ccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedee" + 60 | "eff0f1f2f3f4f5f6f7f8f9fafbfcfdfe", 61 | hash: "3fb735061abc519dfe979e54c1ee5bfad0a9d858b3315bad34bde999efd724dd", 62 | }, 63 | } 64 | 65 | func TestVectors(t *testing.T) { 66 | for i, v := range vectors { 67 | h, err := New(v.hashsize, v.conf) 68 | if err != nil { 69 | t.Fatalf("Test vector %d : Failed to create new BLAKE2s instance: %s", i, err) 70 | } 71 | msg := fromHex(v.msg) 72 | expSum := fromHex(v.hash) 73 | 74 | h.Write(msg) 75 | sum := h.Sum(nil) 76 | if !bytes.Equal(sum, expSum) { 77 | t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(expSum)) 78 | } 79 | 80 | sum, err = Sum(msg, v.hashsize, v.conf) 81 | if err != nil { 82 | t.Fatalf("Test vector %d : function Sum failed: %s", i, err) 83 | } 84 | if !bytes.Equal(sum, expSum) { 85 | t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(expSum)) 86 | } 87 | } 88 | } 89 | 90 | func generateSequence(out []byte, seed uint32) { 91 | a := 0xDEAD4BAD * seed // prime 92 | b := uint32(1) 93 | 94 | for i := range out { // fill the buf 95 | t := a + b 96 | a = b 97 | b = t 98 | out[i] = byte(t >> 24) 99 | } 100 | } 101 | 102 | // BLAKE2s self-test validation from 103 | // https://tools.ietf.org/html/rfc7693#appendix-E 104 | func TestSelfTest(t *testing.T) { 105 | var result = [32]byte{ 106 | 0x6A, 0x41, 0x1F, 0x08, 0xCE, 0x25, 0xAD, 0xCD, 107 | 0xFB, 0x02, 0xAB, 0xA6, 0x41, 0x45, 0x1C, 0xEC, 108 | 0x53, 0xC5, 0x98, 0xB2, 0x4F, 0x4F, 0xC7, 0x87, 109 | 0xFB, 0xDC, 0x88, 0x79, 0x7F, 0x4C, 0x1D, 0xFE, 110 | } 111 | var hashLens = [4]int{16, 20, 28, 32} 112 | var msgLens = [6]int{0, 3, 64, 65, 255, 1024} 113 | 114 | msg := make([]byte, 1024) 115 | key := make([]byte, 32) 116 | 117 | h, err := New(32, nil) 118 | if err != nil { 119 | t.Fatalf("Failed to create BLAKE2s instance: %s", err) 120 | } 121 | for _, hashsize := range hashLens { 122 | for _, msgLength := range msgLens { 123 | generateSequence(msg[:msgLength], uint32(msgLength)) // unkeyed hash 124 | md, err := Sum(msg[:msgLength], hashsize, nil) 125 | if err != nil { 126 | t.Fatalf("Selftest failed: Failed to compute unkeyed hash: %s", err) 127 | } 128 | h.Write(md) 129 | 130 | generateSequence(key[:], uint32(hashsize)) // keyed hash 131 | md, err = Sum(msg[:msgLength], hashsize, &Config{Key: key[:hashsize]}) 132 | if err != nil { 133 | t.Fatalf("Selftest failed: Failed to compute keyed hash: %s", err) 134 | } 135 | h.Write(md) 136 | } 137 | } 138 | 139 | sum := h.Sum(nil) 140 | if !bytes.Equal(sum, result[:]) { 141 | t.Fatalf("Selftest failed:\nFound: %s\nExpected: %s", hex.EncodeToString(sum), hex.EncodeToString(result[:])) 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /poly1305/poly1305.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package poly1305 implements Poly1305 one-time message authentication code as 5 | // specified in http://cr.yp.to/mac/poly1305-20050329.pdf. 6 | // 7 | // Poly1305 is a fast, one-time authentication function. It is infeasible for an 8 | // attacker to generate an authenticator for a message without the key. 9 | // However, a key must only be used for a single message. Authenticating two 10 | // different messages with the same key allows an attacker to forge 11 | // authenticators for other messages with the same key. 12 | // 13 | // Poly1305 was originally coupled with AES in order to make Poly1305-AES. 14 | // AES was used with a fixed key in order to generate one-time keys from an 15 | // nonce. However, in this package AES isn't used and the one-time key is 16 | // specified directly. 17 | package poly1305 18 | 19 | import ( 20 | "crypto/subtle" 21 | "errors" 22 | ) 23 | 24 | // The size of the poly1305 authentication tag in bytes. 25 | const TagSize = 16 26 | 27 | const ( 28 | msgBlock = uint32(1 << 24) 29 | finalBlock = uint32(0) 30 | ) 31 | 32 | // Verify returns true if and only if the mac is a valid authenticator 33 | // for msg with the given key. 34 | func Verify(mac *[TagSize]byte, msg []byte, key *[32]byte) bool { 35 | var sum [TagSize]byte 36 | Sum(&sum, msg, key) 37 | return subtle.ConstantTimeCompare(sum[:], mac[:]) == 1 38 | } 39 | 40 | // New returns a hash.Hash computing the poly1305 sum. 41 | // Notice that Poly1305 is inseure if one key is used twice. 42 | func New(key *[32]byte) *Hash { 43 | p := new(Hash) 44 | initialize(&(p.r), &(p.pad), key) 45 | return p 46 | } 47 | 48 | var writeAfterSumErr error = errors.New("checksum already computed - adding more data is not allowed") 49 | 50 | // Hash implements a Poly1305 writer interface. 51 | // Poly1305 cannot used like common hash.Hash implementations, 52 | // beause of using a Poly1305 key twice breaks its security. 53 | // So poly1305.Hash does not support some kind of reset. 54 | type Hash struct { 55 | h, r [5]uint32 56 | pad [4]uint32 57 | 58 | buf [TagSize]byte 59 | off int 60 | done bool 61 | } 62 | 63 | // Write adds more data to the running Poly1305 hash. 64 | // This function returns an non-nil error, if a call 65 | // to Write happens after the hash's Sum function was 66 | // called. So it's not possible to compute the checksum 67 | // and than add more data. 68 | func (p *Hash) Write(msg []byte) (int, error) { 69 | if p.done { 70 | return 0, writeAfterSumErr 71 | } 72 | n := len(msg) 73 | 74 | if p.off > 0 { 75 | dif := TagSize - p.off 76 | if n > dif { 77 | p.off += copy(p.buf[p.off:], msg[:dif]) 78 | msg = msg[dif:] 79 | core(p.buf[:], msgBlock, &(p.h), &(p.r)) 80 | p.off = 0 81 | } else { 82 | p.off += copy(p.buf[p.off:], msg) 83 | return n, nil 84 | } 85 | } 86 | 87 | length := len(msg) & (^(TagSize - 1)) 88 | if length > 0 { 89 | core(msg[:length], msgBlock, &(p.h), &(p.r)) 90 | msg = msg[length:] 91 | } 92 | if len(msg) > 0 { 93 | p.off += copy(p.buf[p.off:], msg) 94 | } 95 | 96 | return n, nil 97 | } 98 | 99 | // Sum computes the Poly1305 checksum of the prevouisly 100 | // processed data and writes it to out. It is legal to 101 | // call this function more than one time. 102 | func (p *Hash) Sum(out *[TagSize]byte) { 103 | h, r := p.h, p.r 104 | pad := p.pad 105 | 106 | if p.off > 0 { 107 | var buf [TagSize]byte 108 | copy(buf[:], p.buf[:p.off]) 109 | buf[p.off] = 1 // invariant: p.off < TagSize 110 | 111 | core(buf[:], finalBlock, &h, &r) 112 | } 113 | 114 | finalize(out, &h, &pad) 115 | p.done = true 116 | } 117 | 118 | func finalize(tag *[TagSize]byte, h *[5]uint32, pad *[4]uint32) { 119 | var g0, g1, g2, g3, g4 uint32 120 | 121 | // fully carry h 122 | h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] 123 | 124 | h2 += h1 >> 26 125 | h1 &= 0x3ffffff 126 | h3 += h2 >> 26 127 | h2 &= 0x3ffffff 128 | h4 += h3 >> 26 129 | h3 &= 0x3ffffff 130 | h0 += 5 * (h4 >> 26) 131 | h4 &= 0x3ffffff 132 | h1 += h0 >> 26 133 | h0 &= 0x3ffffff 134 | 135 | // h + -p 136 | g0 = h0 + 5 137 | 138 | g1 = h1 + (g0 >> 26) 139 | g0 &= 0x3ffffff 140 | g2 = h2 + (g1 >> 26) 141 | g1 &= 0x3ffffff 142 | g3 = h3 + (g2 >> 26) 143 | g2 &= 0x3ffffff 144 | g4 = h4 + (g3 >> 26) - (1 << 26) 145 | g3 &= 0x3ffffff 146 | 147 | // select h if h < p else h + -p 148 | mask := (g4 >> (32 - 1)) - 1 149 | g0 &= mask 150 | g1 &= mask 151 | g2 &= mask 152 | g3 &= mask 153 | g4 &= mask 154 | mask = ^mask 155 | h0 = (h0 & mask) | g0 156 | h1 = (h1 & mask) | g1 157 | h2 = (h2 & mask) | g2 158 | h3 = (h3 & mask) | g3 159 | h4 = (h4 & mask) | g4 160 | 161 | // h %= 2^128 162 | h0 |= h1 << 26 163 | h1 = ((h1 >> 6) | (h2 << 20)) 164 | h2 = ((h2 >> 12) | (h3 << 14)) 165 | h3 = ((h3 >> 18) | (h4 << 8)) 166 | 167 | // tag = (h + pad) % (2^128) 168 | f := uint64(h0) + uint64(pad[0]) 169 | h0 = uint32(f) 170 | f = uint64(h1) + uint64(pad[1]) + (f >> 32) 171 | h1 = uint32(f) 172 | f = uint64(h2) + uint64(pad[2]) + (f >> 32) 173 | h2 = uint32(f) 174 | f = uint64(h3) + uint64(pad[3]) + (f >> 32) 175 | h3 = uint32(f) 176 | 177 | extractHash(tag, h0, h1, h2, h3) 178 | } 179 | -------------------------------------------------------------------------------- /cipher/eax.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package cipher implements additional block cipher modes 5 | // that can be wrapped around low-level block cipher implementations. 6 | // For standard block cipher modes see: https://golang.org/pkg/crypto/cipher 7 | package cipher 8 | 9 | import ( 10 | "crypto/cipher" 11 | "crypto/subtle" 12 | "errors" 13 | "hash" 14 | 15 | "github.com/enceve/crypto" 16 | "github.com/enceve/crypto/cmac" 17 | ) 18 | 19 | const ( 20 | nTag = 0x0 // The nonce tag constant 21 | hTag = 0x1 // The additional data tag constant 22 | cTag = 0x2 // The ciphertext tag constant 23 | ) 24 | 25 | // The EAX cipher 26 | type eaxCipher struct { 27 | blockCipher cipher.Block 28 | ctr, block []byte 29 | mac hash.Hash 30 | size int 31 | } 32 | 33 | // NewEAX returns a cipher.AEAD wrapping the cipher.Block. 34 | // EAX is a two pass-scheme AEAD cipher with provable security. 35 | // For authentication EAX uses CMac (OMAC1). 36 | // The tagsize argument specifies the number of bytes of the auth. tag 37 | // and must be between 1 and the block size of the cipher. 38 | // This function returns a non-nil error if the given block cipher 39 | // is not supported by CMac (see crypto/cmac for details) 40 | func NewEAX(c cipher.Block, tagsize int) (cipher.AEAD, error) { 41 | m, err := cmac.New(c) 42 | if err != nil { 43 | return nil, err 44 | } 45 | if tagsize < 1 || tagsize > c.BlockSize() { 46 | return nil, errors.New("tagSize must between 1 and BlockSize() of the given cipher") 47 | } 48 | return &eaxCipher{ 49 | blockCipher: c, 50 | mac: m, 51 | ctr: make([]byte, c.BlockSize()), 52 | block: make([]byte, c.BlockSize()), 53 | size: tagsize, 54 | }, nil 55 | } 56 | 57 | func (c *eaxCipher) NonceSize() int { return c.blockCipher.BlockSize() } 58 | 59 | func (c *eaxCipher) Overhead() int { return c.size } 60 | 61 | func (c *eaxCipher) Seal(dst, nonce, plaintext, additionalData []byte) []byte { 62 | if n := len(nonce); n != c.blockCipher.BlockSize() { 63 | panic(crypto.NonceSizeError(n)) 64 | } 65 | if len(dst) < len(plaintext) { 66 | panic("dst buffer to small") 67 | } 68 | 69 | tag := make([]byte, c.mac.BlockSize()) 70 | 71 | // process nonce 72 | tag[len(tag)-1] = nTag 73 | c.mac.Write(tag) 74 | c.mac.Write(nonce) 75 | authNonce := c.mac.Sum(nil) 76 | c.mac.Reset() 77 | 78 | // process additional data 79 | tag[len(tag)-1] = hTag 80 | c.mac.Write(tag) 81 | c.mac.Write(additionalData) 82 | authData := c.mac.Sum(nil) 83 | c.mac.Reset() 84 | 85 | // encrypt 86 | n := len(plaintext) 87 | copy(c.ctr, authNonce) // set the ctr-mode nonce 88 | c.ctrCrypt(dst, plaintext) 89 | 90 | // process ciphertext 91 | tag[len(tag)-1] = cTag 92 | c.mac.Write(tag) 93 | c.mac.Write(dst[:n]) 94 | tag = c.mac.Sum(tag[:0]) 95 | c.mac.Reset() 96 | 97 | for i := range tag { 98 | tag[i] ^= authData[i] ^ authNonce[i] 99 | } 100 | return append(dst[:n], tag[:c.size]...) 101 | } 102 | 103 | func (c *eaxCipher) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { 104 | if n := len(nonce); n != c.blockCipher.BlockSize() { 105 | return nil, crypto.NonceSizeError(n) 106 | } 107 | if len(ciphertext) < c.size { 108 | return nil, crypto.AuthenticationError{} 109 | } 110 | if len(dst) < len(ciphertext)-c.mac.Size() { 111 | panic("dst buffer to small") 112 | } 113 | 114 | hash := ciphertext[len(ciphertext)-c.size:] 115 | ciphertext = ciphertext[:len(ciphertext)-c.size] 116 | 117 | tag := make([]byte, c.mac.BlockSize()) 118 | 119 | // process nonce 120 | tag[len(tag)-1] = nTag 121 | c.mac.Write(tag) 122 | c.mac.Write(nonce) 123 | authNonce := c.mac.Sum(nil) 124 | c.mac.Reset() 125 | 126 | // process additional data 127 | tag[len(tag)-1] = hTag 128 | c.mac.Write(tag) 129 | c.mac.Write(additionalData) 130 | authData := c.mac.Sum(nil) 131 | c.mac.Reset() 132 | 133 | // process ciphertext 134 | tag[len(tag)-1] = cTag 135 | c.mac.Write(tag) 136 | c.mac.Write(ciphertext) 137 | tag = c.mac.Sum(tag[:0]) 138 | c.mac.Reset() 139 | 140 | for i := range tag { 141 | tag[i] ^= authData[i] ^ authNonce[i] 142 | } 143 | 144 | if subtle.ConstantTimeCompare(tag[:c.size], hash) != 1 { 145 | return nil, crypto.AuthenticationError{} 146 | } 147 | 148 | // decrypt 149 | n := len(ciphertext) 150 | copy(c.ctr, authNonce) // set the ctr-mode nonce 151 | c.ctrCrypt(dst, ciphertext) 152 | 153 | return dst[:n], nil 154 | } 155 | 156 | // ctrCrypt encrypts the bytes in src with the CTR mode and writes 157 | // the ciphertext into dst 158 | func (c *eaxCipher) ctrCrypt(dst, src []byte) { 159 | length := len(src) 160 | bs := c.blockCipher.BlockSize() 161 | n := length & (^(length - bs)) 162 | 163 | for i := 0; i < n; i += bs { 164 | j := i + bs 165 | c.blockCipher.Encrypt(c.block, c.ctr) 166 | crypto.XOR(dst[i:j], src[i:j], c.block) 167 | 168 | // Increment counter 169 | for k := len(c.ctr) - 1; k >= 0; k-- { 170 | c.ctr[k]++ 171 | if c.ctr[k] != 0 { 172 | break 173 | } 174 | } 175 | } 176 | if n < length { 177 | c.blockCipher.Encrypt(c.block, c.ctr) 178 | crypto.XOR(dst[n:], src[n:], c.block) 179 | } 180 | // no reset of ctr needed - Seal or Open does this for us 181 | } 182 | -------------------------------------------------------------------------------- /cmac/cmac.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | // Package cmac implements the fast CMac MAC based on 5 | // a block cipher. This mode of operation fixes security 6 | // deficiencies of CBC-MAC (CBC-MAC is secure only for 7 | // fixed-length messages). CMac is equal to OMAC1. 8 | // This implementations supports block ciphers with a 9 | // block size of: 10 | // - 64 bit (8 byte) 11 | // - 128 bit (16 byte) 12 | // - 256 bit (32 byte) 13 | // - 512 bit (64 byte) 14 | // - 1024 bit (128 byte) 15 | // Common ciphers like AES, Serpent etc. operate on 128 bit 16 | // blocks. 256, 512 and 1024 are supported for the Threefish 17 | // tweakable block cipher. Ciphers with 64 bit blocks are 18 | // supported, but not recommened. 19 | // CMac (using AES) is specified in RFC 4493. 20 | package cmac 21 | 22 | import ( 23 | "crypto/cipher" 24 | "crypto/subtle" 25 | "errors" 26 | "hash" 27 | 28 | "github.com/enceve/crypto" 29 | ) 30 | 31 | const ( 32 | // minimal irreducible polynomial for blocksize 33 | p64 = 0x1b // for 64 bit block ciphers 34 | p128 = 0x87 // for 128 bit block ciphers (like AES) 35 | p256 = 0x425 // special for large block ciphers (Threefish) 36 | p512 = 0x125 // special for large block ciphers (Threefish) 37 | p1024 = 0x80043 // special for large block ciphers (Threefish) 38 | ) 39 | 40 | // Sum computes the CMac checksum of msg using the cipher.Block. 41 | // If the block cipher is not supported by CMac (see package doc), 42 | // a non-nil error is returned. 43 | func Sum(msg []byte, c cipher.Block) ([]byte, error) { 44 | mac, err := New(c) 45 | if err != nil { 46 | return nil, err 47 | } 48 | mac.Write(msg) 49 | return mac.Sum(nil), nil 50 | } 51 | 52 | // Verify computes the CMac checksum of msg and compares it with the 53 | // given mac. This functions returns true if and only if the given mac 54 | // is equal to computed one. If the block cipher is not supported 55 | // by CMac (see package doc), this function returns false. 56 | func Verify(mac, msg []byte, c cipher.Block) bool { 57 | sum, err := Sum(msg, c) 58 | if err != nil { 59 | return false 60 | } 61 | return subtle.ConstantTimeCompare(mac, sum) == 1 62 | } 63 | 64 | // New returns a hash.Hash computing the CMac checksum. 65 | // If the block cipher is not supported by CMac 66 | // (see package doc), a non-nil error is returned. 67 | func New(c cipher.Block) (hash.Hash, error) { 68 | if c == nil { 69 | return nil, errors.New("the cipher.Block must not be nil") 70 | } 71 | bs := c.BlockSize() 72 | 73 | var p int 74 | switch bs { 75 | default: 76 | return nil, errors.New("cipher block size not supported") 77 | case 8: 78 | p = p64 79 | case 16: 80 | p = p128 81 | case 32: 82 | p = p256 83 | case 64: 84 | p = p512 85 | case 128: 86 | p = p1024 87 | } 88 | 89 | m := &macFunc{ 90 | cipher: c, 91 | k0: make([]byte, bs), 92 | k1: make([]byte, bs), 93 | buf: make([]byte, bs), 94 | } 95 | c.Encrypt(m.k0, m.k0) 96 | 97 | v := shift(m.k0, m.k0) 98 | m.k0[bs-1] ^= byte(subtle.ConstantTimeSelect(v, p, 0)) 99 | 100 | v = shift(m.k1, m.k0) 101 | m.k1[bs-1] ^= byte(subtle.ConstantTimeSelect(v, p, 0)) 102 | 103 | return m, nil 104 | } 105 | 106 | // The CMac message auth. function 107 | type macFunc struct { 108 | cipher cipher.Block 109 | k0, k1 []byte 110 | buf []byte 111 | off int 112 | } 113 | 114 | func (h *macFunc) Size() int { return h.cipher.BlockSize() } 115 | 116 | func (h *macFunc) BlockSize() int { return h.cipher.BlockSize() } 117 | 118 | func (h *macFunc) Reset() { 119 | for i := range h.buf { 120 | h.buf[i] = 0 121 | } 122 | h.off = 0 123 | } 124 | 125 | func (h *macFunc) Write(msg []byte) (int, error) { 126 | bs := h.BlockSize() 127 | n := len(msg) 128 | 129 | if h.off > 0 { 130 | dif := bs - h.off 131 | if n > dif { 132 | crypto.XOR(h.buf[h.off:], h.buf[h.off:], msg[:dif]) 133 | msg = msg[dif:] 134 | h.cipher.Encrypt(h.buf, h.buf) 135 | h.off = 0 136 | } else { 137 | crypto.XOR(h.buf[h.off:], h.buf[h.off:], msg) 138 | h.off += n 139 | return n, nil 140 | } 141 | } 142 | 143 | if length := len(msg); length > bs { 144 | nn := length & (^(bs - 1)) 145 | if length == nn { 146 | nn -= bs 147 | } 148 | for i := 0; i < nn; i += bs { 149 | crypto.XOR(h.buf, h.buf, msg[i:i+bs]) 150 | h.cipher.Encrypt(h.buf, h.buf) 151 | } 152 | msg = msg[nn:] 153 | } 154 | 155 | if length := len(msg); length > 0 { 156 | crypto.XOR(h.buf[h.off:], h.buf[h.off:], msg) 157 | h.off += length 158 | } 159 | 160 | return n, nil 161 | } 162 | 163 | func (h *macFunc) Sum(b []byte) []byte { 164 | bs := h.cipher.BlockSize() 165 | 166 | // Don't change the buffer so the 167 | // caller can keep writing and suming. 168 | hash := make([]byte, bs) 169 | 170 | k := h.k0 171 | if h.off < bs { 172 | k = h.k1 173 | } 174 | crypto.XOR(hash, k, h.buf) 175 | if h.off < h.cipher.BlockSize() { 176 | hash[h.off] ^= 0x80 177 | } 178 | 179 | h.cipher.Encrypt(hash, hash) 180 | return append(b, hash...) 181 | } 182 | 183 | func shift(dst, src []byte) int { 184 | var b, bit byte 185 | for i := len(src) - 1; i >= 0; i-- { // a range would be nice 186 | bit = src[i] >> 7 187 | dst[i] = src[i]<<1 | b 188 | b = bit 189 | } 190 | return int(b) 191 | } 192 | -------------------------------------------------------------------------------- /skein/skein256/skein256.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | package skein256 5 | 6 | import ( 7 | "github.com/enceve/crypto/skein" 8 | "github.com/enceve/crypto/skein/threefish" 9 | ) 10 | 11 | type hashFunc struct { 12 | hashsize int 13 | hVal, hValCpy [5]uint64 14 | tweak [3]uint64 15 | block [threefish.BlockSize256]byte 16 | off int 17 | hasMsg bool 18 | } 19 | 20 | func (s *hashFunc) BlockSize() int { return threefish.BlockSize256 } 21 | 22 | func (s *hashFunc) Size() int { return s.hashsize } 23 | 24 | func (s *hashFunc) Reset() { 25 | for i := range s.block { 26 | s.block[i] = 0 27 | } 28 | s.off = 0 29 | s.hasMsg = false 30 | 31 | s.hVal = s.hValCpy 32 | 33 | s.tweak[0] = 0 34 | s.tweak[1] = skein.CfgMessage<<56 | skein.FirstBlock 35 | } 36 | 37 | func (s *hashFunc) Write(p []byte) (n int, err error) { 38 | s.hasMsg = true 39 | 40 | n = len(p) 41 | var block [4]uint64 42 | 43 | dif := threefish.BlockSize256 - s.off 44 | if s.off > 0 && n > dif { 45 | s.off += copy(s.block[s.off:], p[:dif]) 46 | p = p[dif:] 47 | if s.off == threefish.BlockSize256 && len(p) > 0 { 48 | bytesToBlock(&block, s.block[:]) 49 | s.update(&block) 50 | s.off = 0 51 | } 52 | } 53 | 54 | if length := len(p); length > threefish.BlockSize256 { 55 | nn := length & (^(threefish.BlockSize256 - 1)) // length -= (length % BlockSize) 56 | if length == nn { 57 | nn -= threefish.BlockSize256 58 | } 59 | for i := 0; i < len(p[:nn]); i += threefish.BlockSize256 { 60 | bytesToBlock(&block, p[i:]) 61 | s.update(&block) 62 | } 63 | p = p[nn:] 64 | } 65 | 66 | if len(p) > 0 { 67 | s.off += copy(s.block[s.off:], p) 68 | } 69 | return 70 | } 71 | 72 | func (s *hashFunc) Sum(b []byte) []byte { 73 | s0 := *s // copy 74 | 75 | if s0.hasMsg { 76 | s0.finalizeHash() 77 | } 78 | 79 | var out [threefish.BlockSize256]byte 80 | var ctr uint64 81 | 82 | for i := s0.hashsize; i > 0; i -= threefish.BlockSize256 { 83 | s0.output(&out, ctr) 84 | ctr++ 85 | b = append(b, out[:]...) 86 | } 87 | 88 | return b[:s0.hashsize] 89 | } 90 | 91 | func (s *hashFunc) update(block *[4]uint64) { 92 | threefish.IncrementTweak(&(s.tweak), threefish.BlockSize256) 93 | 94 | threefish.UBI256(block, &(s.hVal), &(s.tweak)) 95 | 96 | s.tweak[1] &^= skein.FirstBlock 97 | } 98 | 99 | func (s *hashFunc) output(dst *[threefish.BlockSize256]byte, counter uint64) { 100 | var block [4]uint64 101 | block[0] = counter 102 | 103 | hVal := s.hVal 104 | var outTweak = [3]uint64{8, skein.CfgOutput<<56 | skein.FirstBlock | skein.FinalBlock, 0} 105 | 106 | threefish.UBI256(&block, &hVal, &outTweak) 107 | block[0] ^= counter 108 | 109 | blockToBytes(dst[:], &block) 110 | } 111 | 112 | func (s *hashFunc) initialize(hashsize int, conf *skein.Config) { 113 | if hashsize < 1 { 114 | panic("skein256: invalid hashsize for Skein-256") 115 | } 116 | 117 | s.hashsize = hashsize 118 | 119 | var key, pubKey, keyID, nonce, personal []byte 120 | if conf != nil { 121 | key = conf.Key 122 | pubKey = conf.PublicKey 123 | keyID = conf.KeyID 124 | nonce = conf.Nonce 125 | personal = conf.Personal 126 | } 127 | 128 | if len(key) > 0 { 129 | s.tweak[0] = 0 130 | s.tweak[1] = skein.CfgKey<<56 | skein.FirstBlock 131 | s.Write(key) 132 | s.finalizeHash() 133 | } 134 | 135 | var cfg [32]byte 136 | schemaId := skein.SchemaID 137 | cfg[0] = byte(schemaId) 138 | cfg[1] = byte(schemaId >> 8) 139 | cfg[2] = byte(schemaId >> 16) 140 | cfg[3] = byte(schemaId >> 24) 141 | cfg[4] = byte(schemaId >> 32) 142 | cfg[5] = byte(schemaId >> 40) 143 | cfg[6] = byte(schemaId >> 48) 144 | cfg[7] = byte(schemaId >> 56) 145 | 146 | bits := uint64(s.hashsize * 8) 147 | cfg[8] = byte(bits) 148 | cfg[9] = byte(bits >> 8) 149 | cfg[10] = byte(bits >> 16) 150 | cfg[11] = byte(bits >> 24) 151 | cfg[12] = byte(bits >> 32) 152 | cfg[13] = byte(bits >> 40) 153 | cfg[14] = byte(bits >> 48) 154 | cfg[15] = byte(bits >> 56) 155 | 156 | s.tweak[0] = 0 157 | s.tweak[1] = skein.CfgConfig<<56 | skein.FirstBlock 158 | s.Write(cfg[:]) 159 | s.finalizeHash() 160 | 161 | if len(personal) > 0 { 162 | s.tweak[0] = 0 163 | s.tweak[1] = skein.CfgPersonal<<56 | skein.FirstBlock 164 | s.Write(personal) 165 | s.finalizeHash() 166 | } 167 | 168 | if len(pubKey) > 0 { 169 | s.tweak[0] = 0 170 | s.tweak[1] = skein.CfgPublicKey<<56 | skein.FirstBlock 171 | s.Write(pubKey) 172 | s.finalizeHash() 173 | } 174 | 175 | if len(keyID) > 0 { 176 | s.tweak[0] = 0 177 | s.tweak[1] = skein.CfgKeyID<<56 | skein.FirstBlock 178 | s.Write(keyID) 179 | s.finalizeHash() 180 | } 181 | 182 | if len(nonce) > 0 { 183 | s.tweak[0] = 0 184 | s.tweak[1] = skein.CfgNonce<<56 | skein.FirstBlock 185 | s.Write(nonce) 186 | s.finalizeHash() 187 | } 188 | 189 | s.hValCpy = s.hVal 190 | 191 | s.Reset() 192 | } 193 | 194 | func (s *hashFunc) finalizeHash() { 195 | threefish.IncrementTweak(&(s.tweak), uint64(s.off)) 196 | s.tweak[1] |= skein.FinalBlock // set the last block flag 197 | 198 | for i := s.off; i < len(s.block); i++ { 199 | s.block[i] = 0 200 | } 201 | s.off = 0 202 | 203 | var block [4]uint64 204 | bytesToBlock(&block, s.block[:]) 205 | 206 | threefish.UBI256(&block, &(s.hVal), &(s.tweak)) 207 | } 208 | -------------------------------------------------------------------------------- /skein/skein1024/skein1024.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file 3 | 4 | package skein1024 5 | 6 | import ( 7 | "github.com/enceve/crypto/skein" 8 | "github.com/enceve/crypto/skein/threefish" 9 | ) 10 | 11 | type hashFunc struct { 12 | hashsize int 13 | hVal, hValCpy [17]uint64 14 | tweak [3]uint64 15 | block [threefish.BlockSize1024]byte 16 | off int 17 | hasMsg bool 18 | } 19 | 20 | func (s *hashFunc) BlockSize() int { return threefish.BlockSize1024 } 21 | 22 | func (s *hashFunc) Size() int { return s.hashsize } 23 | 24 | func (s *hashFunc) Reset() { 25 | for i := range s.block { 26 | s.block[i] = 0 27 | } 28 | s.off = 0 29 | s.hasMsg = false 30 | 31 | s.hVal = s.hValCpy 32 | 33 | s.tweak[0] = 0 34 | s.tweak[1] = skein.CfgMessage<<56 | skein.FirstBlock 35 | } 36 | 37 | func (s *hashFunc) Write(p []byte) (n int, err error) { 38 | s.hasMsg = true 39 | 40 | n = len(p) 41 | var block [16]uint64 42 | 43 | dif := threefish.BlockSize1024 - s.off 44 | if s.off > 0 && n > dif { 45 | s.off += copy(s.block[s.off:], p[:dif]) 46 | p = p[dif:] 47 | if s.off == threefish.BlockSize1024 && len(p) > 0 { 48 | bytesToBlock(&block, s.block[:]) 49 | s.update(&block) 50 | s.off = 0 51 | } 52 | } 53 | 54 | if length := len(p); length > threefish.BlockSize1024 { 55 | nn := length & (^(threefish.BlockSize1024 - 1)) // length -= (length % BlockSize) 56 | if length == nn { 57 | nn -= threefish.BlockSize1024 58 | } 59 | for i := 0; i < len(p[:nn]); i += threefish.BlockSize1024 { 60 | bytesToBlock(&block, p[i:]) 61 | s.update(&block) 62 | } 63 | p = p[nn:] 64 | } 65 | 66 | if len(p) > 0 { 67 | s.off += copy(s.block[s.off:], p) 68 | } 69 | return 70 | } 71 | 72 | func (s *hashFunc) Sum(b []byte) []byte { 73 | s0 := *s // copy 74 | 75 | if s0.hasMsg { 76 | s0.finalizeHash() 77 | } 78 | 79 | var out [threefish.BlockSize1024]byte 80 | var ctr uint64 81 | for i := s0.hashsize; i > 0; i -= threefish.BlockSize1024 { 82 | s0.output(&out, ctr) 83 | ctr++ 84 | b = append(b, out[:]...) 85 | } 86 | 87 | return b[:s0.hashsize] 88 | } 89 | 90 | func (s *hashFunc) update(block *[16]uint64) { 91 | threefish.IncrementTweak(&(s.tweak), threefish.BlockSize1024) 92 | 93 | threefish.UBI1024(block, &(s.hVal), &(s.tweak)) 94 | 95 | s.tweak[1] &^= skein.FirstBlock 96 | } 97 | 98 | func (s *hashFunc) output(dst *[threefish.BlockSize1024]byte, counter uint64) { 99 | var block [16]uint64 100 | block[0] = counter 101 | 102 | hVal := s.hVal 103 | var outTweak = [3]uint64{8, skein.CfgOutput<<56 | skein.FirstBlock | skein.FinalBlock, 0} 104 | 105 | threefish.UBI1024(&block, &hVal, &outTweak) 106 | block[0] ^= counter 107 | 108 | blockToBytes(dst[:], &block) 109 | } 110 | 111 | func (s *hashFunc) initialize(hashsize int, conf *skein.Config) { 112 | if hashsize < 1 { 113 | panic("skein1024: invalid hashsize for Skein-1024") 114 | } 115 | 116 | s.hashsize = hashsize 117 | 118 | var key, pubKey, keyID, nonce, personal []byte 119 | if conf != nil { 120 | key = conf.Key 121 | pubKey = conf.PublicKey 122 | keyID = conf.KeyID 123 | nonce = conf.Nonce 124 | personal = conf.Personal 125 | } 126 | 127 | if len(key) > 0 { 128 | s.tweak[0] = 0 129 | s.tweak[1] = skein.CfgKey<<56 | skein.FirstBlock 130 | s.Write(key) 131 | s.finalizeHash() 132 | } 133 | 134 | var cfg [32]byte 135 | schemaId := skein.SchemaID 136 | cfg[0] = byte(schemaId) 137 | cfg[1] = byte(schemaId >> 8) 138 | cfg[2] = byte(schemaId >> 16) 139 | cfg[3] = byte(schemaId >> 24) 140 | cfg[4] = byte(schemaId >> 32) 141 | cfg[5] = byte(schemaId >> 40) 142 | cfg[6] = byte(schemaId >> 48) 143 | cfg[7] = byte(schemaId >> 56) 144 | 145 | bits := uint64(s.hashsize * 8) 146 | cfg[8] = byte(bits) 147 | cfg[9] = byte(bits >> 8) 148 | cfg[10] = byte(bits >> 16) 149 | cfg[11] = byte(bits >> 24) 150 | cfg[12] = byte(bits >> 32) 151 | cfg[13] = byte(bits >> 40) 152 | cfg[14] = byte(bits >> 48) 153 | cfg[15] = byte(bits >> 56) 154 | 155 | s.tweak[0] = 0 156 | s.tweak[1] = skein.CfgConfig<<56 | skein.FirstBlock 157 | s.Write(cfg[:]) 158 | s.finalizeHash() 159 | 160 | if len(personal) > 0 { 161 | s.tweak[0] = 0 162 | s.tweak[1] = skein.CfgPersonal<<56 | skein.FirstBlock 163 | s.Write(personal) 164 | s.finalizeHash() 165 | } 166 | 167 | if len(pubKey) > 0 { 168 | s.tweak[0] = 0 169 | s.tweak[1] = skein.CfgPublicKey<<56 | skein.FirstBlock 170 | s.Write(pubKey) 171 | s.finalizeHash() 172 | } 173 | 174 | if len(keyID) > 0 { 175 | s.tweak[0] = 0 176 | s.tweak[1] = skein.CfgKeyID<<56 | skein.FirstBlock 177 | s.Write(keyID) 178 | s.finalizeHash() 179 | } 180 | 181 | if len(nonce) > 0 { 182 | s.tweak[0] = 0 183 | s.tweak[1] = skein.CfgNonce<<56 | skein.FirstBlock 184 | s.Write(nonce) 185 | s.finalizeHash() 186 | } 187 | 188 | s.hValCpy = s.hVal 189 | 190 | s.Reset() 191 | } 192 | 193 | func (s *hashFunc) finalizeHash() { 194 | threefish.IncrementTweak(&(s.tweak), uint64(s.off)) 195 | s.tweak[1] |= skein.FinalBlock // set the last block flag 196 | 197 | for i := s.off; i < len(s.block); i++ { 198 | s.block[i] = 0 199 | } 200 | s.off = 0 201 | 202 | var block [16]uint64 203 | bytesToBlock(&block, s.block[:]) 204 | 205 | threefish.UBI1024(&block, &(s.hVal), &(s.tweak)) 206 | } 207 | -------------------------------------------------------------------------------- /chacha20/chachaPoly1305_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package chacha20 5 | 6 | import "testing" 7 | 8 | var recFunc = func(t *testing.T, msg string) { 9 | if recover() == nil { 10 | t.Fatalf("Expected error: %s", msg) 11 | } 12 | } 13 | 14 | func TestNewChaCha20Poly1305WithTagSize(t *testing.T) { 15 | var key [32]byte 16 | _, err := NewChaCha20Poly1305WithTagSize(&key, 0) 17 | if err == nil { 18 | t.Fatalf("NewChaCha20Poly1305WithTagSize accepted invalid tagsize: %d", 0) 19 | } 20 | 21 | _, err = NewChaCha20Poly1305WithTagSize(&key, 17) 22 | if err == nil { 23 | t.Fatalf("NewChaCha20Poly1305WithTagSize accepted invalid tagsize: %d", 0) 24 | } 25 | } 26 | 27 | func TestOverhead(t *testing.T) { 28 | var key [32]byte 29 | c := NewChaCha20Poly1305(&key) 30 | 31 | if o := c.Overhead(); o != TagSize { 32 | t.Fatalf("Expected %d but Overhead() returned %d", TagSize, o) 33 | } 34 | 35 | c, err := NewChaCha20Poly1305WithTagSize(&key, 12) 36 | if err != nil { 37 | t.Fatalf("Failed to create ChaCha20Poly1305 instance: %s", err) 38 | } 39 | if o := c.Overhead(); o != 12 { 40 | t.Fatalf("Expected %d but Overhead() returned %d", 12, o) 41 | } 42 | } 43 | 44 | func TestNonceSize(t *testing.T) { 45 | var key [32]byte 46 | c := NewChaCha20Poly1305(&key) 47 | if n := c.NonceSize(); n != NonceSize { 48 | t.Fatalf("Expected %d but NonceSize() returned %d", TagSize, n) 49 | } 50 | } 51 | 52 | func TestSeal(t *testing.T) { 53 | var key [32]byte 54 | c := NewChaCha20Poly1305(&key) 55 | 56 | var ( 57 | nonce [NonceSize]byte 58 | src [64]byte 59 | dst [64 + TagSize]byte 60 | ) 61 | 62 | mustFail := func(msg string, dst, nonce, src []byte) { 63 | defer recFunc(t, msg) 64 | c.Seal(dst, nonce, src, nil) 65 | } 66 | 67 | mustFail("nonce size is invalid", dst[:], nonce[:NonceSize-1], src[:]) 68 | 69 | mustFail("dst length invalid", dst[:len(dst)-2], nonce[:], src[:]) 70 | } 71 | 72 | func TestOpen(t *testing.T) { 73 | var key [32]byte 74 | c := NewChaCha20Poly1305(&key) 75 | 76 | var ( 77 | nonce [NonceSize]byte 78 | src [64]byte 79 | dst [64 + TagSize]byte 80 | ) 81 | 82 | _, err := c.Open(dst[:], nonce[:NonceSize-1], src[:], nil) 83 | if err == nil { 84 | t.Fatal("Open() accepted invalid nonce size") 85 | } 86 | 87 | _, err = c.Open(dst[:], nonce[:], src[:TagSize-1], nil) 88 | if err == nil { 89 | t.Fatal("Open() accepted invalid ciphertext length") 90 | } 91 | 92 | mustFail := func(msg string, dst, nonce, src []byte) { 93 | defer recFunc(t, msg) 94 | c.Open(dst, nonce, src, nil) 95 | } 96 | 97 | mustFail("dst length invalid", dst[:len(src)-TagSize-1], nonce[:], src[:]) 98 | 99 | // Check tag verification 100 | c.Seal(dst[:], nonce[:], src[:], nil) 101 | dst[len(src)+1] += 1 // modify tag 102 | 103 | _, err = c.Open(src[:], nonce[:], dst[:], nil) 104 | if err == nil { 105 | t.Fatal("Open() accepted invalid auth. tag") 106 | } 107 | } 108 | 109 | func BenchmarkSeal64B(b *testing.B) { 110 | var key [32]byte 111 | var nonce [12]byte 112 | c := NewChaCha20Poly1305(&key) 113 | 114 | msg := make([]byte, 64) 115 | dst := make([]byte, len(msg)+TagSize) 116 | data := make([]byte, 32) 117 | 118 | b.SetBytes(int64(len(msg))) 119 | for i := 0; i < b.N; i++ { 120 | dst = c.Seal(dst, nonce[:], msg, data) 121 | } 122 | } 123 | 124 | func BenchmarkSeal1K(b *testing.B) { 125 | var key [32]byte 126 | var nonce [12]byte 127 | c := NewChaCha20Poly1305(&key) 128 | 129 | msg := make([]byte, 1024) 130 | dst := make([]byte, len(msg)+TagSize) 131 | data := make([]byte, 32) 132 | 133 | b.SetBytes(int64(len(msg))) 134 | for i := 0; i < b.N; i++ { 135 | dst = c.Seal(dst, nonce[:], msg, data) 136 | } 137 | } 138 | 139 | func BenchmarkSeal64K(b *testing.B) { 140 | var key [32]byte 141 | var nonce [12]byte 142 | c := NewChaCha20Poly1305(&key) 143 | 144 | msg := make([]byte, 64*1024) 145 | dst := make([]byte, len(msg)+TagSize) 146 | data := make([]byte, 32) 147 | 148 | b.SetBytes(int64(len(msg))) 149 | for i := 0; i < b.N; i++ { 150 | dst = c.Seal(dst, nonce[:], msg, data) 151 | } 152 | } 153 | 154 | func BenchmarkOpen64B(b *testing.B) { 155 | var key [32]byte 156 | var nonce [12]byte 157 | c := NewChaCha20Poly1305(&key) 158 | 159 | msg := make([]byte, 64) 160 | dst := make([]byte, len(msg)) 161 | ciphertext := make([]byte, len(msg)+TagSize) 162 | data := make([]byte, 32) 163 | ciphertext = c.Seal(ciphertext, nonce[:], msg, data) 164 | 165 | b.SetBytes(int64(len(msg))) 166 | for i := 0; i < b.N; i++ { 167 | dst, _ = c.Open(dst, nonce[:], ciphertext, data) 168 | } 169 | } 170 | 171 | func BenchmarkOpen1K(b *testing.B) { 172 | var key [32]byte 173 | var nonce [12]byte 174 | c := NewChaCha20Poly1305(&key) 175 | 176 | msg := make([]byte, 1024) 177 | dst := make([]byte, len(msg)) 178 | ciphertext := make([]byte, len(msg)+TagSize) 179 | data := make([]byte, 32) 180 | ciphertext = c.Seal(ciphertext, nonce[:], msg, data) 181 | 182 | b.SetBytes(int64(len(msg))) 183 | for i := 0; i < b.N; i++ { 184 | dst, _ = c.Open(dst, nonce[:], ciphertext, data) 185 | } 186 | } 187 | 188 | func BenchmarkOpen64K(b *testing.B) { 189 | var key [32]byte 190 | var nonce [12]byte 191 | c := NewChaCha20Poly1305(&key) 192 | 193 | msg := make([]byte, 64*1024) 194 | dst := make([]byte, len(msg)) 195 | ciphertext := make([]byte, len(msg)+TagSize) 196 | data := make([]byte, 32) 197 | ciphertext = c.Seal(ciphertext, nonce[:], msg, data) 198 | 199 | b.SetBytes(int64(len(msg))) 200 | for i := 0; i < b.N; i++ { 201 | dst, _ = c.Open(dst, nonce[:], ciphertext, data) 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /blake2/blake2_test.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a license 2 | // that can be found in the LICENSE file. 3 | 4 | package blake2 5 | 6 | import ( 7 | "bytes" 8 | "encoding/hex" 9 | "testing" 10 | 11 | "github.com/enceve/crypto/blake2/blake2b" 12 | "github.com/enceve/crypto/blake2/blake2s" 13 | ) 14 | 15 | var msgLens = [8]int{0, 63, 64, 65, 127, 128, 129, 1024} 16 | var keyLens = [8]int{0, 16, 24, 32} 17 | 18 | func generateSequence(out []byte, seed uint32) { 19 | a := 0xDEAD4BAD * seed 20 | b := uint32(1) 21 | 22 | for i := range out { 23 | t := a + b 24 | a = b 25 | b = t 26 | out[i] = byte(t >> 24) 27 | } 28 | } 29 | 30 | func TestSum512(t *testing.T) { 31 | var sum [64]byte 32 | msg := make([]byte, 1024) 33 | key := make([]byte, 64) 34 | 35 | for _, kl := range keyLens { 36 | for _, ml := range msgLens { 37 | m := msg[:ml] 38 | 39 | generateSequence(m, uint32(kl+ml)) 40 | expected, err := blake2b.Sum(m, 64, nil) 41 | if err != nil { 42 | t.Fatalf("Failed to compute BLAKE2b sum: %s", err) 43 | } 44 | Sum512(&sum, m, nil) 45 | if !bytes.Equal(sum[:], expected) { 46 | t.Fatalf("Unkeyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) 47 | } 48 | 49 | k := key[:kl] 50 | generateSequence(k, uint32(ml)) 51 | expected, err = blake2b.Sum(m, 64, &blake2b.Config{Key: k}) 52 | if err != nil { 53 | t.Fatalf("Keyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) 54 | } 55 | Sum512(&sum, m, k) 56 | if !bytes.Equal(sum[:], expected) { 57 | t.Fatalf("") 58 | } 59 | } 60 | } 61 | } 62 | 63 | func TestSum256b(t *testing.T) { 64 | var sum [32]byte 65 | msg := make([]byte, 1024) 66 | key := make([]byte, 64) 67 | 68 | for _, kl := range keyLens { 69 | for _, ml := range msgLens { 70 | m := msg[:ml] 71 | 72 | generateSequence(m, uint32(kl+ml)) 73 | expected, err := blake2b.Sum(m, 32, nil) 74 | if err != nil { 75 | t.Fatalf("Failed to compute BLAKE2b sum: %s", err) 76 | } 77 | Sum256b(&sum, m, nil) 78 | if !bytes.Equal(sum[:], expected) { 79 | t.Fatalf("Unkeyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) 80 | } 81 | 82 | k := key[:kl] 83 | generateSequence(k, uint32(ml)) 84 | expected, err = blake2b.Sum(m, 32, &blake2b.Config{Key: k}) 85 | if err != nil { 86 | t.Fatalf("Keyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) 87 | } 88 | Sum256b(&sum, m, k) 89 | if !bytes.Equal(sum[:], expected) { 90 | t.Fatalf("") 91 | } 92 | } 93 | } 94 | } 95 | 96 | func TestSum256s(t *testing.T) { 97 | var sum [32]byte 98 | msg := make([]byte, 1024) 99 | key := make([]byte, 64) 100 | 101 | for _, kl := range keyLens { 102 | for _, ml := range msgLens { 103 | m := msg[:ml] 104 | 105 | generateSequence(m, uint32(kl+ml)) 106 | expected, err := blake2s.Sum(m, 32, nil) 107 | if err != nil { 108 | t.Fatalf("Failed to compute BLAKE2b sum: %s", err) 109 | } 110 | Sum256s(&sum, m, nil) 111 | if !bytes.Equal(sum[:], expected) { 112 | t.Fatalf("Unkeyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) 113 | } 114 | 115 | k := key[:kl] 116 | generateSequence(k, uint32(ml)) 117 | expected, err = blake2s.Sum(m, 32, &blake2s.Config{Key: k}) 118 | if err != nil { 119 | t.Fatalf("Keyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) 120 | } 121 | Sum256s(&sum, m, k) 122 | if !bytes.Equal(sum[:], expected) { 123 | t.Fatalf("") 124 | } 125 | } 126 | } 127 | } 128 | 129 | func TestSum160s(t *testing.T) { 130 | var sum [20]byte 131 | msg := make([]byte, 1024) 132 | key := make([]byte, 64) 133 | 134 | for _, kl := range keyLens { 135 | for _, ml := range msgLens { 136 | m := msg[:ml] 137 | 138 | generateSequence(m, uint32(kl+ml)) 139 | expected, err := blake2s.Sum(m, 20, nil) 140 | if err != nil { 141 | t.Fatalf("Failed to compute BLAKE2b sum: %s", err) 142 | } 143 | Sum160s(&sum, m, nil) 144 | if !bytes.Equal(sum[:], expected) { 145 | t.Fatalf("Unkeyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) 146 | } 147 | 148 | k := key[:kl] 149 | generateSequence(k, uint32(ml)) 150 | expected, err = blake2s.Sum(m, 20, &blake2s.Config{Key: k}) 151 | if err != nil { 152 | t.Fatalf("Keyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) 153 | } 154 | Sum160s(&sum, m, k) 155 | if !bytes.Equal(sum[:], expected) { 156 | t.Fatalf("") 157 | } 158 | } 159 | } 160 | } 161 | 162 | // Benchmarks 163 | 164 | func benchmarkSum512(b *testing.B, size int) { 165 | var sum512 [64]byte 166 | buf := make([]byte, size) 167 | b.SetBytes(int64(size)) 168 | b.ResetTimer() 169 | for i := 0; i < b.N; i++ { 170 | Sum512(&sum512, buf, nil) 171 | } 172 | } 173 | 174 | func benchmarkSum256s(b *testing.B, size int) { 175 | var sum256s [32]byte 176 | buf := make([]byte, size) 177 | b.SetBytes(int64(size)) 178 | b.ResetTimer() 179 | for i := 0; i < b.N; i++ { 180 | Sum256s(&sum256s, buf, nil) 181 | } 182 | } 183 | 184 | func BenchmarkSum512_64(b *testing.B) { benchmarkSum512(b, 64) } 185 | func BenchmarkSum512_1024(b *testing.B) { benchmarkSum512(b, 1024) } 186 | func BenchmarkSum256s_64(b *testing.B) { benchmarkSum256s(b, 64) } 187 | func BenchmarkSum256s_1024(b *testing.B) { benchmarkSum256s(b, 1024) } 188 | --------------------------------------------------------------------------------