Bitcoin Core 22.99.0
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)
15namespace sha256_sse4
16{
17void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
18}
19#endif
20#endif
21
23{
24void Transform_4way(unsigned char* out, const unsigned char* in);
25}
26
28{
29void Transform_8way(unsigned char* out, const unsigned char* in);
30}
31
33{
34void Transform_2way(unsigned char* out, const unsigned char* in);
35}
36
37namespace sha256_shani
38{
39void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
40}
41
42// Internal implementation code.
43namespace
44{
46namespace sha256
47{
48uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
49uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
50uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
51uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
52uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
53uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
54
56void 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
65void 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
78void 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
164void 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
417typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t);
418typedef void (*TransformD64Type)(unsigned char*, const unsigned char*);
419
420template<TransformType tr>
421void 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
459TransformType Transform = sha256::Transform;
460TransformD64Type TransformD64 = sha256::TransformD64;
461TransformD64Type TransformD64_2way = nullptr;
462TransformD64Type TransformD64_4way = nullptr;
463TransformD64Type TransformD64_8way = nullptr;
464
465bool 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__))
552bool 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
562std::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
633{
634 sha256::Initialize(s);
635}
636
637CSHA256& 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
663void 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
687void 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}
A hasher class for SHA-256.
Definition: sha256.h:14
CSHA256 & Reset()
Definition: sha256.cpp:680
unsigned char buf[64]
Definition: sha256.h:17
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:663
uint64_t bytes
Definition: sha256.h:18
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:637
uint32_t s[8]
Definition: sha256.h:16
CSHA256()
Definition: sha256.cpp:632
static void WriteBE32(unsigned char *ptr, uint32_t x)
Definition: common.h:77
static void WriteBE64(unsigned char *ptr, uint64_t x)
Definition: common.h:83
static uint32_t ReadBE32(const unsigned char *ptr)
Definition: common.h:63
#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)
Internal SHA-256 implementation.
Definition: sha256.cpp:47
void Transform_8way(unsigned char *out, const unsigned char *in)
void Transform_2way(unsigned char *out, const unsigned char *in)
void Transform_4way(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:687
std::string SHA256AutoDetect()
Autodetect the best available SHA256 implementation.
Definition: sha256.cpp:562
assert(!tx.IsCoinBase())