fuzz coverage

Coverage Report

Created: 2026-04-24 13:48

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