Skip to content

Commit

Permalink
Allow sieves to specify what items they return
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Dec 7, 2024
1 parent 3095e20 commit f763bc6
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 14 deletions.
19 changes: 12 additions & 7 deletions src/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ use crate::SieveFactory;
/// Sieves through the results of `sieve_factory` and returns the first item for which `predicate` is `true`.
///
/// If `sieve_factory` signals that no more results can be created, returns `None`.
pub fn sieve_and_find<R, S, T>(rng: &mut R, sieve_factory: S, predicate: impl Fn(&mut R, &T) -> bool) -> Option<T>
pub fn sieve_and_find<R, S>(
rng: &mut R,
sieve_factory: S,
predicate: impl Fn(&mut R, &S::Item) -> bool,
) -> Option<S::Item>
where
S: SieveFactory<T>,
S: SieveFactory,
R: CryptoRngCore,
{
// We could use `SieveIterator` here, but it requires cloning the `rng`.
Expand Down Expand Up @@ -63,13 +67,13 @@ where
/// A structure that chains the creation of sieves, returning the results from one until it is exhausted,
/// and then creating a new one.
#[derive(Debug)]
pub struct SieveIterator<'a, R: CryptoRngCore, T, S: SieveFactory<T>> {
pub struct SieveIterator<'a, R: CryptoRngCore, S: SieveFactory> {
sieve_factory: S,
sieve: S::Sieve,
rng: &'a mut R,
}

impl<'a, R: CryptoRngCore, T, S: SieveFactory<T>> SieveIterator<'a, R, T, S> {
impl<'a, R: CryptoRngCore, S: SieveFactory> SieveIterator<'a, R, S> {
/// Creates a new chained iterator producing results from sieves returned from `sieve_factory`.
pub fn new(rng: &'a mut R, sieve_factory: S) -> Option<Self> {
let mut sieve_factory = sieve_factory;
Expand All @@ -82,8 +86,8 @@ impl<'a, R: CryptoRngCore, T, S: SieveFactory<T>> SieveIterator<'a, R, T, S> {
}
}

impl<'a, R: CryptoRngCore, T, S: SieveFactory<T>> Iterator for SieveIterator<'a, R, T, S> {
type Item = T;
impl<'a, R: CryptoRngCore, S: SieveFactory> Iterator for SieveIterator<'a, R, S> {
type Item = S::Item;

fn next(&mut self) -> Option<Self::Item> {
loop {
Expand Down Expand Up @@ -113,7 +117,8 @@ mod tests {
count: usize,
}

impl SieveFactory<usize> for TestSieveFactory {
impl SieveFactory for TestSieveFactory {
type Item = usize;
type Sieve = core::ops::Range<usize>;

fn make_sieve(
Expand Down
14 changes: 9 additions & 5 deletions src/hazmat/sieve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! before proceeding with slower tests.
use alloc::{vec, vec::Vec};
use core::marker::PhantomData;
use core::num::{NonZero, NonZeroU32};

use crypto_bigint::{Integer, Odd, RandomBits};
Expand Down Expand Up @@ -247,12 +248,13 @@ impl<T: Integer> Iterator for SmallPrimesSieve<T> {

/// A sieve returning numbers that are not multiples of a set of small factors.
#[derive(Debug, Clone, Copy)]
pub struct SmallPrimesSieveFactory {
pub struct SmallPrimesSieveFactory<T> {
max_bit_length: NonZeroU32,
safe_primes: bool,
phantom: PhantomData<T>,
}

impl SmallPrimesSieveFactory {
impl<T: Integer + RandomBits> SmallPrimesSieveFactory<T> {
fn new_impl(max_bit_length: u32, safe_primes: bool) -> Self {
if !safe_primes && max_bit_length < 2 {
panic!("`bit_length` must be 2 or greater.");
Expand All @@ -264,6 +266,7 @@ impl SmallPrimesSieveFactory {
Self {
max_bit_length,
safe_primes,
phantom: PhantomData,
}
}

Expand All @@ -280,7 +283,8 @@ impl SmallPrimesSieveFactory {
}
}

impl<T: Integer + RandomBits> SieveFactory<T> for SmallPrimesSieveFactory {
impl<T: Integer + RandomBits> SieveFactory for SmallPrimesSieveFactory<T> {
type Item = T;
type Sieve = SmallPrimesSieve<T>;
fn make_sieve(
&mut self,
Expand Down Expand Up @@ -446,12 +450,12 @@ mod tests {
#[test]
#[should_panic(expected = "`bit_length` must be 2 or greater")]
fn too_few_bits_regular_primes() {
let _fac = SmallPrimesSieveFactory::new(1);
let _fac = SmallPrimesSieveFactory::<U64>::new(1);
}

#[test]
#[should_panic(expected = "`bit_length` must be 3 or greater")]
fn too_few_bits_safe_primes() {
let _fac = SmallPrimesSieveFactory::new_safe_primes(2);
let _fac = SmallPrimesSieveFactory::<U64>::new_safe_primes(2);
}
}
7 changes: 5 additions & 2 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ use rand_core::CryptoRngCore;
use crate::{generate_prime_with_rng, generate_safe_prime_with_rng, is_prime_with_rng, is_safe_prime_with_rng};

/// A type producing sieves for random prime generation.
pub trait SieveFactory<T> {
pub trait SieveFactory {
/// The type of items returning by the sieves.
type Item;

/// The resulting sieve.
type Sieve: Iterator<Item = T>;
type Sieve: Iterator<Item = Self::Item>;

/// Makes a sieve given an RNG and the previous exhausted sieve (if any).
///
Expand Down

0 comments on commit f763bc6

Please sign in to comment.