Browse Source

Update to last circomlib version

On a Intel(R) Core(TM) i7-8705G CPU @ 3.10GHz, with 32 GB of RAM:

- Before ff:
hash    time:   [927.61 us 927.78 us 927.98 us]

- Previous commit:
hash    time:   [26.495 us 26.503 us 26.512 us]

- New:
hash    time:   [9.8622 us 9.9953 us 10.127 us]
master
arnaucube 4 years ago
parent
commit
f30ebf7b71
6 changed files with 105 additions and 277 deletions
  1. +3
    -0
      Cargo.toml
  2. +2
    -5
      benches/bench_mimc_hash.rs
  3. +0
    -3
      gen_constants/.gitignore
  4. +0
    -14
      gen_constants/Cargo.toml
  5. +0
    -122
      gen_constants/src/main.rs
  6. +100
    -133
      src/lib.rs

+ 3
- 0
Cargo.toml

@ -11,6 +11,9 @@ readme = "README.md"
[dependencies] [dependencies]
ff = {package="ff_ce" , version="0.11", features = ["derive"]} ff = {package="ff_ce" , version="0.11", features = ["derive"]}
rand = "0.4" rand = "0.4"
num = "0.2.0"
num-bigint = "0.2.2"
tiny-keccak = "1.5"
[dev-dependencies] [dev-dependencies]
criterion = "0.3" criterion = "0.3"

+ 2
- 5
benches/bench_mimc_hash.rs

@ -15,12 +15,9 @@ fn criterion_benchmark(c: &mut Criterion) {
"12242166908188651009877250812424843524687801523336557272219921456462821518061", "12242166908188651009877250812424843524687801523336557272219921456462821518061",
) )
.unwrap(); .unwrap();
let mut big_arr: Vec<Fr> = Vec::new();
big_arr.push(b1.clone());
big_arr.push(b2.clone());
let mimc7 = Mimc7::new();
let mimc7 = Mimc7::new(91);
c.bench_function("hash", |b| b.iter(|| mimc7.hash(big_arr.clone())));
c.bench_function("hash", |b| b.iter(|| mimc7.hash(&b1, &b2)));
} }
criterion_group!(benches, criterion_benchmark); criterion_group!(benches, criterion_benchmark);

+ 0
- 3
gen_constants/.gitignore

@ -1,3 +0,0 @@
/target
**/*.rs.bk
Cargo.lock

+ 0
- 14
gen_constants/Cargo.toml

@ -1,14 +0,0 @@
[package]
name = "gen_constants"
version = "0.1.0"
authors = ["arnaucube <root@arnaucube.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
num = "0.2.0"
num-bigint = "0.2.2"
num-traits = "0.2.8"
tiny-keccak = "1.5"
rustc-hex = "1.0.0"

+ 0
- 122
gen_constants/src/main.rs

@ -1,122 +0,0 @@
extern crate num;
extern crate num_bigint;
extern crate num_traits;
use tiny_keccak::Keccak;
use num_bigint::{BigInt, Sign};
use num_traits::Zero;
const SEED: &str = "mimc";
pub struct Constants {
// seed_hash: BigInt,
// iv: BigInt,
r: BigInt,
n_rounds: i64,
cts: Vec<BigInt>,
}
pub fn modulus(a: &BigInt, m: &BigInt) -> BigInt {
((a % m) + m) % m
}
pub fn generate_constants() -> Constants {
let r: BigInt = BigInt::parse_bytes(
b"21888242871839275222246405745257275088548364400416034343698204186575808495617",
10,
)
.unwrap();
let mut keccak = Keccak::new_keccak256();
let mut h = [0u8; 32];
keccak.update(SEED.as_bytes());
keccak.finalize(&mut h);
let mut keccak = Keccak::new_keccak256();
let mut h_iv = [0u8; 32];
let seed_iv = format!("{}{}", SEED, "_iv");
keccak.update(seed_iv.as_bytes());
keccak.finalize(&mut h_iv);
// let seed_hash: BigInt = BigInt::from_bytes_be(Sign::Plus, &h);
// let c: BigInt = BigInt::from_bytes_be(Sign::Plus, &h_iv);
// let iv: BigInt = c % &r;
let n_rounds: i64 = 91;
let cts = get_constants(&r, SEED, n_rounds);
Constants {
// seed_hash: seed_hash,
// iv: iv,
r: r,
n_rounds: n_rounds,
cts: cts,
}
}
pub fn get_constants(r: &BigInt, seed: &str, n_rounds: i64) -> Vec<BigInt> {
let mut cts: Vec<BigInt> = Vec::new();
cts.push(Zero::zero());
let mut keccak = Keccak::new_keccak256();
let mut h = [0u8; 32];
keccak.update(seed.as_bytes());
keccak.finalize(&mut h);
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 = [0u8; 32];
keccak.update(&c_bytes[..]);
keccak.finalize(&mut h);
c = BigInt::from_bytes_be(Sign::Plus, &h);
let n = modulus(&c, &r);
cts.push(n);
}
// let l = cts.len();
// cts[l-1] = Zero::zero();
cts
}
fn main() {
let c = generate_constants();
println!("let cts_str: Vec<&str> = vec![");
for i in 0..c.cts.len() {
println!(" {:?},", c.cts[i].to_string());
}
println!("];");
println!("let n_rounds: i64 = {:?};", c.n_rounds);
}
#[cfg(test)]
mod tests {
use super::*;
use rustc_hex::ToHex;
#[test]
fn test_sha3() {
let mut keccak = Keccak::new_keccak256();
let mut res = [0u8; 32];
keccak.update(SEED.as_bytes());
keccak.finalize(&mut res);
assert_eq!(
res.to_hex(),
"b6e489e6b37224a50bebfddbe7d89fa8fdcaa84304a70bd13f79b5d9f7951e9e"
);
let mut keccak = Keccak::new_keccak256();
let mut res = [0u8; 32];
keccak.update(SEED.as_bytes());
keccak.finalize(&mut res);
let c = BigInt::from_bytes_be(Sign::Plus, &res);
assert_eq!(
c.to_string(),
"82724731331859054037315113496710413141112897654334566532528783843265082629790"
);
}
}

+ 100
- 133
src/lib.rs

@ -8,142 +8,79 @@ use ff::*;
#[PrimeFieldGenerator = "7"] #[PrimeFieldGenerator = "7"]
pub struct Fr(FrRepr); 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 { pub struct Constants {
n_rounds: i64,
n_rounds: usize,
cts: Vec<Fr>, 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 { Constants {
n_rounds: n_rounds, n_rounds: n_rounds,
cts: cts, 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 = [0u8; 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 = [0u8; 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 { pub struct Mimc7 {
constants: Constants, constants: Constants,
} }
impl Mimc7 { impl Mimc7 {
pub fn new() -> Mimc7 {
pub fn new(n_rounds: usize) -> Mimc7 {
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(); 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; let mut t: Fr;
if i == 0 { if i == 0 {
t = x_in.clone(); t = x_in.clone();
@ -164,6 +101,16 @@ impl Mimc7 {
h.add_assign(&k); h.add_assign(&k);
h 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)] #[cfg(test)]
@ -171,8 +118,8 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn test_load_constants() {
let constants = load_constants();
fn test_generate_constants() {
let constants = generate_constants(91);
assert_eq!( assert_eq!(
"Fr(0x2e2ebbb178296b63d88ec198f0976ad98bc1d4eb0d921ddd2eb86cb7e70a98e5)", "Fr(0x2e2ebbb178296b63d88ec198f0976ad98bc1d4eb0d921ddd2eb86cb7e70a98e5)",
constants.cts[1].to_string() constants.cts[1].to_string()
@ -180,7 +127,27 @@ mod tests {
} }
#[test] #[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 b12: Fr = Fr::from_str("12").unwrap();
let b45: Fr = Fr::from_str("45").unwrap(); let b45: Fr = Fr::from_str("45").unwrap();
let b78: Fr = Fr::from_str("78").unwrap(); let b78: Fr = Fr::from_str("78").unwrap();
@ -188,32 +155,32 @@ mod tests {
let mut big_arr1: Vec<Fr> = Vec::new(); let mut big_arr1: Vec<Fr> = Vec::new();
big_arr1.push(b12.clone()); 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!( assert_eq!(
h1.to_string(), h1.to_string(),
"Fr(0x237c92644dbddb86d8a259e0e923aaab65a93f1ec5758b8799988894ac0958fd)" "Fr(0x237c92644dbddb86d8a259e0e923aaab65a93f1ec5758b8799988894ac0958fd)"
); );
let mh2 = mimc7.mimc7_hash(&b12, &b45);
let mh2 = mimc7.hash(&b12, &b45);
assert_eq!( assert_eq!(
mh2.to_string(), mh2.to_string(),
"Fr(0x2ba7ebad3c6b6f5a20bdecba2333c63173ca1a5f2f49d958081d9fa7179c44e4)" "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!( assert_eq!(
h2.to_string(), h2.to_string(),
"Fr(0x067f3202335ea256ae6e6aadcd2d5f7f4b06a00b2d1e0de903980d5ab552dc70)" "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!( assert_eq!(
h1.to_string(), h1.to_string(),
"Fr(0x15ff7fe9793346a17c3150804bcb36d161c8662b110c50f55ccb7113948d8879)" "Fr(0x15ff7fe9793346a17c3150804bcb36d161c8662b110c50f55ccb7113948d8879)"
@ -224,8 +191,8 @@ mod tests {
big_arr1.push(b45.clone()); big_arr1.push(b45.clone());
big_arr1.push(b78.clone()); big_arr1.push(b78.clone());
big_arr1.push(b41.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!( assert_eq!(
h1.to_string(), h1.to_string(),
"Fr(0x284bc1f34f335933a23a433b6ff3ee179d682cd5e5e2fcdd2d964afa85104beb)" "Fr(0x284bc1f34f335933a23a433b6ff3ee179d682cd5e5e2fcdd2d964afa85104beb)"
@ -238,8 +205,8 @@ mod tests {
let mut big_arr1: Vec<Fr> = Vec::new(); let mut big_arr1: Vec<Fr> = Vec::new();
big_arr1.push(r_1.clone()); 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!( assert_eq!(
h1.to_string(), h1.to_string(),
"Fr(0x0a4fffe99225f9972ec39fd780dd084f349286c723d4dd42ad05e2e7421fef0e)" "Fr(0x0a4fffe99225f9972ec39fd780dd084f349286c723d4dd42ad05e2e7421fef0e)"

Loading…
Cancel
Save