solana_ed25519_sha512/
lib.rs

1use core::mem::MaybeUninit;
2
3#[inline(always)]
4const fn rotr(x: u64, n: u32) -> u64 {
5    (x >> n) | (x << (64 - n))
6}
7
8#[inline(always)]
9const fn gamma0(x: u64) -> u64 {
10    rotr(x, 1) ^ rotr(x, 8) ^ (x >> 7)
11}
12
13#[inline(always)]
14const fn gamma1(x: u64) -> u64 {
15    rotr(x, 19) ^ rotr(x, 61) ^ (x >> 6)
16}
17
18#[inline(always)]
19const fn ch(x: u64, y: u64, z: u64) -> u64 {
20    (x & y) ^ (!x & z)
21}
22
23#[inline(always)]
24const fn maj(x: u64, y: u64, z: u64) -> u64 {
25    (x & y) ^ (x & z) ^ (y & z)
26}
27
28#[inline(always)]
29const fn sigma0(x: u64) -> u64 {
30    rotr(x, 28) ^ rotr(x, 34) ^ rotr(x, 39)
31}
32
33#[inline(always)]
34const fn sigma1(x: u64) -> u64 {
35    rotr(x, 14) ^ rotr(x, 18) ^ rotr(x, 41)
36}
37
38#[inline(always)]
39pub fn hash(r: &[u8; 32], pubkey: &[u8; 32], digest: &[u8; 32]) -> [u8; 64] {
40    let mut words = MaybeUninit::<[u64; 80]>::uninit();
41    let w = unsafe { words.assume_init_mut() };
42    w[0] = u64::from_be_bytes([r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]]);
43    w[1] = u64::from_be_bytes([r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]]);
44    w[2] = u64::from_be_bytes([r[16], r[17], r[18], r[19], r[20], r[21], r[22], r[23]]);
45    w[3] = u64::from_be_bytes([r[24], r[25], r[26], r[27], r[28], r[29], r[30], r[31]]);
46    w[4] = u64::from_be_bytes([
47        pubkey[0], pubkey[1], pubkey[2], pubkey[3], pubkey[4], pubkey[5], pubkey[6], pubkey[7],
48    ]);
49    w[5] = u64::from_be_bytes([
50        pubkey[8], pubkey[9], pubkey[10], pubkey[11], pubkey[12], pubkey[13], pubkey[14],
51        pubkey[15],
52    ]);
53    w[6] = u64::from_be_bytes([
54        pubkey[16], pubkey[17], pubkey[18], pubkey[19], pubkey[20], pubkey[21], pubkey[22],
55        pubkey[23],
56    ]);
57    w[7] = u64::from_be_bytes([
58        pubkey[24], pubkey[25], pubkey[26], pubkey[27], pubkey[28], pubkey[29], pubkey[30],
59        pubkey[31],
60    ]);
61    w[8] = u64::from_be_bytes([
62        digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7],
63    ]);
64    w[9] = u64::from_be_bytes([
65        digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14],
66        digest[15],
67    ]);
68    w[10] = u64::from_be_bytes([
69        digest[16], digest[17], digest[18], digest[19], digest[20], digest[21], digest[22],
70        digest[23],
71    ]);
72    w[11] = u64::from_be_bytes([
73        digest[24], digest[25], digest[26], digest[27], digest[28], digest[29], digest[30],
74        digest[31],
75    ]);
76    w[12] = 0x8000000000000000; // Padding bit
77    w[13] = 0x0000000000000000; // Explicity set this
78    w[14] = 0x0000000000000000; // And this
79    w[15] = 0x0000000000000300;
80    for i in 16..80 {
81        w[i] = w[i - 16]
82            .wrapping_add(gamma0(w[i - 15]))
83            .wrapping_add(w[i - 7])
84            .wrapping_add(gamma1(w[i - 2]));
85    }
86
87    // Round 0
88    let mut t1 = 0x5be0cd19137e2179u64
89        .wrapping_add(sigma1(0x510e527fade682d1u64))
90        .wrapping_add(ch(
91            0x510e527fade682d1u64,
92            0x9b05688c2b3e6c1fu64,
93            0x1f83d9abfb41bd6bu64,
94        ))
95        .wrapping_add(0x428A2F98D728AE22)
96        .wrapping_add(w[0]);
97    let mut t2 = 0x4334C1BEA164F555;
98    let mut h = 0x1f83d9abfb41bd6bu64;
99    let mut g = 0x9b05688c2b3e6c1fu64;
100    let mut f = 0x510e527fade682d1u64;
101    let mut e = 0xa54ff53a5f1d36f1u64.wrapping_add(t1);
102    let mut d = 0x3c6ef372fe94f82bu64;
103    let mut c = 0xbb67ae8584caa73bu64;
104    let mut b = 0x6a09e667f3bcc908u64;
105    let mut a = t1.wrapping_add(t2);
106
107    // Round 1
108    t1 = h
109        .wrapping_add(sigma1(e))
110        .wrapping_add(ch(e, f, g))
111        .wrapping_add(0x7137449123EF65CD)
112        .wrapping_add(w[1]);
113    t2 = sigma0(a).wrapping_add(maj(a, b, c));
114    h = g;
115    g = f;
116    f = e;
117    e = d.wrapping_add(t1);
118    d = c;
119    c = b;
120    b = a;
121    a = t1.wrapping_add(t2);
122
123    // Round 2
124    t1 = h
125        .wrapping_add(sigma1(e))
126        .wrapping_add(ch(e, f, g))
127        .wrapping_add(0xB5C0FBCFEC4D3B2F)
128        .wrapping_add(w[2]);
129    t2 = sigma0(a).wrapping_add(maj(a, b, c));
130    h = g;
131    g = f;
132    f = e;
133    e = d.wrapping_add(t1);
134    d = c;
135    c = b;
136    b = a;
137    a = t1.wrapping_add(t2);
138
139    // Round 3
140    t1 = h
141        .wrapping_add(sigma1(e))
142        .wrapping_add(ch(e, f, g))
143        .wrapping_add(0xE9B5DBA58189DBBC)
144        .wrapping_add(w[3]);
145    t2 = sigma0(a).wrapping_add(maj(a, b, c));
146    h = g;
147    g = f;
148    f = e;
149    e = d.wrapping_add(t1);
150    d = c;
151    c = b;
152    b = a;
153    a = t1.wrapping_add(t2);
154
155    // Round 4
156    t1 = h
157        .wrapping_add(sigma1(e))
158        .wrapping_add(ch(e, f, g))
159        .wrapping_add(0x3956C25BF348B538)
160        .wrapping_add(w[4]);
161    t2 = sigma0(a).wrapping_add(maj(a, b, c));
162    h = g;
163    g = f;
164    f = e;
165    e = d.wrapping_add(t1);
166    d = c;
167    c = b;
168    b = a;
169    a = t1.wrapping_add(t2);
170
171    // Round 5
172    t1 = h
173        .wrapping_add(sigma1(e))
174        .wrapping_add(ch(e, f, g))
175        .wrapping_add(0x59F111F1B605D019)
176        .wrapping_add(w[5]);
177    t2 = sigma0(a).wrapping_add(maj(a, b, c));
178    h = g;
179    g = f;
180    f = e;
181    e = d.wrapping_add(t1);
182    d = c;
183    c = b;
184    b = a;
185    a = t1.wrapping_add(t2);
186
187    // Round 6
188    t1 = h
189        .wrapping_add(sigma1(e))
190        .wrapping_add(ch(e, f, g))
191        .wrapping_add(0x923F82A4AF194F9B)
192        .wrapping_add(w[6]);
193    t2 = sigma0(a).wrapping_add(maj(a, b, c));
194    h = g;
195    g = f;
196    f = e;
197    e = d.wrapping_add(t1);
198    d = c;
199    c = b;
200    b = a;
201    a = t1.wrapping_add(t2);
202
203    // Round 7
204    t1 = h
205        .wrapping_add(sigma1(e))
206        .wrapping_add(ch(e, f, g))
207        .wrapping_add(0xAB1C5ED5DA6D8118)
208        .wrapping_add(w[7]);
209    t2 = sigma0(a).wrapping_add(maj(a, b, c));
210    h = g;
211    g = f;
212    f = e;
213    e = d.wrapping_add(t1);
214    d = c;
215    c = b;
216    b = a;
217    a = t1.wrapping_add(t2);
218
219    // Round 8
220    t1 = h
221        .wrapping_add(sigma1(e))
222        .wrapping_add(ch(e, f, g))
223        .wrapping_add(0xD807AA98A3030242)
224        .wrapping_add(w[8]);
225    t2 = sigma0(a).wrapping_add(maj(a, b, c));
226    h = g;
227    g = f;
228    f = e;
229    e = d.wrapping_add(t1);
230    d = c;
231    c = b;
232    b = a;
233    a = t1.wrapping_add(t2);
234
235    // Round 9
236    t1 = h
237        .wrapping_add(sigma1(e))
238        .wrapping_add(ch(e, f, g))
239        .wrapping_add(0x12835B0145706FBE)
240        .wrapping_add(w[9]);
241    t2 = sigma0(a).wrapping_add(maj(a, b, c));
242    h = g;
243    g = f;
244    f = e;
245    e = d.wrapping_add(t1);
246    d = c;
247    c = b;
248    b = a;
249    a = t1.wrapping_add(t2);
250
251    // Round 10
252    t1 = h
253        .wrapping_add(sigma1(e))
254        .wrapping_add(ch(e, f, g))
255        .wrapping_add(0x243185BE4EE4B28C)
256        .wrapping_add(w[10]);
257    t2 = sigma0(a).wrapping_add(maj(a, b, c));
258    h = g;
259    g = f;
260    f = e;
261    e = d.wrapping_add(t1);
262    d = c;
263    c = b;
264    b = a;
265    a = t1.wrapping_add(t2);
266
267    // Round 11
268    t1 = h
269        .wrapping_add(sigma1(e))
270        .wrapping_add(ch(e, f, g))
271        .wrapping_add(0x550C7DC3D5FFB4E2)
272        .wrapping_add(w[11]);
273    t2 = sigma0(a).wrapping_add(maj(a, b, c));
274    h = g;
275    g = f;
276    f = e;
277    e = d.wrapping_add(t1);
278    d = c;
279    c = b;
280    b = a;
281    a = t1.wrapping_add(t2);
282
283    // Round 12
284    t1 = h
285        .wrapping_add(sigma1(e))
286        .wrapping_add(ch(e, f, g))
287        .wrapping_add(0x72BE5D74F27B896F)
288        .wrapping_add(w[12]);
289    t2 = sigma0(a).wrapping_add(maj(a, b, c));
290    h = g;
291    g = f;
292    f = e;
293    e = d.wrapping_add(t1);
294    d = c;
295    c = b;
296    b = a;
297    a = t1.wrapping_add(t2);
298
299    // Round 13
300    t1 = h
301        .wrapping_add(sigma1(e))
302        .wrapping_add(ch(e, f, g))
303        .wrapping_add(0x80DEB1FE3B1696B1)
304        .wrapping_add(w[13]);
305    t2 = sigma0(a).wrapping_add(maj(a, b, c));
306    h = g;
307    g = f;
308    f = e;
309    e = d.wrapping_add(t1);
310    d = c;
311    c = b;
312    b = a;
313    a = t1.wrapping_add(t2);
314
315    // Round 14
316    t1 = h
317        .wrapping_add(sigma1(e))
318        .wrapping_add(ch(e, f, g))
319        .wrapping_add(0x9BDC06A725C71235)
320        .wrapping_add(w[14]);
321    t2 = sigma0(a).wrapping_add(maj(a, b, c));
322    h = g;
323    g = f;
324    f = e;
325    e = d.wrapping_add(t1);
326    d = c;
327    c = b;
328    b = a;
329    a = t1.wrapping_add(t2);
330
331    // Round 15
332    t1 = h
333        .wrapping_add(sigma1(e))
334        .wrapping_add(ch(e, f, g))
335        .wrapping_add(0xC19BF174CF692694)
336        .wrapping_add(w[15]);
337    t2 = sigma0(a).wrapping_add(maj(a, b, c));
338    h = g;
339    g = f;
340    f = e;
341    e = d.wrapping_add(t1);
342    d = c;
343    c = b;
344    b = a;
345    a = t1.wrapping_add(t2);
346
347    // Round 16
348    t1 = h
349        .wrapping_add(sigma1(e))
350        .wrapping_add(ch(e, f, g))
351        .wrapping_add(0xE49B69C19EF14AD2)
352        .wrapping_add(w[16]);
353    t2 = sigma0(a).wrapping_add(maj(a, b, c));
354    h = g;
355    g = f;
356    f = e;
357    e = d.wrapping_add(t1);
358    d = c;
359    c = b;
360    b = a;
361    a = t1.wrapping_add(t2);
362
363    // Round 17
364    t1 = h
365        .wrapping_add(sigma1(e))
366        .wrapping_add(ch(e, f, g))
367        .wrapping_add(0xEFBE4786384F25E3)
368        .wrapping_add(w[17]);
369    t2 = sigma0(a).wrapping_add(maj(a, b, c));
370    h = g;
371    g = f;
372    f = e;
373    e = d.wrapping_add(t1);
374    d = c;
375    c = b;
376    b = a;
377    a = t1.wrapping_add(t2);
378
379    // Round 18
380    t1 = h
381        .wrapping_add(sigma1(e))
382        .wrapping_add(ch(e, f, g))
383        .wrapping_add(0x0FC19DC68B8CD5B5)
384        .wrapping_add(w[18]);
385    t2 = sigma0(a).wrapping_add(maj(a, b, c));
386    h = g;
387    g = f;
388    f = e;
389    e = d.wrapping_add(t1);
390    d = c;
391    c = b;
392    b = a;
393    a = t1.wrapping_add(t2);
394
395    // Round 19
396    t1 = h
397        .wrapping_add(sigma1(e))
398        .wrapping_add(ch(e, f, g))
399        .wrapping_add(0x240CA1CC77AC9C65)
400        .wrapping_add(w[19]);
401    t2 = sigma0(a).wrapping_add(maj(a, b, c));
402    h = g;
403    g = f;
404    f = e;
405    e = d.wrapping_add(t1);
406    d = c;
407    c = b;
408    b = a;
409    a = t1.wrapping_add(t2);
410
411    // Round 20
412    t1 = h
413        .wrapping_add(sigma1(e))
414        .wrapping_add(ch(e, f, g))
415        .wrapping_add(0x2DE92C6F592B0275)
416        .wrapping_add(w[20]);
417    t2 = sigma0(a).wrapping_add(maj(a, b, c));
418    h = g;
419    g = f;
420    f = e;
421    e = d.wrapping_add(t1);
422    d = c;
423    c = b;
424    b = a;
425    a = t1.wrapping_add(t2);
426
427    // Round 21
428    t1 = h
429        .wrapping_add(sigma1(e))
430        .wrapping_add(ch(e, f, g))
431        .wrapping_add(0x4A7484AA6EA6E483)
432        .wrapping_add(w[21]);
433    t2 = sigma0(a).wrapping_add(maj(a, b, c));
434    h = g;
435    g = f;
436    f = e;
437    e = d.wrapping_add(t1);
438    d = c;
439    c = b;
440    b = a;
441    a = t1.wrapping_add(t2);
442
443    // Round 22
444    t1 = h
445        .wrapping_add(sigma1(e))
446        .wrapping_add(ch(e, f, g))
447        .wrapping_add(0x5CB0A9DCBD41FBD4)
448        .wrapping_add(w[22]);
449    t2 = sigma0(a).wrapping_add(maj(a, b, c));
450    h = g;
451    g = f;
452    f = e;
453    e = d.wrapping_add(t1);
454    d = c;
455    c = b;
456    b = a;
457    a = t1.wrapping_add(t2);
458
459    // Round 23
460    t1 = h
461        .wrapping_add(sigma1(e))
462        .wrapping_add(ch(e, f, g))
463        .wrapping_add(0x76F988DA831153B5)
464        .wrapping_add(w[23]);
465    t2 = sigma0(a).wrapping_add(maj(a, b, c));
466    h = g;
467    g = f;
468    f = e;
469    e = d.wrapping_add(t1);
470    d = c;
471    c = b;
472    b = a;
473    a = t1.wrapping_add(t2);
474
475    // Round 24
476    t1 = h
477        .wrapping_add(sigma1(e))
478        .wrapping_add(ch(e, f, g))
479        .wrapping_add(0x983E5152EE66DFAB)
480        .wrapping_add(w[24]);
481    t2 = sigma0(a).wrapping_add(maj(a, b, c));
482    h = g;
483    g = f;
484    f = e;
485    e = d.wrapping_add(t1);
486    d = c;
487    c = b;
488    b = a;
489    a = t1.wrapping_add(t2);
490
491    // Round 25
492    t1 = h
493        .wrapping_add(sigma1(e))
494        .wrapping_add(ch(e, f, g))
495        .wrapping_add(0xA831C66D2DB43210)
496        .wrapping_add(w[25]);
497    t2 = sigma0(a).wrapping_add(maj(a, b, c));
498    h = g;
499    g = f;
500    f = e;
501    e = d.wrapping_add(t1);
502    d = c;
503    c = b;
504    b = a;
505    a = t1.wrapping_add(t2);
506
507    // Round 26
508    t1 = h
509        .wrapping_add(sigma1(e))
510        .wrapping_add(ch(e, f, g))
511        .wrapping_add(0xB00327C898FB213F)
512        .wrapping_add(w[26]);
513    t2 = sigma0(a).wrapping_add(maj(a, b, c));
514    h = g;
515    g = f;
516    f = e;
517    e = d.wrapping_add(t1);
518    d = c;
519    c = b;
520    b = a;
521    a = t1.wrapping_add(t2);
522
523    // Round 27
524    t1 = h
525        .wrapping_add(sigma1(e))
526        .wrapping_add(ch(e, f, g))
527        .wrapping_add(0xBF597FC7BEEF0EE4)
528        .wrapping_add(w[27]);
529    t2 = sigma0(a).wrapping_add(maj(a, b, c));
530    h = g;
531    g = f;
532    f = e;
533    e = d.wrapping_add(t1);
534    d = c;
535    c = b;
536    b = a;
537    a = t1.wrapping_add(t2);
538
539    // Round 28
540    t1 = h
541        .wrapping_add(sigma1(e))
542        .wrapping_add(ch(e, f, g))
543        .wrapping_add(0xC6E00BF33DA88FC2)
544        .wrapping_add(w[28]);
545    t2 = sigma0(a).wrapping_add(maj(a, b, c));
546    h = g;
547    g = f;
548    f = e;
549    e = d.wrapping_add(t1);
550    d = c;
551    c = b;
552    b = a;
553    a = t1.wrapping_add(t2);
554
555    // Round 29
556    t1 = h
557        .wrapping_add(sigma1(e))
558        .wrapping_add(ch(e, f, g))
559        .wrapping_add(0xD5A79147930AA725)
560        .wrapping_add(w[29]);
561    t2 = sigma0(a).wrapping_add(maj(a, b, c));
562    h = g;
563    g = f;
564    f = e;
565    e = d.wrapping_add(t1);
566    d = c;
567    c = b;
568    b = a;
569    a = t1.wrapping_add(t2);
570
571    // Round 30
572    t1 = h
573        .wrapping_add(sigma1(e))
574        .wrapping_add(ch(e, f, g))
575        .wrapping_add(0x06CA6351E003826F)
576        .wrapping_add(w[30]);
577    t2 = sigma0(a).wrapping_add(maj(a, b, c));
578    h = g;
579    g = f;
580    f = e;
581    e = d.wrapping_add(t1);
582    d = c;
583    c = b;
584    b = a;
585    a = t1.wrapping_add(t2);
586
587    // Round 31
588    t1 = h
589        .wrapping_add(sigma1(e))
590        .wrapping_add(ch(e, f, g))
591        .wrapping_add(0x142929670A0E6E70)
592        .wrapping_add(w[31]);
593    t2 = sigma0(a).wrapping_add(maj(a, b, c));
594    h = g;
595    g = f;
596    f = e;
597    e = d.wrapping_add(t1);
598    d = c;
599    c = b;
600    b = a;
601    a = t1.wrapping_add(t2);
602
603    // Round 32
604    t1 = h
605        .wrapping_add(sigma1(e))
606        .wrapping_add(ch(e, f, g))
607        .wrapping_add(0x27B70A8546D22FFC)
608        .wrapping_add(w[32]);
609    t2 = sigma0(a).wrapping_add(maj(a, b, c));
610    h = g;
611    g = f;
612    f = e;
613    e = d.wrapping_add(t1);
614    d = c;
615    c = b;
616    b = a;
617    a = t1.wrapping_add(t2);
618
619    // Round 33
620    t1 = h
621        .wrapping_add(sigma1(e))
622        .wrapping_add(ch(e, f, g))
623        .wrapping_add(0x2E1B21385C26C926)
624        .wrapping_add(w[33]);
625    t2 = sigma0(a).wrapping_add(maj(a, b, c));
626    h = g;
627    g = f;
628    f = e;
629    e = d.wrapping_add(t1);
630    d = c;
631    c = b;
632    b = a;
633    a = t1.wrapping_add(t2);
634
635    // Round 34
636    t1 = h
637        .wrapping_add(sigma1(e))
638        .wrapping_add(ch(e, f, g))
639        .wrapping_add(0x4D2C6DFC5AC42AED)
640        .wrapping_add(w[34]);
641    t2 = sigma0(a).wrapping_add(maj(a, b, c));
642    h = g;
643    g = f;
644    f = e;
645    e = d.wrapping_add(t1);
646    d = c;
647    c = b;
648    b = a;
649    a = t1.wrapping_add(t2);
650
651    // Round 35
652    t1 = h
653        .wrapping_add(sigma1(e))
654        .wrapping_add(ch(e, f, g))
655        .wrapping_add(0x53380D139D95B3DF)
656        .wrapping_add(w[35]);
657    t2 = sigma0(a).wrapping_add(maj(a, b, c));
658    h = g;
659    g = f;
660    f = e;
661    e = d.wrapping_add(t1);
662    d = c;
663    c = b;
664    b = a;
665    a = t1.wrapping_add(t2);
666
667    // Round 36
668    t1 = h
669        .wrapping_add(sigma1(e))
670        .wrapping_add(ch(e, f, g))
671        .wrapping_add(0x650A73548BAF63DE)
672        .wrapping_add(w[36]);
673    t2 = sigma0(a).wrapping_add(maj(a, b, c));
674    h = g;
675    g = f;
676    f = e;
677    e = d.wrapping_add(t1);
678    d = c;
679    c = b;
680    b = a;
681    a = t1.wrapping_add(t2);
682
683    // Round 37
684    t1 = h
685        .wrapping_add(sigma1(e))
686        .wrapping_add(ch(e, f, g))
687        .wrapping_add(0x766A0ABB3C77B2A8)
688        .wrapping_add(w[37]);
689    t2 = sigma0(a).wrapping_add(maj(a, b, c));
690    h = g;
691    g = f;
692    f = e;
693    e = d.wrapping_add(t1);
694    d = c;
695    c = b;
696    b = a;
697    a = t1.wrapping_add(t2);
698
699    // Round 38
700    t1 = h
701        .wrapping_add(sigma1(e))
702        .wrapping_add(ch(e, f, g))
703        .wrapping_add(0x81C2C92E47EDAEE6)
704        .wrapping_add(w[38]);
705    t2 = sigma0(a).wrapping_add(maj(a, b, c));
706    h = g;
707    g = f;
708    f = e;
709    e = d.wrapping_add(t1);
710    d = c;
711    c = b;
712    b = a;
713    a = t1.wrapping_add(t2);
714
715    // Round 39
716    t1 = h
717        .wrapping_add(sigma1(e))
718        .wrapping_add(ch(e, f, g))
719        .wrapping_add(0x92722C851482353B)
720        .wrapping_add(w[39]);
721    t2 = sigma0(a).wrapping_add(maj(a, b, c));
722    h = g;
723    g = f;
724    f = e;
725    e = d.wrapping_add(t1);
726    d = c;
727    c = b;
728    b = a;
729    a = t1.wrapping_add(t2);
730
731    // Round 40
732    t1 = h
733        .wrapping_add(sigma1(e))
734        .wrapping_add(ch(e, f, g))
735        .wrapping_add(0xA2BFE8A14CF10364)
736        .wrapping_add(w[40]);
737    t2 = sigma0(a).wrapping_add(maj(a, b, c));
738    h = g;
739    g = f;
740    f = e;
741    e = d.wrapping_add(t1);
742    d = c;
743    c = b;
744    b = a;
745    a = t1.wrapping_add(t2);
746
747    // Round 41
748    t1 = h
749        .wrapping_add(sigma1(e))
750        .wrapping_add(ch(e, f, g))
751        .wrapping_add(0xA81A664BBC423001)
752        .wrapping_add(w[41]);
753    t2 = sigma0(a).wrapping_add(maj(a, b, c));
754    h = g;
755    g = f;
756    f = e;
757    e = d.wrapping_add(t1);
758    d = c;
759    c = b;
760    b = a;
761    a = t1.wrapping_add(t2);
762
763    // Round 42
764    t1 = h
765        .wrapping_add(sigma1(e))
766        .wrapping_add(ch(e, f, g))
767        .wrapping_add(0xC24B8B70D0F89791)
768        .wrapping_add(w[42]);
769    t2 = sigma0(a).wrapping_add(maj(a, b, c));
770    h = g;
771    g = f;
772    f = e;
773    e = d.wrapping_add(t1);
774    d = c;
775    c = b;
776    b = a;
777    a = t1.wrapping_add(t2);
778
779    // Round 43
780    t1 = h
781        .wrapping_add(sigma1(e))
782        .wrapping_add(ch(e, f, g))
783        .wrapping_add(0xC76C51A30654BE30)
784        .wrapping_add(w[43]);
785    t2 = sigma0(a).wrapping_add(maj(a, b, c));
786    h = g;
787    g = f;
788    f = e;
789    e = d.wrapping_add(t1);
790    d = c;
791    c = b;
792    b = a;
793    a = t1.wrapping_add(t2);
794
795    // Round 44
796    t1 = h
797        .wrapping_add(sigma1(e))
798        .wrapping_add(ch(e, f, g))
799        .wrapping_add(0xD192E819D6EF5218)
800        .wrapping_add(w[44]);
801    t2 = sigma0(a).wrapping_add(maj(a, b, c));
802    h = g;
803    g = f;
804    f = e;
805    e = d.wrapping_add(t1);
806    d = c;
807    c = b;
808    b = a;
809    a = t1.wrapping_add(t2);
810
811    // Round 45
812    t1 = h
813        .wrapping_add(sigma1(e))
814        .wrapping_add(ch(e, f, g))
815        .wrapping_add(0xD69906245565A910)
816        .wrapping_add(w[45]);
817    t2 = sigma0(a).wrapping_add(maj(a, b, c));
818    h = g;
819    g = f;
820    f = e;
821    e = d.wrapping_add(t1);
822    d = c;
823    c = b;
824    b = a;
825    a = t1.wrapping_add(t2);
826
827    // Round 46
828    t1 = h
829        .wrapping_add(sigma1(e))
830        .wrapping_add(ch(e, f, g))
831        .wrapping_add(0xF40E35855771202A)
832        .wrapping_add(w[46]);
833    t2 = sigma0(a).wrapping_add(maj(a, b, c));
834    h = g;
835    g = f;
836    f = e;
837    e = d.wrapping_add(t1);
838    d = c;
839    c = b;
840    b = a;
841    a = t1.wrapping_add(t2);
842
843    // Round 47
844    t1 = h
845        .wrapping_add(sigma1(e))
846        .wrapping_add(ch(e, f, g))
847        .wrapping_add(0x106AA07032BBD1B8)
848        .wrapping_add(w[47]);
849    t2 = sigma0(a).wrapping_add(maj(a, b, c));
850    h = g;
851    g = f;
852    f = e;
853    e = d.wrapping_add(t1);
854    d = c;
855    c = b;
856    b = a;
857    a = t1.wrapping_add(t2);
858
859    // Round 48
860    t1 = h
861        .wrapping_add(sigma1(e))
862        .wrapping_add(ch(e, f, g))
863        .wrapping_add(0x19A4C116B8D2D0C8)
864        .wrapping_add(w[48]);
865    t2 = sigma0(a).wrapping_add(maj(a, b, c));
866    h = g;
867    g = f;
868    f = e;
869    e = d.wrapping_add(t1);
870    d = c;
871    c = b;
872    b = a;
873    a = t1.wrapping_add(t2);
874
875    // Round 49
876    t1 = h
877        .wrapping_add(sigma1(e))
878        .wrapping_add(ch(e, f, g))
879        .wrapping_add(0x1E376C085141AB53)
880        .wrapping_add(w[49]);
881    t2 = sigma0(a).wrapping_add(maj(a, b, c));
882    h = g;
883    g = f;
884    f = e;
885    e = d.wrapping_add(t1);
886    d = c;
887    c = b;
888    b = a;
889    a = t1.wrapping_add(t2);
890
891    // Round 50
892    t1 = h
893        .wrapping_add(sigma1(e))
894        .wrapping_add(ch(e, f, g))
895        .wrapping_add(0x2748774CDF8EEB99)
896        .wrapping_add(w[50]);
897    t2 = sigma0(a).wrapping_add(maj(a, b, c));
898    h = g;
899    g = f;
900    f = e;
901    e = d.wrapping_add(t1);
902    d = c;
903    c = b;
904    b = a;
905    a = t1.wrapping_add(t2);
906
907    // Round 51
908    t1 = h
909        .wrapping_add(sigma1(e))
910        .wrapping_add(ch(e, f, g))
911        .wrapping_add(0x34B0BCB5E19B48A8)
912        .wrapping_add(w[51]);
913    t2 = sigma0(a).wrapping_add(maj(a, b, c));
914    h = g;
915    g = f;
916    f = e;
917    e = d.wrapping_add(t1);
918    d = c;
919    c = b;
920    b = a;
921    a = t1.wrapping_add(t2);
922
923    // Round 52
924    t1 = h
925        .wrapping_add(sigma1(e))
926        .wrapping_add(ch(e, f, g))
927        .wrapping_add(0x391C0CB3C5C95A63)
928        .wrapping_add(w[52]);
929    t2 = sigma0(a).wrapping_add(maj(a, b, c));
930    h = g;
931    g = f;
932    f = e;
933    e = d.wrapping_add(t1);
934    d = c;
935    c = b;
936    b = a;
937    a = t1.wrapping_add(t2);
938
939    // Round 53
940    t1 = h
941        .wrapping_add(sigma1(e))
942        .wrapping_add(ch(e, f, g))
943        .wrapping_add(0x4ED8AA4AE3418ACB)
944        .wrapping_add(w[53]);
945    t2 = sigma0(a).wrapping_add(maj(a, b, c));
946    h = g;
947    g = f;
948    f = e;
949    e = d.wrapping_add(t1);
950    d = c;
951    c = b;
952    b = a;
953    a = t1.wrapping_add(t2);
954
955    // Round 54
956    t1 = h
957        .wrapping_add(sigma1(e))
958        .wrapping_add(ch(e, f, g))
959        .wrapping_add(0x5B9CCA4F7763E373)
960        .wrapping_add(w[54]);
961    t2 = sigma0(a).wrapping_add(maj(a, b, c));
962    h = g;
963    g = f;
964    f = e;
965    e = d.wrapping_add(t1);
966    d = c;
967    c = b;
968    b = a;
969    a = t1.wrapping_add(t2);
970
971    // Round 55
972    t1 = h
973        .wrapping_add(sigma1(e))
974        .wrapping_add(ch(e, f, g))
975        .wrapping_add(0x682E6FF3D6B2B8A3)
976        .wrapping_add(w[55]);
977    t2 = sigma0(a).wrapping_add(maj(a, b, c));
978    h = g;
979    g = f;
980    f = e;
981    e = d.wrapping_add(t1);
982    d = c;
983    c = b;
984    b = a;
985    a = t1.wrapping_add(t2);
986
987    // Round 56
988    t1 = h
989        .wrapping_add(sigma1(e))
990        .wrapping_add(ch(e, f, g))
991        .wrapping_add(0x748F82EE5DEFB2FC)
992        .wrapping_add(w[56]);
993    t2 = sigma0(a).wrapping_add(maj(a, b, c));
994    h = g;
995    g = f;
996    f = e;
997    e = d.wrapping_add(t1);
998    d = c;
999    c = b;
1000    b = a;
1001    a = t1.wrapping_add(t2);
1002
1003    // Round 57
1004    t1 = h
1005        .wrapping_add(sigma1(e))
1006        .wrapping_add(ch(e, f, g))
1007        .wrapping_add(0x78A5636F43172F60)
1008        .wrapping_add(w[57]);
1009    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1010    h = g;
1011    g = f;
1012    f = e;
1013    e = d.wrapping_add(t1);
1014    d = c;
1015    c = b;
1016    b = a;
1017    a = t1.wrapping_add(t2);
1018
1019    // Round 58
1020    t1 = h
1021        .wrapping_add(sigma1(e))
1022        .wrapping_add(ch(e, f, g))
1023        .wrapping_add(0x84C87814A1F0AB72)
1024        .wrapping_add(w[58]);
1025    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1026    h = g;
1027    g = f;
1028    f = e;
1029    e = d.wrapping_add(t1);
1030    d = c;
1031    c = b;
1032    b = a;
1033    a = t1.wrapping_add(t2);
1034
1035    // Round 59
1036    t1 = h
1037        .wrapping_add(sigma1(e))
1038        .wrapping_add(ch(e, f, g))
1039        .wrapping_add(0x8CC702081A6439EC)
1040        .wrapping_add(w[59]);
1041    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1042    h = g;
1043    g = f;
1044    f = e;
1045    e = d.wrapping_add(t1);
1046    d = c;
1047    c = b;
1048    b = a;
1049    a = t1.wrapping_add(t2);
1050
1051    // Round 60
1052    t1 = h
1053        .wrapping_add(sigma1(e))
1054        .wrapping_add(ch(e, f, g))
1055        .wrapping_add(0x90BEFFFA23631E28)
1056        .wrapping_add(w[60]);
1057    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1058    h = g;
1059    g = f;
1060    f = e;
1061    e = d.wrapping_add(t1);
1062    d = c;
1063    c = b;
1064    b = a;
1065    a = t1.wrapping_add(t2);
1066
1067    // Round 61
1068    t1 = h
1069        .wrapping_add(sigma1(e))
1070        .wrapping_add(ch(e, f, g))
1071        .wrapping_add(0xA4506CEBDE82BDE9)
1072        .wrapping_add(w[61]);
1073    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1074    h = g;
1075    g = f;
1076    f = e;
1077    e = d.wrapping_add(t1);
1078    d = c;
1079    c = b;
1080    b = a;
1081    a = t1.wrapping_add(t2);
1082
1083    // Round 62
1084    t1 = h
1085        .wrapping_add(sigma1(e))
1086        .wrapping_add(ch(e, f, g))
1087        .wrapping_add(0xBEF9A3F7B2C67915)
1088        .wrapping_add(w[62]);
1089    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1090    h = g;
1091    g = f;
1092    f = e;
1093    e = d.wrapping_add(t1);
1094    d = c;
1095    c = b;
1096    b = a;
1097    a = t1.wrapping_add(t2);
1098
1099    // Round 63
1100    t1 = h
1101        .wrapping_add(sigma1(e))
1102        .wrapping_add(ch(e, f, g))
1103        .wrapping_add(0xC67178F2E372532B)
1104        .wrapping_add(w[63]);
1105    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1106    h = g;
1107    g = f;
1108    f = e;
1109    e = d.wrapping_add(t1);
1110    d = c;
1111    c = b;
1112    b = a;
1113    a = t1.wrapping_add(t2);
1114
1115    // Round 64
1116    t1 = h
1117        .wrapping_add(sigma1(e))
1118        .wrapping_add(ch(e, f, g))
1119        .wrapping_add(0xCA273ECEEA26619C)
1120        .wrapping_add(w[64]);
1121    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1122    h = g;
1123    g = f;
1124    f = e;
1125    e = d.wrapping_add(t1);
1126    d = c;
1127    c = b;
1128    b = a;
1129    a = t1.wrapping_add(t2);
1130
1131    // Round 65
1132    t1 = h
1133        .wrapping_add(sigma1(e))
1134        .wrapping_add(ch(e, f, g))
1135        .wrapping_add(0xD186B8C721C0C207)
1136        .wrapping_add(w[65]);
1137    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1138    h = g;
1139    g = f;
1140    f = e;
1141    e = d.wrapping_add(t1);
1142    d = c;
1143    c = b;
1144    b = a;
1145    a = t1.wrapping_add(t2);
1146
1147    // Round 66
1148    t1 = h
1149        .wrapping_add(sigma1(e))
1150        .wrapping_add(ch(e, f, g))
1151        .wrapping_add(0xEADA7DD6CDE0EB1E)
1152        .wrapping_add(w[66]);
1153    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1154    h = g;
1155    g = f;
1156    f = e;
1157    e = d.wrapping_add(t1);
1158    d = c;
1159    c = b;
1160    b = a;
1161    a = t1.wrapping_add(t2);
1162
1163    // Round 67
1164    t1 = h
1165        .wrapping_add(sigma1(e))
1166        .wrapping_add(ch(e, f, g))
1167        .wrapping_add(0xF57D4F7FEE6ED178)
1168        .wrapping_add(w[67]);
1169    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1170    h = g;
1171    g = f;
1172    f = e;
1173    e = d.wrapping_add(t1);
1174    d = c;
1175    c = b;
1176    b = a;
1177    a = t1.wrapping_add(t2);
1178
1179    // Round 68
1180    t1 = h
1181        .wrapping_add(sigma1(e))
1182        .wrapping_add(ch(e, f, g))
1183        .wrapping_add(0x06F067AA72176FBA)
1184        .wrapping_add(w[68]);
1185    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1186    h = g;
1187    g = f;
1188    f = e;
1189    e = d.wrapping_add(t1);
1190    d = c;
1191    c = b;
1192    b = a;
1193    a = t1.wrapping_add(t2);
1194
1195    // Round 69
1196    t1 = h
1197        .wrapping_add(sigma1(e))
1198        .wrapping_add(ch(e, f, g))
1199        .wrapping_add(0x0A637DC5A2C898A6)
1200        .wrapping_add(w[69]);
1201    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1202    h = g;
1203    g = f;
1204    f = e;
1205    e = d.wrapping_add(t1);
1206    d = c;
1207    c = b;
1208    b = a;
1209    a = t1.wrapping_add(t2);
1210
1211    // Round 70
1212    t1 = h
1213        .wrapping_add(sigma1(e))
1214        .wrapping_add(ch(e, f, g))
1215        .wrapping_add(0x113F9804BEF90DAE)
1216        .wrapping_add(w[70]);
1217    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1218    h = g;
1219    g = f;
1220    f = e;
1221    e = d.wrapping_add(t1);
1222    d = c;
1223    c = b;
1224    b = a;
1225    a = t1.wrapping_add(t2);
1226
1227    // Round 71
1228    t1 = h
1229        .wrapping_add(sigma1(e))
1230        .wrapping_add(ch(e, f, g))
1231        .wrapping_add(0x1B710B35131C471B)
1232        .wrapping_add(w[71]);
1233    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1234    h = g;
1235    g = f;
1236    f = e;
1237    e = d.wrapping_add(t1);
1238    d = c;
1239    c = b;
1240    b = a;
1241    a = t1.wrapping_add(t2);
1242
1243    // Round 72
1244    t1 = h
1245        .wrapping_add(sigma1(e))
1246        .wrapping_add(ch(e, f, g))
1247        .wrapping_add(0x28DB77F523047D84)
1248        .wrapping_add(w[72]);
1249    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1250    h = g;
1251    g = f;
1252    f = e;
1253    e = d.wrapping_add(t1);
1254    d = c;
1255    c = b;
1256    b = a;
1257    a = t1.wrapping_add(t2);
1258
1259    // Round 73
1260    t1 = h
1261        .wrapping_add(sigma1(e))
1262        .wrapping_add(ch(e, f, g))
1263        .wrapping_add(0x32CAAB7B40C72493)
1264        .wrapping_add(w[73]);
1265    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1266    h = g;
1267    g = f;
1268    f = e;
1269    e = d.wrapping_add(t1);
1270    d = c;
1271    c = b;
1272    b = a;
1273    a = t1.wrapping_add(t2);
1274
1275    // Round 74
1276    t1 = h
1277        .wrapping_add(sigma1(e))
1278        .wrapping_add(ch(e, f, g))
1279        .wrapping_add(0x3C9EBE0A15C9BEBC)
1280        .wrapping_add(w[74]);
1281    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1282    h = g;
1283    g = f;
1284    f = e;
1285    e = d.wrapping_add(t1);
1286    d = c;
1287    c = b;
1288    b = a;
1289    a = t1.wrapping_add(t2);
1290
1291    // Round 75
1292    t1 = h
1293        .wrapping_add(sigma1(e))
1294        .wrapping_add(ch(e, f, g))
1295        .wrapping_add(0x431D67C49C100D4C)
1296        .wrapping_add(w[75]);
1297    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1298    h = g;
1299    g = f;
1300    f = e;
1301    e = d.wrapping_add(t1);
1302    d = c;
1303    c = b;
1304    b = a;
1305    a = t1.wrapping_add(t2);
1306
1307    // Round 76
1308    t1 = h
1309        .wrapping_add(sigma1(e))
1310        .wrapping_add(ch(e, f, g))
1311        .wrapping_add(0x4CC5D4BECB3E42B6)
1312        .wrapping_add(w[76]);
1313    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1314    h = g;
1315    g = f;
1316    f = e;
1317    e = d.wrapping_add(t1);
1318    d = c;
1319    c = b;
1320    b = a;
1321    a = t1.wrapping_add(t2);
1322
1323    // Round 77
1324    t1 = h
1325        .wrapping_add(sigma1(e))
1326        .wrapping_add(ch(e, f, g))
1327        .wrapping_add(0x597F299CFC657E2A)
1328        .wrapping_add(w[77]);
1329    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1330    h = g;
1331    g = f;
1332    f = e;
1333    e = d.wrapping_add(t1);
1334    d = c;
1335    c = b;
1336    b = a;
1337    a = t1.wrapping_add(t2);
1338
1339    // Round 78
1340    t1 = h
1341        .wrapping_add(sigma1(e))
1342        .wrapping_add(ch(e, f, g))
1343        .wrapping_add(0x5FCB6FAB3AD6FAEC)
1344        .wrapping_add(w[78]);
1345    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1346    h = g;
1347    g = f;
1348    f = e;
1349    e = d.wrapping_add(t1);
1350    d = c;
1351    c = b;
1352    b = a;
1353    a = t1.wrapping_add(t2);
1354
1355    // Round 79
1356    t1 = h
1357        .wrapping_add(sigma1(e))
1358        .wrapping_add(ch(e, f, g))
1359        .wrapping_add(0x6C44198C4A475817)
1360        .wrapping_add(w[79]);
1361    t2 = sigma0(a).wrapping_add(maj(a, b, c));
1362    h = g;
1363    g = f;
1364    f = e;
1365    e = d.wrapping_add(t1);
1366    d = c;
1367    c = b;
1368    b = a;
1369    a = t1.wrapping_add(t2);
1370
1371    // Final state values
1372    let state = [
1373        0x6a09e667f3bcc908u64.wrapping_add(a).to_be_bytes(),
1374        0xbb67ae8584caa73bu64.wrapping_add(b).to_be_bytes(),
1375        0x3c6ef372fe94f82bu64.wrapping_add(c).to_be_bytes(),
1376        0xa54ff53a5f1d36f1u64.wrapping_add(d).to_be_bytes(),
1377        0x510e527fade682d1u64.wrapping_add(e).to_be_bytes(),
1378        0x9b05688c2b3e6c1fu64.wrapping_add(f).to_be_bytes(),
1379        0x1f83d9abfb41bd6bu64.wrapping_add(g).to_be_bytes(),
1380        0x5be0cd19137e2179u64.wrapping_add(h).to_be_bytes(),
1381    ];
1382
1383    // Convert to bytes
1384    let mut result = [0u8; 64];
1385    for (i, &word) in state.iter().enumerate() {
1386        result[i * 8..(i + 1) * 8].copy_from_slice(&word);
1387    }
1388
1389    result
1390}