diff --git a/src/uniform_sieve.rs b/src/uniform_sieve.rs index 5701db2..f318bac 100644 --- a/src/uniform_sieve.rs +++ b/src/uniform_sieve.rs @@ -8,15 +8,14 @@ use rand_core::CryptoRngCore; use rand_core::OsRng; use tracing::trace; -use crate::hazmat::precomputed::SMALL_PRIMES; use crate::is_prime; /// Generate primes using a pseudo-uniform distribution. /// Actors in this play are: -/// n: the number of bits in the prime we're looking for, e.g. 512 -/// l: the number of top bits that are re-sampled on every iteration, e.g. 64 -/// m: a product of all small odd primes up to a bound ß chosen such that the bit size of m is n - l, e.g. ß = 512 - 64 -/// b: picked uniformly at random among integers less than m and coprime to m (use unit generation algorithm from JP06) -/// λ: Carmichael's function: the LCM of the λ(p)s for each prime used to compute m. Each λ(p) is simply p-1 because each prime appears once and we exclude 2. +/// n: the number of bits in the prime we're looking for, e.g. 512 +/// l: the number of top bits that are re-sampled on every iteration, e.g. 64 +/// m: a product of all small odd primes up to a bound ß chosen such that the bit size of m is n - l, e.g. ß = 512 - 64 +/// b: picked uniformly at random among integers less than m and coprime to m (use unit generation algorithm from JP06) +/// λ: Carmichael's function: the LCM of the λ(p)s for each prime used to compute m. Each λ(p) is simply p-1 because each prime appears once and we exclude 2. // TODO(dp): Proper docs here, explaining when this is useful and why, discussion about the distribution quality etc. // TODO(dp): The `l` value isn't used anywhere but will be necessary to include so we can look for primes of the desired bit size. @@ -112,7 +111,6 @@ impl_generate_prime! { // (c) Go to Step 2 // 4. Output k // TODO(dp): probably unify this with "algorithm2" yeah? -#[allow(unused)] #[inline(always)] fn jp06_unitgen(rng: &mut impl CryptoRngCore, m: T, lambda_m: T) -> T where @@ -148,7 +146,7 @@ where r = T::random_bits(rng, m_bits); } let r = T::Monty::new(r, prms); - k = k + r * u; + k += r * u; u = m_monty_plus_one - k.pow_bounded_exp(&lambda_m, lambda_m.bits_vartime()); } k.retrieve() @@ -202,14 +200,15 @@ where // our case, each λ(p) is simply p-1 because each prime appears once (and we exclude 2). // `a_max` is the upper bound on the part of a prime candidate that is re-randomized on each iteration and set to 2^n/m -1 // Find constant values for common `T`s sized from 64 to 4096 in the test `generate_constants`. -#[allow(unused)] +#[cfg(test)] fn calculate_constants(a_max_bits: u32) -> (T, T, T) where T: FixedInteger + crypto_bigint::Gcd, { + use crate::hazmat::precomputed::SMALL_PRIMES; + let mut m = T::ONE; let mut lambda_m = T::ONE; - let a_max_bits = core::cmp::max(32, a_max_bits); for (i, prime) in SMALL_PRIMES.iter().enumerate() { let prime_t = T::from(*prime);