Bitcoin Core  0.18.99
P2P Digital Currency
sha256.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2018 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 <crypto/sha256.h>
6 #include <crypto/common.h>
7 
8 #include <assert.h>
9 #include <string.h>
10 #include <atomic>
11 
12 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
13 #if defined(USE_ASM)
14 #include <cpuid.h>
15 namespace sha256_sse4
16 {
17 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
18 }
19 #endif
20 #endif
21 
22 namespace sha256d64_sse41
23 {
24 void Transform_4way(unsigned char* out, const unsigned char* in);
25 }
26 
27 namespace sha256d64_avx2
28 {
29 void Transform_8way(unsigned char* out, const unsigned char* in);
30 }
31 
32 namespace sha256d64_shani
33 {
34 void Transform_2way(unsigned char* out, const unsigned char* in);
35 }
36 
37 namespace sha256_shani
38 {
39 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
40 }
41 
42 // Internal implementation code.
43 namespace
44 {
46 namespace sha256
47 {
48 uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
49 uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
50 uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
51 uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
52 uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
53 uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
54 
56 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)
57 {
58  uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k;
59  uint32_t t2 = Sigma0(a) + Maj(a, b, c);
60  d += t1;
61  h = t1 + t2;
62 }
63 
65 void inline Initialize(uint32_t* s)
66 {
67  s[0] = 0x6a09e667ul;
68  s[1] = 0xbb67ae85ul;
69  s[2] = 0x3c6ef372ul;
70  s[3] = 0xa54ff53aul;
71  s[4] = 0x510e527ful;
72  s[5] = 0x9b05688cul;
73  s[6] = 0x1f83d9abul;
74  s[7] = 0x5be0cd19ul;
75 }
76 
78 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
79 {
80  while (blocks--) {
81  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];
82  uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
83 
84  Round(a, b, c, d, e, f, g, h, 0x428a2f98 + (w0 = ReadBE32(chunk + 0)));
85  Round(h, a, b, c, d, e, f, g, 0x71374491 + (w1 = ReadBE32(chunk + 4)));
86  Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf + (w2 = ReadBE32(chunk + 8)));
87  Round(f, g, h, a, b, c, d, e, 0xe9b5dba5 + (w3 = ReadBE32(chunk + 12)));
88  Round(e, f, g, h, a, b, c, d, 0x3956c25b + (w4 = ReadBE32(chunk + 16)));
89  Round(d, e, f, g, h, a, b, c, 0x59f111f1 + (w5 = ReadBE32(chunk + 20)));
90  Round(c, d, e, f, g, h, a, b, 0x923f82a4 + (w6 = ReadBE32(chunk + 24)));
91  Round(b, c, d, e, f, g, h, a, 0xab1c5ed5 + (w7 = ReadBE32(chunk + 28)));
92  Round(a, b, c, d, e, f, g, h, 0xd807aa98 + (w8 = ReadBE32(chunk + 32)));
93  Round(h, a, b, c, d, e, f, g, 0x12835b01 + (w9 = ReadBE32(chunk + 36)));
94  Round(g, h, a, b, c, d, e, f, 0x243185be + (w10 = ReadBE32(chunk + 40)));
95  Round(f, g, h, a, b, c, d, e, 0x550c7dc3 + (w11 = ReadBE32(chunk + 44)));
96  Round(e, f, g, h, a, b, c, d, 0x72be5d74 + (w12 = ReadBE32(chunk + 48)));
97  Round(d, e, f, g, h, a, b, c, 0x80deb1fe + (w13 = ReadBE32(chunk + 52)));
98  Round(c, d, e, f, g, h, a, b, 0x9bdc06a7 + (w14 = ReadBE32(chunk + 56)));
99  Round(b, c, d, e, f, g, h, a, 0xc19bf174 + (w15 = ReadBE32(chunk + 60)));
100 
101  Round(a, b, c, d, e, f, g, h, 0xe49b69c1 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
102  Round(h, a, b, c, d, e, f, g, 0xefbe4786 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
103  Round(g, h, a, b, c, d, e, f, 0x0fc19dc6 + (w2 += sigma1(w0) + w11 + sigma0(w3)));
104  Round(f, g, h, a, b, c, d, e, 0x240ca1cc + (w3 += sigma1(w1) + w12 + sigma0(w4)));
105  Round(e, f, g, h, a, b, c, d, 0x2de92c6f + (w4 += sigma1(w2) + w13 + sigma0(w5)));
106  Round(d, e, f, g, h, a, b, c, 0x4a7484aa + (w5 += sigma1(w3) + w14 + sigma0(w6)));
107  Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc + (w6 += sigma1(w4) + w15 + sigma0(w7)));
108  Round(b, c, d, e, f, g, h, a, 0x76f988da + (w7 += sigma1(w5) + w0 + sigma0(w8)));
109  Round(a, b, c, d, e, f, g, h, 0x983e5152 + (w8 += sigma1(w6) + w1 + sigma0(w9)));
110  Round(h, a, b, c, d, e, f, g, 0xa831c66d + (w9 += sigma1(w7) + w2 + sigma0(w10)));
111  Round(g, h, a, b, c, d, e, f, 0xb00327c8 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
112  Round(f, g, h, a, b, c, d, e, 0xbf597fc7 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
113  Round(e, f, g, h, a, b, c, d, 0xc6e00bf3 + (w12 += sigma1(w10) + w5 + sigma0(w13)));
114  Round(d, e, f, g, h, a, b, c, 0xd5a79147 + (w13 += sigma1(w11) + w6 + sigma0(w14)));
115  Round(c, d, e, f, g, h, a, b, 0x06ca6351 + (w14 += sigma1(w12) + w7 + sigma0(w15)));
116  Round(b, c, d, e, f, g, h, a, 0x14292967 + (w15 += sigma1(w13) + w8 + sigma0(w0)));
117 
118  Round(a, b, c, d, e, f, g, h, 0x27b70a85 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
119  Round(h, a, b, c, d, e, f, g, 0x2e1b2138 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
120  Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc + (w2 += sigma1(w0) + w11 + sigma0(w3)));
121  Round(f, g, h, a, b, c, d, e, 0x53380d13 + (w3 += sigma1(w1) + w12 + sigma0(w4)));
122  Round(e, f, g, h, a, b, c, d, 0x650a7354 + (w4 += sigma1(w2) + w13 + sigma0(w5)));
123  Round(d, e, f, g, h, a, b, c, 0x766a0abb + (w5 += sigma1(w3) + w14 + sigma0(w6)));
124  Round(c, d, e, f, g, h, a, b, 0x81c2c92e + (w6 += sigma1(w4) + w15 + sigma0(w7)));
125  Round(b, c, d, e, f, g, h, a, 0x92722c85 + (w7 += sigma1(w5) + w0 + sigma0(w8)));
126  Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1 + (w8 += sigma1(w6) + w1 + sigma0(w9)));
127  Round(h, a, b, c, d, e, f, g, 0xa81a664b + (w9 += sigma1(w7) + w2 + sigma0(w10)));
128  Round(g, h, a, b, c, d, e, f, 0xc24b8b70 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
129  Round(f, g, h, a, b, c, d, e, 0xc76c51a3 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
130  Round(e, f, g, h, a, b, c, d, 0xd192e819 + (w12 += sigma1(w10) + w5 + sigma0(w13)));
131  Round(d, e, f, g, h, a, b, c, 0xd6990624 + (w13 += sigma1(w11) + w6 + sigma0(w14)));
132  Round(c, d, e, f, g, h, a, b, 0xf40e3585 + (w14 += sigma1(w12) + w7 + sigma0(w15)));
133  Round(b, c, d, e, f, g, h, a, 0x106aa070 + (w15 += sigma1(w13) + w8 + sigma0(w0)));
134 
135  Round(a, b, c, d, e, f, g, h, 0x19a4c116 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
136  Round(h, a, b, c, d, e, f, g, 0x1e376c08 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
137  Round(g, h, a, b, c, d, e, f, 0x2748774c + (w2 += sigma1(w0) + w11 + sigma0(w3)));
138  Round(f, g, h, a, b, c, d, e, 0x34b0bcb5 + (w3 += sigma1(w1) + w12 + sigma0(w4)));
139  Round(e, f, g, h, a, b, c, d, 0x391c0cb3 + (w4 += sigma1(w2) + w13 + sigma0(w5)));
140  Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a + (w5 += sigma1(w3) + w14 + sigma0(w6)));
141  Round(c, d, e, f, g, h, a, b, 0x5b9cca4f + (w6 += sigma1(w4) + w15 + sigma0(w7)));
142  Round(b, c, d, e, f, g, h, a, 0x682e6ff3 + (w7 += sigma1(w5) + w0 + sigma0(w8)));
143  Round(a, b, c, d, e, f, g, h, 0x748f82ee + (w8 += sigma1(w6) + w1 + sigma0(w9)));
144  Round(h, a, b, c, d, e, f, g, 0x78a5636f + (w9 += sigma1(w7) + w2 + sigma0(w10)));
145  Round(g, h, a, b, c, d, e, f, 0x84c87814 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
146  Round(f, g, h, a, b, c, d, e, 0x8cc70208 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
147  Round(e, f, g, h, a, b, c, d, 0x90befffa + (w12 += sigma1(w10) + w5 + sigma0(w13)));
148  Round(d, e, f, g, h, a, b, c, 0xa4506ceb + (w13 += sigma1(w11) + w6 + sigma0(w14)));
149  Round(c, d, e, f, g, h, a, b, 0xbef9a3f7 + (w14 + sigma1(w12) + w7 + sigma0(w15)));
150  Round(b, c, d, e, f, g, h, a, 0xc67178f2 + (w15 + sigma1(w13) + w8 + sigma0(w0)));
151 
152  s[0] += a;
153  s[1] += b;
154  s[2] += c;
155  s[3] += d;
156  s[4] += e;
157  s[5] += f;
158  s[6] += g;
159  s[7] += h;
160  chunk += 64;
161  }
162 }
163 
164 void TransformD64(unsigned char* out, const unsigned char* in)
165 {
166  // Transform 1
167  uint32_t a = 0x6a09e667ul;
168  uint32_t b = 0xbb67ae85ul;
169  uint32_t c = 0x3c6ef372ul;
170  uint32_t d = 0xa54ff53aul;
171  uint32_t e = 0x510e527ful;
172  uint32_t f = 0x9b05688cul;
173  uint32_t g = 0x1f83d9abul;
174  uint32_t h = 0x5be0cd19ul;
175 
176  uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
177 
178  Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + (w0 = ReadBE32(in + 0)));
179  Round(h, a, b, c, d, e, f, g, 0x71374491ul + (w1 = ReadBE32(in + 4)));
180  Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + (w2 = ReadBE32(in + 8)));
181  Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + (w3 = ReadBE32(in + 12)));
182  Round(e, f, g, h, a, b, c, d, 0x3956c25bul + (w4 = ReadBE32(in + 16)));
183  Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + (w5 = ReadBE32(in + 20)));
184  Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + (w6 = ReadBE32(in + 24)));
185  Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + (w7 = ReadBE32(in + 28)));
186  Round(a, b, c, d, e, f, g, h, 0xd807aa98ul + (w8 = ReadBE32(in + 32)));
187  Round(h, a, b, c, d, e, f, g, 0x12835b01ul + (w9 = ReadBE32(in + 36)));
188  Round(g, h, a, b, c, d, e, f, 0x243185beul + (w10 = ReadBE32(in + 40)));
189  Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul + (w11 = ReadBE32(in + 44)));
190  Round(e, f, g, h, a, b, c, d, 0x72be5d74ul + (w12 = ReadBE32(in + 48)));
191  Round(d, e, f, g, h, a, b, c, 0x80deb1feul + (w13 = ReadBE32(in + 52)));
192  Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul + (w14 = ReadBE32(in + 56)));
193  Round(b, c, d, e, f, g, h, a, 0xc19bf174ul + (w15 = ReadBE32(in + 60)));
194  Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
195  Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
196  Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
197  Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
198  Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + w13 + sigma0(w5)));
199  Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
200  Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
201  Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
202  Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
203  Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
204  Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
205  Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
206  Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
207  Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
208  Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
209  Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
210  Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
211  Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
212  Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
213  Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
214  Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
215  Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
216  Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
217  Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
218  Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
219  Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
220  Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
221  Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
222  Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
223  Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
224  Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
225  Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
226  Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
227  Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
228  Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
229  Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
230  Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
231  Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
232  Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
233  Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
234  Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
235  Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
236  Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
237  Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
238  Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
239  Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
240  Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
241  Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
242 
243  a += 0x6a09e667ul;
244  b += 0xbb67ae85ul;
245  c += 0x3c6ef372ul;
246  d += 0xa54ff53aul;
247  e += 0x510e527ful;
248  f += 0x9b05688cul;
249  g += 0x1f83d9abul;
250  h += 0x5be0cd19ul;
251 
252  uint32_t t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h;
253 
254  // Transform 2
255  Round(a, b, c, d, e, f, g, h, 0xc28a2f98ul);
256  Round(h, a, b, c, d, e, f, g, 0x71374491ul);
257  Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful);
258  Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul);
259  Round(e, f, g, h, a, b, c, d, 0x3956c25bul);
260  Round(d, e, f, g, h, a, b, c, 0x59f111f1ul);
261  Round(c, d, e, f, g, h, a, b, 0x923f82a4ul);
262  Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul);
263  Round(a, b, c, d, e, f, g, h, 0xd807aa98ul);
264  Round(h, a, b, c, d, e, f, g, 0x12835b01ul);
265  Round(g, h, a, b, c, d, e, f, 0x243185beul);
266  Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul);
267  Round(e, f, g, h, a, b, c, d, 0x72be5d74ul);
268  Round(d, e, f, g, h, a, b, c, 0x80deb1feul);
269  Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul);
270  Round(b, c, d, e, f, g, h, a, 0xc19bf374ul);
271  Round(a, b, c, d, e, f, g, h, 0x649b69c1ul);
272  Round(h, a, b, c, d, e, f, g, 0xf0fe4786ul);
273  Round(g, h, a, b, c, d, e, f, 0x0fe1edc6ul);
274  Round(f, g, h, a, b, c, d, e, 0x240cf254ul);
275  Round(e, f, g, h, a, b, c, d, 0x4fe9346ful);
276  Round(d, e, f, g, h, a, b, c, 0x6cc984beul);
277  Round(c, d, e, f, g, h, a, b, 0x61b9411eul);
278  Round(b, c, d, e, f, g, h, a, 0x16f988faul);
279  Round(a, b, c, d, e, f, g, h, 0xf2c65152ul);
280  Round(h, a, b, c, d, e, f, g, 0xa88e5a6dul);
281  Round(g, h, a, b, c, d, e, f, 0xb019fc65ul);
282  Round(f, g, h, a, b, c, d, e, 0xb9d99ec7ul);
283  Round(e, f, g, h, a, b, c, d, 0x9a1231c3ul);
284  Round(d, e, f, g, h, a, b, c, 0xe70eeaa0ul);
285  Round(c, d, e, f, g, h, a, b, 0xfdb1232bul);
286  Round(b, c, d, e, f, g, h, a, 0xc7353eb0ul);
287  Round(a, b, c, d, e, f, g, h, 0x3069bad5ul);
288  Round(h, a, b, c, d, e, f, g, 0xcb976d5ful);
289  Round(g, h, a, b, c, d, e, f, 0x5a0f118ful);
290  Round(f, g, h, a, b, c, d, e, 0xdc1eeefdul);
291  Round(e, f, g, h, a, b, c, d, 0x0a35b689ul);
292  Round(d, e, f, g, h, a, b, c, 0xde0b7a04ul);
293  Round(c, d, e, f, g, h, a, b, 0x58f4ca9dul);
294  Round(b, c, d, e, f, g, h, a, 0xe15d5b16ul);
295  Round(a, b, c, d, e, f, g, h, 0x007f3e86ul);
296  Round(h, a, b, c, d, e, f, g, 0x37088980ul);
297  Round(g, h, a, b, c, d, e, f, 0xa507ea32ul);
298  Round(f, g, h, a, b, c, d, e, 0x6fab9537ul);
299  Round(e, f, g, h, a, b, c, d, 0x17406110ul);
300  Round(d, e, f, g, h, a, b, c, 0x0d8cd6f1ul);
301  Round(c, d, e, f, g, h, a, b, 0xcdaa3b6dul);
302  Round(b, c, d, e, f, g, h, a, 0xc0bbbe37ul);
303  Round(a, b, c, d, e, f, g, h, 0x83613bdaul);
304  Round(h, a, b, c, d, e, f, g, 0xdb48a363ul);
305  Round(g, h, a, b, c, d, e, f, 0x0b02e931ul);
306  Round(f, g, h, a, b, c, d, e, 0x6fd15ca7ul);
307  Round(e, f, g, h, a, b, c, d, 0x521afacaul);
308  Round(d, e, f, g, h, a, b, c, 0x31338431ul);
309  Round(c, d, e, f, g, h, a, b, 0x6ed41a95ul);
310  Round(b, c, d, e, f, g, h, a, 0x6d437890ul);
311  Round(a, b, c, d, e, f, g, h, 0xc39c91f2ul);
312  Round(h, a, b, c, d, e, f, g, 0x9eccabbdul);
313  Round(g, h, a, b, c, d, e, f, 0xb5c9a0e6ul);
314  Round(f, g, h, a, b, c, d, e, 0x532fb63cul);
315  Round(e, f, g, h, a, b, c, d, 0xd2c741c6ul);
316  Round(d, e, f, g, h, a, b, c, 0x07237ea3ul);
317  Round(c, d, e, f, g, h, a, b, 0xa4954b68ul);
318  Round(b, c, d, e, f, g, h, a, 0x4c191d76ul);
319 
320  w0 = t0 + a;
321  w1 = t1 + b;
322  w2 = t2 + c;
323  w3 = t3 + d;
324  w4 = t4 + e;
325  w5 = t5 + f;
326  w6 = t6 + g;
327  w7 = t7 + h;
328 
329  // Transform 3
330  a = 0x6a09e667ul;
331  b = 0xbb67ae85ul;
332  c = 0x3c6ef372ul;
333  d = 0xa54ff53aul;
334  e = 0x510e527ful;
335  f = 0x9b05688cul;
336  g = 0x1f83d9abul;
337  h = 0x5be0cd19ul;
338 
339  Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + w0);
340  Round(h, a, b, c, d, e, f, g, 0x71374491ul + w1);
341  Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + w2);
342  Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + w3);
343  Round(e, f, g, h, a, b, c, d, 0x3956c25bul + w4);
344  Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + w5);
345  Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + w6);
346  Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + w7);
347  Round(a, b, c, d, e, f, g, h, 0x5807aa98ul);
348  Round(h, a, b, c, d, e, f, g, 0x12835b01ul);
349  Round(g, h, a, b, c, d, e, f, 0x243185beul);
350  Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul);
351  Round(e, f, g, h, a, b, c, d, 0x72be5d74ul);
352  Round(d, e, f, g, h, a, b, c, 0x80deb1feul);
353  Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul);
354  Round(b, c, d, e, f, g, h, a, 0xc19bf274ul);
355  Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma0(w1)));
356  Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += 0xa00000ul + sigma0(w2)));
357  Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + sigma0(w3)));
358  Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + sigma0(w4)));
359  Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + sigma0(w5)));
360  Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + sigma0(w6)));
361  Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + 0x100ul + sigma0(w7)));
362  Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + 0x11002000ul));
363  Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 = 0x80000000ul + sigma1(w6) + w1));
364  Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 = sigma1(w7) + w2));
365  Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 = sigma1(w8) + w3));
366  Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 = sigma1(w9) + w4));
367  Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 = sigma1(w10) + w5));
368  Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 = sigma1(w11) + w6));
369  Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 = sigma1(w12) + w7 + 0x400022ul));
370  Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 = 0x100ul + sigma1(w13) + w8 + sigma0(w0)));
371  Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
372  Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
373  Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
374  Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
375  Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
376  Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
377  Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
378  Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
379  Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
380  Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
381  Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
382  Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
383  Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
384  Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
385  Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
386  Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
387  Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
388  Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
389  Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
390  Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
391  Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
392  Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
393  Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
394  Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
395  Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
396  Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
397  Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
398  Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
399  Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
400  Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
401  Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
402  Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
403 
404  // Output
405  WriteBE32(out + 0, a + 0x6a09e667ul);
406  WriteBE32(out + 4, b + 0xbb67ae85ul);
407  WriteBE32(out + 8, c + 0x3c6ef372ul);
408  WriteBE32(out + 12, d + 0xa54ff53aul);
409  WriteBE32(out + 16, e + 0x510e527ful);
410  WriteBE32(out + 20, f + 0x9b05688cul);
411  WriteBE32(out + 24, g + 0x1f83d9abul);
412  WriteBE32(out + 28, h + 0x5be0cd19ul);
413 }
414 
415 } // namespace sha256
416 
417 typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t);
418 typedef void (*TransformD64Type)(unsigned char*, const unsigned char*);
419 
420 template<TransformType tr>
421 void TransformD64Wrapper(unsigned char* out, const unsigned char* in)
422 {
423  uint32_t s[8];
424  static const unsigned char padding1[64] = {
425  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
426  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
427  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
428  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0
429  };
430  unsigned char buffer2[64] = {
431  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
432  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
433  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
434  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
435  };
436  sha256::Initialize(s);
437  tr(s, in, 1);
438  tr(s, padding1, 1);
439  WriteBE32(buffer2 + 0, s[0]);
440  WriteBE32(buffer2 + 4, s[1]);
441  WriteBE32(buffer2 + 8, s[2]);
442  WriteBE32(buffer2 + 12, s[3]);
443  WriteBE32(buffer2 + 16, s[4]);
444  WriteBE32(buffer2 + 20, s[5]);
445  WriteBE32(buffer2 + 24, s[6]);
446  WriteBE32(buffer2 + 28, s[7]);
447  sha256::Initialize(s);
448  tr(s, buffer2, 1);
449  WriteBE32(out + 0, s[0]);
450  WriteBE32(out + 4, s[1]);
451  WriteBE32(out + 8, s[2]);
452  WriteBE32(out + 12, s[3]);
453  WriteBE32(out + 16, s[4]);
454  WriteBE32(out + 20, s[5]);
455  WriteBE32(out + 24, s[6]);
456  WriteBE32(out + 28, s[7]);
457 }
458 
459 TransformType Transform = sha256::Transform;
460 TransformD64Type TransformD64 = sha256::TransformD64;
461 TransformD64Type TransformD64_2way = nullptr;
462 TransformD64Type TransformD64_4way = nullptr;
463 TransformD64Type TransformD64_8way = nullptr;
464 
465 bool SelfTest() {
466  // Input state (equal to the initial SHA256 state)
467  static const uint32_t init[8] = {
468  0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
469  };
470  // Some random input data to test with
471  static const unsigned char data[641] = "-" // Intentionally not aligned
472  "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
473  "eiusmod tempor incididunt ut labore et dolore magna aliqua. Et m"
474  "olestie ac feugiat sed lectus vestibulum mattis ullamcorper. Mor"
475  "bi blandit cursus risus at ultrices mi tempus imperdiet nulla. N"
476  "unc congue nisi vita suscipit tellus mauris. Imperdiet proin fer"
477  "mentum leo vel orci. Massa tempor nec feugiat nisl pretium fusce"
478  " id velit. Telus in metus vulputate eu scelerisque felis. Mi tem"
479  "pus imperdiet nulla malesuada pellentesque. Tristique magna sit.";
480  // Expected output state for hashing the i*64 first input bytes above (excluding SHA256 padding).
481  static const uint32_t result[9][8] = {
482  {0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul},
483  {0x91f8ec6bul, 0x4da10fe3ul, 0x1c9c292cul, 0x45e18185ul, 0x435cc111ul, 0x3ca26f09ul, 0xeb954caeul, 0x402a7069ul},
484  {0xcabea5acul, 0x374fb97cul, 0x182ad996ul, 0x7bd69cbful, 0x450ff900ul, 0xc1d2be8aul, 0x6a41d505ul, 0xe6212dc3ul},
485  {0xbcff09d6ul, 0x3e76f36eul, 0x3ecb2501ul, 0x78866e97ul, 0xe1c1e2fdul, 0x32f4eafful, 0x8aa6c4e5ul, 0xdfc024bcul},
486  {0xa08c5d94ul, 0x0a862f93ul, 0x6b7f2f40ul, 0x8f9fae76ul, 0x6d40439ful, 0x79dcee0cul, 0x3e39ff3aul, 0xdc3bdbb1ul},
487  {0x216a0895ul, 0x9f1a3662ul, 0xe99946f9ul, 0x87ba4364ul, 0x0fb5db2cul, 0x12bed3d3ul, 0x6689c0c7ul, 0x292f1b04ul},
488  {0xca3067f8ul, 0xbc8c2656ul, 0x37cb7e0dul, 0x9b6b8b0ful, 0x46dc380bul, 0xf1287f57ul, 0xc42e4b23ul, 0x3fefe94dul},
489  {0x3e4c4039ul, 0xbb6fca8cul, 0x6f27d2f7ul, 0x301e44a4ul, 0x8352ba14ul, 0x5769ce37ul, 0x48a1155ful, 0xc0e1c4c6ul},
490  {0xfe2fa9ddul, 0x69d0862bul, 0x1ae0db23ul, 0x471f9244ul, 0xf55c0145ul, 0xc30f9c3bul, 0x40a84ea0ul, 0x5b8a266cul},
491  };
492  // Expected output for each of the individual 8 64-byte messages under full double SHA256 (including padding).
493  static const unsigned char result_d64[256] = {
494  0x09, 0x3a, 0xc4, 0xd0, 0x0f, 0xf7, 0x57, 0xe1, 0x72, 0x85, 0x79, 0x42, 0xfe, 0xe7, 0xe0, 0xa0,
495  0xfc, 0x52, 0xd7, 0xdb, 0x07, 0x63, 0x45, 0xfb, 0x53, 0x14, 0x7d, 0x17, 0x22, 0x86, 0xf0, 0x52,
496  0x48, 0xb6, 0x11, 0x9e, 0x6e, 0x48, 0x81, 0x6d, 0xcc, 0x57, 0x1f, 0xb2, 0x97, 0xa8, 0xd5, 0x25,
497  0x9b, 0x82, 0xaa, 0x89, 0xe2, 0xfd, 0x2d, 0x56, 0xe8, 0x28, 0x83, 0x0b, 0xe2, 0xfa, 0x53, 0xb7,
498  0xd6, 0x6b, 0x07, 0x85, 0x83, 0xb0, 0x10, 0xa2, 0xf5, 0x51, 0x3c, 0xf9, 0x60, 0x03, 0xab, 0x45,
499  0x6c, 0x15, 0x6e, 0xef, 0xb5, 0xac, 0x3e, 0x6c, 0xdf, 0xb4, 0x92, 0x22, 0x2d, 0xce, 0xbf, 0x3e,
500  0xe9, 0xe5, 0xf6, 0x29, 0x0e, 0x01, 0x4f, 0xd2, 0xd4, 0x45, 0x65, 0xb3, 0xbb, 0xf2, 0x4c, 0x16,
501  0x37, 0x50, 0x3c, 0x6e, 0x49, 0x8c, 0x5a, 0x89, 0x2b, 0x1b, 0xab, 0xc4, 0x37, 0xd1, 0x46, 0xe9,
502  0x3d, 0x0e, 0x85, 0xa2, 0x50, 0x73, 0xa1, 0x5e, 0x54, 0x37, 0xd7, 0x94, 0x17, 0x56, 0xc2, 0xd8,
503  0xe5, 0x9f, 0xed, 0x4e, 0xae, 0x15, 0x42, 0x06, 0x0d, 0x74, 0x74, 0x5e, 0x24, 0x30, 0xce, 0xd1,
504  0x9e, 0x50, 0xa3, 0x9a, 0xb8, 0xf0, 0x4a, 0x57, 0x69, 0x78, 0x67, 0x12, 0x84, 0x58, 0xbe, 0xc7,
505  0x36, 0xaa, 0xee, 0x7c, 0x64, 0xa3, 0x76, 0xec, 0xff, 0x55, 0x41, 0x00, 0x2a, 0x44, 0x68, 0x4d,
506  0xb6, 0x53, 0x9e, 0x1c, 0x95, 0xb7, 0xca, 0xdc, 0x7f, 0x7d, 0x74, 0x27, 0x5c, 0x8e, 0xa6, 0x84,
507  0xb5, 0xac, 0x87, 0xa9, 0xf3, 0xff, 0x75, 0xf2, 0x34, 0xcd, 0x1a, 0x3b, 0x82, 0x2c, 0x2b, 0x4e,
508  0x6a, 0x46, 0x30, 0xa6, 0x89, 0x86, 0x23, 0xac, 0xf8, 0xa5, 0x15, 0xe9, 0x0a, 0xaa, 0x1e, 0x9a,
509  0xd7, 0x93, 0x6b, 0x28, 0xe4, 0x3b, 0xfd, 0x59, 0xc6, 0xed, 0x7c, 0x5f, 0xa5, 0x41, 0xcb, 0x51
510  };
511 
512 
513  // Test Transform() for 0 through 8 transformations.
514  for (size_t i = 0; i <= 8; ++i) {
515  uint32_t state[8];
516  std::copy(init, init + 8, state);
517  Transform(state, data + 1, i);
518  if (!std::equal(state, state + 8, result[i])) return false;
519  }
520 
521  // Test TransformD64
522  unsigned char out[32];
523  TransformD64(out, data + 1);
524  if (!std::equal(out, out + 32, result_d64)) return false;
525 
526  // Test TransformD64_2way, if available.
527  if (TransformD64_2way) {
528  unsigned char out[64];
529  TransformD64_2way(out, data + 1);
530  if (!std::equal(out, out + 64, result_d64)) return false;
531  }
532 
533  // Test TransformD64_4way, if available.
534  if (TransformD64_4way) {
535  unsigned char out[128];
536  TransformD64_4way(out, data + 1);
537  if (!std::equal(out, out + 128, result_d64)) return false;
538  }
539 
540  // Test TransformD64_8way, if available.
541  if (TransformD64_8way) {
542  unsigned char out[256];
543  TransformD64_8way(out, data + 1);
544  if (!std::equal(out, out + 256, result_d64)) return false;
545  }
546 
547  return true;
548 }
549 
550 
551 #if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
552 // We can't use cpuid.h's __get_cpuid as it does not support subleafs.
553 void inline cpuid(uint32_t leaf, uint32_t subleaf, uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d)
554 {
555 #ifdef __GNUC__
556  __cpuid_count(leaf, subleaf, a, b, c, d);
557 #else
558  __asm__ ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(leaf), "2"(subleaf));
559 #endif
560 }
561 
563 bool AVXEnabled()
564 {
565  uint32_t a, d;
566  __asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0));
567  return (a & 6) == 6;
568 }
569 #endif
570 } // namespace
571 
572 
573 std::string SHA256AutoDetect()
574 {
575  std::string ret = "standard";
576 #if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
577  bool have_sse4 = false;
578  bool have_xsave = false;
579  bool have_avx = false;
580  bool have_avx2 = false;
581  bool have_shani = false;
582  bool enabled_avx = false;
583 
584  (void)AVXEnabled;
585  (void)have_sse4;
586  (void)have_avx;
587  (void)have_xsave;
588  (void)have_avx2;
589  (void)have_shani;
590  (void)enabled_avx;
591 
592  uint32_t eax, ebx, ecx, edx;
593  cpuid(1, 0, eax, ebx, ecx, edx);
594  have_sse4 = (ecx >> 19) & 1;
595  have_xsave = (ecx >> 27) & 1;
596  have_avx = (ecx >> 28) & 1;
597  if (have_xsave && have_avx) {
598  enabled_avx = AVXEnabled();
599  }
600  if (have_sse4) {
601  cpuid(7, 0, eax, ebx, ecx, edx);
602  have_avx2 = (ebx >> 5) & 1;
603  have_shani = (ebx >> 29) & 1;
604  }
605 
606 #if defined(ENABLE_SHANI) && !defined(BUILD_BITCOIN_INTERNAL)
607  if (have_shani) {
609  TransformD64 = TransformD64Wrapper<sha256_shani::Transform>;
610  TransformD64_2way = sha256d64_shani::Transform_2way;
611  ret = "shani(1way,2way)";
612  have_sse4 = false; // Disable SSE4/AVX2;
613  have_avx2 = false;
614  }
615 #endif
616 
617  if (have_sse4) {
618 #if defined(__x86_64__) || defined(__amd64__)
620  TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>;
621  ret = "sse4(1way)";
622 #endif
623 #if defined(ENABLE_SSE41) && !defined(BUILD_BITCOIN_INTERNAL)
624  TransformD64_4way = sha256d64_sse41::Transform_4way;
625  ret += ",sse41(4way)";
626 #endif
627  }
628 
629 #if defined(ENABLE_AVX2) && !defined(BUILD_BITCOIN_INTERNAL)
630  if (have_avx2 && have_avx && enabled_avx) {
631  TransformD64_8way = sha256d64_avx2::Transform_8way;
632  ret += ",avx2(8way)";
633  }
634 #endif
635 #endif
636 
637  assert(SelfTest());
638  return ret;
639 }
640 
642 
643 CSHA256::CSHA256() : bytes(0)
644 {
645  sha256::Initialize(s);
646 }
647 
648 CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
649 {
650  const unsigned char* end = data + len;
651  size_t bufsize = bytes % 64;
652  if (bufsize && bufsize + len >= 64) {
653  // Fill the buffer, and process it.
654  memcpy(buf + bufsize, data, 64 - bufsize);
655  bytes += 64 - bufsize;
656  data += 64 - bufsize;
657  Transform(s, buf, 1);
658  bufsize = 0;
659  }
660  if (end - data >= 64) {
661  size_t blocks = (end - data) / 64;
662  Transform(s, data, blocks);
663  data += 64 * blocks;
664  bytes += 64 * blocks;
665  }
666  if (end > data) {
667  // Fill the buffer with what remains.
668  memcpy(buf + bufsize, data, end - data);
669  bytes += end - data;
670  }
671  return *this;
672 }
673 
674 void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
675 {
676  static const unsigned char pad[64] = {0x80};
677  unsigned char sizedesc[8];
678  WriteBE64(sizedesc, bytes << 3);
679  Write(pad, 1 + ((119 - (bytes % 64)) % 64));
680  Write(sizedesc, 8);
681  WriteBE32(hash, s[0]);
682  WriteBE32(hash + 4, s[1]);
683  WriteBE32(hash + 8, s[2]);
684  WriteBE32(hash + 12, s[3]);
685  WriteBE32(hash + 16, s[4]);
686  WriteBE32(hash + 20, s[5]);
687  WriteBE32(hash + 24, s[6]);
688  WriteBE32(hash + 28, s[7]);
689 }
690 
692 {
693  bytes = 0;
694  sha256::Initialize(s);
695  return *this;
696 }
697 
698 void SHA256D64(unsigned char* out, const unsigned char* in, size_t blocks)
699 {
700  if (TransformD64_8way) {
701  while (blocks >= 8) {
702  TransformD64_8way(out, in);
703  out += 256;
704  in += 512;
705  blocks -= 8;
706  }
707  }
708  if (TransformD64_4way) {
709  while (blocks >= 4) {
710  TransformD64_4way(out, in);
711  out += 128;
712  in += 256;
713  blocks -= 4;
714  }
715  }
716  if (TransformD64_2way) {
717  while (blocks >= 2) {
718  TransformD64_2way(out, in);
719  out += 64;
720  in += 128;
721  blocks -= 2;
722  }
723  }
724  while (blocks) {
725  TransformD64(out, in);
726  out += 32;
727  in += 64;
728  --blocks;
729  }
730 }
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:648
#define Round(a, b, c, d, e, f, g, h, k, w)
Definition: hash_impl.h:23
void Transform_2way(unsigned char *out, const unsigned char *in)
#define Maj(x, y, z)
Definition: hash_impl.h:17
uint32_t s[8]
Definition: sha256.h:16
#define sigma1(x)
Definition: hash_impl.h:21
static void WriteBE64(unsigned char *ptr, uint64_t x)
Definition: common.h:76
std::string SHA256AutoDetect()
Autodetect the best available SHA256 implementation.
Definition: sha256.cpp:573
#define sigma0(x)
Definition: hash_impl.h:20
CSHA256 & Reset()
Definition: sha256.cpp:691
#define Sigma0(x)
Definition: hash_impl.h:18
void Transform(uint32_t *s, const unsigned char *chunk, size_t blocks)
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:674
static uint32_t ReadBE32(const unsigned char *ptr)
Definition: common.h:56
void Transform_8way(unsigned char *out, const unsigned char *in)
#define Sigma1(x)
Definition: hash_impl.h:19
uint64_t bytes
Definition: sha256.h:18
void * memcpy(void *a, const void *b, size_t c)
#define Ch(x, y, z)
Definition: hash_impl.h:16
Internal SHA-256 implementation.
Definition: sha256.cpp:46
void Transform_4way(unsigned char *out, const unsigned char *in)
static const size_t OUTPUT_SIZE
Definition: sha256.h:21
CSHA256()
Definition: sha256.cpp:643
static void WriteBE32(unsigned char *ptr, uint32_t x)
Definition: common.h:70
void SHA256D64(unsigned char *out, const unsigned char *in, size_t blocks)
Compute multiple double-SHA256&#39;s of 64-byte blobs.
Definition: sha256.cpp:698
unsigned char buf[64]
Definition: sha256.h:17
A hasher class for SHA-256.
Definition: sha256.h:13