5#include <bitcoin-build-config.h>
14#if !defined(DISABLE_OPTIMIZED_SHA256)
17#if defined(__linux__) && defined(ENABLE_ARM_SHANI)
22#if defined(__APPLE__) && defined(ENABLE_ARM_SHANI)
24#include <sys/sysctl.h>
27#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
30void Transform(uint32_t*
s,
const unsigned char* chunk,
size_t blocks);
51void Transform(uint32_t*
s,
const unsigned char* chunk,
size_t blocks);
56void Transform(uint32_t*
s,
const unsigned char* chunk,
size_t blocks);
71uint32_t
inline Ch(uint32_t x, uint32_t y, uint32_t z) {
return z ^ (x & (y ^ z)); }
72uint32_t
inline Maj(uint32_t x, uint32_t y, uint32_t z) {
return (x & y) | (z & (x | y)); }
73uint32_t
inline Sigma0(uint32_t x) {
return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
74uint32_t
inline Sigma1(uint32_t x) {
return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
75uint32_t
inline sigma0(uint32_t x) {
return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
76uint32_t
inline sigma1(uint32_t x) {
return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
79void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t
g, uint32_t& h, uint32_t
k)
88void inline Initialize(uint32_t*
s)
101void Transform(uint32_t*
s,
const unsigned char* chunk,
size_t blocks)
104 uint32_t a =
s[0], b =
s[1], c =
s[2], d =
s[3], e =
s[4], f =
s[5],
g =
s[6], h =
s[7];
105 uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
107 Round(a, b, c, d, e, f,
g, h, 0x428a2f98 + (w0 =
ReadBE32(chunk + 0)));
108 Round(h, a, b, c, d, e, f,
g, 0x71374491 + (w1 =
ReadBE32(chunk + 4)));
109 Round(
g, h, a, b, c, d, e, f, 0xb5c0fbcf + (w2 =
ReadBE32(chunk + 8)));
110 Round(f,
g, h, a, b, c, d, e, 0xe9b5dba5 + (w3 =
ReadBE32(chunk + 12)));
111 Round(e, f,
g, h, a, b, c, d, 0x3956c25b + (w4 =
ReadBE32(chunk + 16)));
112 Round(d, e, f,
g, h, a, b, c, 0x59f111f1 + (w5 =
ReadBE32(chunk + 20)));
113 Round(c, d, e, f,
g, h, a, b, 0x923f82a4 + (w6 =
ReadBE32(chunk + 24)));
114 Round(b, c, d, e, f,
g, h, a, 0xab1c5ed5 + (w7 =
ReadBE32(chunk + 28)));
115 Round(a, b, c, d, e, f,
g, h, 0xd807aa98 + (w8 =
ReadBE32(chunk + 32)));
116 Round(h, a, b, c, d, e, f,
g, 0x12835b01 + (w9 =
ReadBE32(chunk + 36)));
117 Round(
g, h, a, b, c, d, e, f, 0x243185be + (w10 =
ReadBE32(chunk + 40)));
118 Round(f,
g, h, a, b, c, d, e, 0x550c7dc3 + (w11 =
ReadBE32(chunk + 44)));
119 Round(e, f,
g, h, a, b, c, d, 0x72be5d74 + (w12 =
ReadBE32(chunk + 48)));
120 Round(d, e, f,
g, h, a, b, c, 0x80deb1fe + (w13 =
ReadBE32(chunk + 52)));
121 Round(c, d, e, f,
g, h, a, b, 0x9bdc06a7 + (w14 =
ReadBE32(chunk + 56)));
122 Round(b, c, d, e, f,
g, h, a, 0xc19bf174 + (w15 =
ReadBE32(chunk + 60)));
187void TransformD64(
unsigned char*
out,
const unsigned char* in)
190 uint32_t a = 0x6a09e667ul;
191 uint32_t b = 0xbb67ae85ul;
192 uint32_t c = 0x3c6ef372ul;
193 uint32_t d = 0xa54ff53aul;
194 uint32_t e = 0x510e527ful;
195 uint32_t f = 0x9b05688cul;
196 uint32_t
g = 0x1f83d9abul;
197 uint32_t h = 0x5be0cd19ul;
199 uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
201 Round(a, b, c, d, e, f,
g, h, 0x428a2f98ul + (w0 =
ReadBE32(in + 0)));
202 Round(h, a, b, c, d, e, f,
g, 0x71374491ul + (w1 =
ReadBE32(in + 4)));
203 Round(
g, h, a, b, c, d, e, f, 0xb5c0fbcful + (w2 =
ReadBE32(in + 8)));
204 Round(f,
g, h, a, b, c, d, e, 0xe9b5dba5ul + (w3 =
ReadBE32(in + 12)));
205 Round(e, f,
g, h, a, b, c, d, 0x3956c25bul + (w4 =
ReadBE32(in + 16)));
206 Round(d, e, f,
g, h, a, b, c, 0x59f111f1ul + (w5 =
ReadBE32(in + 20)));
207 Round(c, d, e, f,
g, h, a, b, 0x923f82a4ul + (w6 =
ReadBE32(in + 24)));
208 Round(b, c, d, e, f,
g, h, a, 0xab1c5ed5ul + (w7 =
ReadBE32(in + 28)));
209 Round(a, b, c, d, e, f,
g, h, 0xd807aa98ul + (w8 =
ReadBE32(in + 32)));
210 Round(h, a, b, c, d, e, f,
g, 0x12835b01ul + (w9 =
ReadBE32(in + 36)));
211 Round(
g, h, a, b, c, d, e, f, 0x243185beul + (w10 =
ReadBE32(in + 40)));
212 Round(f,
g, h, a, b, c, d, e, 0x550c7dc3ul + (w11 =
ReadBE32(in + 44)));
213 Round(e, f,
g, h, a, b, c, d, 0x72be5d74ul + (w12 =
ReadBE32(in + 48)));
214 Round(d, e, f,
g, h, a, b, c, 0x80deb1feul + (w13 =
ReadBE32(in + 52)));
215 Round(c, d, e, f,
g, h, a, b, 0x9bdc06a7ul + (w14 =
ReadBE32(in + 56)));
216 Round(b, c, d, e, f,
g, h, a, 0xc19bf174ul + (w15 =
ReadBE32(in + 60)));
229 Round(e, f,
g, h, a, b, c, d, 0xc6e00bf3ul + (w12 +=
sigma1(w10) + w5 +
sigma0(w13)));
230 Round(d, e, f,
g, h, a, b, c, 0xd5a79147ul + (w13 +=
sigma1(w11) + w6 +
sigma0(w14)));
231 Round(c, d, e, f,
g, h, a, b, 0x06ca6351ul + (w14 +=
sigma1(w12) + w7 +
sigma0(w15)));
245 Round(e, f,
g, h, a, b, c, d, 0xd192e819ul + (w12 +=
sigma1(w10) + w5 +
sigma0(w13)));
246 Round(d, e, f,
g, h, a, b, c, 0xd6990624ul + (w13 +=
sigma1(w11) + w6 +
sigma0(w14)));
247 Round(c, d, e, f,
g, h, a, b, 0xf40e3585ul + (w14 +=
sigma1(w12) + w7 +
sigma0(w15)));
261 Round(e, f,
g, h, a, b, c, d, 0x90befffaul + (w12 +=
sigma1(w10) + w5 +
sigma0(w13)));
262 Round(d, e, f,
g, h, a, b, c, 0xa4506cebul + (w13 +=
sigma1(w11) + w6 +
sigma0(w14)));
275 uint32_t t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 =
g, t7 = h;
278 Round(a, b, c, d, e, f,
g, h, 0xc28a2f98ul);
279 Round(h, a, b, c, d, e, f,
g, 0x71374491ul);
280 Round(
g, h, a, b, c, d, e, f, 0xb5c0fbcful);
281 Round(f,
g, h, a, b, c, d, e, 0xe9b5dba5ul);
282 Round(e, f,
g, h, a, b, c, d, 0x3956c25bul);
283 Round(d, e, f,
g, h, a, b, c, 0x59f111f1ul);
284 Round(c, d, e, f,
g, h, a, b, 0x923f82a4ul);
285 Round(b, c, d, e, f,
g, h, a, 0xab1c5ed5ul);
286 Round(a, b, c, d, e, f,
g, h, 0xd807aa98ul);
287 Round(h, a, b, c, d, e, f,
g, 0x12835b01ul);
288 Round(
g, h, a, b, c, d, e, f, 0x243185beul);
289 Round(f,
g, h, a, b, c, d, e, 0x550c7dc3ul);
290 Round(e, f,
g, h, a, b, c, d, 0x72be5d74ul);
291 Round(d, e, f,
g, h, a, b, c, 0x80deb1feul);
292 Round(c, d, e, f,
g, h, a, b, 0x9bdc06a7ul);
293 Round(b, c, d, e, f,
g, h, a, 0xc19bf374ul);
294 Round(a, b, c, d, e, f,
g, h, 0x649b69c1ul);
295 Round(h, a, b, c, d, e, f,
g, 0xf0fe4786ul);
296 Round(
g, h, a, b, c, d, e, f, 0x0fe1edc6ul);
297 Round(f,
g, h, a, b, c, d, e, 0x240cf254ul);
298 Round(e, f,
g, h, a, b, c, d, 0x4fe9346ful);
299 Round(d, e, f,
g, h, a, b, c, 0x6cc984beul);
300 Round(c, d, e, f,
g, h, a, b, 0x61b9411eul);
301 Round(b, c, d, e, f,
g, h, a, 0x16f988faul);
302 Round(a, b, c, d, e, f,
g, h, 0xf2c65152ul);
303 Round(h, a, b, c, d, e, f,
g, 0xa88e5a6dul);
304 Round(
g, h, a, b, c, d, e, f, 0xb019fc65ul);
305 Round(f,
g, h, a, b, c, d, e, 0xb9d99ec7ul);
306 Round(e, f,
g, h, a, b, c, d, 0x9a1231c3ul);
307 Round(d, e, f,
g, h, a, b, c, 0xe70eeaa0ul);
308 Round(c, d, e, f,
g, h, a, b, 0xfdb1232bul);
309 Round(b, c, d, e, f,
g, h, a, 0xc7353eb0ul);
310 Round(a, b, c, d, e, f,
g, h, 0x3069bad5ul);
311 Round(h, a, b, c, d, e, f,
g, 0xcb976d5ful);
312 Round(
g, h, a, b, c, d, e, f, 0x5a0f118ful);
313 Round(f,
g, h, a, b, c, d, e, 0xdc1eeefdul);
314 Round(e, f,
g, h, a, b, c, d, 0x0a35b689ul);
315 Round(d, e, f,
g, h, a, b, c, 0xde0b7a04ul);
316 Round(c, d, e, f,
g, h, a, b, 0x58f4ca9dul);
317 Round(b, c, d, e, f,
g, h, a, 0xe15d5b16ul);
318 Round(a, b, c, d, e, f,
g, h, 0x007f3e86ul);
319 Round(h, a, b, c, d, e, f,
g, 0x37088980ul);
320 Round(
g, h, a, b, c, d, e, f, 0xa507ea32ul);
321 Round(f,
g, h, a, b, c, d, e, 0x6fab9537ul);
322 Round(e, f,
g, h, a, b, c, d, 0x17406110ul);
323 Round(d, e, f,
g, h, a, b, c, 0x0d8cd6f1ul);
324 Round(c, d, e, f,
g, h, a, b, 0xcdaa3b6dul);
325 Round(b, c, d, e, f,
g, h, a, 0xc0bbbe37ul);
326 Round(a, b, c, d, e, f,
g, h, 0x83613bdaul);
327 Round(h, a, b, c, d, e, f,
g, 0xdb48a363ul);
328 Round(
g, h, a, b, c, d, e, f, 0x0b02e931ul);
329 Round(f,
g, h, a, b, c, d, e, 0x6fd15ca7ul);
330 Round(e, f,
g, h, a, b, c, d, 0x521afacaul);
331 Round(d, e, f,
g, h, a, b, c, 0x31338431ul);
332 Round(c, d, e, f,
g, h, a, b, 0x6ed41a95ul);
333 Round(b, c, d, e, f,
g, h, a, 0x6d437890ul);
334 Round(a, b, c, d, e, f,
g, h, 0xc39c91f2ul);
335 Round(h, a, b, c, d, e, f,
g, 0x9eccabbdul);
336 Round(
g, h, a, b, c, d, e, f, 0xb5c9a0e6ul);
337 Round(f,
g, h, a, b, c, d, e, 0x532fb63cul);
338 Round(e, f,
g, h, a, b, c, d, 0xd2c741c6ul);
339 Round(d, e, f,
g, h, a, b, c, 0x07237ea3ul);
340 Round(c, d, e, f,
g, h, a, b, 0xa4954b68ul);
341 Round(b, c, d, e, f,
g, h, a, 0x4c191d76ul);
362 Round(a, b, c, d, e, f,
g, h, 0x428a2f98ul + w0);
363 Round(h, a, b, c, d, e, f,
g, 0x71374491ul + w1);
364 Round(
g, h, a, b, c, d, e, f, 0xb5c0fbcful + w2);
365 Round(f,
g, h, a, b, c, d, e, 0xe9b5dba5ul + w3);
366 Round(e, f,
g, h, a, b, c, d, 0x3956c25bul + w4);
367 Round(d, e, f,
g, h, a, b, c, 0x59f111f1ul + w5);
368 Round(c, d, e, f,
g, h, a, b, 0x923f82a4ul + w6);
369 Round(b, c, d, e, f,
g, h, a, 0xab1c5ed5ul + w7);
370 Round(a, b, c, d, e, f,
g, h, 0x5807aa98ul);
371 Round(h, a, b, c, d, e, f,
g, 0x12835b01ul);
372 Round(
g, h, a, b, c, d, e, f, 0x243185beul);
373 Round(f,
g, h, a, b, c, d, e, 0x550c7dc3ul);
374 Round(e, f,
g, h, a, b, c, d, 0x72be5d74ul);
375 Round(d, e, f,
g, h, a, b, c, 0x80deb1feul);
376 Round(c, d, e, f,
g, h, a, b, 0x9bdc06a7ul);
377 Round(b, c, d, e, f,
g, h, a, 0xc19bf274ul);
378 Round(a, b, c, d, e, f,
g, h, 0xe49b69c1ul + (w0 +=
sigma0(w1)));
379 Round(h, a, b, c, d, e, f,
g, 0xefbe4786ul + (w1 += 0xa00000ul +
sigma0(w2)));
384 Round(c, d, e, f,
g, h, a, b, 0x5cb0a9dcul + (w6 +=
sigma1(w4) + 0x100ul +
sigma0(w7)));
385 Round(b, c, d, e, f,
g, h, a, 0x76f988daul + (w7 +=
sigma1(w5) + w0 + 0x11002000ul));
386 Round(a, b, c, d, e, f,
g, h, 0x983e5152ul + (w8 = 0x80000000ul +
sigma1(w6) + w1));
387 Round(h, a, b, c, d, e, f,
g, 0xa831c66dul + (w9 =
sigma1(w7) + w2));
388 Round(
g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 =
sigma1(w8) + w3));
389 Round(f,
g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 =
sigma1(w9) + w4));
390 Round(e, f,
g, h, a, b, c, d, 0xc6e00bf3ul + (w12 =
sigma1(w10) + w5));
391 Round(d, e, f,
g, h, a, b, c, 0xd5a79147ul + (w13 =
sigma1(w11) + w6));
392 Round(c, d, e, f,
g, h, a, b, 0x06ca6351ul + (w14 =
sigma1(w12) + w7 + 0x400022ul));
393 Round(b, c, d, e, f,
g, h, a, 0x14292967ul + (w15 = 0x100ul +
sigma1(w13) + w8 +
sigma0(w0)));
406 Round(e, f,
g, h, a, b, c, d, 0xd192e819ul + (w12 +=
sigma1(w10) + w5 +
sigma0(w13)));
407 Round(d, e, f,
g, h, a, b, c, 0xd6990624ul + (w13 +=
sigma1(w11) + w6 +
sigma0(w14)));
408 Round(c, d, e, f,
g, h, a, b, 0xf40e3585ul + (w14 +=
sigma1(w12) + w7 +
sigma0(w15)));
422 Round(e, f,
g, h, a, b, c, d, 0x90befffaul + (w12 +=
sigma1(w10) + w5 +
sigma0(w13)));
423 Round(d, e, f,
g, h, a, b, c, 0xa4506cebul + (w13 +=
sigma1(w11) + w6 +
sigma0(w14)));
440typedef void (*TransformType)(uint32_t*,
const unsigned char*, size_t);
441typedef void (*TransformD64Type)(
unsigned char*,
const unsigned char*);
443template<TransformType tr>
444void TransformD64Wrapper(
unsigned char*
out,
const unsigned char* in)
447 static const unsigned char padding1[64] = {
448 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
449 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
450 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
451 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0
453 unsigned char buffer2[64] = {
454 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
455 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
456 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
457 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
459 sha256::Initialize(
s);
470 sha256::Initialize(
s);
483TransformD64Type TransformD64 = sha256::TransformD64;
484TransformD64Type TransformD64_2way =
nullptr;
485TransformD64Type TransformD64_4way =
nullptr;
486TransformD64Type TransformD64_8way =
nullptr;
490 static const uint32_t
init[8] = {
491 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
494 static const unsigned char data[641] =
"-"
495 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
496 "eiusmod tempor incididunt ut labore et dolore magna aliqua. Et m"
497 "olestie ac feugiat sed lectus vestibulum mattis ullamcorper. Mor"
498 "bi blandit cursus risus at ultrices mi tempus imperdiet nulla. N"
499 "unc congue nisi vita suscipit tellus mauris. Imperdiet proin fer"
500 "mentum leo vel orci. Massa tempor nec feugiat nisl pretium fusce"
501 " id velit. Telus in metus vulputate eu scelerisque felis. Mi tem"
502 "pus imperdiet nulla malesuada pellentesque. Tristique magna sit.";
504 static const uint32_t result[9][8] = {
505 {0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul},
506 {0x91f8ec6bul, 0x4da10fe3ul, 0x1c9c292cul, 0x45e18185ul, 0x435cc111ul, 0x3ca26f09ul, 0xeb954caeul, 0x402a7069ul},
507 {0xcabea5acul, 0x374fb97cul, 0x182ad996ul, 0x7bd69cbful, 0x450ff900ul, 0xc1d2be8aul, 0x6a41d505ul, 0xe6212dc3ul},
508 {0xbcff09d6ul, 0x3e76f36eul, 0x3ecb2501ul, 0x78866e97ul, 0xe1c1e2fdul, 0x32f4eafful, 0x8aa6c4e5ul, 0xdfc024bcul},
509 {0xa08c5d94ul, 0x0a862f93ul, 0x6b7f2f40ul, 0x8f9fae76ul, 0x6d40439ful, 0x79dcee0cul, 0x3e39ff3aul, 0xdc3bdbb1ul},
510 {0x216a0895ul, 0x9f1a3662ul, 0xe99946f9ul, 0x87ba4364ul, 0x0fb5db2cul, 0x12bed3d3ul, 0x6689c0c7ul, 0x292f1b04ul},
511 {0xca3067f8ul, 0xbc8c2656ul, 0x37cb7e0dul, 0x9b6b8b0ful, 0x46dc380bul, 0xf1287f57ul, 0xc42e4b23ul, 0x3fefe94dul},
512 {0x3e4c4039ul, 0xbb6fca8cul, 0x6f27d2f7ul, 0x301e44a4ul, 0x8352ba14ul, 0x5769ce37ul, 0x48a1155ful, 0xc0e1c4c6ul},
513 {0xfe2fa9ddul, 0x69d0862bul, 0x1ae0db23ul, 0x471f9244ul, 0xf55c0145ul, 0xc30f9c3bul, 0x40a84ea0ul, 0x5b8a266cul},
516 static const unsigned char result_d64[256] = {
517 0x09, 0x3a, 0xc4, 0xd0, 0x0f, 0xf7, 0x57, 0xe1, 0x72, 0x85, 0x79, 0x42, 0xfe, 0xe7, 0xe0, 0xa0,
518 0xfc, 0x52, 0xd7, 0xdb, 0x07, 0x63, 0x45, 0xfb, 0x53, 0x14, 0x7d, 0x17, 0x22, 0x86, 0xf0, 0x52,
519 0x48, 0xb6, 0x11, 0x9e, 0x6e, 0x48, 0x81, 0x6d, 0xcc, 0x57, 0x1f, 0xb2, 0x97, 0xa8, 0xd5, 0x25,
520 0x9b, 0x82, 0xaa, 0x89, 0xe2, 0xfd, 0x2d, 0x56, 0xe8, 0x28, 0x83, 0x0b, 0xe2, 0xfa, 0x53, 0xb7,
521 0xd6, 0x6b, 0x07, 0x85, 0x83, 0xb0, 0x10, 0xa2, 0xf5, 0x51, 0x3c, 0xf9, 0x60, 0x03, 0xab, 0x45,
522 0x6c, 0x15, 0x6e, 0xef, 0xb5, 0xac, 0x3e, 0x6c, 0xdf, 0xb4, 0x92, 0x22, 0x2d, 0xce, 0xbf, 0x3e,
523 0xe9, 0xe5, 0xf6, 0x29, 0x0e, 0x01, 0x4f, 0xd2, 0xd4, 0x45, 0x65, 0xb3, 0xbb, 0xf2, 0x4c, 0x16,
524 0x37, 0x50, 0x3c, 0x6e, 0x49, 0x8c, 0x5a, 0x89, 0x2b, 0x1b, 0xab, 0xc4, 0x37, 0xd1, 0x46, 0xe9,
525 0x3d, 0x0e, 0x85, 0xa2, 0x50, 0x73, 0xa1, 0x5e, 0x54, 0x37, 0xd7, 0x94, 0x17, 0x56, 0xc2, 0xd8,
526 0xe5, 0x9f, 0xed, 0x4e, 0xae, 0x15, 0x42, 0x06, 0x0d, 0x74, 0x74, 0x5e, 0x24, 0x30, 0xce, 0xd1,
527 0x9e, 0x50, 0xa3, 0x9a, 0xb8, 0xf0, 0x4a, 0x57, 0x69, 0x78, 0x67, 0x12, 0x84, 0x58, 0xbe, 0xc7,
528 0x36, 0xaa, 0xee, 0x7c, 0x64, 0xa3, 0x76, 0xec, 0xff, 0x55, 0x41, 0x00, 0x2a, 0x44, 0x68, 0x4d,
529 0xb6, 0x53, 0x9e, 0x1c, 0x95, 0xb7, 0xca, 0xdc, 0x7f, 0x7d, 0x74, 0x27, 0x5c, 0x8e, 0xa6, 0x84,
530 0xb5, 0xac, 0x87, 0xa9, 0xf3, 0xff, 0x75, 0xf2, 0x34, 0xcd, 0x1a, 0x3b, 0x82, 0x2c, 0x2b, 0x4e,
531 0x6a, 0x46, 0x30, 0xa6, 0x89, 0x86, 0x23, 0xac, 0xf8, 0xa5, 0x15, 0xe9, 0x0a, 0xaa, 0x1e, 0x9a,
532 0xd7, 0x93, 0x6b, 0x28, 0xe4, 0x3b, 0xfd, 0x59, 0xc6, 0xed, 0x7c, 0x5f, 0xa5, 0x41, 0xcb, 0x51
537 for (
size_t i = 0; i <= 8; ++i) {
541 if (!std::equal(state, state + 8, result[i]))
return false;
545 unsigned char out[32];
547 if (!std::equal(
out,
out + 32, result_d64))
return false;
550 if (TransformD64_2way) {
551 unsigned char out[64];
552 TransformD64_2way(
out,
data + 1);
553 if (!std::equal(
out,
out + 64, result_d64))
return false;
557 if (TransformD64_4way) {
558 unsigned char out[128];
559 TransformD64_4way(
out,
data + 1);
560 if (!std::equal(
out,
out + 128, result_d64))
return false;
564 if (TransformD64_8way) {
565 unsigned char out[256];
566 TransformD64_8way(
out,
data + 1);
567 if (!std::equal(
out,
out + 256, result_d64))
return false;
573#if !defined(DISABLE_OPTIMIZED_SHA256)
574#if (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
579 __asm__(
"xgetbv" :
"=a"(a),
"=d"(d) :
"c"(0));
589 std::string
ret =
"standard";
591 TransformD64 = sha256::TransformD64;
592 TransformD64_2way =
nullptr;
593 TransformD64_4way =
nullptr;
594 TransformD64_8way =
nullptr;
596#if !defined(DISABLE_OPTIMIZED_SHA256)
597#if defined(HAVE_GETCPUID)
598 bool have_sse4 =
false;
599 bool have_xsave =
false;
600 bool have_avx =
false;
601 [[maybe_unused]]
bool have_avx2 =
false;
602 [[maybe_unused]]
bool have_x86_shani =
false;
603 [[maybe_unused]]
bool enabled_avx =
false;
605 uint32_t eax, ebx, ecx, edx;
606 GetCPUID(1, 0, eax, ebx, ecx, edx);
608 have_sse4 = (ecx >> 19) & 1;
610 have_xsave = (ecx >> 27) & 1;
611 have_avx = (ecx >> 28) & 1;
612 if (have_xsave && have_avx) {
613 enabled_avx = AVXEnabled();
616 GetCPUID(7, 0, eax, ebx, ecx, edx);
618 have_avx2 = (ebx >> 5) & 1;
621 have_x86_shani = (ebx >> 29) & 1;
625#if defined(ENABLE_SSE41) && defined(ENABLE_X86_SHANI)
626 if (have_x86_shani) {
628 TransformD64 = TransformD64Wrapper<sha256_x86_shani::Transform>;
630 ret =
"x86_shani(1way,2way)";
637#if defined(__x86_64__) || defined(__amd64__)
639 TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>;
642#if defined(ENABLE_SSE41)
644 ret +=
",sse41(4way)";
648#if defined(ENABLE_AVX2)
649 if (have_avx2 && have_avx && enabled_avx) {
651 ret +=
",avx2(8way)";
656#if defined(ENABLE_ARM_SHANI)
657 bool have_arm_shani =
false;
659#if defined(__linux__)
661 if (getauxval(AT_HWCAP2) & HWCAP2_SHA2) {
662 have_arm_shani =
true;
665#if defined(__aarch64__)
666 if (getauxval(AT_HWCAP) & HWCAP_SHA2) {
667 have_arm_shani =
true;
672#if defined(__APPLE__)
674 size_t len =
sizeof(val);
675 if (sysctlbyname(
"hw.optional.arm.FEAT_SHA256", &val, &len,
nullptr, 0) == 0) {
676 have_arm_shani = val != 0;
681 if (have_arm_shani) {
683 TransformD64 = TransformD64Wrapper<sha256_arm_shani::Transform>;
685 ret =
"arm_shani(1way,2way)";
698 sha256::Initialize(
s);
703 const unsigned char* end =
data + len;
704 size_t bufsize =
bytes % 64;
705 if (bufsize && bufsize + len >= 64) {
707 memcpy(
buf + bufsize,
data, 64 - bufsize);
708 bytes += 64 - bufsize;
709 data += 64 - bufsize;
713 if (end -
data >= 64) {
714 size_t blocks = (end -
data) / 64;
717 bytes += 64 * blocks;
729 static const unsigned char pad[64] = {0x80};
730 unsigned char sizedesc[8];
747 sha256::Initialize(
s);
751void SHA256D64(
unsigned char*
out,
const unsigned char* in,
size_t blocks)
753 if (TransformD64_8way) {
754 while (blocks >= 8) {
755 TransformD64_8way(
out, in);
761 if (TransformD64_4way) {
762 while (blocks >= 4) {
763 TransformD64_4way(
out, in);
769 if (TransformD64_2way) {
770 while (blocks >= 2) {
771 TransformD64_2way(
out, in);
778 TransformD64(
out, in);
A hasher class for SHA-256.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA256 & Write(const unsigned char *data, size_t len)
static void WriteBE32(unsigned char *ptr, uint32_t x)
static void WriteBE64(unsigned char *ptr, uint64_t x)
static uint32_t ReadBE32(const unsigned char *ptr)
#define Round(a, b, c, d, e, f, g, h, k, w)
void Transform(uint32_t *s, const unsigned char *chunk, size_t blocks)
void Transform(uint32_t *s, const unsigned char *chunk, size_t blocks)
Internal SHA-256 implementation.
void Transform_2way(unsigned char *out, const unsigned char *in)
void Transform_8way(unsigned char *out, const unsigned char *in)
void Transform_4way(unsigned char *out, const unsigned char *in)
void Transform_2way(unsigned char *out, const unsigned char *in)
void SHA256D64(unsigned char *out, const unsigned char *in, size_t blocks)
Compute multiple double-SHA256's of 64-byte blobs.
std::string SHA256AutoDetect(sha256_implementation::UseImplementation use_implementation)
Autodetect the best available SHA256 implementation.