diff options
author | Rutger Broekhoff | 2023-12-29 21:31:53 +0100 |
---|---|---|
committer | Rutger Broekhoff | 2023-12-29 21:31:53 +0100 |
commit | 404aeae4545d2426c089a5f8d5e82dae56f5212b (patch) | |
tree | 2d84e00af272b39fc04f3795ae06bc48970e57b5 /vendor/github.com/minio/sha256-simd/sha256.go | |
parent | 209d8b0187ed025dec9ac149ebcced3462877bff (diff) | |
download | gitolfs3-404aeae4545d2426c089a5f8d5e82dae56f5212b.tar.gz gitolfs3-404aeae4545d2426c089a5f8d5e82dae56f5212b.zip |
Make Nix builds work
Diffstat (limited to 'vendor/github.com/minio/sha256-simd/sha256.go')
-rw-r--r-- | vendor/github.com/minio/sha256-simd/sha256.go | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/vendor/github.com/minio/sha256-simd/sha256.go b/vendor/github.com/minio/sha256-simd/sha256.go new file mode 100644 index 0000000..f146bbd --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256.go | |||
@@ -0,0 +1,468 @@ | |||
1 | /* | ||
2 | * Minio Cloud Storage, (C) 2016 Minio, Inc. | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package sha256 | ||
18 | |||
19 | import ( | ||
20 | "crypto/sha256" | ||
21 | "encoding/binary" | ||
22 | "errors" | ||
23 | "hash" | ||
24 | ) | ||
25 | |||
26 | // Size - The size of a SHA256 checksum in bytes. | ||
27 | const Size = 32 | ||
28 | |||
29 | // BlockSize - The blocksize of SHA256 in bytes. | ||
30 | const BlockSize = 64 | ||
31 | |||
32 | const ( | ||
33 | chunk = BlockSize | ||
34 | init0 = 0x6A09E667 | ||
35 | init1 = 0xBB67AE85 | ||
36 | init2 = 0x3C6EF372 | ||
37 | init3 = 0xA54FF53A | ||
38 | init4 = 0x510E527F | ||
39 | init5 = 0x9B05688C | ||
40 | init6 = 0x1F83D9AB | ||
41 | init7 = 0x5BE0CD19 | ||
42 | ) | ||
43 | |||
44 | // digest represents the partial evaluation of a checksum. | ||
45 | type digest struct { | ||
46 | h [8]uint32 | ||
47 | x [chunk]byte | ||
48 | nx int | ||
49 | len uint64 | ||
50 | } | ||
51 | |||
52 | // Reset digest back to default | ||
53 | func (d *digest) Reset() { | ||
54 | d.h[0] = init0 | ||
55 | d.h[1] = init1 | ||
56 | d.h[2] = init2 | ||
57 | d.h[3] = init3 | ||
58 | d.h[4] = init4 | ||
59 | d.h[5] = init5 | ||
60 | d.h[6] = init6 | ||
61 | d.h[7] = init7 | ||
62 | d.nx = 0 | ||
63 | d.len = 0 | ||
64 | } | ||
65 | |||
66 | type blockfuncType int | ||
67 | |||
68 | const ( | ||
69 | blockfuncStdlib blockfuncType = iota | ||
70 | blockfuncIntelSha | ||
71 | blockfuncArmSha2 | ||
72 | blockfuncForceGeneric = -1 | ||
73 | ) | ||
74 | |||
75 | var blockfunc blockfuncType | ||
76 | |||
77 | func init() { | ||
78 | switch { | ||
79 | case hasIntelSha: | ||
80 | blockfunc = blockfuncIntelSha | ||
81 | case hasArmSha2(): | ||
82 | blockfunc = blockfuncArmSha2 | ||
83 | } | ||
84 | } | ||
85 | |||
86 | // New returns a new hash.Hash computing the SHA256 checksum. | ||
87 | func New() hash.Hash { | ||
88 | if blockfunc == blockfuncStdlib { | ||
89 | // Fallback to the standard golang implementation | ||
90 | // if no features were found. | ||
91 | return sha256.New() | ||
92 | } | ||
93 | |||
94 | d := new(digest) | ||
95 | d.Reset() | ||
96 | return d | ||
97 | } | ||
98 | |||
99 | // Sum256 - single caller sha256 helper | ||
100 | func Sum256(data []byte) (result [Size]byte) { | ||
101 | var d digest | ||
102 | d.Reset() | ||
103 | d.Write(data) | ||
104 | result = d.checkSum() | ||
105 | return | ||
106 | } | ||
107 | |||
108 | // Return size of checksum | ||
109 | func (d *digest) Size() int { return Size } | ||
110 | |||
111 | // Return blocksize of checksum | ||
112 | func (d *digest) BlockSize() int { return BlockSize } | ||
113 | |||
114 | // Write to digest | ||
115 | func (d *digest) Write(p []byte) (nn int, err error) { | ||
116 | nn = len(p) | ||
117 | d.len += uint64(nn) | ||
118 | if d.nx > 0 { | ||
119 | n := copy(d.x[d.nx:], p) | ||
120 | d.nx += n | ||
121 | if d.nx == chunk { | ||
122 | block(d, d.x[:]) | ||
123 | d.nx = 0 | ||
124 | } | ||
125 | p = p[n:] | ||
126 | } | ||
127 | if len(p) >= chunk { | ||
128 | n := len(p) &^ (chunk - 1) | ||
129 | block(d, p[:n]) | ||
130 | p = p[n:] | ||
131 | } | ||
132 | if len(p) > 0 { | ||
133 | d.nx = copy(d.x[:], p) | ||
134 | } | ||
135 | return | ||
136 | } | ||
137 | |||
138 | // Return sha256 sum in bytes | ||
139 | func (d *digest) Sum(in []byte) []byte { | ||
140 | // Make a copy of d0 so that caller can keep writing and summing. | ||
141 | d0 := *d | ||
142 | hash := d0.checkSum() | ||
143 | return append(in, hash[:]...) | ||
144 | } | ||
145 | |||
146 | // Intermediate checksum function | ||
147 | func (d *digest) checkSum() (digest [Size]byte) { | ||
148 | n := d.nx | ||
149 | |||
150 | var k [64]byte | ||
151 | copy(k[:], d.x[:n]) | ||
152 | |||
153 | k[n] = 0x80 | ||
154 | |||
155 | if n >= 56 { | ||
156 | block(d, k[:]) | ||
157 | |||
158 | // clear block buffer - go compiles this to optimal 1x xorps + 4x movups | ||
159 | // unfortunately expressing this more succinctly results in much worse code | ||
160 | k[0] = 0 | ||
161 | k[1] = 0 | ||
162 | k[2] = 0 | ||
163 | k[3] = 0 | ||
164 | k[4] = 0 | ||
165 | k[5] = 0 | ||
166 | k[6] = 0 | ||
167 | k[7] = 0 | ||
168 | k[8] = 0 | ||
169 | k[9] = 0 | ||
170 | k[10] = 0 | ||
171 | k[11] = 0 | ||
172 | k[12] = 0 | ||
173 | k[13] = 0 | ||
174 | k[14] = 0 | ||
175 | k[15] = 0 | ||
176 | k[16] = 0 | ||
177 | k[17] = 0 | ||
178 | k[18] = 0 | ||
179 | k[19] = 0 | ||
180 | k[20] = 0 | ||
181 | k[21] = 0 | ||
182 | k[22] = 0 | ||
183 | k[23] = 0 | ||
184 | k[24] = 0 | ||
185 | k[25] = 0 | ||
186 | k[26] = 0 | ||
187 | k[27] = 0 | ||
188 | k[28] = 0 | ||
189 | k[29] = 0 | ||
190 | k[30] = 0 | ||
191 | k[31] = 0 | ||
192 | k[32] = 0 | ||
193 | k[33] = 0 | ||
194 | k[34] = 0 | ||
195 | k[35] = 0 | ||
196 | k[36] = 0 | ||
197 | k[37] = 0 | ||
198 | k[38] = 0 | ||
199 | k[39] = 0 | ||
200 | k[40] = 0 | ||
201 | k[41] = 0 | ||
202 | k[42] = 0 | ||
203 | k[43] = 0 | ||
204 | k[44] = 0 | ||
205 | k[45] = 0 | ||
206 | k[46] = 0 | ||
207 | k[47] = 0 | ||
208 | k[48] = 0 | ||
209 | k[49] = 0 | ||
210 | k[50] = 0 | ||
211 | k[51] = 0 | ||
212 | k[52] = 0 | ||
213 | k[53] = 0 | ||
214 | k[54] = 0 | ||
215 | k[55] = 0 | ||
216 | k[56] = 0 | ||
217 | k[57] = 0 | ||
218 | k[58] = 0 | ||
219 | k[59] = 0 | ||
220 | k[60] = 0 | ||
221 | k[61] = 0 | ||
222 | k[62] = 0 | ||
223 | k[63] = 0 | ||
224 | } | ||
225 | binary.BigEndian.PutUint64(k[56:64], uint64(d.len)<<3) | ||
226 | block(d, k[:]) | ||
227 | |||
228 | { | ||
229 | const i = 0 | ||
230 | binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) | ||
231 | } | ||
232 | { | ||
233 | const i = 1 | ||
234 | binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) | ||
235 | } | ||
236 | { | ||
237 | const i = 2 | ||
238 | binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) | ||
239 | } | ||
240 | { | ||
241 | const i = 3 | ||
242 | binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) | ||
243 | } | ||
244 | { | ||
245 | const i = 4 | ||
246 | binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) | ||
247 | } | ||
248 | { | ||
249 | const i = 5 | ||
250 | binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) | ||
251 | } | ||
252 | { | ||
253 | const i = 6 | ||
254 | binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) | ||
255 | } | ||
256 | { | ||
257 | const i = 7 | ||
258 | binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) | ||
259 | } | ||
260 | |||
261 | return | ||
262 | } | ||
263 | |||
264 | func block(dig *digest, p []byte) { | ||
265 | if blockfunc == blockfuncIntelSha { | ||
266 | blockIntelShaGo(dig, p) | ||
267 | } else if blockfunc == blockfuncArmSha2 { | ||
268 | blockArmSha2Go(dig, p) | ||
269 | } else { | ||
270 | blockGeneric(dig, p) | ||
271 | } | ||
272 | } | ||
273 | |||
274 | func blockGeneric(dig *digest, p []byte) { | ||
275 | var w [64]uint32 | ||
276 | h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] | ||
277 | for len(p) >= chunk { | ||
278 | // Can interlace the computation of w with the | ||
279 | // rounds below if needed for speed. | ||
280 | for i := 0; i < 16; i++ { | ||
281 | j := i * 4 | ||
282 | w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3]) | ||
283 | } | ||
284 | for i := 16; i < 64; i++ { | ||
285 | v1 := w[i-2] | ||
286 | t1 := (v1>>17 | v1<<(32-17)) ^ (v1>>19 | v1<<(32-19)) ^ (v1 >> 10) | ||
287 | v2 := w[i-15] | ||
288 | t2 := (v2>>7 | v2<<(32-7)) ^ (v2>>18 | v2<<(32-18)) ^ (v2 >> 3) | ||
289 | w[i] = t1 + w[i-7] + t2 + w[i-16] | ||
290 | } | ||
291 | |||
292 | a, b, c, d, e, f, g, h := h0, h1, h2, h3, h4, h5, h6, h7 | ||
293 | |||
294 | for i := 0; i < 64; i++ { | ||
295 | t1 := h + ((e>>6 | e<<(32-6)) ^ (e>>11 | e<<(32-11)) ^ (e>>25 | e<<(32-25))) + ((e & f) ^ (^e & g)) + _K[i] + w[i] | ||
296 | |||
297 | t2 := ((a>>2 | a<<(32-2)) ^ (a>>13 | a<<(32-13)) ^ (a>>22 | a<<(32-22))) + ((a & b) ^ (a & c) ^ (b & c)) | ||
298 | |||
299 | h = g | ||
300 | g = f | ||
301 | f = e | ||
302 | e = d + t1 | ||
303 | d = c | ||
304 | c = b | ||
305 | b = a | ||
306 | a = t1 + t2 | ||
307 | } | ||
308 | |||
309 | h0 += a | ||
310 | h1 += b | ||
311 | h2 += c | ||
312 | h3 += d | ||
313 | h4 += e | ||
314 | h5 += f | ||
315 | h6 += g | ||
316 | h7 += h | ||
317 | |||
318 | p = p[chunk:] | ||
319 | } | ||
320 | |||
321 | dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7 | ||
322 | } | ||
323 | |||
324 | var _K = []uint32{ | ||
325 | 0x428a2f98, | ||
326 | 0x71374491, | ||
327 | 0xb5c0fbcf, | ||
328 | 0xe9b5dba5, | ||
329 | 0x3956c25b, | ||
330 | 0x59f111f1, | ||
331 | 0x923f82a4, | ||
332 | 0xab1c5ed5, | ||
333 | 0xd807aa98, | ||
334 | 0x12835b01, | ||
335 | 0x243185be, | ||
336 | 0x550c7dc3, | ||
337 | 0x72be5d74, | ||
338 | 0x80deb1fe, | ||
339 | 0x9bdc06a7, | ||
340 | 0xc19bf174, | ||
341 | 0xe49b69c1, | ||
342 | 0xefbe4786, | ||
343 | 0x0fc19dc6, | ||
344 | 0x240ca1cc, | ||
345 | 0x2de92c6f, | ||
346 | 0x4a7484aa, | ||
347 | 0x5cb0a9dc, | ||
348 | 0x76f988da, | ||
349 | 0x983e5152, | ||
350 | 0xa831c66d, | ||
351 | 0xb00327c8, | ||
352 | 0xbf597fc7, | ||
353 | 0xc6e00bf3, | ||
354 | 0xd5a79147, | ||
355 | 0x06ca6351, | ||
356 | 0x14292967, | ||
357 | 0x27b70a85, | ||
358 | 0x2e1b2138, | ||
359 | 0x4d2c6dfc, | ||
360 | 0x53380d13, | ||
361 | 0x650a7354, | ||
362 | 0x766a0abb, | ||
363 | 0x81c2c92e, | ||
364 | 0x92722c85, | ||
365 | 0xa2bfe8a1, | ||
366 | 0xa81a664b, | ||
367 | 0xc24b8b70, | ||
368 | 0xc76c51a3, | ||
369 | 0xd192e819, | ||
370 | 0xd6990624, | ||
371 | 0xf40e3585, | ||
372 | 0x106aa070, | ||
373 | 0x19a4c116, | ||
374 | 0x1e376c08, | ||
375 | 0x2748774c, | ||
376 | 0x34b0bcb5, | ||
377 | 0x391c0cb3, | ||
378 | 0x4ed8aa4a, | ||
379 | 0x5b9cca4f, | ||
380 | 0x682e6ff3, | ||
381 | 0x748f82ee, | ||
382 | 0x78a5636f, | ||
383 | 0x84c87814, | ||
384 | 0x8cc70208, | ||
385 | 0x90befffa, | ||
386 | 0xa4506ceb, | ||
387 | 0xbef9a3f7, | ||
388 | 0xc67178f2, | ||
389 | } | ||
390 | |||
391 | const ( | ||
392 | magic256 = "sha\x03" | ||
393 | marshaledSize = len(magic256) + 8*4 + chunk + 8 | ||
394 | ) | ||
395 | |||
396 | func (d *digest) MarshalBinary() ([]byte, error) { | ||
397 | b := make([]byte, 0, marshaledSize) | ||
398 | b = append(b, magic256...) | ||
399 | b = appendUint32(b, d.h[0]) | ||
400 | b = appendUint32(b, d.h[1]) | ||
401 | b = appendUint32(b, d.h[2]) | ||
402 | b = appendUint32(b, d.h[3]) | ||
403 | b = appendUint32(b, d.h[4]) | ||
404 | b = appendUint32(b, d.h[5]) | ||
405 | b = appendUint32(b, d.h[6]) | ||
406 | b = appendUint32(b, d.h[7]) | ||
407 | b = append(b, d.x[:d.nx]...) | ||
408 | b = b[:len(b)+len(d.x)-d.nx] // already zero | ||
409 | b = appendUint64(b, d.len) | ||
410 | return b, nil | ||
411 | } | ||
412 | |||
413 | func (d *digest) UnmarshalBinary(b []byte) error { | ||
414 | if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 { | ||
415 | return errors.New("crypto/sha256: invalid hash state identifier") | ||
416 | } | ||
417 | if len(b) != marshaledSize { | ||
418 | return errors.New("crypto/sha256: invalid hash state size") | ||
419 | } | ||
420 | b = b[len(magic256):] | ||
421 | b, d.h[0] = consumeUint32(b) | ||
422 | b, d.h[1] = consumeUint32(b) | ||
423 | b, d.h[2] = consumeUint32(b) | ||
424 | b, d.h[3] = consumeUint32(b) | ||
425 | b, d.h[4] = consumeUint32(b) | ||
426 | b, d.h[5] = consumeUint32(b) | ||
427 | b, d.h[6] = consumeUint32(b) | ||
428 | b, d.h[7] = consumeUint32(b) | ||
429 | b = b[copy(d.x[:], b):] | ||
430 | b, d.len = consumeUint64(b) | ||
431 | d.nx = int(d.len % chunk) | ||
432 | return nil | ||
433 | } | ||
434 | |||
435 | func appendUint32(b []byte, v uint32) []byte { | ||
436 | return append(b, | ||
437 | byte(v>>24), | ||
438 | byte(v>>16), | ||
439 | byte(v>>8), | ||
440 | byte(v), | ||
441 | ) | ||
442 | } | ||
443 | |||
444 | func appendUint64(b []byte, v uint64) []byte { | ||
445 | return append(b, | ||
446 | byte(v>>56), | ||
447 | byte(v>>48), | ||
448 | byte(v>>40), | ||
449 | byte(v>>32), | ||
450 | byte(v>>24), | ||
451 | byte(v>>16), | ||
452 | byte(v>>8), | ||
453 | byte(v), | ||
454 | ) | ||
455 | } | ||
456 | |||
457 | func consumeUint64(b []byte) ([]byte, uint64) { | ||
458 | _ = b[7] | ||
459 | x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | | ||
460 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 | ||
461 | return b[8:], x | ||
462 | } | ||
463 | |||
464 | func consumeUint32(b []byte) ([]byte, uint32) { | ||
465 | _ = b[3] | ||
466 | x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 | ||
467 | return b[4:], x | ||
468 | } | ||