@ -8,142 +8,79 @@ use ff::*;
#[ PrimeFieldGenerator = " 7 " ]
pub struct Fr ( FrRepr ) ;
extern crate num ;
extern crate num_bigint ;
use num_bigint ::{ BigInt , Sign } ;
use tiny_keccak ::Keccak ;
const SEED : & str = "mimc" ;
pub struct Constants {
n_rounds : i64 ,
n_rounds : usize ,
cts : Vec < Fr > ,
}
pub fn load_constants ( ) -> Constants {
// constants generated from the 'gen_constants' subpackage
let cts_str : Vec < & str > = vec ! [
"0" ,
"20888961410941983456478427210666206549300505294776164667214940546594746570981" ,
"15265126113435022738560151911929040668591755459209400716467504685752745317193" ,
"8334177627492981984476504167502758309043212251641796197711684499645635709656" ,
"1374324219480165500871639364801692115397519265181803854177629327624133579404" ,
"11442588683664344394633565859260176446561886575962616332903193988751292992472" ,
"2558901189096558760448896669327086721003508630712968559048179091037845349145" ,
"11189978595292752354820141775598510151189959177917284797737745690127318076389" ,
"3262966573163560839685415914157855077211340576201936620532175028036746741754" ,
"17029914891543225301403832095880481731551830725367286980611178737703889171730" ,
"4614037031668406927330683909387957156531244689520944789503628527855167665518" ,
"19647356996769918391113967168615123299113119185942498194367262335168397100658" ,
"5040699236106090655289931820723926657076483236860546282406111821875672148900" ,
"2632385916954580941368956176626336146806721642583847728103570779270161510514" ,
"17691411851977575435597871505860208507285462834710151833948561098560743654671" ,
"11482807709115676646560379017491661435505951727793345550942389701970904563183" ,
"8360838254132998143349158726141014535383109403565779450210746881879715734773" ,
"12663821244032248511491386323242575231591777785787269938928497649288048289525" ,
"3067001377342968891237590775929219083706800062321980129409398033259904188058" ,
"8536471869378957766675292398190944925664113548202769136103887479787957959589" ,
"19825444354178182240559170937204690272111734703605805530888940813160705385792" ,
"16703465144013840124940690347975638755097486902749048533167980887413919317592" ,
"13061236261277650370863439564453267964462486225679643020432589226741411380501" ,
"10864774797625152707517901967943775867717907803542223029967000416969007792571" ,
"10035653564014594269791753415727486340557376923045841607746250017541686319774" ,
"3446968588058668564420958894889124905706353937375068998436129414772610003289" ,
"4653317306466493184743870159523234588955994456998076243468148492375236846006" ,
"8486711143589723036499933521576871883500223198263343024003617825616410932026" ,
"250710584458582618659378487568129931785810765264752039738223488321597070280" ,
"2104159799604932521291371026105311735948154964200596636974609406977292675173" ,
"16313562605837709339799839901240652934758303521543693857533755376563489378839" ,
"6032365105133504724925793806318578936233045029919447519826248813478479197288" ,
"14025118133847866722315446277964222215118620050302054655768867040006542798474" ,
"7400123822125662712777833064081316757896757785777291653271747396958201309118" ,
"1744432620323851751204287974553233986555641872755053103823939564833813704825" ,
"8316378125659383262515151597439205374263247719876250938893842106722210729522" ,
"6739722627047123650704294650168547689199576889424317598327664349670094847386" ,
"21211457866117465531949733809706514799713333930924902519246949506964470524162" ,
"13718112532745211817410303291774369209520657938741992779396229864894885156527" ,
"5264534817993325015357427094323255342713527811596856940387954546330728068658" ,
"18884137497114307927425084003812022333609937761793387700010402412840002189451" ,
"5148596049900083984813839872929010525572543381981952060869301611018636120248" ,
"19799686398774806587970184652860783461860993790013219899147141137827718662674" ,
"19240878651604412704364448729659032944342952609050243268894572835672205984837" ,
"10546185249390392695582524554167530669949955276893453512788278945742408153192" ,
"5507959600969845538113649209272736011390582494851145043668969080335346810411" ,
"18177751737739153338153217698774510185696788019377850245260475034576050820091" ,
"19603444733183990109492724100282114612026332366576932662794133334264283907557" ,
"10548274686824425401349248282213580046351514091431715597441736281987273193140" ,
"1823201861560942974198127384034483127920205835821334101215923769688644479957" ,
"11867589662193422187545516240823411225342068709600734253659804646934346124945" ,
"18718569356736340558616379408444812528964066420519677106145092918482774343613" ,
"10530777752259630125564678480897857853807637120039176813174150229243735996839" ,
"20486583726592018813337145844457018474256372770211860618687961310422228379031" ,
"12690713110714036569415168795200156516217175005650145422920562694422306200486" ,
"17386427286863519095301372413760745749282643730629659997153085139065756667205" ,
"2216432659854733047132347621569505613620980842043977268828076165669557467682" ,
"6309765381643925252238633914530877025934201680691496500372265330505506717193" ,
"20806323192073945401862788605803131761175139076694468214027227878952047793390" ,
"4037040458505567977365391535756875199663510397600316887746139396052445718861" ,
"19948974083684238245321361840704327952464170097132407924861169241740046562673" ,
"845322671528508199439318170916419179535949348988022948153107378280175750024" ,
"16222384601744433420585982239113457177459602187868460608565289920306145389382" ,
"10232118865851112229330353999139005145127746617219324244541194256766741433339" ,
"6699067738555349409504843460654299019000594109597429103342076743347235369120" ,
"6220784880752427143725783746407285094967584864656399181815603544365010379208" ,
"6129250029437675212264306655559561251995722990149771051304736001195288083309" ,
"10773245783118750721454994239248013870822765715268323522295722350908043393604" ,
"4490242021765793917495398271905043433053432245571325177153467194570741607167" ,
"19596995117319480189066041930051006586888908165330319666010398892494684778526" ,
"837850695495734270707668553360118467905109360511302468085569220634750561083" ,
"11803922811376367215191737026157445294481406304781326649717082177394185903907" ,
"10201298324909697255105265958780781450978049256931478989759448189112393506592" ,
"13564695482314888817576351063608519127702411536552857463682060761575100923924" ,
"9262808208636973454201420823766139682381973240743541030659775288508921362724" ,
"173271062536305557219323722062711383294158572562695717740068656098441040230" ,
"18120430890549410286417591505529104700901943324772175772035648111937818237369" ,
"20484495168135072493552514219686101965206843697794133766912991150184337935627" ,
"19155651295705203459475805213866664350848604323501251939850063308319753686505" ,
"11971299749478202793661982361798418342615500543489781306376058267926437157297" ,
"18285310723116790056148596536349375622245669010373674803854111592441823052978" ,
"7069216248902547653615508023941692395371990416048967468982099270925308100727" ,
"6465151453746412132599596984628739550147379072443683076388208843341824127379" ,
"16143532858389170960690347742477978826830511669766530042104134302796355145785" ,
"19362583304414853660976404410208489566967618125972377176980367224623492419647" ,
"1702213613534733786921602839210290505213503664731919006932367875629005980493" ,
"10781825404476535814285389902565833897646945212027592373510689209734812292327" ,
"4212716923652881254737947578600828255798948993302968210248673545442808456151" ,
"7594017890037021425366623750593200398174488805473151513558919864633711506220" ,
"18979889247746272055963929241596362599320706910852082477600815822482192194401" ,
"13602139229813231349386885113156901793661719180900395818909719758150455500533" ,
] ;
let n_rounds : i64 = 91 ;
pub fn generate_constants ( n_rounds : usize ) -> Constants {
let cts = get_constants ( SEED , n_rounds ) ;
let mut cts : Vec < Fr > = Vec ::new ( ) ;
for i in 0 . . cts_str . len ( ) {
let n : Fr = Fr ::from_str ( cts_str [ i ] ) . unwrap ( ) ;
cts . push ( n ) ;
}
Constants {
n_rounds : n_rounds ,
cts : cts ,
}
}
pub fn get_constants ( seed : & str , n_rounds : usize ) -> Vec < Fr > {
let mut cts : Vec < Fr > = Vec ::new ( ) ;
cts . push ( Fr ::zero ( ) ) ;
let mut keccak = Keccak ::new_keccak256 ( ) ;
let mut h = [ 0 u8 ; 32 ] ;
keccak . update ( seed . as_bytes ( ) ) ;
keccak . finalize ( & mut h ) ;
let r : BigInt = BigInt ::parse_bytes (
b" 21888242871839275222246405745257275088548364400416034343698204186575808495617 " ,
10 ,
)
. unwrap ( ) ;
let mut c = BigInt ::from_bytes_be ( Sign ::Plus , & h ) ;
for _ in 1 . . n_rounds {
let ( _ , c_bytes ) = c . to_bytes_be ( ) ;
let mut c_bytes32 : [ u8 ; 32 ] = [ 0 ; 32 ] ;
let diff = c_bytes32 . len ( ) - c_bytes . len ( ) ;
c_bytes32 [ diff . . ] . copy_from_slice ( & c_bytes [ . . ] ) ;
let mut keccak = Keccak ::new_keccak256 ( ) ;
let mut h = [ 0 u8 ; 32 ] ;
keccak . update ( & c_bytes [ . . ] ) ;
keccak . finalize ( & mut h ) ;
c = BigInt ::from_bytes_be ( Sign ::Plus , & h ) ;
let n = modulus ( & c , & r ) ;
cts . push ( Fr ::from_str ( & n . to_string ( ) ) . unwrap ( ) ) ;
}
cts
}
pub fn modulus ( a : & BigInt , m : & BigInt ) -> BigInt {
( ( a % m ) + m ) % m
}
pub struct Mimc7 {
constants : Constants ,
}
impl Mimc7 {
pub fn new ( ) -> Mimc7 {
pub fn new ( n_rounds : usize ) -> Mimc7 {
Mimc7 {
constants : load_constants ( ) ,
}
}
pub fn hash ( & self , arr : Vec < Fr > ) -> Fr {
let mut h : Fr = Fr ::zero ( ) ;
for i in 0 . . arr . len ( ) {
h . add_assign ( & self . mimc7_hash ( & arr [ i ] , & h ) ) ;
h . add_assign ( & arr [ i ] . clone ( ) ) ;
constants : generate_constants ( n_rounds ) ,
}
h
}
pub fn mimc7_hash ( & self , x_in : & Fr , k : & Fr ) -> Fr {
pub fn hash ( & self , x_in : & Fr , k : & Fr ) -> Fr {
let mut h : Fr = Fr ::zero ( ) ;
for i in 0 . . self . constants . n_rounds as usize {
for i in 0 . . self . constants . n_rounds {
let mut t : Fr ;
if i = = 0 {
t = x_in . clone ( ) ;
@ -164,6 +101,16 @@ impl Mimc7 {
h . add_assign ( & k ) ;
h
}
pub fn multi_hash ( & self , arr : Vec < Fr > , key : & Fr ) -> Fr {
let mut r = key . clone ( ) ;
for i in 0 . . arr . len ( ) {
let h = self . hash ( & arr [ i ] , & r ) ;
r . add_assign ( & arr [ i ] ) ;
r . add_assign ( & h ) ;
}
r
}
}
#[ cfg(test) ]
@ -171,8 +118,8 @@ mod tests {
use super ::* ;
#[ test ]
fn test_load _constants ( ) {
let constants = load_constants ( ) ;
fn test_generate _constants ( ) {
let constants = generate_constants ( 91 ) ;
assert_eq ! (
"Fr(0x2e2ebbb178296b63d88ec198f0976ad98bc1d4eb0d921ddd2eb86cb7e70a98e5)" ,
constants . cts [ 1 ] . to_string ( )
@ -180,7 +127,27 @@ mod tests {
}
#[ test ]
fn test_mimc7 ( ) {
fn test_mimc ( ) {
let b1 : Fr = Fr ::from_str ( "1" ) . unwrap ( ) ;
let b2 : Fr = Fr ::from_str ( "2" ) . unwrap ( ) ;
let mimc7 = Mimc7 ::new ( 91 ) ;
let h1 = mimc7 . hash ( & b1 , & b2 ) ;
assert_eq ! (
h1 . to_string ( ) ,
"Fr(0x176c6eefc3fdf8d6136002d8e6f7a885bbd1c4e3957b93ddc1ec3ae7859f1a08)"
) ;
let b3 : Fr = Fr ::from_str ( "3" ) . unwrap ( ) ;
let mut arr : Vec < Fr > = Vec ::new ( ) ;
arr . push ( b1 . clone ( ) ) ;
arr . push ( b2 . clone ( ) ) ;
arr . push ( b3 . clone ( ) ) ;
let h1 = mimc7 . multi_hash ( arr , & Fr ::zero ( ) ) ;
assert_eq ! (
h1 . to_string ( ) ,
"Fr(0x25f5a6429a9764564be3955e6f56b0b9143c571528fd30a80ae6c27dc8b4a40c)"
) ;
let b12 : Fr = Fr ::from_str ( "12" ) . unwrap ( ) ;
let b45 : Fr = Fr ::from_str ( "45" ) . unwrap ( ) ;
let b78 : Fr = Fr ::from_str ( "78" ) . unwrap ( ) ;
@ -188,32 +155,32 @@ mod tests {
let mut big_arr1 : Vec < Fr > = Vec ::new ( ) ;
big_arr1 . push ( b12 . clone ( ) ) ;
let mimc7 = Mimc7 ::new ( ) ;
let h1 = mimc7 . hash ( big_arr1 ) ;
let mimc7 = Mimc7 ::new ( 91 ) ;
let h1 = mimc7 . multi_ hash( big_arr1 , & Fr ::zero ( ) ) ;
assert_eq ! (
h1 . to_string ( ) ,
"Fr(0x237c92644dbddb86d8a259e0e923aaab65a93f1ec5758b8799988894ac0958fd)"
) ;
let mh2 = mimc7 . mimc7_ hash( & b12 , & b45 ) ;
let mh2 = mimc7 . hash ( & b12 , & b45 ) ;
assert_eq ! (
mh2 . to_string ( ) ,
"Fr(0x2ba7ebad3c6b6f5a20bdecba2333c63173ca1a5f2f49d958081d9fa7179c44e4)"
) ;
let mut big_arr2 : Vec < Fr > = Vec ::new ( ) ;
big_arr2 . push ( b78 . clone ( ) ) ;
big_arr2 . push ( b41 . clone ( ) ) ;
let h2 = mimc7 . hash ( big_arr2 ) ;
let mut big_arr1 : Vec < Fr > = Vec ::new ( ) ;
big_arr1 . push ( b78 . clone ( ) ) ;
big_arr1 . push ( b41 . clone ( ) ) ;
let h2 = mimc7 . multi_ hash( big_arr1 , & Fr ::zero ( ) ) ;
assert_eq ! (
h2 . to_string ( ) ,
"Fr(0x067f3202335ea256ae6e6aadcd2d5f7f4b06a00b2d1e0de903980d5ab552dc70)"
) ;
let mut big_arr2 : Vec < Fr > = Vec ::new ( ) ;
big_arr2 . push ( b12 . clone ( ) ) ;
big_arr2 . push ( b45 . clone ( ) ) ;
let h1 = mimc7 . hash ( big_arr2 ) ;
let mut big_arr1 : Vec < Fr > = Vec ::new ( ) ;
big_arr1 . push ( b12 . clone ( ) ) ;
big_arr1 . push ( b45 . clone ( ) ) ;
let h1 = mimc7 . multi_ hash( big_arr1 , & Fr ::zero ( ) ) ;
assert_eq ! (
h1 . to_string ( ) ,
"Fr(0x15ff7fe9793346a17c3150804bcb36d161c8662b110c50f55ccb7113948d8879)"
@ -224,8 +191,8 @@ mod tests {
big_arr1 . push ( b45 . clone ( ) ) ;
big_arr1 . push ( b78 . clone ( ) ) ;
big_arr1 . push ( b41 . clone ( ) ) ;
let mimc7 = Mimc7 ::new ( ) ;
let h1 = mimc7 . hash ( big_arr1 ) ;
let mimc7 = Mimc7 ::new ( 91 ) ;
let h1 = mimc7 . multi_ hash( big_arr1 , & Fr ::zero ( ) ) ;
assert_eq ! (
h1 . to_string ( ) ,
"Fr(0x284bc1f34f335933a23a433b6ff3ee179d682cd5e5e2fcdd2d964afa85104beb)"
@ -238,8 +205,8 @@ mod tests {
let mut big_arr1 : Vec < Fr > = Vec ::new ( ) ;
big_arr1 . push ( r_1 . clone ( ) ) ;
let mimc7 = Mimc7 ::new ( ) ;
let h1 = mimc7 . hash ( big_arr1 ) ;
let mimc7 = Mimc7 ::new ( 91 ) ;
let h1 = mimc7 . multi_ hash( big_arr1 , & Fr ::zero ( ) ) ;
assert_eq ! (
h1 . to_string ( ) ,
"Fr(0x0a4fffe99225f9972ec39fd780dd084f349286c723d4dd42ad05e2e7421fef0e)"