You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.2 KiB

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