arnaucube
arnaucube/mimc-rsPublic Self-hosted repository
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}