1use core::ops::Range;
7
8use math::{fields::f64::BaseElement, FieldElement, StarkField};
9
10use super::{super::mds::mds_f64_8x8::mds_multiply, exp_acc, Digest, ElementHasher, Hasher};
11
12mod digest;
13pub use digest::ElementDigest;
14
15#[cfg(test)]
16mod tests;
17
18const STATE_WIDTH: usize = 8;
24
25const RATE_RANGE: Range<usize> = 4..8;
27const RATE_WIDTH: usize = RATE_RANGE.end - RATE_RANGE.start;
28
29const INPUT1_RANGE: Range<usize> = 0..4;
31const INPUT2_RANGE: Range<usize> = 4..8;
32
33const CAPACITY_RANGE: Range<usize> = 0..4;
35
36const DIGEST_RANGE: Range<usize> = 4..8;
41const DIGEST_SIZE: usize = DIGEST_RANGE.end - DIGEST_RANGE.start;
42
43const NUM_ROUNDS: usize = 7;
46
47#[cfg(test)]
53const ALPHA: u64 = 7;
54#[cfg(test)]
55const INV_ALPHA: u64 = 10540996611094048183;
56
57pub struct RpJive64_256();
113
114impl Hasher for RpJive64_256 {
115 type Digest = ElementDigest;
116
117 const COLLISION_RESISTANCE: u32 = 128;
118
119 fn hash(bytes: &[u8]) -> Self::Digest {
120 let num_elements = if bytes.len() % 7 == 0 {
124 bytes.len() / 7
125 } else {
126 bytes.len() / 7 + 1
127 };
128
129 let mut state = [BaseElement::ZERO; STATE_WIDTH];
132 if num_elements % RATE_WIDTH != 0 {
133 state[CAPACITY_RANGE.start] = BaseElement::ONE;
134 }
135
136 let mut i = 0;
140 let mut buf = [0_u8; 8];
141 for (index, chunk) in bytes.chunks(7).enumerate() {
142 if index < num_elements - 1 {
143 buf[..7].copy_from_slice(chunk);
144 } else {
145 let chunk_len = chunk.len();
150 buf = [0_u8; 8];
151 buf[..chunk_len].copy_from_slice(chunk);
152 buf[chunk_len] = 1;
153 }
154
155 state[RATE_RANGE.start + i] += BaseElement::new(u64::from_le_bytes(buf));
159 i += 1;
160 if i % RATE_WIDTH == 0 {
161 Self::apply_permutation(&mut state);
162 i = 0;
163 }
164 }
165
166 if i > 0 {
171 state[RATE_RANGE.start + i] = BaseElement::ONE;
172 i += 1;
173 while i != RATE_WIDTH {
174 state[RATE_RANGE.start + i] = BaseElement::ZERO;
175 i += 1;
176 }
177 Self::apply_permutation(&mut state);
178 }
179
180 ElementDigest::new(state[DIGEST_RANGE].try_into().unwrap())
182 }
183
184 fn merge(values: &[Self::Digest; 2]) -> Self::Digest {
187 let initial_state: [BaseElement; STATE_WIDTH] =
189 Self::Digest::digests_as_elements(values).try_into().unwrap();
190 let mut state = initial_state;
191
192 Self::apply_permutation(&mut state);
194
195 Self::apply_jive_summation(&initial_state, &state)
196 }
197
198 fn merge_many(values: &[Self::Digest]) -> Self::Digest {
199 Self::hash_elements(ElementDigest::digests_as_elements(values))
200 }
201
202 fn merge_with_int(seed: Self::Digest, value: u64) -> Self::Digest {
205 let mut state = [BaseElement::ZERO; STATE_WIDTH];
212 state[INPUT1_RANGE].copy_from_slice(seed.as_elements());
213 state[INPUT2_RANGE.start] = BaseElement::new(value);
214 if value < BaseElement::MODULUS {
215 state[INPUT2_RANGE.end - 1] = BaseElement::new(DIGEST_SIZE as u64 + 1);
216 } else {
217 state[INPUT2_RANGE.start + 1] = BaseElement::new(value / BaseElement::MODULUS);
218 state[INPUT2_RANGE.end - 1] = BaseElement::new(DIGEST_SIZE as u64 + 2);
219 }
220
221 let initial_state = state;
222 Self::apply_permutation(&mut state);
224
225 Self::apply_jive_summation(&initial_state, &state)
226 }
227}
228
229impl ElementHasher for RpJive64_256 {
230 type BaseField = BaseElement;
231
232 fn hash_elements<E: FieldElement<BaseField = Self::BaseField>>(elements: &[E]) -> Self::Digest {
233 let elements = E::slice_as_base_elements(elements);
235
236 let mut state = [BaseElement::ZERO; STATE_WIDTH];
239 if elements.len() % RATE_WIDTH != 0 {
240 state[CAPACITY_RANGE.start] = BaseElement::ONE;
241 }
242
243 let mut i = 0;
247 for &element in elements.iter() {
248 state[RATE_RANGE.start + i] += element;
249 i += 1;
250 if i % RATE_WIDTH == 0 {
251 Self::apply_permutation(&mut state);
252 i = 0;
253 }
254 }
255
256 if i > 0 {
261 state[RATE_RANGE.start + i] = BaseElement::ONE;
262 i += 1;
263 while i != RATE_WIDTH {
264 state[RATE_RANGE.start + i] = BaseElement::ZERO;
265 i += 1;
266 }
267 Self::apply_permutation(&mut state);
268 }
269
270 ElementDigest::new(state[DIGEST_RANGE].try_into().unwrap())
272 }
273}
274
275impl RpJive64_256 {
279 pub const NUM_ROUNDS: usize = NUM_ROUNDS;
284
285 pub const STATE_WIDTH: usize = STATE_WIDTH;
288
289 pub const RATE_RANGE: Range<usize> = RATE_RANGE;
291
292 pub const CAPACITY_RANGE: Range<usize> = CAPACITY_RANGE;
294
295 pub const DIGEST_RANGE: Range<usize> = DIGEST_RANGE;
297
298 pub const MDS: [[BaseElement; STATE_WIDTH]; STATE_WIDTH] = MDS;
300
301 pub const INV_MDS: [[BaseElement; STATE_WIDTH]; STATE_WIDTH] = INV_MDS;
303
304 pub const ARK1: [[BaseElement; STATE_WIDTH]; NUM_ROUNDS] = ARK1;
306
307 pub const ARK2: [[BaseElement; STATE_WIDTH]; NUM_ROUNDS] = ARK2;
309
310 pub fn apply_permutation(state: &mut [BaseElement; STATE_WIDTH]) {
315 for i in 0..NUM_ROUNDS {
318 Self::apply_round(state, i);
319 }
320 }
321
322 #[inline(always)]
324 pub fn apply_round(state: &mut [BaseElement; STATE_WIDTH], round: usize) {
325 Self::apply_sbox(state);
327 Self::apply_mds(state);
328 Self::add_constants(state, &ARK1[round]);
329
330 Self::apply_inv_sbox(state);
332 Self::apply_mds(state);
333 Self::add_constants(state, &ARK2[round]);
334 }
335
336 #[inline(always)]
337 pub fn apply_jive_summation(
338 initial_state: &[BaseElement; STATE_WIDTH],
339 final_state: &[BaseElement; STATE_WIDTH],
340 ) -> ElementDigest {
341 let mut result = [BaseElement::ZERO; DIGEST_SIZE];
342 for (i, r) in result.iter_mut().enumerate() {
343 *r = initial_state[i]
344 + initial_state[DIGEST_SIZE + i]
345 + final_state[i]
346 + final_state[DIGEST_SIZE + i];
347 }
348
349 ElementDigest::new(result)
350 }
351
352 #[inline(always)]
356 fn apply_mds(state: &mut [BaseElement; STATE_WIDTH]) {
357 mds_multiply(state)
358 }
359
360 #[inline(always)]
361 fn add_constants(state: &mut [BaseElement; STATE_WIDTH], ark: &[BaseElement; STATE_WIDTH]) {
362 state.iter_mut().zip(ark).for_each(|(s, &k)| *s += k);
363 }
364
365 #[inline(always)]
366 fn apply_sbox(state: &mut [BaseElement; STATE_WIDTH]) {
367 state[0] = state[0].exp7();
368 state[1] = state[1].exp7();
369 state[2] = state[2].exp7();
370 state[3] = state[3].exp7();
371 state[4] = state[4].exp7();
372 state[5] = state[5].exp7();
373 state[6] = state[6].exp7();
374 state[7] = state[7].exp7();
375 }
376
377 #[inline(always)]
378 fn apply_inv_sbox(state: &mut [BaseElement; STATE_WIDTH]) {
379 let mut t1 = *state;
384 t1.iter_mut().for_each(|t| *t = t.square());
385
386 let mut t2 = t1;
388 t2.iter_mut().for_each(|t| *t = t.square());
389
390 let t3 = exp_acc::<BaseElement, STATE_WIDTH, 3>(t2, t2);
392
393 let t4 = exp_acc::<BaseElement, STATE_WIDTH, 6>(t3, t3);
395
396 let t5 = exp_acc::<BaseElement, STATE_WIDTH, 12>(t4, t4);
398
399 let t6 = exp_acc::<BaseElement, STATE_WIDTH, 6>(t5, t3);
401
402 let t7 = exp_acc::<BaseElement, STATE_WIDTH, 31>(t6, t6);
404
405 for (i, s) in state.iter_mut().enumerate() {
407 let a = (t7[i].square() * t6[i]).square().square();
408 let b = t1[i] * t2[i] * *s;
409 *s = a * b;
410 }
411 }
412}
413
414const MDS: [[BaseElement; STATE_WIDTH]; STATE_WIDTH] = [
418 [
419 BaseElement::new(23),
420 BaseElement::new(8),
421 BaseElement::new(13),
422 BaseElement::new(10),
423 BaseElement::new(7),
424 BaseElement::new(6),
425 BaseElement::new(21),
426 BaseElement::new(8),
427 ],
428 [
429 BaseElement::new(8),
430 BaseElement::new(23),
431 BaseElement::new(8),
432 BaseElement::new(13),
433 BaseElement::new(10),
434 BaseElement::new(7),
435 BaseElement::new(6),
436 BaseElement::new(21),
437 ],
438 [
439 BaseElement::new(21),
440 BaseElement::new(8),
441 BaseElement::new(23),
442 BaseElement::new(8),
443 BaseElement::new(13),
444 BaseElement::new(10),
445 BaseElement::new(7),
446 BaseElement::new(6),
447 ],
448 [
449 BaseElement::new(6),
450 BaseElement::new(21),
451 BaseElement::new(8),
452 BaseElement::new(23),
453 BaseElement::new(8),
454 BaseElement::new(13),
455 BaseElement::new(10),
456 BaseElement::new(7),
457 ],
458 [
459 BaseElement::new(7),
460 BaseElement::new(6),
461 BaseElement::new(21),
462 BaseElement::new(8),
463 BaseElement::new(23),
464 BaseElement::new(8),
465 BaseElement::new(13),
466 BaseElement::new(10),
467 ],
468 [
469 BaseElement::new(10),
470 BaseElement::new(7),
471 BaseElement::new(6),
472 BaseElement::new(21),
473 BaseElement::new(8),
474 BaseElement::new(23),
475 BaseElement::new(8),
476 BaseElement::new(13),
477 ],
478 [
479 BaseElement::new(13),
480 BaseElement::new(10),
481 BaseElement::new(7),
482 BaseElement::new(6),
483 BaseElement::new(21),
484 BaseElement::new(8),
485 BaseElement::new(23),
486 BaseElement::new(8),
487 ],
488 [
489 BaseElement::new(8),
490 BaseElement::new(13),
491 BaseElement::new(10),
492 BaseElement::new(7),
493 BaseElement::new(6),
494 BaseElement::new(21),
495 BaseElement::new(8),
496 BaseElement::new(23),
497 ],
498];
499
500const INV_MDS: [[BaseElement; STATE_WIDTH]; STATE_WIDTH] = [
502 [
503 BaseElement::new(10671399028204489528),
504 BaseElement::new(15436289366139187412),
505 BaseElement::new(4624329233769728317),
506 BaseElement::new(18200084821960740316),
507 BaseElement::new(8736112961492104393),
508 BaseElement::new(1953609990965186349),
509 BaseElement::new(12477339747250042564),
510 BaseElement::new(1495657543820456485),
511 ],
512 [
513 BaseElement::new(1495657543820456485),
514 BaseElement::new(10671399028204489528),
515 BaseElement::new(15436289366139187412),
516 BaseElement::new(4624329233769728317),
517 BaseElement::new(18200084821960740316),
518 BaseElement::new(8736112961492104393),
519 BaseElement::new(1953609990965186349),
520 BaseElement::new(12477339747250042564),
521 ],
522 [
523 BaseElement::new(12477339747250042564),
524 BaseElement::new(1495657543820456485),
525 BaseElement::new(10671399028204489528),
526 BaseElement::new(15436289366139187412),
527 BaseElement::new(4624329233769728317),
528 BaseElement::new(18200084821960740316),
529 BaseElement::new(8736112961492104393),
530 BaseElement::new(1953609990965186349),
531 ],
532 [
533 BaseElement::new(1953609990965186349),
534 BaseElement::new(12477339747250042564),
535 BaseElement::new(1495657543820456485),
536 BaseElement::new(10671399028204489528),
537 BaseElement::new(15436289366139187412),
538 BaseElement::new(4624329233769728317),
539 BaseElement::new(18200084821960740316),
540 BaseElement::new(8736112961492104393),
541 ],
542 [
543 BaseElement::new(8736112961492104393),
544 BaseElement::new(1953609990965186349),
545 BaseElement::new(12477339747250042564),
546 BaseElement::new(1495657543820456485),
547 BaseElement::new(10671399028204489528),
548 BaseElement::new(15436289366139187412),
549 BaseElement::new(4624329233769728317),
550 BaseElement::new(18200084821960740316),
551 ],
552 [
553 BaseElement::new(18200084821960740316),
554 BaseElement::new(8736112961492104393),
555 BaseElement::new(1953609990965186349),
556 BaseElement::new(12477339747250042564),
557 BaseElement::new(1495657543820456485),
558 BaseElement::new(10671399028204489528),
559 BaseElement::new(15436289366139187412),
560 BaseElement::new(4624329233769728317),
561 ],
562 [
563 BaseElement::new(4624329233769728317),
564 BaseElement::new(18200084821960740316),
565 BaseElement::new(8736112961492104393),
566 BaseElement::new(1953609990965186349),
567 BaseElement::new(12477339747250042564),
568 BaseElement::new(1495657543820456485),
569 BaseElement::new(10671399028204489528),
570 BaseElement::new(15436289366139187412),
571 ],
572 [
573 BaseElement::new(15436289366139187412),
574 BaseElement::new(4624329233769728317),
575 BaseElement::new(18200084821960740316),
576 BaseElement::new(8736112961492104393),
577 BaseElement::new(1953609990965186349),
578 BaseElement::new(12477339747250042564),
579 BaseElement::new(1495657543820456485),
580 BaseElement::new(10671399028204489528),
581 ],
582];
583
584const ARK1: [[BaseElement; STATE_WIDTH]; NUM_ROUNDS] = [
593 [
594 BaseElement::new(5250156239823432273),
595 BaseElement::new(17991370199276831394),
596 BaseElement::new(15363758995121189373),
597 BaseElement::new(7550390719632034712),
598 BaseElement::new(705744964663370588),
599 BaseElement::new(14718080047998507086),
600 BaseElement::new(15612952641514293932),
601 BaseElement::new(8827614218997241655),
602 ],
603 [
604 BaseElement::new(3820104553051581938),
605 BaseElement::new(3385456123263281593),
606 BaseElement::new(16094709323995557719),
607 BaseElement::new(16303336019291352506),
608 BaseElement::new(8678496957982514796),
609 BaseElement::new(498270172890916765),
610 BaseElement::new(17676155962043649331),
611 BaseElement::new(14993644560894569061),
612 ],
613 [
614 BaseElement::new(14258773164148374760),
615 BaseElement::new(1655972393090532756),
616 BaseElement::new(7105012644980738960),
617 BaseElement::new(11852376844296856307),
618 BaseElement::new(17816158174482938174),
619 BaseElement::new(3981864273667206359),
620 BaseElement::new(2807469273751819673),
621 BaseElement::new(14974221859211617968),
622 ],
623 [
624 BaseElement::new(15947271309323471269),
625 BaseElement::new(14698197888879866148),
626 BaseElement::new(14077077040726269118),
627 BaseElement::new(2859805440338816615),
628 BaseElement::new(4945184696648790387),
629 BaseElement::new(15183288803792940883),
630 BaseElement::new(7601775560447886378),
631 BaseElement::new(6477224812816853098),
632 ],
633 [
634 BaseElement::new(18213733347601447845),
635 BaseElement::new(10031679943792626621),
636 BaseElement::new(5971928707867502549),
637 BaseElement::new(4916840084933933812),
638 BaseElement::new(3613815642787339926),
639 BaseElement::new(16715066477165606893),
640 BaseElement::new(14603075385258290966),
641 BaseElement::new(6037771699330759024),
642 ],
643 [
644 BaseElement::new(11092469678405138663),
645 BaseElement::new(14512788091784891767),
646 BaseElement::new(12690682422447262976),
647 BaseElement::new(4807355108863118656),
648 BaseElement::new(5207405791308193025),
649 BaseElement::new(5970889292753030887),
650 BaseElement::new(17691092604759176390),
651 BaseElement::new(2731892623388788619),
652 ],
653 [
654 BaseElement::new(9320990164295747317),
655 BaseElement::new(8313044787501051613),
656 BaseElement::new(15388579942433649113),
657 BaseElement::new(16827303822369113172),
658 BaseElement::new(7362247368635881413),
659 BaseElement::new(5501558211335089067),
660 BaseElement::new(16959364163466644433),
661 BaseElement::new(15127897185888596873),
662 ],
663];
664
665const ARK2: [[BaseElement; STATE_WIDTH]; NUM_ROUNDS] = [
666 [
667 BaseElement::new(9860068499471230379),
668 BaseElement::new(10391494434594667033),
669 BaseElement::new(4986587677027284267),
670 BaseElement::new(17781977240739864050),
671 BaseElement::new(6888921375142581299),
672 BaseElement::new(8950831725295674725),
673 BaseElement::new(17048848277806802259),
674 BaseElement::new(14146306451370933851),
675 ],
676 [
677 BaseElement::new(707569561928852298),
678 BaseElement::new(6724851263229096394),
679 BaseElement::new(16052786826295129381),
680 BaseElement::new(1966016718617096590),
681 BaseElement::new(9416027981257317341),
682 BaseElement::new(650995073054283087),
683 BaseElement::new(10013853213448688130),
684 BaseElement::new(14400137552134409897),
685 ],
686 [
687 BaseElement::new(7149263702162640230),
688 BaseElement::new(7096225564191267298),
689 BaseElement::new(12197502430442379401),
690 BaseElement::new(12804378092281676880),
691 BaseElement::new(17409570408925731570),
692 BaseElement::new(2819914464281065415),
693 BaseElement::new(15831648359524824910),
694 BaseElement::new(15629743966484525526),
695 ],
696 [
697 BaseElement::new(17953398529773387863),
698 BaseElement::new(6198711330432012203),
699 BaseElement::new(9157726872360640492),
700 BaseElement::new(9493333679697066249),
701 BaseElement::new(16030612341681265024),
702 BaseElement::new(4739709630031417239),
703 BaseElement::new(18287301685877696586),
704 BaseElement::new(8798230489526342293),
705 ],
706 [
707 BaseElement::new(11624786627634502148),
708 BaseElement::new(12924370583547723043),
709 BaseElement::new(11192385058160295505),
710 BaseElement::new(14350900531623057057),
711 BaseElement::new(6649040255431543914),
712 BaseElement::new(2106567763792008889),
713 BaseElement::new(12434281915569617273),
714 BaseElement::new(8101377239551798417),
715 ],
716 [
717 BaseElement::new(13925815041351874730),
718 BaseElement::new(15981136477777934021),
719 BaseElement::new(17398194123970783302),
720 BaseElement::new(17377636820017036987),
721 BaseElement::new(5173992930377549692),
722 BaseElement::new(3688194845376511083),
723 BaseElement::new(16177005022792194790),
724 BaseElement::new(6482787365501773067),
725 ],
726 [
727 BaseElement::new(9197066592623932055),
728 BaseElement::new(1777435748159421921),
729 BaseElement::new(5079482957444239813),
730 BaseElement::new(15080163201683705054),
731 BaseElement::new(4278835591662809119),
732 BaseElement::new(6609842793229774583),
733 BaseElement::new(651644751771720476),
734 BaseElement::new(14434199410773467460),
735 ],
736];