Skip to content

Commit d0c9632

Browse files
committed
Specialized double sha256 for 64 byte inputs
1 parent 57f3463 commit d0c9632

File tree

4 files changed

+335
-1
lines changed

4 files changed

+335
-1
lines changed

src/bench/crypto_hash.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ static void SHA256_32b(benchmark::State& state)
5252
}
5353
}
5454

55+
static void SHA256D64_1024(benchmark::State& state)
56+
{
57+
std::vector<uint8_t> in(64 * 1024, 0);
58+
while (state.KeepRunning()) {
59+
SHA256D64(in.data(), in.data(), 1024);
60+
}
61+
}
62+
5563
static void SHA512(benchmark::State& state)
5664
{
5765
uint8_t hash[CSHA512::OUTPUT_SIZE];
@@ -94,5 +102,6 @@ BENCHMARK(SHA512, 330);
94102

95103
BENCHMARK(SHA256_32b, 4700 * 1000);
96104
BENCHMARK(SipHash_32b, 40 * 1000 * 1000);
105+
BENCHMARK(SHA256D64_1024, 7400);
97106
BENCHMARK(FastRandom_32bit, 110 * 1000 * 1000);
98107
BENCHMARK(FastRandom_1bit, 440 * 1000 * 1000);

src/crypto/sha256.cpp

Lines changed: 303 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,300 @@ void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
141141
}
142142
}
143143

144+
void TransformD64(unsigned char* out, const unsigned char* in)
145+
{
146+
// Transform 1
147+
uint32_t a = 0x6a09e667ul;
148+
uint32_t b = 0xbb67ae85ul;
149+
uint32_t c = 0x3c6ef372ul;
150+
uint32_t d = 0xa54ff53aul;
151+
uint32_t e = 0x510e527ful;
152+
uint32_t f = 0x9b05688cul;
153+
uint32_t g = 0x1f83d9abul;
154+
uint32_t h = 0x5be0cd19ul;
155+
156+
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
157+
158+
Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + (w0 = ReadBE32(in + 0)));
159+
Round(h, a, b, c, d, e, f, g, 0x71374491ul + (w1 = ReadBE32(in + 4)));
160+
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + (w2 = ReadBE32(in + 8)));
161+
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + (w3 = ReadBE32(in + 12)));
162+
Round(e, f, g, h, a, b, c, d, 0x3956c25bul + (w4 = ReadBE32(in + 16)));
163+
Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + (w5 = ReadBE32(in + 20)));
164+
Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + (w6 = ReadBE32(in + 24)));
165+
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + (w7 = ReadBE32(in + 28)));
166+
Round(a, b, c, d, e, f, g, h, 0xd807aa98ul + (w8 = ReadBE32(in + 32)));
167+
Round(h, a, b, c, d, e, f, g, 0x12835b01ul + (w9 = ReadBE32(in + 36)));
168+
Round(g, h, a, b, c, d, e, f, 0x243185beul + (w10 = ReadBE32(in + 40)));
169+
Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul + (w11 = ReadBE32(in + 44)));
170+
Round(e, f, g, h, a, b, c, d, 0x72be5d74ul + (w12 = ReadBE32(in + 48)));
171+
Round(d, e, f, g, h, a, b, c, 0x80deb1feul + (w13 = ReadBE32(in + 52)));
172+
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul + (w14 = ReadBE32(in + 56)));
173+
Round(b, c, d, e, f, g, h, a, 0xc19bf174ul + (w15 = ReadBE32(in + 60)));
174+
Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
175+
Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
176+
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
177+
Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
178+
Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + w13 + sigma0(w5)));
179+
Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
180+
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
181+
Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
182+
Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
183+
Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
184+
Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
185+
Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
186+
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
187+
Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
188+
Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
189+
Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
190+
Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
191+
Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
192+
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
193+
Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
194+
Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
195+
Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
196+
Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
197+
Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
198+
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
199+
Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
200+
Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
201+
Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
202+
Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
203+
Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
204+
Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
205+
Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
206+
Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
207+
Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
208+
Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
209+
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
210+
Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
211+
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
212+
Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
213+
Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
214+
Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
215+
Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
216+
Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
217+
Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
218+
Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
219+
Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
220+
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
221+
Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
222+
223+
a += 0x6a09e667ul;
224+
b += 0xbb67ae85ul;
225+
c += 0x3c6ef372ul;
226+
d += 0xa54ff53aul;
227+
e += 0x510e527ful;
228+
f += 0x9b05688cul;
229+
g += 0x1f83d9abul;
230+
h += 0x5be0cd19ul;
231+
232+
uint32_t t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h;
233+
234+
// Transform 2
235+
Round(a, b, c, d, e, f, g, h, 0xc28a2f98ul);
236+
Round(h, a, b, c, d, e, f, g, 0x71374491ul);
237+
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful);
238+
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul);
239+
Round(e, f, g, h, a, b, c, d, 0x3956c25bul);
240+
Round(d, e, f, g, h, a, b, c, 0x59f111f1ul);
241+
Round(c, d, e, f, g, h, a, b, 0x923f82a4ul);
242+
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul);
243+
Round(a, b, c, d, e, f, g, h, 0xd807aa98ul);
244+
Round(h, a, b, c, d, e, f, g, 0x12835b01ul);
245+
Round(g, h, a, b, c, d, e, f, 0x243185beul);
246+
Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul);
247+
Round(e, f, g, h, a, b, c, d, 0x72be5d74ul);
248+
Round(d, e, f, g, h, a, b, c, 0x80deb1feul);
249+
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul);
250+
Round(b, c, d, e, f, g, h, a, 0xc19bf374ul);
251+
Round(a, b, c, d, e, f, g, h, 0x649b69c1ul);
252+
Round(h, a, b, c, d, e, f, g, 0xf0fe4786ul);
253+
Round(g, h, a, b, c, d, e, f, 0x0fe1edc6ul);
254+
Round(f, g, h, a, b, c, d, e, 0x240cf254ul);
255+
Round(e, f, g, h, a, b, c, d, 0x4fe9346ful);
256+
Round(d, e, f, g, h, a, b, c, 0x6cc984beul);
257+
Round(c, d, e, f, g, h, a, b, 0x61b9411eul);
258+
Round(b, c, d, e, f, g, h, a, 0x16f988faul);
259+
Round(a, b, c, d, e, f, g, h, 0xf2c65152ul);
260+
Round(h, a, b, c, d, e, f, g, 0xa88e5a6dul);
261+
Round(g, h, a, b, c, d, e, f, 0xb019fc65ul);
262+
Round(f, g, h, a, b, c, d, e, 0xb9d99ec7ul);
263+
Round(e, f, g, h, a, b, c, d, 0x9a1231c3ul);
264+
Round(d, e, f, g, h, a, b, c, 0xe70eeaa0ul);
265+
Round(c, d, e, f, g, h, a, b, 0xfdb1232bul);
266+
Round(b, c, d, e, f, g, h, a, 0xc7353eb0ul);
267+
Round(a, b, c, d, e, f, g, h, 0x3069bad5ul);
268+
Round(h, a, b, c, d, e, f, g, 0xcb976d5ful);
269+
Round(g, h, a, b, c, d, e, f, 0x5a0f118ful);
270+
Round(f, g, h, a, b, c, d, e, 0xdc1eeefdul);
271+
Round(e, f, g, h, a, b, c, d, 0x0a35b689ul);
272+
Round(d, e, f, g, h, a, b, c, 0xde0b7a04ul);
273+
Round(c, d, e, f, g, h, a, b, 0x58f4ca9dul);
274+
Round(b, c, d, e, f, g, h, a, 0xe15d5b16ul);
275+
Round(a, b, c, d, e, f, g, h, 0x007f3e86ul);
276+
Round(h, a, b, c, d, e, f, g, 0x37088980ul);
277+
Round(g, h, a, b, c, d, e, f, 0xa507ea32ul);
278+
Round(f, g, h, a, b, c, d, e, 0x6fab9537ul);
279+
Round(e, f, g, h, a, b, c, d, 0x17406110ul);
280+
Round(d, e, f, g, h, a, b, c, 0x0d8cd6f1ul);
281+
Round(c, d, e, f, g, h, a, b, 0xcdaa3b6dul);
282+
Round(b, c, d, e, f, g, h, a, 0xc0bbbe37ul);
283+
Round(a, b, c, d, e, f, g, h, 0x83613bdaul);
284+
Round(h, a, b, c, d, e, f, g, 0xdb48a363ul);
285+
Round(g, h, a, b, c, d, e, f, 0x0b02e931ul);
286+
Round(f, g, h, a, b, c, d, e, 0x6fd15ca7ul);
287+
Round(e, f, g, h, a, b, c, d, 0x521afacaul);
288+
Round(d, e, f, g, h, a, b, c, 0x31338431ul);
289+
Round(c, d, e, f, g, h, a, b, 0x6ed41a95ul);
290+
Round(b, c, d, e, f, g, h, a, 0x6d437890ul);
291+
Round(a, b, c, d, e, f, g, h, 0xc39c91f2ul);
292+
Round(h, a, b, c, d, e, f, g, 0x9eccabbdul);
293+
Round(g, h, a, b, c, d, e, f, 0xb5c9a0e6ul);
294+
Round(f, g, h, a, b, c, d, e, 0x532fb63cul);
295+
Round(e, f, g, h, a, b, c, d, 0xd2c741c6ul);
296+
Round(d, e, f, g, h, a, b, c, 0x07237ea3ul);
297+
Round(c, d, e, f, g, h, a, b, 0xa4954b68ul);
298+
Round(b, c, d, e, f, g, h, a, 0x4c191d76ul);
299+
300+
w0 = t0 + a;
301+
w1 = t1 + b;
302+
w2 = t2 + c;
303+
w3 = t3 + d;
304+
w4 = t4 + e;
305+
w5 = t5 + f;
306+
w6 = t6 + g;
307+
w7 = t7 + h;
308+
309+
// Transform 3
310+
a = 0x6a09e667ul;
311+
b = 0xbb67ae85ul;
312+
c = 0x3c6ef372ul;
313+
d = 0xa54ff53aul;
314+
e = 0x510e527ful;
315+
f = 0x9b05688cul;
316+
g = 0x1f83d9abul;
317+
h = 0x5be0cd19ul;
318+
319+
Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + w0);
320+
Round(h, a, b, c, d, e, f, g, 0x71374491ul + w1);
321+
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + w2);
322+
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + w3);
323+
Round(e, f, g, h, a, b, c, d, 0x3956c25bul + w4);
324+
Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + w5);
325+
Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + w6);
326+
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + w7);
327+
Round(a, b, c, d, e, f, g, h, 0x5807aa98ul);
328+
Round(h, a, b, c, d, e, f, g, 0x12835b01ul);
329+
Round(g, h, a, b, c, d, e, f, 0x243185beul);
330+
Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul);
331+
Round(e, f, g, h, a, b, c, d, 0x72be5d74ul);
332+
Round(d, e, f, g, h, a, b, c, 0x80deb1feul);
333+
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul);
334+
Round(b, c, d, e, f, g, h, a, 0xc19bf274ul);
335+
Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma0(w1)));
336+
Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += 0xa00000ul + sigma0(w2)));
337+
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + sigma0(w3)));
338+
Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + sigma0(w4)));
339+
Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + sigma0(w5)));
340+
Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + sigma0(w6)));
341+
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + 0x100ul + sigma0(w7)));
342+
Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + 0x11002000ul));
343+
Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 = 0x80000000ul + sigma1(w6) + w1));
344+
Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 = sigma1(w7) + w2));
345+
Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 = sigma1(w8) + w3));
346+
Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 = sigma1(w9) + w4));
347+
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 = sigma1(w10) + w5));
348+
Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 = sigma1(w11) + w6));
349+
Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 = sigma1(w12) + w7 + 0x400022ul));
350+
Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 = 0x100ul + sigma1(w13) + w8 + sigma0(w0)));
351+
Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
352+
Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
353+
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
354+
Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
355+
Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
356+
Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
357+
Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
358+
Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
359+
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
360+
Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
361+
Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
362+
Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
363+
Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
364+
Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
365+
Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
366+
Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
367+
Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
368+
Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
369+
Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
370+
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
371+
Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
372+
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
373+
Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
374+
Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
375+
Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
376+
Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
377+
Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
378+
Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
379+
Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
380+
Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
381+
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
382+
Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
383+
384+
// Output
385+
WriteBE32(out + 0, a + 0x6a09e667ul);
386+
WriteBE32(out + 4, b + 0xbb67ae85ul);
387+
WriteBE32(out + 8, c + 0x3c6ef372ul);
388+
WriteBE32(out + 12, d + 0xa54ff53aul);
389+
WriteBE32(out + 16, e + 0x510e527ful);
390+
WriteBE32(out + 20, f + 0x9b05688cul);
391+
WriteBE32(out + 24, g + 0x1f83d9abul);
392+
WriteBE32(out + 28, h + 0x5be0cd19ul);
393+
}
394+
144395
} // namespace sha256
145396

146397
typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t);
398+
typedef void (*TransformD64Type)(unsigned char*, const unsigned char*);
399+
400+
template<TransformType tr>
401+
void TransformD64Wrapper(unsigned char* out, const unsigned char* in)
402+
{
403+
uint32_t s[8];
404+
static const unsigned char padding1[64] = {
405+
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
406+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
407+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
408+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0
409+
};
410+
unsigned char buffer2[64] = {
411+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
412+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
413+
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
414+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
415+
};
416+
sha256::Initialize(s);
417+
tr(s, in, 1);
418+
tr(s, padding1, 1);
419+
WriteBE32(buffer2 + 0, s[0]);
420+
WriteBE32(buffer2 + 4, s[1]);
421+
WriteBE32(buffer2 + 8, s[2]);
422+
WriteBE32(buffer2 + 12, s[3]);
423+
WriteBE32(buffer2 + 16, s[4]);
424+
WriteBE32(buffer2 + 20, s[5]);
425+
WriteBE32(buffer2 + 24, s[6]);
426+
WriteBE32(buffer2 + 28, s[7]);
427+
sha256::Initialize(s);
428+
tr(s, buffer2, 1);
429+
WriteBE32(out + 0, s[0]);
430+
WriteBE32(out + 4, s[1]);
431+
WriteBE32(out + 8, s[2]);
432+
WriteBE32(out + 12, s[3]);
433+
WriteBE32(out + 16, s[4]);
434+
WriteBE32(out + 20, s[5]);
435+
WriteBE32(out + 24, s[6]);
436+
WriteBE32(out + 28, s[7]);
437+
}
147438

148439
bool SelfTest(TransformType tr) {
149440
static const unsigned char in1[65] = {0, 0x80};
@@ -173,7 +464,7 @@ bool SelfTest(TransformType tr) {
173464
}
174465

175466
TransformType Transform = sha256::Transform;
176-
467+
TransformD64Type TransformD64 = sha256::TransformD64;
177468
} // namespace
178469

179470
std::string SHA256AutoDetect()
@@ -182,6 +473,7 @@ std::string SHA256AutoDetect()
182473
uint32_t eax, ebx, ecx, edx;
183474
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx >> 19) & 1) {
184475
Transform = sha256_sse4::Transform;
476+
TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>;
185477
assert(SelfTest(Transform));
186478
return "sse4";
187479
}
@@ -247,3 +539,13 @@ CSHA256& CSHA256::Reset()
247539
sha256::Initialize(s);
248540
return *this;
249541
}
542+
543+
void SHA256D64(unsigned char* out, const unsigned char* in, size_t blocks)
544+
{
545+
while (blocks) {
546+
TransformD64(out, in);
547+
out += 32;
548+
in += 64;
549+
--blocks;
550+
}
551+
}

src/crypto/sha256.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,11 @@ class CSHA256
3131
*/
3232
std::string SHA256AutoDetect();
3333

34+
/** Compute multiple double-SHA256's of 64-byte blobs.
35+
* output: pointer to a blocks*32 byte output buffer
36+
* input: pointer to a blocks*64 byte input buffer
37+
* blocks: the number of hashes to compute.
38+
*/
39+
void SHA256D64(unsigned char* output, const unsigned char* input, size_t blocks);
40+
3441
#endif // BITCOIN_CRYPTO_SHA256_H

src/test/crypto_tests.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,4 +546,20 @@ BOOST_AUTO_TEST_CASE(countbits_tests)
546546
}
547547
}
548548

549+
BOOST_AUTO_TEST_CASE(sha256d64)
550+
{
551+
for (int i = 0; i <= 32; ++i) {
552+
unsigned char in[64 * 32];
553+
unsigned char out1[32 * 32], out2[32 * 32];
554+
for (int j = 0; j < 64 * i; ++j) {
555+
in[j] = InsecureRandBits(8);
556+
}
557+
for (int j = 0; j < i; ++j) {
558+
CHash256().Write(in + 64 * j, 64).Finalize(out1 + 32 * j);
559+
}
560+
SHA256D64(out2, in, i);
561+
BOOST_CHECK(memcmp(out1, out2, 32 * i) == 0);
562+
}
563+
}
564+
549565
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)