1use std::str::FromStr;
2
3pub struct Hasher {
4 p: u128,
5 n_rounds: u8,
6 c: Vec<u128>
7}
8
9impl Default for Hasher {
10 fn default() -> Self {
11 Hasher {
12 p: u128::from_str("340282366920938463463374607431768211455").expect("Failed conversion"),
13 n_rounds: 10,
14 c: vec![
15 0,
16 u128::from_str("25823191961023811529686723375255045").expect("Failed conversion"),
17 u128::from_str("48376936063113800887806988124358800").expect("Failed conversion"),
18 u128::from_str("75580405153655082660116863095114839").expect("Failed conversion"),
19 u128::from_str("66651710483985382365580181188706173").expect("Failed conversion"),
20 u128::from_str("45887003413921204775397977044284378").expect("Failed conversion"),
21 u128::from_str("14399999722617037892747232478295923").expect("Failed conversion"),
22 u128::from_str("29376176727758177809204424209125257").expect("Failed conversion"),
23 u128::from_str("13768859312518298840937540532277016").expect("Failed conversion"),
24 u128::from_str("54749662990362840569021981534456448").expect("Failed conversion"),
25 u128::from_str("25161436470718351277017231215227846").expect("Failed conversion"),
26 u128::from_str("90370030464179443930112165274275271").expect("Failed conversion"),
27 u128::from_str("92014788260850167582827910417652439").expect("Failed conversion"),
28 u128::from_str("40376490640073034398204558905403523").expect("Failed conversion"),
29 u128::from_str("90379224439153137712327643289289624").expect("Failed conversion"),
30 u128::from_str("11220341520269979188892857030918685").expect("Failed conversion"),
31 u128::from_str("11480168113674888067906254878279274").expect("Failed conversion"),
32 u128::from_str("11144081894867681653997893051446803").expect("Failed conversion"),
33 u128::from_str("64965960071752809090438003157362764").expect("Failed conversion"),
34 u128::from_str("98428510787134995495896453413714864").expect("Failed conversion")
35 ]
36 }
37 }
38}
39
40impl Hasher {
41 fn mimc_feistel(il: u128, ir: u128, k: u128) -> (u128, u128) {
42 let hasher = Hasher::default();
43 let mut last_l = il.clone();
44 let mut last_r = ir.clone();
45
46 for i in 0..hasher.n_rounds {
47 let mask = last_r.wrapping_add(k).checked_rem(hasher.p).unwrap();
48 let mask = mask.wrapping_add(hasher.c[i as usize]).checked_rem(hasher.p).unwrap();
49 let mask2 = mask.wrapping_mul(mask).checked_rem(hasher.p).unwrap();
50 let mask4 = mask2.wrapping_mul(mask2).checked_rem(hasher.p).unwrap();
51 let mask = mask4.wrapping_mul(mask).checked_rem(hasher.p).unwrap();
52
53 let temp = last_r;
54 last_r = last_l.wrapping_add(mask).checked_rem(hasher.p).unwrap();
55 last_l = temp;
56 }
57
58 (last_l, last_r)
59 }
60
61 pub fn mimc_sponge(left: u128, right: u128, k: u128) -> u128 {
62 let mut last_r = left.clone();
63 let mut last_l = right.clone();
64
65 for _ in 0..Hasher::default().n_rounds {
66 let (new_last_r, new_last_l) = Hasher::mimc_feistel(last_r, last_l, k);
67
68 last_r = new_last_r.wrapping_add(1).checked_rem(Hasher::default().p).unwrap();
69 last_l = new_last_l.clone();
70 }
71
72 last_r
73 }
74}