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.

154 lines
3.8 KiB

  1. use blake2::digest::{Input, VariableOutput};
  2. use blake2::VarBlake2b;
  3. extern crate num;
  4. extern crate num_bigint;
  5. extern crate num_traits;
  6. use num_bigint::{BigInt, Sign};
  7. use num_traits::{One, Zero};
  8. const SEED: &str = "poseidon";
  9. const NROUNDSF: usize = 8;
  10. const NROUNDSP: usize = 57;
  11. const T: usize = 6;
  12. #[derive(Debug)]
  13. pub struct Constants {
  14. c: Vec<BigInt>,
  15. m: Vec<Vec<BigInt>>,
  16. }
  17. pub fn generate_constants() -> Constants {
  18. let r: BigInt = BigInt::parse_bytes(
  19. b"21888242871839275222246405745257275088548364400416034343698204186575808495617",
  20. 10,
  21. )
  22. .unwrap();
  23. let c = get_pseudo_random(&r, format!("{}{}", SEED, "_constants"), NROUNDSF + NROUNDSP);
  24. let m = get_mds(&r);
  25. Constants { c: c, m: m }
  26. }
  27. pub fn get_pseudo_random(r: &BigInt, seed: String, n: usize) -> Vec<BigInt> {
  28. let mut hasher = VarBlake2b::new(32).unwrap();
  29. hasher.input(seed.as_bytes());
  30. let mut h = hasher.vec_result();
  31. let mut res: Vec<BigInt> = Vec::new();
  32. while res.len() < n {
  33. let new_n: BigInt = modulus(&BigInt::from_bytes_le(Sign::Plus, &h), &r);
  34. res.push(new_n);
  35. let mut hasher = VarBlake2b::new(32).unwrap();
  36. hasher.input(h);
  37. h = hasher.vec_result();
  38. }
  39. res
  40. }
  41. pub fn nonce_to_string(n: usize) -> String {
  42. let mut r = format!("{}", n);
  43. while r.len() < 4 {
  44. r = format!("0{}", r);
  45. }
  46. r
  47. }
  48. pub fn get_mds(r: &BigInt) -> Vec<Vec<BigInt>> {
  49. let mut nonce = 0;
  50. let mut cauchy_matrix = get_pseudo_random(
  51. r,
  52. format!("{}_matrix_{}", SEED, nonce_to_string(nonce)),
  53. T * 2,
  54. );
  55. while !check_all_different(&cauchy_matrix) {
  56. nonce = nonce + 1;
  57. cauchy_matrix = get_pseudo_random(
  58. r,
  59. format!("{}_matrix_{}", SEED, nonce_to_string(nonce)),
  60. T * 2,
  61. );
  62. }
  63. let mut m: Vec<Vec<BigInt>> = Vec::new();
  64. for i in 0..T {
  65. let mut mi: Vec<BigInt> = Vec::new();
  66. for j in 0..T {
  67. mi.push(modinv(
  68. &modulus(&(&cauchy_matrix[i] - &cauchy_matrix[T + j]), &r),
  69. &r,
  70. ));
  71. }
  72. m.push(mi);
  73. }
  74. m
  75. }
  76. pub fn check_all_different(v: &Vec<BigInt>) -> bool {
  77. let zero: BigInt = Zero::zero();
  78. for i in 0..v.len() {
  79. if v[i] == zero {
  80. return false;
  81. }
  82. for j in i + 1..v.len() {
  83. if v[i] == v[j] {
  84. return false;
  85. }
  86. }
  87. }
  88. true
  89. }
  90. pub fn modulus(a: &BigInt, m: &BigInt) -> BigInt {
  91. ((a % m) + m) % m
  92. }
  93. pub fn modinv(a: &BigInt, q: &BigInt) -> BigInt {
  94. let mut mn = (q.clone(), a.clone());
  95. let mut xy: (BigInt, BigInt) = (Zero::zero(), One::one());
  96. let big_zero: BigInt = Zero::zero();
  97. while mn.1 != big_zero {
  98. xy = (xy.1.clone(), xy.0 - (mn.0.clone() / mn.1.clone()) * xy.1);
  99. mn = (mn.1.clone(), modulus(&mn.0, &mn.1));
  100. }
  101. while xy.0 < Zero::zero() {
  102. xy.0 = modulus(&xy.0, q);
  103. }
  104. xy.0
  105. }
  106. fn main() {
  107. let c = generate_constants();
  108. println!("let c_str: Vec<&str> = vec![");
  109. for i in 0..c.c.len() {
  110. println!(" {:?},", c.c[i].to_string());
  111. }
  112. println!("];\n");
  113. println!("let m_str: Vec<Vec<&str>> = vec![");
  114. for i in 0..c.m.len() {
  115. println!(" vec![");
  116. for j in 0..c.m[i].len() {
  117. println!(" {:?},", c.m[i][j].to_string());
  118. }
  119. println!(" ],");
  120. }
  121. println!("];\n");
  122. }
  123. #[cfg(test)]
  124. mod tests {
  125. use super::*;
  126. use rustc_hex::ToHex;
  127. #[test]
  128. fn test_blake2_version() {
  129. let mut hasher = VarBlake2b::new(32).unwrap();
  130. hasher.input(b"poseidon_constants");
  131. let h = hasher.vec_result();
  132. assert_eq!(
  133. h.to_hex(),
  134. "e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1"
  135. );
  136. }
  137. }