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:
Jeff Burdges 2019-03-14 22:33:24 +01:00 committed by Vladimir Komendantskiy
parent c5d06911d9
commit c740ef3b9a
2 changed files with 16 additions and 10 deletions

View File

@ -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"

View File

@ -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
}
}