1
2
3
4
5
6
7
8 package chacha20poly1305
9
10 import (
11 "encoding/binary"
12
13 "golang.org/x/crypto/internal/subtle"
14 "golang.org/x/sys/cpu"
15 )
16
17
18 func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
19
20
21 func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
22
23 var (
24 useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2
25 )
26
27
28
29 func setupState(state *[16]uint32, key *[32]byte, nonce []byte) {
30 state[0] = 0x61707865
31 state[1] = 0x3320646e
32 state[2] = 0x79622d32
33 state[3] = 0x6b206574
34
35 state[4] = binary.LittleEndian.Uint32(key[0:4])
36 state[5] = binary.LittleEndian.Uint32(key[4:8])
37 state[6] = binary.LittleEndian.Uint32(key[8:12])
38 state[7] = binary.LittleEndian.Uint32(key[12:16])
39 state[8] = binary.LittleEndian.Uint32(key[16:20])
40 state[9] = binary.LittleEndian.Uint32(key[20:24])
41 state[10] = binary.LittleEndian.Uint32(key[24:28])
42 state[11] = binary.LittleEndian.Uint32(key[28:32])
43
44 state[12] = 0
45 state[13] = binary.LittleEndian.Uint32(nonce[0:4])
46 state[14] = binary.LittleEndian.Uint32(nonce[4:8])
47 state[15] = binary.LittleEndian.Uint32(nonce[8:12])
48 }
49
50 func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
51 if !cpu.X86.HasSSSE3 {
52 return c.sealGeneric(dst, nonce, plaintext, additionalData)
53 }
54
55 var state [16]uint32
56 setupState(&state, &c.key, nonce)
57
58 ret, out := sliceForAppend(dst, len(plaintext)+16)
59 if subtle.InexactOverlap(out, plaintext) {
60 panic("chacha20poly1305: invalid buffer overlap")
61 }
62 chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
63 return ret
64 }
65
66 func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
67 if !cpu.X86.HasSSSE3 {
68 return c.openGeneric(dst, nonce, ciphertext, additionalData)
69 }
70
71 var state [16]uint32
72 setupState(&state, &c.key, nonce)
73
74 ciphertext = ciphertext[:len(ciphertext)-16]
75 ret, out := sliceForAppend(dst, len(ciphertext))
76 if subtle.InexactOverlap(out, ciphertext) {
77 panic("chacha20poly1305: invalid buffer overlap")
78 }
79 if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
80 for i := range out {
81 out[i] = 0
82 }
83 return nil, errOpen
84 }
85
86 return ret, nil
87 }
88
View as plain text