@ -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 < usize > ,
}
pub fn load_constants ( ) -> Constants {
let ( c_str , m_str ) = constants ::constants ( ) ;
let mut c : Vec < Vec < Fr > > = 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 < Fr > , c : & Vec < Fr > , it : usize ) {
pub fn ark ( & self , state : & mut Vec < Fr > , 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 < Fr > , m : & Vec < Vec < Fr > > ) -> Vec < Fr > {
pub fn mix ( & self , state : & Vec < Fr > , m : & [ Vec < Fr > ] ) -> Vec < Fr > {
let mut new_state : Vec < Fr > = 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 < Fr > ) -> Result < Fr , String > {
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 < Fr > = 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 < Fr > = 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 < Fr > = 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 < Fr > = 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 < Fr > = 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 < Fr > = 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"
) ;
}
}