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