Bitcoin Core  27.99.0
P2P Digital Currency
sha256.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2022 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <config/bitcoin-config.h> // IWYU pragma: keep
6 
7 #include <crypto/sha256.h>
8 #include <crypto/common.h>
9 
10 #include <algorithm>
11 #include <cassert>
12 #include <cstring>
13 
14 #if !defined(DISABLE_OPTIMIZED_SHA256)
15 #include <compat/cpuid.h>
16 
17 #if defined(__linux__) && defined(ENABLE_ARM_SHANI)
18 #include <sys/auxv.h>
19 #include <asm/hwcap.h>
20 #endif
21 
22 #if defined(__APPLE__) && defined(ENABLE_ARM_SHANI)
23 #include <sys/types.h>
24 #include <sys/sysctl.h>
25 #endif
26 
27 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
28 namespace sha256_sse4
29 {
30 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
31 }
32 #endif
33 
34 namespace sha256d64_sse41
35 {
36 void Transform_4way(unsigned char* out, const unsigned char* in);
37 }
38 
39 namespace sha256d64_avx2
40 {
41 void Transform_8way(unsigned char* out, const unsigned char* in);
42 }
43 
45 {
46 void Transform_2way(unsigned char* out, const unsigned char* in);
47 }
48 
50 {
51 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
52 }
53 
55 {
56 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
57 }
58 
60 {
61 void Transform_2way(unsigned char* out, const unsigned char* in);
62 }
63 #endif // DISABLE_OPTIMIZED_SHA256
64 
65 // Internal implementation code.
66 namespace
67 {
69 namespace sha256
70 {
71 uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
72 uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
73 uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
74 uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
75 uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
76 uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
77 
79 void 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)
80 {
81  uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k;
82  uint32_t t2 = Sigma0(a) + Maj(a, b, c);
83  d += t1;
84  h = t1 + t2;
85 }
86 
88 void inline Initialize(uint32_t* s)
89 {
90  s[0] = 0x6a09e667ul;
91  s[1] = 0xbb67ae85ul;
92  s[2] = 0x3c6ef372ul;
93  s[3] = 0xa54ff53aul;
94  s[4] = 0x510e527ful;
95  s[5] = 0x9b05688cul;
96  s[6] = 0x1f83d9abul;
97  s[7] = 0x5be0cd19ul;
98 }
99 
101 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
102 {
103  while (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;
106 
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)));
123 
124  Round(a, b, c, d, e, f, g, h, 0xe49b69c1 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
125  Round(h, a, b, c, d, e, f, g, 0xefbe4786 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
126  Round(g, h, a, b, c, d, e, f, 0x0fc19dc6 + (w2 += sigma1(w0) + w11 + sigma0(w3)));
127  Round(f, g, h, a, b, c, d, e, 0x240ca1cc + (w3 += sigma1(w1) + w12 + sigma0(w4)));
128  Round(e, f, g, h, a, b, c, d, 0x2de92c6f + (w4 += sigma1(w2) + w13 + sigma0(w5)));
129  Round(d, e, f, g, h, a, b, c, 0x4a7484aa + (w5 += sigma1(w3) + w14 + sigma0(w6)));
130  Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc + (w6 += sigma1(w4) + w15 + sigma0(w7)));
131  Round(b, c, d, e, f, g, h, a, 0x76f988da + (w7 += sigma1(w5) + w0 + sigma0(w8)));
132  Round(a, b, c, d, e, f, g, h, 0x983e5152 + (w8 += sigma1(w6) + w1 + sigma0(w9)));
133  Round(h, a, b, c, d, e, f, g, 0xa831c66d + (w9 += sigma1(w7) + w2 + sigma0(w10)));
134  Round(g, h, a, b, c, d, e, f, 0xb00327c8 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
135  Round(f, g, h, a, b, c, d, e, 0xbf597fc7 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
136  Round(e, f, g, h, a, b, c, d, 0xc6e00bf3 + (w12 += sigma1(w10) + w5 + sigma0(w13)));
137  Round(d, e, f, g, h, a, b, c, 0xd5a79147 + (w13 += sigma1(w11) + w6 + sigma0(w14)));
138  Round(c, d, e, f, g, h, a, b, 0x06ca6351 + (w14 += sigma1(w12) + w7 + sigma0(w15)));
139  Round(b, c, d, e, f, g, h, a, 0x14292967 + (w15 += sigma1(w13) + w8 + sigma0(w0)));
140 
141  Round(a, b, c, d, e, f, g, h, 0x27b70a85 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
142  Round(h, a, b, c, d, e, f, g, 0x2e1b2138 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
143  Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc + (w2 += sigma1(w0) + w11 + sigma0(w3)));
144  Round(f, g, h, a, b, c, d, e, 0x53380d13 + (w3 += sigma1(w1) + w12 + sigma0(w4)));
145  Round(e, f, g, h, a, b, c, d, 0x650a7354 + (w4 += sigma1(w2) + w13 + sigma0(w5)));
146  Round(d, e, f, g, h, a, b, c, 0x766a0abb + (w5 += sigma1(w3) + w14 + sigma0(w6)));
147  Round(c, d, e, f, g, h, a, b, 0x81c2c92e + (w6 += sigma1(w4) + w15 + sigma0(w7)));
148  Round(b, c, d, e, f, g, h, a, 0x92722c85 + (w7 += sigma1(w5) + w0 + sigma0(w8)));
149  Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1 + (w8 += sigma1(w6) + w1 + sigma0(w9)));
150  Round(h, a, b, c, d, e, f, g, 0xa81a664b + (w9 += sigma1(w7) + w2 + sigma0(w10)));
151  Round(g, h, a, b, c, d, e, f, 0xc24b8b70 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
152  Round(f, g, h, a, b, c, d, e, 0xc76c51a3 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
153  Round(e, f, g, h, a, b, c, d, 0xd192e819 + (w12 += sigma1(w10) + w5 + sigma0(w13)));
154  Round(d, e, f, g, h, a, b, c, 0xd6990624 + (w13 += sigma1(w11) + w6 + sigma0(w14)));
155  Round(c, d, e, f, g, h, a, b, 0xf40e3585 + (w14 += sigma1(w12) + w7 + sigma0(w15)));
156  Round(b, c, d, e, f, g, h, a, 0x106aa070 + (w15 += sigma1(w13) + w8 + sigma0(w0)));
157 
158  Round(a, b, c, d, e, f, g, h, 0x19a4c116 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
159  Round(h, a, b, c, d, e, f, g, 0x1e376c08 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
160  Round(g, h, a, b, c, d, e, f, 0x2748774c + (w2 += sigma1(w0) + w11 + sigma0(w3)));
161  Round(f, g, h, a, b, c, d, e, 0x34b0bcb5 + (w3 += sigma1(w1) + w12 + sigma0(w4)));
162  Round(e, f, g, h, a, b, c, d, 0x391c0cb3 + (w4 += sigma1(w2) + w13 + sigma0(w5)));
163  Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a + (w5 += sigma1(w3) + w14 + sigma0(w6)));
164  Round(c, d, e, f, g, h, a, b, 0x5b9cca4f + (w6 += sigma1(w4) + w15 + sigma0(w7)));
165  Round(b, c, d, e, f, g, h, a, 0x682e6ff3 + (w7 += sigma1(w5) + w0 + sigma0(w8)));
166  Round(a, b, c, d, e, f, g, h, 0x748f82ee + (w8 += sigma1(w6) + w1 + sigma0(w9)));
167  Round(h, a, b, c, d, e, f, g, 0x78a5636f + (w9 += sigma1(w7) + w2 + sigma0(w10)));
168  Round(g, h, a, b, c, d, e, f, 0x84c87814 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
169  Round(f, g, h, a, b, c, d, e, 0x8cc70208 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
170  Round(e, f, g, h, a, b, c, d, 0x90befffa + (w12 += sigma1(w10) + w5 + sigma0(w13)));
171  Round(d, e, f, g, h, a, b, c, 0xa4506ceb + (w13 += sigma1(w11) + w6 + sigma0(w14)));
172  Round(c, d, e, f, g, h, a, b, 0xbef9a3f7 + (w14 + sigma1(w12) + w7 + sigma0(w15)));
173  Round(b, c, d, e, f, g, h, a, 0xc67178f2 + (w15 + sigma1(w13) + w8 + sigma0(w0)));
174 
175  s[0] += a;
176  s[1] += b;
177  s[2] += c;
178  s[3] += d;
179  s[4] += e;
180  s[5] += f;
181  s[6] += g;
182  s[7] += h;
183  chunk += 64;
184  }
185 }
186 
187 void TransformD64(unsigned char* out, const unsigned char* in)
188 {
189  // Transform 1
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;
198 
199  uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
200 
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)));
217  Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
218  Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
219  Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
220  Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
221  Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + w13 + sigma0(w5)));
222  Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
223  Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
224  Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
225  Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
226  Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
227  Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
228  Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
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)));
232  Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
233  Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
234  Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
235  Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
236  Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
237  Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
238  Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
239  Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
240  Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
241  Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
242  Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
243  Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
244  Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
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)));
248  Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
249  Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
250  Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
251  Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
252  Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
253  Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
254  Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
255  Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
256  Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
257  Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
258  Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
259  Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
260  Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
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)));
263  Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
264  Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
265 
266  a += 0x6a09e667ul;
267  b += 0xbb67ae85ul;
268  c += 0x3c6ef372ul;
269  d += 0xa54ff53aul;
270  e += 0x510e527ful;
271  f += 0x9b05688cul;
272  g += 0x1f83d9abul;
273  h += 0x5be0cd19ul;
274 
275  uint32_t t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h;
276 
277  // Transform 2
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);
342 
343  w0 = t0 + a;
344  w1 = t1 + b;
345  w2 = t2 + c;
346  w3 = t3 + d;
347  w4 = t4 + e;
348  w5 = t5 + f;
349  w6 = t6 + g;
350  w7 = t7 + h;
351 
352  // Transform 3
353  a = 0x6a09e667ul;
354  b = 0xbb67ae85ul;
355  c = 0x3c6ef372ul;
356  d = 0xa54ff53aul;
357  e = 0x510e527ful;
358  f = 0x9b05688cul;
359  g = 0x1f83d9abul;
360  h = 0x5be0cd19ul;
361 
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)));
380  Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + sigma0(w3)));
381  Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + sigma0(w4)));
382  Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + sigma0(w5)));
383  Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + sigma0(w6)));
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)));
394  Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
395  Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
396  Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
397  Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
398  Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
399  Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
400  Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
401  Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
402  Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
403  Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
404  Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
405  Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
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)));
409  Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
410  Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
411  Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
412  Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
413  Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
414  Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
415  Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
416  Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
417  Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
418  Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
419  Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
420  Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
421  Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
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)));
424  Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
425  Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
426 
427  // Output
428  WriteBE32(out + 0, a + 0x6a09e667ul);
429  WriteBE32(out + 4, b + 0xbb67ae85ul);
430  WriteBE32(out + 8, c + 0x3c6ef372ul);
431  WriteBE32(out + 12, d + 0xa54ff53aul);
432  WriteBE32(out + 16, e + 0x510e527ful);
433  WriteBE32(out + 20, f + 0x9b05688cul);
434  WriteBE32(out + 24, g + 0x1f83d9abul);
435  WriteBE32(out + 28, h + 0x5be0cd19ul);
436 }
437 
438 } // namespace sha256
439 
440 typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t);
441 typedef void (*TransformD64Type)(unsigned char*, const unsigned char*);
442 
443 template<TransformType tr>
444 void TransformD64Wrapper(unsigned char* out, const unsigned char* in)
445 {
446  uint32_t s[8];
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
452  };
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
458  };
459  sha256::Initialize(s);
460  tr(s, in, 1);
461  tr(s, padding1, 1);
462  WriteBE32(buffer2 + 0, s[0]);
463  WriteBE32(buffer2 + 4, s[1]);
464  WriteBE32(buffer2 + 8, s[2]);
465  WriteBE32(buffer2 + 12, s[3]);
466  WriteBE32(buffer2 + 16, s[4]);
467  WriteBE32(buffer2 + 20, s[5]);
468  WriteBE32(buffer2 + 24, s[6]);
469  WriteBE32(buffer2 + 28, s[7]);
470  sha256::Initialize(s);
471  tr(s, buffer2, 1);
472  WriteBE32(out + 0, s[0]);
473  WriteBE32(out + 4, s[1]);
474  WriteBE32(out + 8, s[2]);
475  WriteBE32(out + 12, s[3]);
476  WriteBE32(out + 16, s[4]);
477  WriteBE32(out + 20, s[5]);
478  WriteBE32(out + 24, s[6]);
479  WriteBE32(out + 28, s[7]);
480 }
481 
482 TransformType Transform = sha256::Transform;
483 TransformD64Type TransformD64 = sha256::TransformD64;
484 TransformD64Type TransformD64_2way = nullptr;
485 TransformD64Type TransformD64_4way = nullptr;
486 TransformD64Type TransformD64_8way = nullptr;
487 
488 bool SelfTest() {
489  // Input state (equal to the initial SHA256 state)
490  static const uint32_t init[8] = {
491  0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
492  };
493  // Some random input data to test with
494  static const unsigned char data[641] = "-" // Intentionally not aligned
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.";
503  // Expected output state for hashing the i*64 first input bytes above (excluding SHA256 padding).
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},
514  };
515  // Expected output for each of the individual 8 64-byte messages under full double SHA256 (including padding).
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
533  };
534 
535 
536  // Test Transform() for 0 through 8 transformations.
537  for (size_t i = 0; i <= 8; ++i) {
538  uint32_t state[8];
539  std::copy(init, init + 8, state);
540  Transform(state, data + 1, i);
541  if (!std::equal(state, state + 8, result[i])) return false;
542  }
543 
544  // Test TransformD64
545  unsigned char out[32];
546  TransformD64(out, data + 1);
547  if (!std::equal(out, out + 32, result_d64)) return false;
548 
549  // Test TransformD64_2way, if available.
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;
554  }
555 
556  // Test TransformD64_4way, if available.
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;
561  }
562 
563  // Test TransformD64_8way, if available.
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;
568  }
569 
570  return true;
571 }
572 
573 #if !defined(DISABLE_OPTIMIZED_SHA256)
574 #if (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
576 bool AVXEnabled()
577 {
578  uint32_t a, d;
579  __asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0));
580  return (a & 6) == 6;
581 }
582 #endif
583 #endif // DISABLE_OPTIMIZED_SHA256
584 } // namespace
585 
586 
588 {
589  std::string ret = "standard";
591  TransformD64 = sha256::TransformD64;
592  TransformD64_2way = nullptr;
593  TransformD64_4way = nullptr;
594  TransformD64_8way = nullptr;
595 
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;
604 
605  uint32_t eax, ebx, ecx, edx;
606  GetCPUID(1, 0, eax, ebx, ecx, edx);
607  if (use_implementation & sha256_implementation::USE_SSE4) {
608  have_sse4 = (ecx >> 19) & 1;
609  }
610  have_xsave = (ecx >> 27) & 1;
611  have_avx = (ecx >> 28) & 1;
612  if (have_xsave && have_avx) {
613  enabled_avx = AVXEnabled();
614  }
615  if (have_sse4) {
616  GetCPUID(7, 0, eax, ebx, ecx, edx);
617  if (use_implementation & sha256_implementation::USE_AVX2) {
618  have_avx2 = (ebx >> 5) & 1;
619  }
620  if (use_implementation & sha256_implementation::USE_SHANI) {
621  have_x86_shani = (ebx >> 29) & 1;
622  }
623  }
624 
625 #if defined(ENABLE_SSE41) && defined(ENABLE_X86_SHANI)
626  if (have_x86_shani) {
628  TransformD64 = TransformD64Wrapper<sha256_x86_shani::Transform>;
629  TransformD64_2way = sha256d64_x86_shani::Transform_2way;
630  ret = "x86_shani(1way,2way)";
631  have_sse4 = false; // Disable SSE4/AVX2;
632  have_avx2 = false;
633  }
634 #endif
635 
636  if (have_sse4) {
637 #if defined(__x86_64__) || defined(__amd64__)
639  TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>;
640  ret = "sse4(1way)";
641 #endif
642 #if defined(ENABLE_SSE41)
643  TransformD64_4way = sha256d64_sse41::Transform_4way;
644  ret += ",sse41(4way)";
645 #endif
646  }
647 
648 #if defined(ENABLE_AVX2)
649  if (have_avx2 && have_avx && enabled_avx) {
650  TransformD64_8way = sha256d64_avx2::Transform_8way;
651  ret += ",avx2(8way)";
652  }
653 #endif
654 #endif // defined(HAVE_GETCPUID)
655 
656 #if defined(ENABLE_ARM_SHANI)
657  bool have_arm_shani = false;
658  if (use_implementation & sha256_implementation::USE_SHANI) {
659 #if defined(__linux__)
660 #if defined(__arm__) // 32-bit
661  if (getauxval(AT_HWCAP2) & HWCAP2_SHA2) {
662  have_arm_shani = true;
663  }
664 #endif
665 #if defined(__aarch64__) // 64-bit
666  if (getauxval(AT_HWCAP) & HWCAP_SHA2) {
667  have_arm_shani = true;
668  }
669 #endif
670 #endif
671 
672 #if defined(__APPLE__)
673  int val = 0;
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;
677  }
678 #endif
679  }
680 
681  if (have_arm_shani) {
683  TransformD64 = TransformD64Wrapper<sha256_arm_shani::Transform>;
684  TransformD64_2way = sha256d64_arm_shani::Transform_2way;
685  ret = "arm_shani(1way,2way)";
686  }
687 #endif
688 #endif // DISABLE_OPTIMIZED_SHA256
689 
690  assert(SelfTest());
691  return ret;
692 }
693 
695 
697 {
698  sha256::Initialize(s);
699 }
700 
701 CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
702 {
703  const unsigned char* end = data + len;
704  size_t bufsize = bytes % 64;
705  if (bufsize && bufsize + len >= 64) {
706  // Fill the buffer, and process it.
707  memcpy(buf + bufsize, data, 64 - bufsize);
708  bytes += 64 - bufsize;
709  data += 64 - bufsize;
710  Transform(s, buf, 1);
711  bufsize = 0;
712  }
713  if (end - data >= 64) {
714  size_t blocks = (end - data) / 64;
715  Transform(s, data, blocks);
716  data += 64 * blocks;
717  bytes += 64 * blocks;
718  }
719  if (end > data) {
720  // Fill the buffer with what remains.
721  memcpy(buf + bufsize, data, end - data);
722  bytes += end - data;
723  }
724  return *this;
725 }
726 
727 void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
728 {
729  static const unsigned char pad[64] = {0x80};
730  unsigned char sizedesc[8];
731  WriteBE64(sizedesc, bytes << 3);
732  Write(pad, 1 + ((119 - (bytes % 64)) % 64));
733  Write(sizedesc, 8);
734  WriteBE32(hash, s[0]);
735  WriteBE32(hash + 4, s[1]);
736  WriteBE32(hash + 8, s[2]);
737  WriteBE32(hash + 12, s[3]);
738  WriteBE32(hash + 16, s[4]);
739  WriteBE32(hash + 20, s[5]);
740  WriteBE32(hash + 24, s[6]);
741  WriteBE32(hash + 28, s[7]);
742 }
743 
745 {
746  bytes = 0;
747  sha256::Initialize(s);
748  return *this;
749 }
750 
751 void SHA256D64(unsigned char* out, const unsigned char* in, size_t blocks)
752 {
753  if (TransformD64_8way) {
754  while (blocks >= 8) {
755  TransformD64_8way(out, in);
756  out += 256;
757  in += 512;
758  blocks -= 8;
759  }
760  }
761  if (TransformD64_4way) {
762  while (blocks >= 4) {
763  TransformD64_4way(out, in);
764  out += 128;
765  in += 256;
766  blocks -= 4;
767  }
768  }
769  if (TransformD64_2way) {
770  while (blocks >= 2) {
771  TransformD64_2way(out, in);
772  out += 64;
773  in += 128;
774  blocks -= 2;
775  }
776  }
777  while (blocks) {
778  TransformD64(out, in);
779  out += 32;
780  in += 64;
781  --blocks;
782  }
783 }
int ret
A hasher class for SHA-256.
Definition: sha256.h:14
CSHA256 & Reset()
Definition: sha256.cpp:744
unsigned char buf[64]
Definition: sha256.h:17
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:727
uint64_t bytes
Definition: sha256.h:18
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:701
uint32_t s[8]
Definition: sha256.h:16
CSHA256()
Definition: sha256.cpp:696
static void WriteBE32(unsigned char *ptr, uint32_t x)
Definition: common.h:73
static void WriteBE64(unsigned char *ptr, uint64_t x)
Definition: common.h:79
static uint32_t ReadBE32(const unsigned char *ptr)
Definition: common.h:59
#define sigma1(x)
Definition: hash_impl.h:22
#define Maj(x, y, z)
Definition: hash_impl.h:18
#define Round(a, b, c, d, e, f, g, h, k, w)
Definition: hash_impl.h:24
#define Sigma0(x)
Definition: hash_impl.h:19
#define sigma0(x)
Definition: hash_impl.h:21
#define Sigma1(x)
Definition: hash_impl.h:20
#define Ch(x, y, z)
Definition: hash_impl.h:17
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.
Definition: sha256.cpp:70
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.
Definition: sha256.cpp:751
std::string SHA256AutoDetect(sha256_implementation::UseImplementation use_implementation)
Autodetect the best available SHA256 implementation.
Definition: sha256.cpp:587
assert(!tx.IsCoinBase())