diff --git a/chacha20poly1305/chacha20poly1305.go b/chacha20poly1305/chacha20poly1305.go index 3f0dcb9..e28f49d 100644 --- a/chacha20poly1305/chacha20poly1305.go +++ b/chacha20poly1305/chacha20poly1305.go @@ -7,6 +7,7 @@ package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305" import ( "crypto/cipher" + "encoding/binary" "errors" ) @@ -18,7 +19,7 @@ const ( ) type chacha20poly1305 struct { - key [32]byte + key [8]uint32 } // New returns a ChaCha20-Poly1305 AEAD that uses the given, 256-bit key. @@ -27,7 +28,14 @@ func New(key []byte) (cipher.AEAD, error) { return nil, errors.New("chacha20poly1305: bad key length") } ret := new(chacha20poly1305) - copy(ret.key[:], key) + ret.key[0] = binary.LittleEndian.Uint32(key[0:4]) + ret.key[1] = binary.LittleEndian.Uint32(key[4:8]) + ret.key[2] = binary.LittleEndian.Uint32(key[8:12]) + ret.key[3] = binary.LittleEndian.Uint32(key[12:16]) + ret.key[4] = binary.LittleEndian.Uint32(key[16:20]) + ret.key[5] = binary.LittleEndian.Uint32(key[20:24]) + ret.key[6] = binary.LittleEndian.Uint32(key[24:28]) + ret.key[7] = binary.LittleEndian.Uint32(key[28:32]) return ret, nil } diff --git a/chacha20poly1305/chacha20poly1305_amd64.go b/chacha20poly1305/chacha20poly1305_amd64.go index 7cd7ad8..17f94e9 100644 --- a/chacha20poly1305/chacha20poly1305_amd64.go +++ b/chacha20poly1305/chacha20poly1305_amd64.go @@ -72,20 +72,20 @@ func isSet(bitpos uint, value uint32) bool { // setupState writes a ChaCha20 input matrix to state. See // https://tools.ietf.org/html/rfc7539#section-2.3. -func setupState(state *[16]uint32, key *[32]byte, nonce []byte) { +func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) { state[0] = 0x61707865 state[1] = 0x3320646e state[2] = 0x79622d32 state[3] = 0x6b206574 - state[4] = binary.LittleEndian.Uint32(key[:4]) - state[5] = binary.LittleEndian.Uint32(key[4:8]) - state[6] = binary.LittleEndian.Uint32(key[8:12]) - state[7] = binary.LittleEndian.Uint32(key[12:16]) - state[8] = binary.LittleEndian.Uint32(key[16:20]) - state[9] = binary.LittleEndian.Uint32(key[20:24]) - state[10] = binary.LittleEndian.Uint32(key[24:28]) - state[11] = binary.LittleEndian.Uint32(key[28:32]) + state[4] = key[0] + state[5] = key[1] + state[6] = key[2] + state[7] = key[3] + state[8] = key[4] + state[9] = key[5] + state[10] = key[6] + state[11] = key[7] state[12] = 0 state[13] = binary.LittleEndian.Uint32(nonce[:4]) diff --git a/chacha20poly1305/chacha20poly1305_generic.go b/chacha20poly1305/chacha20poly1305_generic.go index 4ac014f..8d28ce2 100644 --- a/chacha20poly1305/chacha20poly1305_generic.go +++ b/chacha20poly1305/chacha20poly1305_generic.go @@ -16,15 +16,17 @@ func roundTo16(n int) int { } func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte { - var counter [16]byte - copy(counter[4:], nonce) + ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize) var polyKey [32]byte - chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key) - - ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize) - counter[0] = 1 - chacha20.XORKeyStream(out, plaintext, &counter, &c.key) + s := chacha20.New(c.key, [3]uint32{ + binary.LittleEndian.Uint32(nonce[0:4]), + binary.LittleEndian.Uint32(nonce[4:8]), + binary.LittleEndian.Uint32(nonce[8:12]), + }) + s.XORKeyStream(polyKey[:], polyKey[:]) + s.Advance() // skip the next 32 bytes + s.XORKeyStream(out, plaintext) polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(plaintext))+8+8) copy(polyInput, additionalData) @@ -44,11 +46,14 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData [] copy(tag[:], ciphertext[len(ciphertext)-16:]) ciphertext = ciphertext[:len(ciphertext)-16] - var counter [16]byte - copy(counter[4:], nonce) - var polyKey [32]byte - chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key) + s := chacha20.New(c.key, [3]uint32{ + binary.LittleEndian.Uint32(nonce[0:4]), + binary.LittleEndian.Uint32(nonce[4:8]), + binary.LittleEndian.Uint32(nonce[8:12]), + }) + s.XORKeyStream(polyKey[:], polyKey[:]) + s.Advance() // skip the next 32 bytes polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(ciphertext))+8+8) copy(polyInput, additionalData) @@ -64,7 +69,6 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData [] return nil, errOpen } - counter[0] = 1 - chacha20.XORKeyStream(out, ciphertext, &counter, &c.key) + s.XORKeyStream(out, ciphertext) return ret, nil }