mirror of https://github.com/poanetwork/vdf.git
sieve with bit-vec (#12)
* Replace vec with bit-vec in sieve * Harmless? Can anyone tell me why this seperate binding was here? * Correct reference for prime uniformity improve reference to Chia network's `inkfish` implementation of "Close to Uniform Prime Number GenerationWith Fewer Random Bits" by Pierre-Alain Fouque and Mehdi Tibouchi https://eprint.iacr.org/2011/481.pdf Closes #11
This commit is contained in:
parent
c5d06911d9
commit
c740ef3b9a
|
@ -26,6 +26,7 @@ description = "An implementation of Verifiable Delay Functions (VDFs) in Rust"
|
|||
classgroup = { path = "../classgroup", version = "^0.1.0" }
|
||||
num-traits = "0.2"
|
||||
sha2 = "0.8"
|
||||
bit-vec = "0.5"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = ">=0.2"
|
||||
|
|
|
@ -15,12 +15,17 @@
|
|||
//! Creation of discriminants.
|
||||
//!
|
||||
//! The [`pot`] tool does not accept a discriminant as a command-line argument.
|
||||
//! Instead, it [generates][1] the discriminant from a (much smaller) seed.
|
||||
//! This file implements this process. The table of precomputed constants used
|
||||
//! is generated by `build.rs`.
|
||||
//! Instead, we generate the discriminant from a (much smaller) seed.
|
||||
//!
|
||||
//! [1]: <https://github.com/Chia-Network/vdf-competition/blob/003b0d202d3b27058159f7a3f6a838e312e7d79e/inkfish/create_discriminant.py>
|
||||
//! For performance, we follow the Chia network's [`inkfish`] implementation
|
||||
//! of ["Close to Uniform Prime Number Generation With Fewer Random Bits"][1]
|
||||
//! by Pierre-Alain Fouque and Mehdi Tibouchi.
|
||||
//! We employ a table of precomputed constants generated by `build.rs`.
|
||||
//!
|
||||
//! [1]: https://eprint.iacr.org/2011/481.pdf
|
||||
//! [`inkfish`]: <https://github.com/Chia-Network/vdf-competition/blob/003b0d202d3b27058159f7a3f6a838e312e7d79e/inkfish/create_discriminant.py>
|
||||
//! [`pot`]: <https://github.com/Chia-Network/vdf-competition/blob/003b0d202d3b27058159f7a3f6a838e312e7d79e/inkfish/cmds.py>
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/constants.rs"));
|
||||
|
||||
use classgroup::BigNumExt;
|
||||
|
@ -90,7 +95,7 @@ pub fn create_discriminant<T: BigNumExt>(seed: &[u8], length: u16) -> T {
|
|||
loop {
|
||||
// Speed up prime-finding by quickly ruling out numbers
|
||||
// that are known to be composite.
|
||||
let mut sieve = vec![false; 1 << 16];
|
||||
let mut sieve = ::bit_vec::BitVec::from_elem(1 << 16, false);
|
||||
for &(p, q) in SIEVE_INFO.iter() {
|
||||
// The reference implementation changes the sign of `n` before taking its
|
||||
// remainder. Instead, we leave `n` as positive, but use ceiling
|
||||
|
@ -98,15 +103,14 @@ pub fn create_discriminant<T: BigNumExt>(seed: &[u8], length: u16) -> T {
|
|||
// equivalent and potentially faster.
|
||||
let mut i: usize = (n.crem_u16(p) as usize * q as usize) % p as usize;
|
||||
while i < sieve.len() {
|
||||
sieve[i] = true;
|
||||
sieve.set(i, true);
|
||||
i += p as usize;
|
||||
}
|
||||
}
|
||||
|
||||
for (i, &x) in sieve.iter().enumerate() {
|
||||
let i = i as u32;
|
||||
for (i, x) in sieve.iter().enumerate() {
|
||||
if !x {
|
||||
let q = u64::from(M) * u64::from(i);
|
||||
let q = u64::from(M) * u64::from(i as u32);
|
||||
n = n + q;
|
||||
if n.probab_prime(2) {
|
||||
return -n;
|
||||
|
@ -115,7 +119,8 @@ pub fn create_discriminant<T: BigNumExt>(seed: &[u8], length: u16) -> T {
|
|||
}
|
||||
}
|
||||
// M is set to a number with many prime factors so the results are
|
||||
// more uniform https://eprint.iacr.org/2011/401.pdf
|
||||
// more uniform https://eprint.iacr.org/2011/481.pdf
|
||||
// TODO: Explain previous reference to https://eprint.iacr.org/2011/401.pdf
|
||||
n = n + (u64::from(M) * (1 << 16)) as u64
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue