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