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 n_rounds: i64 = {:?};", c.n_rounds);
 94}
 95
 96#[cfg(test)]
 97mod tests {
 98    use super::*;
 99    use rustc_hex::ToHex;
100
101    #[test]
102    fn test_sha3() {
103        let mut keccak = Keccak::new_keccak256();
104        let mut res = [0u8; 32];
105        keccak.update(SEED.as_bytes());
106        keccak.finalize(&mut res);
107        assert_eq!(
108            res.to_hex(),
109            "b6e489e6b37224a50bebfddbe7d89fa8fdcaa84304a70bd13f79b5d9f7951e9e"
110        );
111
112        let mut keccak = Keccak::new_keccak256();
113        let mut res = [0u8; 32];
114        keccak.update(SEED.as_bytes());
115        keccak.finalize(&mut res);
116        let c = BigInt::from_bytes_be(Sign::Plus, &res);
117        assert_eq!(
118            c.to_string(),
119            "82724731331859054037315113496710413141112897654334566532528783843265082629790"
120        );
121    }
122}