1use crate::block::LENGTH_QWORDS as BLOCK_LENGTH_QWORDS;
87use crate::digest::LENGTH_QWORDS as DIGEST_LENGTH_QWORDS;
88
89#[allow(clippy::unreadable_literal)]
90const H: [u64; 8] = [
91 0x6A09E667F3BCC908,
92 0xBB67AE8584CAA73B,
93 0x3C6EF372FE94F82B,
94 0xA54FF53A5F1D36F1,
95 0x510E527FADE682D1,
96 0x9B05688C2B3E6C1F,
97 0x1F83D9ABFB41BD6B,
98 0x5BE0CD19137E2179,
99];
100
101#[allow(clippy::unreadable_literal)]
102#[rustfmt::skip]
103const K: [u64; 80] = [
104 0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC,
105 0x3956C25BF348B538, 0x59F111F1B605D019, 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118,
106 0xD807AA98A3030242, 0x12835B0145706FBE, 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2,
107 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, 0x9BDC06A725C71235, 0xC19BF174CF692694,
108 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65,
109 0x2DE92C6F592B0275, 0x4A7484AA6EA6E483, 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5,
110 0x983E5152EE66DFAB, 0xA831C66D2DB43210, 0xB00327C898FB213F, 0xBF597FC7BEEF0EE4,
111 0xC6E00BF33DA88FC2, 0xD5A79147930AA725, 0x06CA6351E003826F, 0x142929670A0E6E70,
112 0x27B70A8546D22FFC, 0x2E1B21385C26C926, 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF,
113 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, 0x81C2C92E47EDAEE6, 0x92722C851482353B,
114 0xA2BFE8A14CF10364, 0xA81A664BBC423001, 0xC24B8B70D0F89791, 0xC76C51A30654BE30,
115 0xD192E819D6EF5218, 0xD69906245565A910, 0xF40E35855771202A, 0x106AA07032BBD1B8,
116 0x19A4C116B8D2D0C8, 0x1E376C085141AB53, 0x2748774CDF8EEB99, 0x34B0BCB5E19B48A8,
117 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3,
118 0x748F82EE5DEFB2FC, 0x78A5636F43172F60, 0x84C87814A1F0AB72, 0x8CC702081A6439EC,
119 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, 0xBEF9A3F7B2C67915, 0xC67178F2E372532B,
120 0xCA273ECEEA26619C, 0xD186B8C721C0C207, 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178,
121 0x06F067AA72176FBA, 0x0A637DC5A2C898A6, 0x113F9804BEF90DAE, 0x1B710B35131C471B,
122 0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C,
123 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817,
124];
125
126#[must_use]
128pub const fn new() -> State {
129 State::new()
130}
131
132#[must_use]
134pub fn default() -> State {
135 State::default()
136}
137
138#[derive(Clone, Copy, Debug, Eq, PartialEq)]
142#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
143pub struct State {
144 pub(crate) a: u64,
145 pub(crate) b: u64,
146 pub(crate) c: u64,
147 pub(crate) d: u64,
148 pub(crate) e: u64,
149 pub(crate) f: u64,
150 pub(crate) g: u64,
151 pub(crate) h: u64,
152}
153
154impl State {
155 #[must_use]
157 pub const fn new() -> Self {
158 let [a, b, c, d, e, f, g, h] = H;
159 Self { a, b, c, d, e, f, g, h }
160 }
161
162 #[must_use]
166 pub const fn update(&self, block: [u64; BLOCK_LENGTH_QWORDS]) -> Self {
167 const fn small_sigma0(x: u64) -> u64 {
168 x.rotate_right(1) ^ x.rotate_right(8) ^ (x >> 7)
169 }
170
171 const fn small_sigma1(x: u64) -> u64 {
172 x.rotate_right(19) ^ x.rotate_right(61) ^ (x >> 6)
173 }
174
175 #[rustfmt::skip]
176 let mut w = [
177 block[0x0], block[0x1], block[0x2], block[0x3],
178 block[0x4], block[0x5], block[0x6], block[0x7],
179 block[0x8], block[0x9], block[0xA], block[0xB],
180 block[0xC], block[0xD], block[0xE], block[0xF],
181 0, 0, 0, 0,
182 0, 0, 0, 0,
183 0, 0, 0, 0,
184 0, 0, 0, 0,
185 0, 0, 0, 0,
186 0, 0, 0, 0,
187 0, 0, 0, 0,
188 0, 0, 0, 0,
189 0, 0, 0, 0,
190 0, 0, 0, 0,
191 0, 0, 0, 0,
192 0, 0, 0, 0,
193 0, 0, 0, 0,
194 0, 0, 0, 0,
195 0, 0, 0, 0,
196 0, 0, 0, 0,
197 ];
198 w[0x10] = small_sigma1(w[0x0E])
199 .wrapping_add(w[0x09])
200 .wrapping_add(small_sigma0(w[0x01]))
201 .wrapping_add(w[0x00]);
202 w[0x11] = small_sigma1(w[0x0F])
203 .wrapping_add(w[0x0A])
204 .wrapping_add(small_sigma0(w[0x02]))
205 .wrapping_add(w[0x01]);
206 w[0x12] = small_sigma1(w[0x10])
207 .wrapping_add(w[0x0B])
208 .wrapping_add(small_sigma0(w[0x03]))
209 .wrapping_add(w[0x02]);
210 w[0x13] = small_sigma1(w[0x11])
211 .wrapping_add(w[0x0C])
212 .wrapping_add(small_sigma0(w[0x04]))
213 .wrapping_add(w[0x03]);
214 w[0x14] = small_sigma1(w[0x12])
215 .wrapping_add(w[0x0D])
216 .wrapping_add(small_sigma0(w[0x05]))
217 .wrapping_add(w[0x04]);
218 w[0x15] = small_sigma1(w[0x13])
219 .wrapping_add(w[0x0E])
220 .wrapping_add(small_sigma0(w[0x06]))
221 .wrapping_add(w[0x05]);
222 w[0x16] = small_sigma1(w[0x14])
223 .wrapping_add(w[0x0F])
224 .wrapping_add(small_sigma0(w[0x07]))
225 .wrapping_add(w[0x06]);
226 w[0x17] = small_sigma1(w[0x15])
227 .wrapping_add(w[0x10])
228 .wrapping_add(small_sigma0(w[0x08]))
229 .wrapping_add(w[0x07]);
230 w[0x18] = small_sigma1(w[0x16])
231 .wrapping_add(w[0x11])
232 .wrapping_add(small_sigma0(w[0x09]))
233 .wrapping_add(w[0x08]);
234 w[0x19] = small_sigma1(w[0x17])
235 .wrapping_add(w[0x12])
236 .wrapping_add(small_sigma0(w[0x0A]))
237 .wrapping_add(w[0x09]);
238 w[0x1A] = small_sigma1(w[0x18])
239 .wrapping_add(w[0x13])
240 .wrapping_add(small_sigma0(w[0x0B]))
241 .wrapping_add(w[0x0A]);
242 w[0x1B] = small_sigma1(w[0x19])
243 .wrapping_add(w[0x14])
244 .wrapping_add(small_sigma0(w[0x0C]))
245 .wrapping_add(w[0x0B]);
246 w[0x1C] = small_sigma1(w[0x1A])
247 .wrapping_add(w[0x15])
248 .wrapping_add(small_sigma0(w[0x0D]))
249 .wrapping_add(w[0x0C]);
250 w[0x1D] = small_sigma1(w[0x1B])
251 .wrapping_add(w[0x16])
252 .wrapping_add(small_sigma0(w[0x0E]))
253 .wrapping_add(w[0x0D]);
254 w[0x1E] = small_sigma1(w[0x1C])
255 .wrapping_add(w[0x17])
256 .wrapping_add(small_sigma0(w[0x0F]))
257 .wrapping_add(w[0x0E]);
258 w[0x1F] = small_sigma1(w[0x1D])
259 .wrapping_add(w[0x18])
260 .wrapping_add(small_sigma0(w[0x10]))
261 .wrapping_add(w[0x0F]);
262 w[0x20] = small_sigma1(w[0x1E])
263 .wrapping_add(w[0x19])
264 .wrapping_add(small_sigma0(w[0x11]))
265 .wrapping_add(w[0x10]);
266 w[0x21] = small_sigma1(w[0x1F])
267 .wrapping_add(w[0x1A])
268 .wrapping_add(small_sigma0(w[0x12]))
269 .wrapping_add(w[0x11]);
270 w[0x22] = small_sigma1(w[0x20])
271 .wrapping_add(w[0x1B])
272 .wrapping_add(small_sigma0(w[0x13]))
273 .wrapping_add(w[0x12]);
274 w[0x23] = small_sigma1(w[0x21])
275 .wrapping_add(w[0x1C])
276 .wrapping_add(small_sigma0(w[0x14]))
277 .wrapping_add(w[0x13]);
278 w[0x24] = small_sigma1(w[0x22])
279 .wrapping_add(w[0x1D])
280 .wrapping_add(small_sigma0(w[0x15]))
281 .wrapping_add(w[0x14]);
282 w[0x25] = small_sigma1(w[0x23])
283 .wrapping_add(w[0x1E])
284 .wrapping_add(small_sigma0(w[0x16]))
285 .wrapping_add(w[0x15]);
286 w[0x26] = small_sigma1(w[0x24])
287 .wrapping_add(w[0x1F])
288 .wrapping_add(small_sigma0(w[0x17]))
289 .wrapping_add(w[0x16]);
290 w[0x27] = small_sigma1(w[0x25])
291 .wrapping_add(w[0x20])
292 .wrapping_add(small_sigma0(w[0x18]))
293 .wrapping_add(w[0x17]);
294 w[0x28] = small_sigma1(w[0x26])
295 .wrapping_add(w[0x21])
296 .wrapping_add(small_sigma0(w[0x19]))
297 .wrapping_add(w[0x18]);
298 w[0x29] = small_sigma1(w[0x27])
299 .wrapping_add(w[0x22])
300 .wrapping_add(small_sigma0(w[0x1A]))
301 .wrapping_add(w[0x19]);
302 w[0x2A] = small_sigma1(w[0x28])
303 .wrapping_add(w[0x23])
304 .wrapping_add(small_sigma0(w[0x1B]))
305 .wrapping_add(w[0x1A]);
306 w[0x2B] = small_sigma1(w[0x29])
307 .wrapping_add(w[0x24])
308 .wrapping_add(small_sigma0(w[0x1C]))
309 .wrapping_add(w[0x1B]);
310 w[0x2C] = small_sigma1(w[0x2A])
311 .wrapping_add(w[0x25])
312 .wrapping_add(small_sigma0(w[0x1D]))
313 .wrapping_add(w[0x1C]);
314 w[0x2D] = small_sigma1(w[0x2B])
315 .wrapping_add(w[0x26])
316 .wrapping_add(small_sigma0(w[0x1E]))
317 .wrapping_add(w[0x1D]);
318 w[0x2E] = small_sigma1(w[0x2C])
319 .wrapping_add(w[0x27])
320 .wrapping_add(small_sigma0(w[0x1F]))
321 .wrapping_add(w[0x1E]);
322 w[0x2F] = small_sigma1(w[0x2D])
323 .wrapping_add(w[0x28])
324 .wrapping_add(small_sigma0(w[0x20]))
325 .wrapping_add(w[0x1F]);
326 w[0x30] = small_sigma1(w[0x2E])
327 .wrapping_add(w[0x29])
328 .wrapping_add(small_sigma0(w[0x21]))
329 .wrapping_add(w[0x20]);
330 w[0x31] = small_sigma1(w[0x2F])
331 .wrapping_add(w[0x2A])
332 .wrapping_add(small_sigma0(w[0x22]))
333 .wrapping_add(w[0x21]);
334 w[0x32] = small_sigma1(w[0x30])
335 .wrapping_add(w[0x2B])
336 .wrapping_add(small_sigma0(w[0x23]))
337 .wrapping_add(w[0x22]);
338 w[0x33] = small_sigma1(w[0x31])
339 .wrapping_add(w[0x2C])
340 .wrapping_add(small_sigma0(w[0x24]))
341 .wrapping_add(w[0x23]);
342 w[0x34] = small_sigma1(w[0x32])
343 .wrapping_add(w[0x2D])
344 .wrapping_add(small_sigma0(w[0x25]))
345 .wrapping_add(w[0x24]);
346 w[0x35] = small_sigma1(w[0x33])
347 .wrapping_add(w[0x2E])
348 .wrapping_add(small_sigma0(w[0x26]))
349 .wrapping_add(w[0x25]);
350 w[0x36] = small_sigma1(w[0x34])
351 .wrapping_add(w[0x2F])
352 .wrapping_add(small_sigma0(w[0x27]))
353 .wrapping_add(w[0x26]);
354 w[0x37] = small_sigma1(w[0x35])
355 .wrapping_add(w[0x30])
356 .wrapping_add(small_sigma0(w[0x28]))
357 .wrapping_add(w[0x27]);
358 w[0x38] = small_sigma1(w[0x36])
359 .wrapping_add(w[0x31])
360 .wrapping_add(small_sigma0(w[0x29]))
361 .wrapping_add(w[0x28]);
362 w[0x39] = small_sigma1(w[0x37])
363 .wrapping_add(w[0x32])
364 .wrapping_add(small_sigma0(w[0x2A]))
365 .wrapping_add(w[0x29]);
366 w[0x3A] = small_sigma1(w[0x38])
367 .wrapping_add(w[0x33])
368 .wrapping_add(small_sigma0(w[0x2B]))
369 .wrapping_add(w[0x2A]);
370 w[0x3B] = small_sigma1(w[0x39])
371 .wrapping_add(w[0x34])
372 .wrapping_add(small_sigma0(w[0x2C]))
373 .wrapping_add(w[0x2B]);
374 w[0x3C] = small_sigma1(w[0x3A])
375 .wrapping_add(w[0x35])
376 .wrapping_add(small_sigma0(w[0x2D]))
377 .wrapping_add(w[0x2C]);
378 w[0x3D] = small_sigma1(w[0x3B])
379 .wrapping_add(w[0x36])
380 .wrapping_add(small_sigma0(w[0x2E]))
381 .wrapping_add(w[0x2D]);
382 w[0x3E] = small_sigma1(w[0x3C])
383 .wrapping_add(w[0x37])
384 .wrapping_add(small_sigma0(w[0x2F]))
385 .wrapping_add(w[0x2E]);
386 w[0x3F] = small_sigma1(w[0x3D])
387 .wrapping_add(w[0x38])
388 .wrapping_add(small_sigma0(w[0x30]))
389 .wrapping_add(w[0x2F]);
390 w[0x40] = small_sigma1(w[0x3E])
391 .wrapping_add(w[0x39])
392 .wrapping_add(small_sigma0(w[0x31]))
393 .wrapping_add(w[0x30]);
394 w[0x41] = small_sigma1(w[0x3F])
395 .wrapping_add(w[0x3A])
396 .wrapping_add(small_sigma0(w[0x32]))
397 .wrapping_add(w[0x31]);
398 w[0x42] = small_sigma1(w[0x40])
399 .wrapping_add(w[0x3B])
400 .wrapping_add(small_sigma0(w[0x33]))
401 .wrapping_add(w[0x32]);
402 w[0x43] = small_sigma1(w[0x41])
403 .wrapping_add(w[0x3C])
404 .wrapping_add(small_sigma0(w[0x34]))
405 .wrapping_add(w[0x33]);
406 w[0x44] = small_sigma1(w[0x42])
407 .wrapping_add(w[0x3D])
408 .wrapping_add(small_sigma0(w[0x35]))
409 .wrapping_add(w[0x34]);
410 w[0x45] = small_sigma1(w[0x43])
411 .wrapping_add(w[0x3E])
412 .wrapping_add(small_sigma0(w[0x36]))
413 .wrapping_add(w[0x35]);
414 w[0x46] = small_sigma1(w[0x44])
415 .wrapping_add(w[0x3F])
416 .wrapping_add(small_sigma0(w[0x37]))
417 .wrapping_add(w[0x36]);
418 w[0x47] = small_sigma1(w[0x45])
419 .wrapping_add(w[0x40])
420 .wrapping_add(small_sigma0(w[0x38]))
421 .wrapping_add(w[0x37]);
422 w[0x48] = small_sigma1(w[0x46])
423 .wrapping_add(w[0x41])
424 .wrapping_add(small_sigma0(w[0x39]))
425 .wrapping_add(w[0x38]);
426 w[0x49] = small_sigma1(w[0x47])
427 .wrapping_add(w[0x42])
428 .wrapping_add(small_sigma0(w[0x3A]))
429 .wrapping_add(w[0x39]);
430 w[0x4A] = small_sigma1(w[0x48])
431 .wrapping_add(w[0x43])
432 .wrapping_add(small_sigma0(w[0x3B]))
433 .wrapping_add(w[0x3A]);
434 w[0x4B] = small_sigma1(w[0x49])
435 .wrapping_add(w[0x44])
436 .wrapping_add(small_sigma0(w[0x3C]))
437 .wrapping_add(w[0x3B]);
438 w[0x4C] = small_sigma1(w[0x4A])
439 .wrapping_add(w[0x45])
440 .wrapping_add(small_sigma0(w[0x3D]))
441 .wrapping_add(w[0x3C]);
442 w[0x4D] = small_sigma1(w[0x4B])
443 .wrapping_add(w[0x46])
444 .wrapping_add(small_sigma0(w[0x3E]))
445 .wrapping_add(w[0x3D]);
446 w[0x4E] = small_sigma1(w[0x4C])
447 .wrapping_add(w[0x47])
448 .wrapping_add(small_sigma0(w[0x3F]))
449 .wrapping_add(w[0x3E]);
450 w[0x4F] = small_sigma1(w[0x4D])
451 .wrapping_add(w[0x48])
452 .wrapping_add(small_sigma0(w[0x40]))
453 .wrapping_add(w[0x3F]);
454
455 let state = *self;
456
457 const fn ch(x: u64, y: u64, z: u64) -> u64 {
458 (x & y) ^ (!x & z)
459 }
460
461 const fn maj(x: u64, y: u64, z: u64) -> u64 {
462 (x & y) ^ (x & z) ^ (y & z)
463 }
464
465 const fn capital_sigma0(x: u64) -> u64 {
466 x.rotate_right(28) ^ x.rotate_right(34) ^ x.rotate_right(39)
467 }
468
469 const fn capital_sigma1(x: u64) -> u64 {
470 x.rotate_right(14) ^ x.rotate_right(18) ^ x.rotate_right(41)
471 }
472
473 #[allow(clippy::too_many_arguments)]
474 #[rustfmt::skip]
475 const fn round(State { a, b, c, d, e, f, g, h }: State, w: u64, k: u64) -> State {
476 let t1 = h.wrapping_add(capital_sigma1(e)).wrapping_add(ch(e, f, g)).wrapping_add(k).wrapping_add(w);
477 let t2 = capital_sigma0(a).wrapping_add(maj(a, b, c));
478 let h = g;
479 let g = f;
480 let f = e;
481 let e = d.wrapping_add(t1);
482 let d = c;
483 let c = b;
484 let b = a;
485 let a = t1.wrapping_add(t2);
486 State { a, b, c, d, e, f, g, h }
487 }
488
489 let state = round(state, w[0x00], K[0x00]);
490 let state = round(state, w[0x01], K[0x01]);
491 let state = round(state, w[0x02], K[0x02]);
492 let state = round(state, w[0x03], K[0x03]);
493 let state = round(state, w[0x04], K[0x04]);
494 let state = round(state, w[0x05], K[0x05]);
495 let state = round(state, w[0x06], K[0x06]);
496 let state = round(state, w[0x07], K[0x07]);
497 let state = round(state, w[0x08], K[0x08]);
498 let state = round(state, w[0x09], K[0x09]);
499 let state = round(state, w[0x0A], K[0x0A]);
500 let state = round(state, w[0x0B], K[0x0B]);
501 let state = round(state, w[0x0C], K[0x0C]);
502 let state = round(state, w[0x0D], K[0x0D]);
503 let state = round(state, w[0x0E], K[0x0E]);
504 let state = round(state, w[0x0F], K[0x0F]);
505 let state = round(state, w[0x10], K[0x10]);
506 let state = round(state, w[0x11], K[0x11]);
507 let state = round(state, w[0x12], K[0x12]);
508 let state = round(state, w[0x13], K[0x13]);
509 let state = round(state, w[0x14], K[0x14]);
510 let state = round(state, w[0x15], K[0x15]);
511 let state = round(state, w[0x16], K[0x16]);
512 let state = round(state, w[0x17], K[0x17]);
513 let state = round(state, w[0x18], K[0x18]);
514 let state = round(state, w[0x19], K[0x19]);
515 let state = round(state, w[0x1A], K[0x1A]);
516 let state = round(state, w[0x1B], K[0x1B]);
517 let state = round(state, w[0x1C], K[0x1C]);
518 let state = round(state, w[0x1D], K[0x1D]);
519 let state = round(state, w[0x1E], K[0x1E]);
520 let state = round(state, w[0x1F], K[0x1F]);
521 let state = round(state, w[0x20], K[0x20]);
522 let state = round(state, w[0x21], K[0x21]);
523 let state = round(state, w[0x22], K[0x22]);
524 let state = round(state, w[0x23], K[0x23]);
525 let state = round(state, w[0x24], K[0x24]);
526 let state = round(state, w[0x25], K[0x25]);
527 let state = round(state, w[0x26], K[0x26]);
528 let state = round(state, w[0x27], K[0x27]);
529 let state = round(state, w[0x28], K[0x28]);
530 let state = round(state, w[0x29], K[0x29]);
531 let state = round(state, w[0x2A], K[0x2A]);
532 let state = round(state, w[0x2B], K[0x2B]);
533 let state = round(state, w[0x2C], K[0x2C]);
534 let state = round(state, w[0x2D], K[0x2D]);
535 let state = round(state, w[0x2E], K[0x2E]);
536 let state = round(state, w[0x2F], K[0x2F]);
537 let state = round(state, w[0x30], K[0x30]);
538 let state = round(state, w[0x31], K[0x31]);
539 let state = round(state, w[0x32], K[0x32]);
540 let state = round(state, w[0x33], K[0x33]);
541 let state = round(state, w[0x34], K[0x34]);
542 let state = round(state, w[0x35], K[0x35]);
543 let state = round(state, w[0x36], K[0x36]);
544 let state = round(state, w[0x37], K[0x37]);
545 let state = round(state, w[0x38], K[0x38]);
546 let state = round(state, w[0x39], K[0x39]);
547 let state = round(state, w[0x3A], K[0x3A]);
548 let state = round(state, w[0x3B], K[0x3B]);
549 let state = round(state, w[0x3C], K[0x3C]);
550 let state = round(state, w[0x3D], K[0x3D]);
551 let state = round(state, w[0x3E], K[0x3E]);
552 let state = round(state, w[0x3F], K[0x3F]);
553 let state = round(state, w[0x40], K[0x40]);
554 let state = round(state, w[0x41], K[0x41]);
555 let state = round(state, w[0x42], K[0x42]);
556 let state = round(state, w[0x43], K[0x43]);
557 let state = round(state, w[0x44], K[0x44]);
558 let state = round(state, w[0x45], K[0x45]);
559 let state = round(state, w[0x46], K[0x46]);
560 let state = round(state, w[0x47], K[0x47]);
561 let state = round(state, w[0x48], K[0x48]);
562 let state = round(state, w[0x49], K[0x49]);
563 let state = round(state, w[0x4A], K[0x4A]);
564 let state = round(state, w[0x4B], K[0x4B]);
565 let state = round(state, w[0x4C], K[0x4C]);
566 let state = round(state, w[0x4D], K[0x4D]);
567 let state = round(state, w[0x4E], K[0x4E]);
568 let state = round(state, w[0x4F], K[0x4F]);
569
570 let Self { a, b, c, d, e, f, g, h } = state;
573
574 let a = a.wrapping_add(self.a);
575 let b = b.wrapping_add(self.b);
576 let c = c.wrapping_add(self.c);
577 let d = d.wrapping_add(self.d);
578 let e = e.wrapping_add(self.e);
579 let f = f.wrapping_add(self.f);
580 let g = g.wrapping_add(self.g);
581 let h = h.wrapping_add(self.h);
582
583 Self { a, b, c, d, e, f, g, h }
586 }
587
588 #[must_use]
590 pub const fn reset(self) -> Self {
591 let [a, b, c, d, e, f, g, h] = H;
592 Self { a, b, c, d, e, f, g, h }
593 }
594
595 #[must_use]
597 pub const fn digest(&self) -> [u64; DIGEST_LENGTH_QWORDS] {
598 let Self { a, b, c, d, e, f, g, h } = *self;
599 [a, b, c, d, e, f, g, h]
600 }
601}
602
603impl Default for State {
604 fn default() -> Self {
605 Self::new()
606 }
607}
608
609#[cfg(test)]
610mod tests {
611 use super::*;
612
613 #[test]
614 fn new_empty() {
615 let digest = new().digest();
616 assert_eq!(
617 digest,
618 [
619 0x6A09E667F3BCC908,
620 0xBB67AE8584CAA73B,
621 0x3C6EF372FE94F82B,
622 0xA54FF53A5F1D36F1,
623 0x510E527FADE682D1,
624 0x9B05688C2B3E6C1F,
625 0x1F83D9ABFB41BD6B,
626 0x5BE0CD19137E2179,
627 ]
628 );
629 }
630
631 #[test]
632 fn default_empty() {
633 let digest = default().digest();
634 assert_eq!(
635 digest,
636 [
637 0x6A09E667F3BCC908,
638 0xBB67AE8584CAA73B,
639 0x3C6EF372FE94F82B,
640 0xA54FF53A5F1D36F1,
641 0x510E527FADE682D1,
642 0x9B05688C2B3E6C1F,
643 0x1F83D9ABFB41BD6B,
644 0x5BE0CD19137E2179,
645 ]
646 );
647 }
648
649 #[test]
650 fn new_zeros() {
651 #[rustfmt::skip]
652 let block = [
653 0x8000000000000000,
654 0x0000000000000000,
655 0x0000000000000000,
656 0x0000000000000000,
657 0x0000000000000000,
658 0x0000000000000000,
659 0x0000000000000000,
660 0x0000000000000000,
661 0x0000000000000000,
662 0x0000000000000000,
663 0x0000000000000000,
664 0x0000000000000000,
665 0x0000000000000000,
666 0x0000000000000000,
667 0x0000000000000000,
668 0x0000000000000000,
669 ];
670 let digest = new().update(block).digest();
671 assert_eq!(
672 digest,
673 [
674 0xCF83E1357EEFB8BD,
675 0xF1542850D66D8007,
676 0xD620E4050B5715DC,
677 0x83F4A921D36CE9CE,
678 0x47D0D13C5D85F2B0,
679 0xFF8318D2877EEC2F,
680 0x63B931BD47417A81,
681 0xA538327AF927DA3E,
682 ]
683 );
684 }
685}