From 568f34442e176bc8e3c778fbd32d820789b89be8 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Fri, 5 May 2023 11:27:50 +0200 Subject: [PATCH] port https://github.com/arnaucube/poseidon-rs to arkworks ff --- Cargo.toml | 14 +++---- README.md | 4 +- benches/bench_poseidon_hash.rs | 7 ++-- src/lib.rs | 74 ++++++++++++---------------------- 4 files changed, 39 insertions(+), 60 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 720497b..6edb60a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,17 @@ [package] -name = "poseidon-rs" -version = "0.0.8" +name = "poseidon-ark" +version = "0.0.1" authors = ["arnaucube "] -edition = "2018" +edition = "2021" license = "GPL-3.0" description = "Poseidon hash implementation" -repository = "https://github.com/arnaucube/poseidon-rs" +repository = "https://github.com/arnaucube/poseidon-ark" readme = "README.md" [dependencies] -ff = {package="ff_ce" , version="0.11", features = ["derive"]} -rand = "0.4" -serde_json = "1.0" +ark-ff = "0.4.0" +ark-bn254 = { version = "0.4.0" } +ark-std = { version = "0.4.0" } [dev-dependencies] criterion = "0.3" diff --git a/README.md b/README.md index 166206d..1f88dba 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# poseidon-rs [![Crates.io](https://img.shields.io/crates/v/poseidon-rs.svg)](https://crates.io/crates/poseidon-rs) [![Test](https://github.com/arnaucube/poseidon-rs/workflows/Test/badge.svg)](https://github.com/arnaucube/poseidon-rs/actions?query=workflow%3ATest) +# poseidon-ark [![Test](https://github.com/arnaucube/poseidon-ark/workflows/Test/badge.svg)](https://github.com/arnaucube/poseidon-ark/actions?query=workflow%3ATest) + +> **Note**: this repo is a fork from https://github.com/arnaucube/poseidon-rs , porting it to arkworks [ff](https://github.com/arkworks-rs/algebra/tree/master/ff). Poseidon hash implementation in Rust, a zkSNARK friendly hash function. diff --git a/benches/bench_poseidon_hash.rs b/benches/bench_poseidon_hash.rs index b8ab56a..104ab0c 100644 --- a/benches/bench_poseidon_hash.rs +++ b/benches/bench_poseidon_hash.rs @@ -1,10 +1,9 @@ use criterion::{criterion_group, criterion_main, Criterion}; -#[macro_use] -extern crate ff; -use ff::*; +use ark_bn254::Fr; +use poseidon_rs::Poseidon; -use poseidon_rs::{Fr, Poseidon}; +use ark_std::str::FromStr; fn criterion_benchmark(c: &mut Criterion) { let b1: Fr = Fr::from_str( diff --git a/src/lib.rs b/src/lib.rs index a94cd20..d9b8fe1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,8 @@ -extern crate rand; -#[macro_use] -extern crate ff; -use ff::*; - -#[derive(PrimeField)] -#[PrimeFieldModulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"] -#[PrimeFieldGenerator = "7"] -pub struct Fr(FrRepr); +use ark_bn254::Fr; +use ark_ff::fields::Field; +use ark_std::str::FromStr; +use ark_std::Zero; +use core::ops::{AddAssign, MulAssign}; mod constants; @@ -17,6 +13,7 @@ pub struct Constants { pub n_rounds_f: usize, pub n_rounds_p: Vec, } + pub fn load_constants() -> Constants { let (c_str, m_str) = constants::constants(); let mut c: Vec> = Vec::new(); @@ -42,8 +39,8 @@ pub fn load_constants() -> Constants { m.push(mi); } Constants { - c: c, - m: m, + c, + m, n_rounds_f: 8, n_rounds_p: vec![56, 57, 56, 60, 60, 63, 64, 63], } @@ -58,7 +55,7 @@ impl Poseidon { constants: load_constants(), } } - pub fn ark(&self, state: &mut Vec, c: &Vec, it: usize) { + pub fn ark(&self, state: &mut Vec, c: &[Fr], it: usize) { for i in 0..state.len() { state[i].add_assign(&c[it + i]); } @@ -68,19 +65,19 @@ impl Poseidon { if i < n_rounds_f / 2 || i >= n_rounds_f / 2 + n_rounds_p { for j in 0..state.len() { let aux = state[j]; - state[j].square(); - state[j].square(); + state[j] = state[j].square(); + state[j] = state[j].square(); state[j].mul_assign(&aux); } } else { let aux = state[0]; - state[0].square(); - state[0].square(); + state[0] = state[0].square(); + state[0] = state[0].square(); state[0].mul_assign(&aux); } } - pub fn mix(&self, state: &Vec, m: &Vec>) -> Vec { + pub fn mix(&self, state: &Vec, m: &[Vec]) -> Vec { let mut new_state: Vec = Vec::new(); for i in 0..state.len() { new_state.push(Fr::zero()); @@ -95,7 +92,7 @@ impl Poseidon { pub fn hash(&self, inp: Vec) -> Result { let t = inp.len() + 1; - if inp.len() == 0 || inp.len() >= self.constants.n_rounds_p.len() - 1 { + if inp.is_empty() || inp.len() >= self.constants.n_rounds_p.len() - 1 { return Err("Wrong inputs length".to_string()); } let n_rounds_f = self.constants.n_rounds_f.clone(); @@ -118,43 +115,24 @@ impl Poseidon { mod tests { use super::*; - #[test] - fn test_ff() { - let a = Fr::from_repr(FrRepr::from(2)).unwrap(); - assert_eq!( - "0000000000000000000000000000000000000000000000000000000000000002", - to_hex(&a) - ); - - let b: Fr = Fr::from_str( - "21888242871839275222246405745257275088548364400416034343698204186575808495619", - ) - .unwrap(); - assert_eq!( - "0000000000000000000000000000000000000000000000000000000000000002", - to_hex(&b) - ); - assert_eq!(&a, &b); - } - #[test] fn test_load_constants() { let cons = load_constants(); assert_eq!( cons.c[0][0].to_string(), - "Fr(0x09c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7)" + "4417881134626180770308697923359573201005643519861877412381846989312604493735" ); assert_eq!( cons.c[cons.c.len() - 1][0].to_string(), - "Fr(0x2088ce9534577bf38be7bc457f2756d558d66e0c07b9cc001a580bd42cda0e77)" + "14715728137766105031387583973733149375806784983272780095398485311648630967927" ); assert_eq!( cons.m[0][0][0].to_string(), - "Fr(0x066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5)" + "2910766817845651019878574839501801340070030115151021261302834310722729507541" ); assert_eq!( cons.m[cons.m.len() - 1][0][0].to_string(), - "Fr(0x0190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56)" + "708458300293891745856425423607721463509413916954480913172999113933455141974" ); } @@ -174,7 +152,7 @@ mod tests { let h = poseidon.hash(big_arr.clone()).unwrap(); assert_eq!( h.to_string(), - "Fr(0x29176100eaa962bdc1fe6c654d6a3c130e96a4d1168b33848b897dc502820133)" // "18586133768512220936620570745912940619677854269274689475585506675881198879027" + "18586133768512220936620570745912940619677854269274689475585506675881198879027" ); let mut big_arr: Vec = Vec::new(); @@ -184,7 +162,7 @@ mod tests { let h = poseidon.hash(big_arr.clone()).unwrap(); assert_eq!( h.to_string(), - "Fr(0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a)" // "7853200120776062878684798364095072458815029376092732009249414926327459813530" + "7853200120776062878684798364095072458815029376092732009249414926327459813530" ); let mut big_arr: Vec = Vec::new(); @@ -197,7 +175,7 @@ mod tests { let h = poseidon.hash(big_arr.clone()).unwrap(); assert_eq!( h.to_string(), - "Fr(0x024058dd1e168f34bac462b6fffe58fd69982807e9884c1c6148182319cee427)" // "1018317224307729531995786483840663576608797660851238720571059489595066344487" + "1018317224307729531995786483840663576608797660851238720571059489595066344487" ); let mut big_arr: Vec = Vec::new(); @@ -211,7 +189,7 @@ mod tests { let h = poseidon.hash(big_arr.clone()).unwrap(); assert_eq!( h.to_string(), - "Fr(0x21e82f465e00a15965e97a44fe3c30f3bf5279d8bf37d4e65765b6c2550f42a1)" // "15336558801450556532856248569924170992202208561737609669134139141992924267169" + "15336558801450556532856248569924170992202208561737609669134139141992924267169" ); let mut big_arr: Vec = Vec::new(); @@ -224,7 +202,7 @@ mod tests { let h = poseidon.hash(big_arr.clone()).unwrap(); assert_eq!( h.to_string(), - "Fr(0x0cd93f1bab9e8c9166ef00f2a1b0e1d66d6a4145e596abe0526247747cc71214)" // "5811595552068139067952687508729883632420015185677766880877743348592482390548" + "5811595552068139067952687508729883632420015185677766880877743348592482390548" ); let mut big_arr: Vec = Vec::new(); @@ -237,7 +215,7 @@ mod tests { let h = poseidon.hash(big_arr.clone()).unwrap(); assert_eq!( h.to_string(), - "Fr(0x1b1caddfc5ea47e09bb445a7447eb9694b8d1b75a97fff58e884398c6b22825a)" // "12263118664590987767234828103155242843640892839966517009184493198782366909018" + "12263118664590987767234828103155242843640892839966517009184493198782366909018" ); let mut big_arr: Vec = Vec::new(); @@ -250,7 +228,7 @@ mod tests { let h = poseidon.hash(big_arr.clone()).unwrap(); assert_eq!( h.to_string(), - "Fr(0x2d1a03850084442813c8ebf094dea47538490a68b05f2239134a4cca2f6302e1)" // "20400040500897583745843009878988256314335038853985262692600694741116813247201" + "20400040500897583745843009878988256314335038853985262692600694741116813247201" ); } }