arnaucube
arnaucube/poseidon-rsPublic Self-hosted repository
gen_constants crate appart
arnaucube root@arnaucube.com
Sun, 19 Jul 2020 12:00:52 +0200
commit

2b0e2faa3ea469871bd9b5fbf5113bd3df79b150

parent

4cba42e76ae1bad266bead39499112d4284840a6

3 files changed, 170 insertions(+), 0 deletions(-)

jump to
A gen_constants/.gitignore

@@ -0,0 +1,3 @@

+/target +**/*.rs.bk +Cargo.lock
A gen_constants/Cargo.toml

@@ -0,0 +1,13 @@

+[package] +name = "gen_constants" +version = "0.0.1" +authors = ["arnaucube <root@arnaucube.com>"] +edition = "2018" +license = "GPL-3.0" + +[dependencies] +num = "0.2.0" +num-bigint = "0.2.2" +num-traits = "0.2.8" +blake2 = "0.8" +rustc-hex = "1.0.0"
A gen_constants/src/main.rs

@@ -0,0 +1,154 @@

+use blake2::digest::{Input, VariableOutput}; +use blake2::VarBlake2b; + +extern crate num; +extern crate num_bigint; +extern crate num_traits; +use num_bigint::{BigInt, Sign}; +use num_traits::{One, Zero}; + +const SEED: &str = "poseidon"; +const NROUNDSF: usize = 8; +const NROUNDSP: usize = 57; +const T: usize = 6; + +#[derive(Debug)] +pub struct Constants { + c: Vec<BigInt>, + m: Vec<Vec<BigInt>>, +} + +pub fn generate_constants() -> Constants { + let r: BigInt = BigInt::parse_bytes( + b"21888242871839275222246405745257275088548364400416034343698204186575808495617", + 10, + ) + .unwrap(); + + let c = get_pseudo_random(&r, format!("{}{}", SEED, "_constants"), NROUNDSF + NROUNDSP); + let m = get_mds(&r); + Constants { c: c, m: m } +} + +pub fn get_pseudo_random(r: &BigInt, seed: String, n: usize) -> Vec<BigInt> { + let mut hasher = VarBlake2b::new(32).unwrap(); + hasher.input(seed.as_bytes()); + let mut h = hasher.vec_result(); + + let mut res: Vec<BigInt> = Vec::new(); + while res.len() < n { + let new_n: BigInt = modulus(&BigInt::from_bytes_le(Sign::Plus, &h), &r); + res.push(new_n); + let mut hasher = VarBlake2b::new(32).unwrap(); + hasher.input(h); + h = hasher.vec_result(); + } + res +} + +pub fn nonce_to_string(n: usize) -> String { + let mut r = format!("{}", n); + while r.len() < 4 { + r = format!("0{}", r); + } + r +} + +pub fn get_mds(r: &BigInt) -> Vec<Vec<BigInt>> { + let mut nonce = 0; + let mut cauchy_matrix = get_pseudo_random( + r, + format!("{}_matrix_{}", SEED, nonce_to_string(nonce)), + T * 2, + ); + while !check_all_different(&cauchy_matrix) { + nonce = nonce + 1; + cauchy_matrix = get_pseudo_random( + r, + format!("{}_matrix_{}", SEED, nonce_to_string(nonce)), + T * 2, + ); + } + let mut m: Vec<Vec<BigInt>> = Vec::new(); + for i in 0..T { + let mut mi: Vec<BigInt> = Vec::new(); + for j in 0..T { + mi.push(modinv( + &modulus(&(&cauchy_matrix[i] - &cauchy_matrix[T + j]), &r), + &r, + )); + } + m.push(mi); + } + m +} + +pub fn check_all_different(v: &Vec<BigInt>) -> bool { + let zero: BigInt = Zero::zero(); + for i in 0..v.len() { + if v[i] == zero { + return false; + } + for j in i + 1..v.len() { + if v[i] == v[j] { + return false; + } + } + } + true +} + +pub fn modulus(a: &BigInt, m: &BigInt) -> BigInt { + ((a % m) + m) % m +} + +pub fn modinv(a: &BigInt, q: &BigInt) -> BigInt { + let mut mn = (q.clone(), a.clone()); + let mut xy: (BigInt, BigInt) = (Zero::zero(), One::one()); + + let big_zero: BigInt = Zero::zero(); + while mn.1 != big_zero { + xy = (xy.1.clone(), xy.0 - (mn.0.clone() / mn.1.clone()) * xy.1); + mn = (mn.1.clone(), modulus(&mn.0, &mn.1)); + } + + while xy.0 < Zero::zero() { + xy.0 = modulus(&xy.0, q); + } + xy.0 +} + +fn main() { + let c = generate_constants(); + println!("let c_str: Vec<&str> = vec!["); + for i in 0..c.c.len() { + println!(" {:?},", c.c[i].to_string()); + } + println!("];\n"); + println!("let m_str: Vec<Vec<&str>> = vec!["); + for i in 0..c.m.len() { + println!(" vec!["); + for j in 0..c.m[i].len() { + println!(" {:?},", c.m[i][j].to_string()); + } + println!(" ],"); + } + println!("];\n"); +} + +#[cfg(test)] +mod tests { + use super::*; + use rustc_hex::ToHex; + + #[test] + fn test_blake2_version() { + let mut hasher = VarBlake2b::new(32).unwrap(); + hasher.input(b"poseidon_constants"); + let h = hasher.vec_result(); + assert_eq!( + h.to_hex(), + "e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1" + ); + } +}