1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 package chacha8rand
50
51 import (
52 "internal/goarch"
53 "unsafe"
54 )
55
56
57
58
59 func setup(seed *[4]uint64, b32 *[16][4]uint32, counter uint32) {
60
61 b := (*[16][2]uint64)(unsafe.Pointer(b32))
62
63
64 b[0][0] = 0x61707865_61707865
65 b[0][1] = 0x61707865_61707865
66
67 b[1][0] = 0x3320646e_3320646e
68 b[1][1] = 0x3320646e_3320646e
69
70 b[2][0] = 0x79622d32_79622d32
71 b[2][1] = 0x79622d32_79622d32
72
73 b[3][0] = 0x6b206574_6b206574
74 b[3][1] = 0x6b206574_6b206574
75
76
77 var x64 uint64
78 var x uint32
79
80 x = uint32(seed[0])
81 x64 = uint64(x)<<32 | uint64(x)
82 b[4][0] = x64
83 b[4][1] = x64
84
85 x = uint32(seed[0] >> 32)
86 x64 = uint64(x)<<32 | uint64(x)
87 b[5][0] = x64
88 b[5][1] = x64
89
90 x = uint32(seed[1])
91 x64 = uint64(x)<<32 | uint64(x)
92 b[6][0] = x64
93 b[6][1] = x64
94
95 x = uint32(seed[1] >> 32)
96 x64 = uint64(x)<<32 | uint64(x)
97 b[7][0] = x64
98 b[7][1] = x64
99
100 x = uint32(seed[2])
101 x64 = uint64(x)<<32 | uint64(x)
102 b[8][0] = x64
103 b[8][1] = x64
104
105 x = uint32(seed[2] >> 32)
106 x64 = uint64(x)<<32 | uint64(x)
107 b[9][0] = x64
108 b[9][1] = x64
109
110 x = uint32(seed[3])
111 x64 = uint64(x)<<32 | uint64(x)
112 b[10][0] = x64
113 b[10][1] = x64
114
115 x = uint32(seed[3] >> 32)
116 x64 = uint64(x)<<32 | uint64(x)
117 b[11][0] = x64
118 b[11][1] = x64
119
120
121 if goarch.BigEndian {
122 b[12][0] = uint64(counter+0)<<32 | uint64(counter+1)
123 b[12][1] = uint64(counter+2)<<32 | uint64(counter+3)
124 } else {
125 b[12][0] = uint64(counter+0) | uint64(counter+1)<<32
126 b[12][1] = uint64(counter+2) | uint64(counter+3)<<32
127 }
128
129
130 b[13][0] = 0
131 b[13][1] = 0
132 b[14][0] = 0
133 b[14][1] = 0
134
135 b[15][0] = 0
136 b[15][1] = 0
137 }
138
139 func _() {
140
141 x := block
142 x = block_generic
143 _ = x
144 }
145
146
147
148
149
150 func block_generic(seed *[4]uint64, buf *[32]uint64, counter uint32) {
151 b := (*[16][4]uint32)(unsafe.Pointer(buf))
152
153 setup(seed, b, counter)
154
155 for i := range b[0] {
156
157 b0 := b[0][i]
158 b1 := b[1][i]
159 b2 := b[2][i]
160 b3 := b[3][i]
161 b4 := b[4][i]
162 b5 := b[5][i]
163 b6 := b[6][i]
164 b7 := b[7][i]
165 b8 := b[8][i]
166 b9 := b[9][i]
167 b10 := b[10][i]
168 b11 := b[11][i]
169 b12 := b[12][i]
170 b13 := b[13][i]
171 b14 := b[14][i]
172 b15 := b[15][i]
173
174
175 for round := 0; round < 4; round++ {
176 b0, b4, b8, b12 = qr(b0, b4, b8, b12)
177 b1, b5, b9, b13 = qr(b1, b5, b9, b13)
178 b2, b6, b10, b14 = qr(b2, b6, b10, b14)
179 b3, b7, b11, b15 = qr(b3, b7, b11, b15)
180
181 b0, b5, b10, b15 = qr(b0, b5, b10, b15)
182 b1, b6, b11, b12 = qr(b1, b6, b11, b12)
183 b2, b7, b8, b13 = qr(b2, b7, b8, b13)
184 b3, b4, b9, b14 = qr(b3, b4, b9, b14)
185 }
186
187
188
189
190
191
192 b[0][i] = b0
193 b[1][i] = b1
194 b[2][i] = b2
195 b[3][i] = b3
196 b[4][i] += b4
197 b[5][i] += b5
198 b[6][i] += b6
199 b[7][i] += b7
200 b[8][i] += b8
201 b[9][i] += b9
202 b[10][i] += b10
203 b[11][i] += b11
204 b[12][i] = b12
205 b[13][i] = b13
206 b[14][i] = b14
207 b[15][i] = b15
208 }
209
210 if goarch.BigEndian {
211
212
213
214 for i, x := range buf {
215 buf[i] = x>>32 | x<<32
216 }
217 }
218 }
219
220
221 func qr(a, b, c, d uint32) (_a, _b, _c, _d uint32) {
222 a += b
223 d ^= a
224 d = d<<16 | d>>16
225 c += d
226 b ^= c
227 b = b<<12 | b>>20
228 a += b
229 d ^= a
230 d = d<<8 | d>>24
231 c += d
232 b ^= c
233 b = b<<7 | b>>25
234 return a, b, c, d
235 }
236
View as plain text