mimc-rs/gen_constants/src/main.rs
gen_constants/src/main.rsRaw
1extern crate num;
2extern crate num_bigint;
3extern crate num_traits;
4
5use tiny_keccak::Keccak;
6
7use num_bigint::{BigInt, Sign};
8use num_traits::Zero;
9
10const SEED: &str = "mimc";
11
12pub struct Constants {
13 // seed_hash: BigInt,
14 // iv: BigInt,
15 r: BigInt,
16 n_rounds: i64,
17 cts: Vec<BigInt>,
18}
19
20pub fn modulus(a: &BigInt, m: &BigInt) -> BigInt {
21 ((a % m) + m) % m
22}
23
24pub fn generate_constants() -> Constants {
25 let r: BigInt = BigInt::parse_bytes(
26 b"21888242871839275222246405745257275088548364400416034343698204186575808495617",
27 10,
28 )
29 .unwrap();
30
31 let mut keccak = Keccak::new_keccak256();
32 let mut h = [0u8; 32];
33 keccak.update(SEED.as_bytes());
34 keccak.finalize(&mut h);
35 let mut keccak = Keccak::new_keccak256();
36 let mut h_iv = [0u8; 32];
37 let seed_iv = format!("{}{}", SEED, "_iv");
38 keccak.update(seed_iv.as_bytes());
39 keccak.finalize(&mut h_iv);
40
41 // let seed_hash: BigInt = BigInt::from_bytes_be(Sign::Plus, &h);
42 // let c: BigInt = BigInt::from_bytes_be(Sign::Plus, &h_iv);
43 // let iv: BigInt = c % &r;
44 let n_rounds: i64 = 91;
45 let cts = get_constants(&r, SEED, n_rounds);
46
47 Constants {
48 // seed_hash: seed_hash,
49 // iv: iv,
50 r: r,
51 n_rounds: n_rounds,
52 cts: cts,
53 }
54}
55
56pub fn get_constants(r: &BigInt, seed: &str, n_rounds: i64) -> Vec<BigInt> {
57 let mut cts: Vec<BigInt> = Vec::new();
58 cts.push(Zero::zero());
59
60 let mut keccak = Keccak::new_keccak256();
61 let mut h = [0u8; 32];
62 keccak.update(seed.as_bytes());
63 keccak.finalize(&mut h);
64
65 let mut c = BigInt::from_bytes_be(Sign::Plus, &h);
66 for _ in 1..n_rounds {
67 let (_, c_bytes) = c.to_bytes_be();
68 let mut c_bytes32: [u8; 32] = [0; 32];
69 let diff = c_bytes32.len() - c_bytes.len();
70 c_bytes32[diff..].copy_from_slice(&c_bytes[..]);
71
72 let mut keccak = Keccak::new_keccak256();
73 let mut h = [0u8; 32];
74 keccak.update(&c_bytes[..]);
75 keccak.finalize(&mut h);
76 c = BigInt::from_bytes_be(Sign::Plus, &h);
77
78 let n = modulus(&c, &r);
79 cts.push(n);
80 }
81 // let l = cts.len();
82 // cts[l-1] = Zero::zero();
83 cts
84}
85
86fn main() {
87 let c = generate_constants();
88 println!("let cts_str: Vec<&str> = vec![");
89 for i in 0..c.cts.len() {
90 println!(" {:?},", c.cts[i].to_string());
91 }
92 println!("];");
93 println!("let r: Fr = Fr::from_str(");
94 println!(" {:?},", c.r.to_string());
95 println!(").unwrap();");
96 println!("let n_rounds: i64 = {:?};", c.n_rounds);
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102 use rustc_hex::ToHex;
103
104 #[test]
105 fn test_sha3() {
106 let mut keccak = Keccak::new_keccak256();
107 let mut res = [0u8; 32];
108 keccak.update(SEED.as_bytes());
109 keccak.finalize(&mut res);
110 assert_eq!(
111 res.to_hex(),
112 "b6e489e6b37224a50bebfddbe7d89fa8fdcaa84304a70bd13f79b5d9f7951e9e"
113 );
114
115 let mut keccak = Keccak::new_keccak256();
116 let mut res = [0u8; 32];
117 keccak.update(SEED.as_bytes());
118 keccak.finalize(&mut res);
119 let c = BigInt::from_bytes_be(Sign::Plus, &res);
120 assert_eq!(
121 c.to_string(),
122 "82724731331859054037315113496710413141112897654334566532528783843265082629790"
123 );
124 }
125}