crypto_primes/
traits.rs

1use crypto_bigint::{Integer, RandomBits, RandomMod};
2use rand_core::CryptoRngCore;
3
4use crate::{generate_prime_with_rng, generate_safe_prime_with_rng, is_prime_with_rng, is_safe_prime_with_rng};
5
6/// A type producing sieves for random prime generation.
7pub trait SieveFactory {
8    /// The type of items returning by the sieves.
9    type Item;
10
11    /// The resulting sieve.
12    type Sieve: Iterator<Item = Self::Item>;
13
14    /// Makes a sieve given an RNG and the previous exhausted sieve (if any).
15    ///
16    /// Returning `None` signals that the prime generation should stop.
17    fn make_sieve(
18        &mut self,
19        rng: &mut (impl CryptoRngCore + ?Sized),
20        previous_sieve: Option<&Self::Sieve>,
21    ) -> Option<Self::Sieve>;
22}
23
24/// Provides a generic way to access methods for random prime number generation
25/// and primality checking, wrapping the standalone functions ([`is_prime_with_rng`] etc).
26pub trait RandomPrimeWithRng {
27    /// Returns a random prime of size `bit_length` using the provided RNG.
28    ///
29    /// Panics if `bit_length` is less than 2, or greater than the bit size of the target `Uint`.
30    ///
31    /// See [`is_prime_with_rng`] for details about the performed checks.
32    fn generate_prime_with_rng(rng: &mut (impl CryptoRngCore + ?Sized), bit_length: u32) -> Self;
33
34    /// Returns a random safe prime (that is, such that `(n - 1) / 2` is also prime)
35    /// of size `bit_length` using the provided RNG.
36    ///
37    /// Panics if `bit_length` is less than 3, or greater than the bit size of the target `Uint`.
38    ///
39    /// See [`is_prime_with_rng`] for details about the performed checks.
40    fn generate_safe_prime_with_rng(rng: &mut (impl CryptoRngCore + ?Sized), bit_length: u32) -> Self;
41
42    /// Probabilistically checks if the given number is prime using the provided RNG.
43    ///
44    /// See [`is_prime_with_rng`] for details about the performed checks.
45    fn is_prime_with_rng(&self, rng: &mut (impl CryptoRngCore + ?Sized)) -> bool;
46
47    /// Probabilistically checks if the given number is a safe prime using the provided RNG.
48    ///
49    /// See [`is_prime_with_rng`] for details about the performed checks.
50    fn is_safe_prime_with_rng(&self, rng: &mut (impl CryptoRngCore + ?Sized)) -> bool;
51}
52
53impl<T> RandomPrimeWithRng for T
54where
55    T: Integer + RandomBits + RandomMod,
56{
57    fn generate_prime_with_rng(rng: &mut (impl CryptoRngCore + ?Sized), bit_length: u32) -> Self {
58        generate_prime_with_rng(rng, bit_length)
59    }
60    fn generate_safe_prime_with_rng(rng: &mut (impl CryptoRngCore + ?Sized), bit_length: u32) -> Self {
61        generate_safe_prime_with_rng(rng, bit_length)
62    }
63    fn is_prime_with_rng(&self, rng: &mut (impl CryptoRngCore + ?Sized)) -> bool {
64        is_prime_with_rng(rng, self)
65    }
66    fn is_safe_prime_with_rng(&self, rng: &mut (impl CryptoRngCore + ?Sized)) -> bool {
67        is_safe_prime_with_rng(rng, self)
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use crypto_bigint::{BoxedUint, U64};
74    use rand_core::OsRng;
75
76    use super::RandomPrimeWithRng;
77
78    #[test]
79    fn uint_impl() {
80        assert!(!U64::from(15u32).is_prime_with_rng(&mut OsRng));
81        assert!(U64::from(19u32).is_prime_with_rng(&mut OsRng));
82
83        assert!(!U64::from(13u32).is_safe_prime_with_rng(&mut OsRng));
84        assert!(U64::from(11u32).is_safe_prime_with_rng(&mut OsRng));
85
86        assert!(U64::generate_prime_with_rng(&mut OsRng, 10).is_prime_with_rng(&mut OsRng));
87        assert!(U64::generate_safe_prime_with_rng(&mut OsRng, 10).is_safe_prime_with_rng(&mut OsRng));
88    }
89
90    #[test]
91    fn boxed_uint_impl() {
92        assert!(!BoxedUint::from(15u32).is_prime_with_rng(&mut OsRng));
93        assert!(BoxedUint::from(19u32).is_prime_with_rng(&mut OsRng));
94
95        assert!(!BoxedUint::from(13u32).is_safe_prime_with_rng(&mut OsRng));
96        assert!(BoxedUint::from(11u32).is_safe_prime_with_rng(&mut OsRng));
97
98        assert!(BoxedUint::generate_prime_with_rng(&mut OsRng, 10).is_prime_with_rng(&mut OsRng));
99        assert!(BoxedUint::generate_safe_prime_with_rng(&mut OsRng, 10).is_safe_prime_with_rng(&mut OsRng));
100    }
101}