From 5f3be9f7d45119de252746c8bf02e87bba565ab6 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Fri, 9 Oct 2020 16:46:43 +0800 Subject: [PATCH 01/17] test(VDF): add bench tests for VDF in rsa group --- Cargo.toml | 5 ++ README.md | 20 +++++- benches/vdf/rsa_group.rs | 139 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 benches/vdf/rsa_group.rs diff --git a/Cargo.toml b/Cargo.toml index 75fdbf5..60473ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,3 +29,8 @@ sha2 = "0.9.1" name = "bench-vdf-class" path = "benches/vdf/class_group.rs" harness = false + +[[bench]] +name = "bench-vdf-rsa" +path = "benches/vdf/rsa_group.rs" +harness = false diff --git a/README.md b/README.md index 0bec857..f6a7e5f 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Use `Cargo build`. The library uses bindings to PARI c library. Running `Cargo build` for the first time will take PARI from the _depend_ folder and install it on the machine. It was tested on MacOS and Linux. If you encounter a problem with installation of PARI, please open an issue and try to install it [manually](https://pari.math.u-bordeaux.fr/download.html). Bindings are generated automatically on the fly which might slow down the build procces by a few seconds. -Test +Unit-test ------------------- Tests in rust are multi-thearded if possible. However, PARI configuration supports a single thread. Therefore to make sure all tests run with defined behaviour please use `cargo test -- --test-threads=1`. @@ -49,6 +49,24 @@ Tests in rust are multi-thearded if possible. However, PARI configuration suppor We use tests to demonstrate correctness of each primitive: At the end of each primitive `.rs` file there is a test to show the correct usage of the primitive. There is usually one test or more to show soundness of the implementation, i.e. not knowing a witness will fail a PoK. For all tests we assume 128bit security (conservatively translates into 1600bit Discriminant). +Bench-test +------------------- +Currenly this library supports benchmarking Wesolowski VDF in class_group vs in rsa_group. As aforementioned, PARI configuration only supports a single thread. To benchtest using PARI we need to use `--jobs 1` flag. + +You can change and expand the test cases in `benches/vdf/class_group.rs`. You may also need to increase pari_init size (first parameter in `pari_init`) in src/primitives/vdf.rs if testing a larger `t`. We recommend testing each case respectively (i.e., `for &i in &[1_000] {`, `for &i in &[2_000] {` ..., instead of `for &i in &[1_000, 2_000, 5_000] {`) if the memory is limited. + +**Usage** + +benchmarking class_group VDF: +``` +cargo bench --bench bench-vdf-class --jobs 1 +``` + +benchmarking rsa_group VDF: +``` +cargo bench --bench bench-vdf-rsa --jobs 1 +``` + Security ------------------- Security assumptions can differ between primitives and are discussed in the relevant papers. They should be understood well before using any primitive. The code is not audited and we did not attempted to make it constant time. Do not use this library in production system. diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs new file mode 100644 index 0000000..0fd8814 --- /dev/null +++ b/benches/vdf/rsa_group.rs @@ -0,0 +1,139 @@ +#[macro_use] +extern crate criterion; + +use criterion::Criterion; +use rug::Integer; +use sha2::{Digest, Sha256}; + +/// algo_2 from the paper +fn verify(modulus: &Integer, g: &Integer, t: u64, y: &Integer, pi: &Integer) -> bool { + let modulus = modulus.clone(); + + let l = hash_to_prime(&modulus, &[&g, &y]); + + let r = Integer::from(2).pow_mod(&Integer::from(t), &l).unwrap(); + let pi_l = pi.clone().pow_mod(&l, &modulus).unwrap(); + let g_r = g.clone().pow_mod(&r, &modulus).unwrap(); + let pi_l_g_r = pi_l * g_r; + + Integer::from(pi_l_g_r.div_rem_floor(modulus.clone()).1) == y.clone() +} + +/// algo_3 from the paper +fn eval(modulus: &Integer, g: &Integer, t: u64) -> (Integer, Integer) { + let modulus = modulus.clone(); + + // y <- (g^2)^t + let mut y = g.clone(); + for _ in 0..t { + y = y.clone() * y.clone(); + y = y.div_rem_floor(modulus.clone()).1; + } + + let l = hash_to_prime(&modulus, &[&g, &y]); + + // algo_4 from the paper, long division + // TODO: consider algo_5 instead + let mut b: Integer; + let mut r = Integer::from(1); + let mut r2: Integer; + let two = Integer::from(2); + let mut pi = Integer::from(1); + + for _ in 0..t { + r2 = r.clone() * two.clone(); + b = r2.clone().div_rem_floor(l.clone()).0; + r = r2.clone().div_rem_floor(l.clone()).1; + let pi_2 = pi.clone().pow_mod(&two, &modulus).unwrap(); + let g_b = g.clone().pow_mod(&b, &modulus).unwrap(); + pi = pi_2 * g_b; + } + pi = Integer::from(pi.div_rem_floor(modulus.clone()).1); + (y, pi) +} + +/// int(H("residue"||x)) mod N +fn h_g(modulus: &Integer, seed: &Integer) -> Integer { + let modulus = modulus.clone(); + let mut hasher = Sha256::new(); + hasher.update("residue".as_bytes()); + hasher.update(&seed.clone().to_string_radix(16).as_bytes()); + let result_hex = hasher.finalize(); + let result_hex_str = format!("{:#x}", result_hex); + let result_int = Integer::from_str_radix(&result_hex_str, 16).unwrap(); + + // inverse, to get enough security bits + match result_int.invert(&modulus.clone()) { + Ok(inverse) => inverse, + Err(unchanged) => unchanged, + } +} + +fn hash_to_prime(modulus: &Integer, inputs: &[&Integer]) -> Integer { + let mut hasher = Sha256::new(); + for input in inputs { + hasher.update(input.to_string_radix(16).as_bytes()); + hasher.update("\n".as_bytes()); + } + let hashed_hex = hasher.finalize(); + let hashed_hex_str = format!("{:#x}", hashed_hex); + let hashed_int = Integer::from_str_radix(&hashed_hex_str, 16).unwrap(); + + // inverse, to get enough security bits + let inverse = match hashed_int.invert(&modulus.clone()) { + Ok(inverse) => inverse, + Err(unchanged) => unchanged, + }; + + Integer::from(inverse.next_prime().div_rem_floor(modulus.clone()).1) +} + +fn benches_rsa(c: &mut Criterion) { + let bench_eval = |c: &mut Criterion, difficulty: u64, modulus: &Integer, seed: &Integer| { + c.bench_function(&format!("eval with difficulty {}", difficulty), move |b| { + b.iter(|| eval(&modulus, &seed, difficulty)) + }); + }; + let bench_verify = |c: &mut Criterion, + difficulty: u64, + modulus: &Integer, + seed: &Integer, + y: &Integer, + pi: &Integer| { + c.bench_function( + &format!("verify with difficulty {}", difficulty), + move |b| b.iter(|| verify(&modulus, &seed, difficulty, &y, &pi)), + ); + }; + + /// RSA-2048 modulus, taken from [Wikipedia](https://en.wikipedia.org/wiki/RSA_numbers#RSA-2048). + pub const MODULUS: &str = + "251959084756578934940271832400483985714292821262040320277771378360436620207075955562640185258807\ + 8440691829064124951508218929855914917618450280848912007284499268739280728777673597141834727026189\ + 6375014971824691165077613379859095700097330459748808428401797429100642458691817195118746121515172\ + 6546322822168699875491824224336372590851418654620435767984233871847744479207399342365848238242811\ + 9816381501067481045166037730605620161967625613384414360383390441495263443219011465754445417842402\ + 0924616515723350778707749817125772467962926386356373289912154831438167899885040445364023527381951\ + 378636564391212010397122822120720357"; + let modulus = Integer::from_str_radix(MODULUS, 10).unwrap(); + + const TEST_HASH: &str = "1eeb30c7163271850b6d018e8282093ac6755a771da6267edf6c9b4fce9242ba"; + let seed_hash = Integer::from_str_radix(TEST_HASH, 16).unwrap(); + let seed = Integer::from(seed_hash.div_rem_floor(modulus.clone()).1); + + // g <- H_G(x) + let g = h_g(&modulus, &seed); + + for &i in &[1_000, 2_000, 5_000, 10_000, 100_000, 1_000_000] { + // precompute for verification + let (y, pi) = eval(&modulus, &g, i); + let result = verify(&modulus, &g, i, &y, &pi); + assert!(result); + + bench_eval(c, i, &modulus, &seed); + bench_verify(c, i, &modulus, &seed, &y, &pi) + } +} + +criterion_group!(benches, benches_rsa); +criterion_main!(benches); From e778a1dc959e39f1c611744779ca322fffc9d7d2 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Wed, 18 Nov 2020 19:15:43 +0800 Subject: [PATCH 02/17] opt --- benches/vdf/rsa_group.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 0fd8814..19d072d 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -57,13 +57,11 @@ fn h_g(modulus: &Integer, seed: &Integer) -> Integer { let modulus = modulus.clone(); let mut hasher = Sha256::new(); hasher.update("residue".as_bytes()); - hasher.update(&seed.clone().to_string_radix(16).as_bytes()); - let result_hex = hasher.finalize(); - let result_hex_str = format!("{:#x}", result_hex); - let result_int = Integer::from_str_radix(&result_hex_str, 16).unwrap(); + hasher.update(seed.to_digits::(Order::Lsf)); + let hashed = Integer::from_digits(&hasher.finalize(), Order::Lsf); // inverse, to get enough security bits - match result_int.invert(&modulus.clone()) { + match hashed.invert(&modulus.clone()) { Ok(inverse) => inverse, Err(unchanged) => unchanged, } @@ -72,15 +70,13 @@ fn h_g(modulus: &Integer, seed: &Integer) -> Integer { fn hash_to_prime(modulus: &Integer, inputs: &[&Integer]) -> Integer { let mut hasher = Sha256::new(); for input in inputs { - hasher.update(input.to_string_radix(16).as_bytes()); + hasher.update(input.to_digits::(Order::Lsf)); hasher.update("\n".as_bytes()); } - let hashed_hex = hasher.finalize(); - let hashed_hex_str = format!("{:#x}", hashed_hex); - let hashed_int = Integer::from_str_radix(&hashed_hex_str, 16).unwrap(); + let hashed = Integer::from_digits(&hasher.finalize(), Order::Lsf); // inverse, to get enough security bits - let inverse = match hashed_int.invert(&modulus.clone()) { + let inverse = match hashed.invert(&modulus.clone()) { Ok(inverse) => inverse, Err(unchanged) => unchanged, }; From 0005c5353c0003680afc28bf5341d4d01424e969 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Wed, 18 Nov 2020 20:54:00 +0800 Subject: [PATCH 03/17] fix --- benches/vdf/class_group.rs | 2 +- benches/vdf/rsa_group.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/benches/vdf/class_group.rs b/benches/vdf/class_group.rs index 8826b83..040ecda 100644 --- a/benches/vdf/class_group.rs +++ b/benches/vdf/class_group.rs @@ -28,7 +28,7 @@ fn benches_class(c: &mut Criterion) { // change below to `for &i in &[1_000, 2_000, 5_000, 10_000, 100_000, 1_000_000] {` if needed to expand test cases, // may also need to increase pari_init size (first parameter in `pari_init`) in src/primitives/vdf.rs for &i in &[1_0] { - // precompute for verification + // precompute for benchmarking verification let t = BigInt::from(i); let vdf_out_proof = VDF::eval(&a_b_delta, &seed, &t); let res = vdf_out_proof.verify(); diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 19d072d..e492741 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -2,7 +2,7 @@ extern crate criterion; use criterion::Criterion; -use rug::Integer; +use rug::{integer::Order, Integer}; use sha2::{Digest, Sha256}; /// algo_2 from the paper @@ -121,7 +121,7 @@ fn benches_rsa(c: &mut Criterion) { let g = h_g(&modulus, &seed); for &i in &[1_000, 2_000, 5_000, 10_000, 100_000, 1_000_000] { - // precompute for verification + // precompute for benchmarking verification let (y, pi) = eval(&modulus, &g, i); let result = verify(&modulus, &g, i, &y, &pi); assert!(result); From 3b73170fd3f64522ab9e5ae04de78b8e21bdf0fa Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Fri, 20 Nov 2020 20:54:59 +0800 Subject: [PATCH 04/17] fix https://github.com/ZenGo-X/class/pull/42#discussion_r526713087 --- benches/vdf/rsa_group.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index e492741..a7a29d4 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -42,8 +42,9 @@ fn eval(modulus: &Integer, g: &Integer, t: u64) -> (Integer, Integer) { for _ in 0..t { r2 = r.clone() * two.clone(); - b = r2.clone().div_rem_floor(l.clone()).0; - r = r2.clone().div_rem_floor(l.clone()).1; + let quo_rem = r2.clone().div_rem_floor(l.clone()); + b = quo_rem.0; + r = quo_rem.1; let pi_2 = pi.clone().pow_mod(&two, &modulus).unwrap(); let g_b = g.clone().pow_mod(&b, &modulus).unwrap(); pi = pi_2 * g_b; From f590cd66443c1a980771c886ca2725de102e32db Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Fri, 20 Nov 2020 21:03:33 +0800 Subject: [PATCH 05/17] clean up rsa_vdf::verify --- benches/vdf/rsa_group.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index a7a29d4..c250964 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -7,16 +7,14 @@ use sha2::{Digest, Sha256}; /// algo_2 from the paper fn verify(modulus: &Integer, g: &Integer, t: u64, y: &Integer, pi: &Integer) -> bool { - let modulus = modulus.clone(); - - let l = hash_to_prime(&modulus, &[&g, &y]); + let l = hash_to_prime(modulus, &[g, y]); let r = Integer::from(2).pow_mod(&Integer::from(t), &l).unwrap(); - let pi_l = pi.clone().pow_mod(&l, &modulus).unwrap(); - let g_r = g.clone().pow_mod(&r, &modulus).unwrap(); + let pi_l = pi.clone().pow_mod(&l, modulus).unwrap(); + let g_r = g.clone().pow_mod(&r, modulus).unwrap(); let pi_l_g_r = pi_l * g_r; - Integer::from(pi_l_g_r.div_rem_floor(modulus.clone()).1) == y.clone() + pi_l_g_r.div_rem_floor(modulus.clone()).1 == *y } /// algo_3 from the paper From 72767a3f4e573c049941ef307ea707d6d4098fad Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Fri, 20 Nov 2020 21:05:59 +0800 Subject: [PATCH 06/17] more clean up rsa_vdf::verify --- benches/vdf/rsa_group.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index c250964..3558be0 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -7,11 +7,11 @@ use sha2::{Digest, Sha256}; /// algo_2 from the paper fn verify(modulus: &Integer, g: &Integer, t: u64, y: &Integer, pi: &Integer) -> bool { - let l = hash_to_prime(modulus, &[g, y]); + let l = &hash_to_prime(modulus, &[g, y]); - let r = Integer::from(2).pow_mod(&Integer::from(t), &l).unwrap(); - let pi_l = pi.clone().pow_mod(&l, modulus).unwrap(); - let g_r = g.clone().pow_mod(&r, modulus).unwrap(); + let r = &Integer::from(2).pow_mod(&Integer::from(t), l).unwrap(); + let pi_l = pi.clone().pow_mod(l, modulus).unwrap(); + let g_r = g.clone().pow_mod(r, modulus).unwrap(); let pi_l_g_r = pi_l * g_r; pi_l_g_r.div_rem_floor(modulus.clone()).1 == *y From 04c881817b1b78e83892f2368dbc51b82f275544 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Fri, 20 Nov 2020 21:13:14 +0800 Subject: [PATCH 07/17] more clean up benches_rsa --- benches/vdf/rsa_group.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 3558be0..d17ae71 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -114,7 +114,7 @@ fn benches_rsa(c: &mut Criterion) { const TEST_HASH: &str = "1eeb30c7163271850b6d018e8282093ac6755a771da6267edf6c9b4fce9242ba"; let seed_hash = Integer::from_str_radix(TEST_HASH, 16).unwrap(); - let seed = Integer::from(seed_hash.div_rem_floor(modulus.clone()).1); + let seed = seed_hash.div_rem_floor(modulus.clone()).1; // g <- H_G(x) let g = h_g(&modulus, &seed); From 183b69c1d07fd2ae5a03bf72eb0fe1230db5eed4 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Fri, 20 Nov 2020 22:11:02 +0800 Subject: [PATCH 08/17] clean up hash_to_prime --- benches/vdf/rsa_group.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index d17ae71..05a6c12 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -75,12 +75,12 @@ fn hash_to_prime(modulus: &Integer, inputs: &[&Integer]) -> Integer { let hashed = Integer::from_digits(&hasher.finalize(), Order::Lsf); // inverse, to get enough security bits - let inverse = match hashed.invert(&modulus.clone()) { + let inverse = match hashed.invert(modulus) { Ok(inverse) => inverse, Err(unchanged) => unchanged, }; - Integer::from(inverse.next_prime().div_rem_floor(modulus.clone()).1) + inverse.next_prime().div_rem_floor(modulus.clone()).1 } fn benches_rsa(c: &mut Criterion) { From ecfa87efbaf166553228fb1666217337ff3e47a2 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Fri, 20 Nov 2020 22:27:16 +0800 Subject: [PATCH 09/17] clean up eval --- benches/vdf/rsa_group.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 05a6c12..933afa7 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -19,8 +19,6 @@ fn verify(modulus: &Integer, g: &Integer, t: u64, y: &Integer, pi: &Integer) -> /// algo_3 from the paper fn eval(modulus: &Integer, g: &Integer, t: u64) -> (Integer, Integer) { - let modulus = modulus.clone(); - // y <- (g^2)^t let mut y = g.clone(); for _ in 0..t { @@ -28,7 +26,7 @@ fn eval(modulus: &Integer, g: &Integer, t: u64) -> (Integer, Integer) { y = y.div_rem_floor(modulus.clone()).1; } - let l = hash_to_prime(&modulus, &[&g, &y]); + let l = hash_to_prime(modulus, &[g, &y]); // algo_4 from the paper, long division // TODO: consider algo_5 instead @@ -43,24 +41,23 @@ fn eval(modulus: &Integer, g: &Integer, t: u64) -> (Integer, Integer) { let quo_rem = r2.clone().div_rem_floor(l.clone()); b = quo_rem.0; r = quo_rem.1; - let pi_2 = pi.clone().pow_mod(&two, &modulus).unwrap(); - let g_b = g.clone().pow_mod(&b, &modulus).unwrap(); + let pi_2 = pi.clone().pow_mod(&two, modulus).unwrap(); + let g_b = g.clone().pow_mod(&b, modulus).unwrap(); pi = pi_2 * g_b; } - pi = Integer::from(pi.div_rem_floor(modulus.clone()).1); - (y, pi) + + (y, pi.div_rem_floor(modulus.clone()).1) } /// int(H("residue"||x)) mod N fn h_g(modulus: &Integer, seed: &Integer) -> Integer { - let modulus = modulus.clone(); let mut hasher = Sha256::new(); hasher.update("residue".as_bytes()); hasher.update(seed.to_digits::(Order::Lsf)); let hashed = Integer::from_digits(&hasher.finalize(), Order::Lsf); // inverse, to get enough security bits - match hashed.invert(&modulus.clone()) { + match hashed.invert(modulus) { Ok(inverse) => inverse, Err(unchanged) => unchanged, } From 5f440ce4641365337fd574534c3d8422bb20603d Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Sat, 21 Nov 2020 09:52:54 +0800 Subject: [PATCH 10/17] fix https://github.com/ZenGo-X/class/pull/42#discussion_r527009931 & https://github.com/ZenGo-X/class/pull/42#discussion_r526736840 --- benches/vdf/rsa_group.rs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 933afa7..074d2e8 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -45,22 +45,31 @@ fn eval(modulus: &Integer, g: &Integer, t: u64) -> (Integer, Integer) { let g_b = g.clone().pow_mod(&b, modulus).unwrap(); pi = pi_2 * g_b; } - + (y, pi.div_rem_floor(modulus.clone()).1) } -/// int(H("residue"||x)) mod N -fn h_g(modulus: &Integer, seed: &Integer) -> Integer { +fn h_g_inner(seed: &Integer) -> Integer { let mut hasher = Sha256::new(); hasher.update("residue".as_bytes()); hasher.update(seed.to_digits::(Order::Lsf)); - let hashed = Integer::from_digits(&hasher.finalize(), Order::Lsf); + Integer::from_digits(&hasher.finalize(), Order::Lsf) +} - // inverse, to get enough security bits - match hashed.invert(modulus) { - Ok(inverse) => inverse, - Err(unchanged) => unchanged, +/// int(H("residue"||x)) mod N +fn h_g(modulus: &Integer, seed: &Integer) -> Integer { + let mut temp = h_g_inner(seed); + let mut result = temp.clone(); + let mut ent = 256; + + while ent < 2048 { + let seed = temp.clone(); + temp = h_g_inner(&seed); + result = (result << 256) + temp.clone(); + ent += 256; } + + result.div_rem_floor(modulus.clone()).1 } fn hash_to_prime(modulus: &Integer, inputs: &[&Integer]) -> Integer { @@ -70,14 +79,7 @@ fn hash_to_prime(modulus: &Integer, inputs: &[&Integer]) -> Integer { hasher.update("\n".as_bytes()); } let hashed = Integer::from_digits(&hasher.finalize(), Order::Lsf); - - // inverse, to get enough security bits - let inverse = match hashed.invert(modulus) { - Ok(inverse) => inverse, - Err(unchanged) => unchanged, - }; - - inverse.next_prime().div_rem_floor(modulus.clone()).1 + hashed.next_prime().div_rem_floor(modulus.clone()).1 } fn benches_rsa(c: &mut Criterion) { From cde9abeaab884988b0c0f0ea1f8a2cfa0fef2ca9 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Sat, 21 Nov 2020 10:40:17 +0800 Subject: [PATCH 11/17] add docs --- benches/vdf/rsa_group.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 074d2e8..75b2016 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -57,16 +57,19 @@ fn h_g_inner(seed: &Integer) -> Integer { } /// int(H("residue"||x)) mod N +/// only run once, so perfomance won't be affected fn h_g(modulus: &Integer, seed: &Integer) -> Integer { + const HASH_ENT: u64 = 256; + const GROUP_ENT: u64 = 2048; let mut temp = h_g_inner(seed); let mut result = temp.clone(); - let mut ent = 256; + let mut ent = HASH_ENT; - while ent < 2048 { + while ent < GROUP_ENT { let seed = temp.clone(); temp = h_g_inner(&seed); - result = (result << 256) + temp.clone(); - ent += 256; + result = (result << HASH_ENT) + temp.clone(); + ent += HASH_ENT; } result.div_rem_floor(modulus.clone()).1 From cddeb50dc2a21ff47d21a1b44d42e09664106926 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Sat, 21 Nov 2020 12:04:39 +0800 Subject: [PATCH 12/17] minor --- benches/vdf/rsa_group.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 75b2016..e6148ff 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -61,17 +61,16 @@ fn h_g_inner(seed: &Integer) -> Integer { fn h_g(modulus: &Integer, seed: &Integer) -> Integer { const HASH_ENT: u64 = 256; const GROUP_ENT: u64 = 2048; + let mut temp = h_g_inner(seed); let mut result = temp.clone(); let mut ent = HASH_ENT; - while ent < GROUP_ENT { let seed = temp.clone(); temp = h_g_inner(&seed); result = (result << HASH_ENT) + temp.clone(); ent += HASH_ENT; } - result.div_rem_floor(modulus.clone()).1 } From 16b18176cd3ebb5faa5142dbc39ccc70a1405073 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Sat, 21 Nov 2020 12:07:46 +0800 Subject: [PATCH 13/17] minor --- benches/vdf/rsa_group.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index e6148ff..801f3e7 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -57,7 +57,7 @@ fn h_g_inner(seed: &Integer) -> Integer { } /// int(H("residue"||x)) mod N -/// only run once, so perfomance won't be affected +/// only run once, so don't need to worry about the perfomance fn h_g(modulus: &Integer, seed: &Integer) -> Integer { const HASH_ENT: u64 = 256; const GROUP_ENT: u64 = 2048; From 34ebb4a4744707156655c64840ba066a88fa2444 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Sat, 21 Nov 2020 12:14:29 +0800 Subject: [PATCH 14/17] fix --- benches/vdf/rsa_group.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 801f3e7..8228069 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -59,8 +59,8 @@ fn h_g_inner(seed: &Integer) -> Integer { /// int(H("residue"||x)) mod N /// only run once, so don't need to worry about the perfomance fn h_g(modulus: &Integer, seed: &Integer) -> Integer { - const HASH_ENT: u64 = 256; - const GROUP_ENT: u64 = 2048; + const HASH_ENT: u32 = 256; + const GROUP_ENT: u32 = 2048; let mut temp = h_g_inner(seed); let mut result = temp.clone(); From ee291ab36d6e6ab54aa94dc47cd5ebb5acd9efb2 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Sat, 21 Nov 2020 12:41:47 +0800 Subject: [PATCH 15/17] improve --- benches/vdf/rsa_group.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 8228069..d389dd3 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -56,19 +56,18 @@ fn h_g_inner(seed: &Integer) -> Integer { Integer::from_digits(&hasher.finalize(), Order::Lsf) } -/// int(H("residue"||x)) mod N +/// hashing an element onto the group /// only run once, so don't need to worry about the perfomance fn h_g(modulus: &Integer, seed: &Integer) -> Integer { const HASH_ENT: u32 = 256; const GROUP_ENT: u32 = 2048; - let mut temp = h_g_inner(seed); - let mut result = temp.clone(); + let mut part = h_g_inner(seed); + let mut result = part.clone(); let mut ent = HASH_ENT; while ent < GROUP_ENT { - let seed = temp.clone(); - temp = h_g_inner(&seed); - result = (result << HASH_ENT) + temp.clone(); + part = h_g_inner(&part); + result = (result << HASH_ENT) + part.clone(); ent += HASH_ENT; } result.div_rem_floor(modulus.clone()).1 From b5ed11072f70e610b16ddab2efa872d43e9ede8a Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Wed, 25 Nov 2020 08:12:33 +0800 Subject: [PATCH 16/17] fix https://github.com/ZenGo-X/class/pull/42#discussion_r528250538 --- benches/vdf/rsa_group.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index d389dd3..03ad018 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -49,27 +49,27 @@ fn eval(modulus: &Integer, g: &Integer, t: u64) -> (Integer, Integer) { (y, pi.div_rem_floor(modulus.clone()).1) } -fn h_g_inner(seed: &Integer) -> Integer { - let mut hasher = Sha256::new(); - hasher.update("residue".as_bytes()); - hasher.update(seed.to_digits::(Order::Lsf)); - Integer::from_digits(&hasher.finalize(), Order::Lsf) -} - /// hashing an element onto the group /// only run once, so don't need to worry about the perfomance fn h_g(modulus: &Integer, seed: &Integer) -> Integer { const HASH_ENT: u32 = 256; const GROUP_ENT: u32 = 2048; - let mut part = h_g_inner(seed); - let mut result = part.clone(); - let mut ent = HASH_ENT; - while ent < GROUP_ENT { - part = h_g_inner(&part); - result = (result << HASH_ENT) + part.clone(); - ent += HASH_ENT; - } + let prefix = "residue_part_".as_bytes(); + let seed_bytes = seed.to_digits::(Order::Lsf); + + // concat 8 sha256 to a sha2048 + let all_2048: Vec = (0..((GROUP_ENT / HASH_ENT) as u8)) + .map(|index| { + let mut hasher = Sha256::new(); + hasher.update(prefix); + hasher.update(vec![index]); + hasher.update(seed_bytes.clone()); + hasher.finalize() + }) + .flatten() + .collect(); + let result = Integer::from_digits(&all_2048, Order::Lsf); result.div_rem_floor(modulus.clone()).1 } From 7f17149e79ea2239e0eb88252ac71e2334d75488 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ Date: Wed, 25 Nov 2020 17:20:26 +0800 Subject: [PATCH 17/17] update docs --- benches/vdf/rsa_group.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benches/vdf/rsa_group.rs b/benches/vdf/rsa_group.rs index 03ad018..df76fc0 100644 --- a/benches/vdf/rsa_group.rs +++ b/benches/vdf/rsa_group.rs @@ -50,7 +50,7 @@ fn eval(modulus: &Integer, g: &Integer, t: u64) -> (Integer, Integer) { } /// hashing an element onto the group -/// only run once, so don't need to worry about the perfomance +/// only run once, so won't downgrade the perfomance fn h_g(modulus: &Integer, seed: &Integer) -> Integer { const HASH_ENT: u32 = 256; const GROUP_ENT: u32 = 2048; @@ -58,7 +58,7 @@ fn h_g(modulus: &Integer, seed: &Integer) -> Integer { let prefix = "residue_part_".as_bytes(); let seed_bytes = seed.to_digits::(Order::Lsf); - // concat 8 sha256 to a sha2048 + // concat 8 sha256 to a 2048-bit hash let all_2048: Vec = (0..((GROUP_ENT / HASH_ENT) as u8)) .map(|index| { let mut hasher = Sha256::new();