Bitcoin Core  0.20.99
P2P Digital Currency
sha256.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2019 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 
11 #include <compat/cpuid.h>
12 
13 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
14 #if defined(USE_ASM)
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 #if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
551 
552 bool AVXEnabled()
553 {
554  uint32_t a, d;
555  __asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0));
556  return (a & 6) == 6;
557 }
558 #endif
559 } // namespace
560 
561 
562 std::string SHA256AutoDetect()
563 {
564  std::string ret = "standard";
565 #if defined(USE_ASM) && defined(HAVE_GETCPUID)
566  bool have_sse4 = false;
567  bool have_xsave = false;
568  bool have_avx = false;
569  bool have_avx2 = false;
570  bool have_shani = false;
571  bool enabled_avx = false;
572 
573  (void)AVXEnabled;
574  (void)have_sse4;
575  (void)have_avx;
576  (void)have_xsave;
577  (void)have_avx2;
578  (void)have_shani;
579  (void)enabled_avx;
580 
581  uint32_t eax, ebx, ecx, edx;
582  GetCPUID(1, 0, eax, ebx, ecx, edx);
583  have_sse4 = (ecx >> 19) & 1;
584  have_xsave = (ecx >> 27) & 1;
585  have_avx = (ecx >> 28) & 1;
586  if (have_xsave && have_avx) {
587  enabled_avx = AVXEnabled();
588  }
589  if (have_sse4) {
590  GetCPUID(7, 0, eax, ebx, ecx, edx);
591  have_avx2 = (ebx >> 5) & 1;
592  have_shani = (ebx >> 29) & 1;
593  }
594 
595 #if defined(ENABLE_SHANI) && !defined(BUILD_BITCOIN_INTERNAL)
596  if (have_shani) {
598  TransformD64 = TransformD64Wrapper<sha256_shani::Transform>;
599  TransformD64_2way = sha256d64_shani::Transform_2way;
600  ret = "shani(1way,2way)";
601  have_sse4 = false; // Disable SSE4/AVX2;
602  have_avx2 = false;
603  }
604 #endif
605 
606  if (have_sse4) {
607 #if defined(__x86_64__) || defined(__amd64__)
609  TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>;
610  ret = "sse4(1way)";
611 #endif
612 #if defined(ENABLE_SSE41) && !defined(BUILD_BITCOIN_INTERNAL)
613  TransformD64_4way = sha256d64_sse41::Transform_4way;
614  ret += ",sse41(4way)";
615 #endif
616  }
617 
618 #if defined(ENABLE_AVX2) && !defined(BUILD_BITCOIN_INTERNAL)
619  if (have_avx2 && have_avx && enabled_avx) {
620  TransformD64_8way = sha256d64_avx2::Transform_8way;
621  ret += ",avx2(8way)";
622  }
623 #endif
624 #endif
625 
626  assert(SelfTest());
627  return ret;
628 }
629 
631 
632 CSHA256::CSHA256() : bytes(0)
633 {
634  sha256::Initialize(s);
635 }
636 
637 CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
638 {
639  const unsigned char* end = data + len;
640  size_t bufsize = bytes % 64;
641  if (bufsize && bufsize + len >= 64) {
642  // Fill the buffer, and process it.
643  memcpy(buf + bufsize, data, 64 - bufsize);
644  bytes += 64 - bufsize;
645  data += 64 - bufsize;
646  Transform(s, buf, 1);
647  bufsize = 0;
648  }
649  if (end - data >= 64) {
650  size_t blocks = (end - data) / 64;
651  Transform(s, data, blocks);
652  data += 64 * blocks;
653  bytes += 64 * blocks;
654  }
655  if (end > data) {
656  // Fill the buffer with what remains.
657  memcpy(buf + bufsize, data, end - data);
658  bytes += end - data;
659  }
660  return *this;
661 }
662 
663 void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
664 {
665  static const unsigned char pad[64] = {0x80};
666  unsigned char sizedesc[8];
667  WriteBE64(sizedesc, bytes << 3);
668  Write(pad, 1 + ((119 - (bytes % 64)) % 64));
669  Write(sizedesc, 8);
670  WriteBE32(hash, s[0]);
671  WriteBE32(hash + 4, s[1]);
672  WriteBE32(hash + 8, s[2]);
673  WriteBE32(hash + 12, s[3]);
674  WriteBE32(hash + 16, s[4]);
675  WriteBE32(hash + 20, s[5]);
676  WriteBE32(hash + 24, s[6]);
677  WriteBE32(hash + 28, s[7]);
678 }
679 
681 {
682  bytes = 0;
683  sha256::Initialize(s);
684  return *this;
685 }
686 
687 void SHA256D64(unsigned char* out, const unsigned char* in, size_t blocks)
688 {
689  if (TransformD64_8way) {
690  while (blocks >= 8) {
691  TransformD64_8way(out, in);
692  out += 256;
693  in += 512;
694  blocks -= 8;
695  }
696  }
697  if (TransformD64_4way) {
698  while (blocks >= 4) {
699  TransformD64_4way(out, in);
700  out += 128;
701  in += 256;
702  blocks -= 4;
703  }
704  }
705  if (TransformD64_2way) {
706  while (blocks >= 2) {
707  TransformD64_2way(out, in);
708  out += 64;
709  in += 128;
710  blocks -= 2;
711  }
712  }
713  while (blocks) {
714  TransformD64(out, in);
715  out += 32;
716  in += 64;
717  --blocks;
718  }
719 }
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:637
#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:562
#define sigma0(x)
Definition: hash_impl.h:20
CSHA256 & Reset()
Definition: sha256.cpp:680
#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:663
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:632
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:687
unsigned char buf[64]
Definition: sha256.h:17
A hasher class for SHA-256.
Definition: sha256.h:13