OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / golang.org / x / crypto / chacha20poly1305 / internal / chacha20 / chacha_generic.go
1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package ChaCha20 implements the core ChaCha20 function as specified in https://tools.ietf.org/html/rfc7539#section-2.3.
6 package chacha20
7
8 import "encoding/binary"
9
10 const rounds = 20
11
12 // core applies the ChaCha20 core function to 16-byte input in, 32-byte key k,
13 // and 16-byte constant c, and puts the result into 64-byte array out.
14 func core(out *[64]byte, in *[16]byte, k *[32]byte) {
15         j0 := uint32(0x61707865)
16         j1 := uint32(0x3320646e)
17         j2 := uint32(0x79622d32)
18         j3 := uint32(0x6b206574)
19         j4 := binary.LittleEndian.Uint32(k[0:4])
20         j5 := binary.LittleEndian.Uint32(k[4:8])
21         j6 := binary.LittleEndian.Uint32(k[8:12])
22         j7 := binary.LittleEndian.Uint32(k[12:16])
23         j8 := binary.LittleEndian.Uint32(k[16:20])
24         j9 := binary.LittleEndian.Uint32(k[20:24])
25         j10 := binary.LittleEndian.Uint32(k[24:28])
26         j11 := binary.LittleEndian.Uint32(k[28:32])
27         j12 := binary.LittleEndian.Uint32(in[0:4])
28         j13 := binary.LittleEndian.Uint32(in[4:8])
29         j14 := binary.LittleEndian.Uint32(in[8:12])
30         j15 := binary.LittleEndian.Uint32(in[12:16])
31
32         x0, x1, x2, x3, x4, x5, x6, x7 := j0, j1, j2, j3, j4, j5, j6, j7
33         x8, x9, x10, x11, x12, x13, x14, x15 := j8, j9, j10, j11, j12, j13, j14, j15
34
35         for i := 0; i < rounds; i += 2 {
36                 x0 += x4
37                 x12 ^= x0
38                 x12 = (x12 << 16) | (x12 >> (16))
39                 x8 += x12
40                 x4 ^= x8
41                 x4 = (x4 << 12) | (x4 >> (20))
42                 x0 += x4
43                 x12 ^= x0
44                 x12 = (x12 << 8) | (x12 >> (24))
45                 x8 += x12
46                 x4 ^= x8
47                 x4 = (x4 << 7) | (x4 >> (25))
48                 x1 += x5
49                 x13 ^= x1
50                 x13 = (x13 << 16) | (x13 >> 16)
51                 x9 += x13
52                 x5 ^= x9
53                 x5 = (x5 << 12) | (x5 >> 20)
54                 x1 += x5
55                 x13 ^= x1
56                 x13 = (x13 << 8) | (x13 >> 24)
57                 x9 += x13
58                 x5 ^= x9
59                 x5 = (x5 << 7) | (x5 >> 25)
60                 x2 += x6
61                 x14 ^= x2
62                 x14 = (x14 << 16) | (x14 >> 16)
63                 x10 += x14
64                 x6 ^= x10
65                 x6 = (x6 << 12) | (x6 >> 20)
66                 x2 += x6
67                 x14 ^= x2
68                 x14 = (x14 << 8) | (x14 >> 24)
69                 x10 += x14
70                 x6 ^= x10
71                 x6 = (x6 << 7) | (x6 >> 25)
72                 x3 += x7
73                 x15 ^= x3
74                 x15 = (x15 << 16) | (x15 >> 16)
75                 x11 += x15
76                 x7 ^= x11
77                 x7 = (x7 << 12) | (x7 >> 20)
78                 x3 += x7
79                 x15 ^= x3
80                 x15 = (x15 << 8) | (x15 >> 24)
81                 x11 += x15
82                 x7 ^= x11
83                 x7 = (x7 << 7) | (x7 >> 25)
84                 x0 += x5
85                 x15 ^= x0
86                 x15 = (x15 << 16) | (x15 >> 16)
87                 x10 += x15
88                 x5 ^= x10
89                 x5 = (x5 << 12) | (x5 >> 20)
90                 x0 += x5
91                 x15 ^= x0
92                 x15 = (x15 << 8) | (x15 >> 24)
93                 x10 += x15
94                 x5 ^= x10
95                 x5 = (x5 << 7) | (x5 >> 25)
96                 x1 += x6
97                 x12 ^= x1
98                 x12 = (x12 << 16) | (x12 >> 16)
99                 x11 += x12
100                 x6 ^= x11
101                 x6 = (x6 << 12) | (x6 >> 20)
102                 x1 += x6
103                 x12 ^= x1
104                 x12 = (x12 << 8) | (x12 >> 24)
105                 x11 += x12
106                 x6 ^= x11
107                 x6 = (x6 << 7) | (x6 >> 25)
108                 x2 += x7
109                 x13 ^= x2
110                 x13 = (x13 << 16) | (x13 >> 16)
111                 x8 += x13
112                 x7 ^= x8
113                 x7 = (x7 << 12) | (x7 >> 20)
114                 x2 += x7
115                 x13 ^= x2
116                 x13 = (x13 << 8) | (x13 >> 24)
117                 x8 += x13
118                 x7 ^= x8
119                 x7 = (x7 << 7) | (x7 >> 25)
120                 x3 += x4
121                 x14 ^= x3
122                 x14 = (x14 << 16) | (x14 >> 16)
123                 x9 += x14
124                 x4 ^= x9
125                 x4 = (x4 << 12) | (x4 >> 20)
126                 x3 += x4
127                 x14 ^= x3
128                 x14 = (x14 << 8) | (x14 >> 24)
129                 x9 += x14
130                 x4 ^= x9
131                 x4 = (x4 << 7) | (x4 >> 25)
132         }
133
134         x0 += j0
135         x1 += j1
136         x2 += j2
137         x3 += j3
138         x4 += j4
139         x5 += j5
140         x6 += j6
141         x7 += j7
142         x8 += j8
143         x9 += j9
144         x10 += j10
145         x11 += j11
146         x12 += j12
147         x13 += j13
148         x14 += j14
149         x15 += j15
150
151         binary.LittleEndian.PutUint32(out[0:4], x0)
152         binary.LittleEndian.PutUint32(out[4:8], x1)
153         binary.LittleEndian.PutUint32(out[8:12], x2)
154         binary.LittleEndian.PutUint32(out[12:16], x3)
155         binary.LittleEndian.PutUint32(out[16:20], x4)
156         binary.LittleEndian.PutUint32(out[20:24], x5)
157         binary.LittleEndian.PutUint32(out[24:28], x6)
158         binary.LittleEndian.PutUint32(out[28:32], x7)
159         binary.LittleEndian.PutUint32(out[32:36], x8)
160         binary.LittleEndian.PutUint32(out[36:40], x9)
161         binary.LittleEndian.PutUint32(out[40:44], x10)
162         binary.LittleEndian.PutUint32(out[44:48], x11)
163         binary.LittleEndian.PutUint32(out[48:52], x12)
164         binary.LittleEndian.PutUint32(out[52:56], x13)
165         binary.LittleEndian.PutUint32(out[56:60], x14)
166         binary.LittleEndian.PutUint32(out[60:64], x15)
167 }
168
169 // XORKeyStream crypts bytes from in to out using the given key and counters.
170 // In and out may be the same slice but otherwise should not overlap. Counter
171 // contains the raw ChaCha20 counter bytes (i.e. block counter followed by
172 // nonce).
173 func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
174         var block [64]byte
175         var counterCopy [16]byte
176         copy(counterCopy[:], counter[:])
177
178         for len(in) >= 64 {
179                 core(&block, &counterCopy, key)
180                 for i, x := range block {
181                         out[i] = in[i] ^ x
182                 }
183                 u := uint32(1)
184                 for i := 0; i < 4; i++ {
185                         u += uint32(counterCopy[i])
186                         counterCopy[i] = byte(u)
187                         u >>= 8
188                 }
189                 in = in[64:]
190                 out = out[64:]
191         }
192
193         if len(in) > 0 {
194                 core(&block, &counterCopy, key)
195                 for i, v := range in {
196                         out[i] = v ^ block[i]
197                 }
198         }
199 }