stealth_lib/
hasher.rs

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}