diff --git a/src/lib.rs b/src/lib.rs index cdfab0abb..a2aa913a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -117,7 +117,7 @@ //! ### Random number generation //! //! When the `rand_core` or `rand` features of this crate are enabled, it's -//! possible to generate random numbers using any CSRNG by using the +//! possible to generate random numbers using any RNG by using the //! [`Random`] trait: //! //! ``` diff --git a/src/limb/rand.rs b/src/limb/rand.rs index bfaf62ebe..96f384789 100644 --- a/src/limb/rand.rs +++ b/src/limb/rand.rs @@ -2,23 +2,23 @@ use super::Limb; use crate::{Encoding, NonZero, Random, RandomMod}; -use rand_core::CryptoRngCore; +use rand_core::RngCore; use subtle::ConstantTimeLess; impl Random for Limb { #[cfg(target_pointer_width = "32")] - fn random(rng: &mut impl CryptoRngCore) -> Self { + fn random(rng: &mut impl RngCore) -> Self { Self(rng.next_u32()) } #[cfg(target_pointer_width = "64")] - fn random(rng: &mut impl CryptoRngCore) -> Self { + fn random(rng: &mut impl RngCore) -> Self { Self(rng.next_u64()) } } impl RandomMod for Limb { - fn random_mod(rng: &mut impl CryptoRngCore, modulus: &NonZero) -> Self { + fn random_mod(rng: &mut impl RngCore, modulus: &NonZero) -> Self { let mut bytes = ::Repr::default(); let n_bits = modulus.bits() as usize; diff --git a/src/modular/const_monty_form.rs b/src/modular/const_monty_form.rs index ab0efbc26..8ad6d40e8 100644 --- a/src/modular/const_monty_form.rs +++ b/src/modular/const_monty_form.rs @@ -15,7 +15,7 @@ use core::{fmt::Debug, marker::PhantomData}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; #[cfg(feature = "rand_core")] -use crate::{rand_core::CryptoRngCore, Random, RandomMod}; +use crate::{rand_core::RngCore, Random, RandomMod}; #[cfg(feature = "serde")] use { @@ -207,7 +207,7 @@ where MOD: ConstMontyParams, { #[inline] - fn random(rng: &mut impl CryptoRngCore) -> Self { + fn random(rng: &mut impl RngCore) -> Self { Self::new(&Uint::random_mod(rng, MOD::MODULUS.as_nz_ref())) } } diff --git a/src/non_zero.rs b/src/non_zero.rs index 3f280b301..7465ec6d9 100644 --- a/src/non_zero.rs +++ b/src/non_zero.rs @@ -12,7 +12,7 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use crate::{ArrayEncoding, ByteArray}; #[cfg(feature = "rand_core")] -use {crate::Random, rand_core::CryptoRngCore}; +use {crate::Random, rand_core::RngCore}; #[cfg(feature = "serde")] use serdect::serde::{ @@ -232,8 +232,7 @@ impl Random for NonZero where T: Random + Zero, { - /// Generate a random `NonZero`. - fn random(mut rng: &mut impl CryptoRngCore) -> Self { + fn random(mut rng: &mut impl RngCore) -> Self { // Use rejection sampling to eliminate zero values. // While this method isn't constant-time, the attacker shouldn't learn // anything about unrelated outputs so long as `rng` is a CSRNG. diff --git a/src/odd.rs b/src/odd.rs index c8a11a712..a7995d027 100644 --- a/src/odd.rs +++ b/src/odd.rs @@ -8,7 +8,7 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use crate::BoxedUint; #[cfg(feature = "rand_core")] -use {crate::Random, rand_core::CryptoRngCore}; +use {crate::Random, rand_core::RngCore}; #[cfg(all(feature = "alloc", feature = "rand_core"))] use crate::RandomBits; @@ -153,7 +153,7 @@ impl PartialOrd> for BoxedUint { #[cfg(feature = "rand_core")] impl Random for Odd> { /// Generate a random `Odd>`. - fn random(rng: &mut impl CryptoRngCore) -> Self { + fn random(rng: &mut impl RngCore) -> Self { let mut ret = Uint::random(rng); ret.limbs[0] |= Limb::ONE; Odd(ret) @@ -163,7 +163,7 @@ impl Random for Odd> { #[cfg(all(feature = "alloc", feature = "rand_core"))] impl Odd { /// Generate a random `Odd>`. - pub fn random(rng: &mut impl CryptoRngCore, bit_length: u32) -> Self { + pub fn random(rng: &mut impl RngCore, bit_length: u32) -> Self { let mut ret = BoxedUint::random_bits(rng, bit_length); ret.limbs[0] |= Limb::ONE; Odd(ret) diff --git a/src/traits.rs b/src/traits.rs index 54bfff62b..a33e5d8f0 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -20,7 +20,7 @@ use subtle::{ }; #[cfg(feature = "rand_core")] -use rand_core::CryptoRngCore; +use rand_core::RngCore; /// Integers whose representation takes a bounded amount of space. pub trait Bounded { @@ -282,8 +282,10 @@ pub trait Constants: ConstZero { /// Random number generation support. #[cfg(feature = "rand_core")] pub trait Random: Sized { - /// Generate a cryptographically secure random value. - fn random(rng: &mut impl CryptoRngCore) -> Self; + /// Generate a random value. + /// + /// If `rng` is a CSRNG, the generation is cryptographically secure as well. + fn random(rng: &mut impl RngCore) -> Self; } /// Possible errors of the methods in [`RandomBits`] trait. @@ -343,28 +345,27 @@ impl core::error::Error for RandomBitsError {} /// Random bits generation support. #[cfg(feature = "rand_core")] pub trait RandomBits: Sized { - /// Generate a cryptographically secure random value in range `[0, 2^bit_length)`. + /// Generate a random value in range `[0, 2^bit_length)`. /// /// A wrapper for [`RandomBits::try_random_bits`] that panics on error. - fn random_bits(rng: &mut impl CryptoRngCore, bit_length: u32) -> Self { + fn random_bits(rng: &mut impl RngCore, bit_length: u32) -> Self { Self::try_random_bits(rng, bit_length).expect("try_random_bits() failed") } - /// Generate a cryptographically secure random value in range `[0, 2^bit_length)`. + /// Generate a random value in range `[0, 2^bit_length)`. /// /// This method is variable time wrt `bit_length`. - fn try_random_bits( - rng: &mut impl CryptoRngCore, - bit_length: u32, - ) -> Result; + /// + /// If `rng` is a CSRNG, the generation is cryptographically secure as well. + fn try_random_bits(rng: &mut impl RngCore, bit_length: u32) -> Result; - /// Generate a cryptographically secure random value in range `[0, 2^bit_length)`, + /// Generate a random value in range `[0, 2^bit_length)`, /// returning an integer with the closest available size to `bits_precision` /// (if the implementing type supports runtime sizing). /// /// A wrapper for [`RandomBits::try_random_bits_with_precision`] that panics on error. fn random_bits_with_precision( - rng: &mut impl CryptoRngCore, + rng: &mut impl RngCore, bit_length: u32, bits_precision: u32, ) -> Self { @@ -372,13 +373,15 @@ pub trait RandomBits: Sized { .expect("try_random_bits_with_precision() failed") } - /// Generate a cryptographically secure random value in range `[0, 2^bit_length)`, + /// Generate a random value in range `[0, 2^bit_length)`, /// returning an integer with the closest available size to `bits_precision` /// (if the implementing type supports runtime sizing). /// /// This method is variable time wrt `bit_length`. + /// + /// If `rng` is a CSRNG, the generation is cryptographically secure as well. fn try_random_bits_with_precision( - rng: &mut impl CryptoRngCore, + rng: &mut impl RngCore, bit_length: u32, bits_precision: u32, ) -> Result; @@ -387,18 +390,17 @@ pub trait RandomBits: Sized { /// Modular random number generation support. #[cfg(feature = "rand_core")] pub trait RandomMod: Sized + Zero { - /// Generate a cryptographically secure random number which is less than - /// a given `modulus`. + /// Generate a random number which is less than a given `modulus`. /// /// This function uses rejection sampling, a method which produces an /// unbiased distribution of in-range values provided the underlying - /// CSRNG is unbiased, but runs in variable-time. + /// RNG is unbiased, but runs in variable-time. /// /// The variable-time nature of the algorithm should not pose a security - /// issue so long as the underlying random number generator is truly a + /// issue so long as the underlying random number generator is a /// CSRNG, where previous outputs are unrelated to subsequent /// outputs and do not reveal information about the RNG's internal state. - fn random_mod(rng: &mut impl CryptoRngCore, modulus: &NonZero) -> Self; + fn random_mod(rng: &mut impl RngCore, modulus: &NonZero) -> Self; } /// Compute `self + rhs mod p`. diff --git a/src/uint/boxed/rand.rs b/src/uint/boxed/rand.rs index 6a2e73966..120aa1eac 100644 --- a/src/uint/boxed/rand.rs +++ b/src/uint/boxed/rand.rs @@ -5,18 +5,15 @@ use crate::{ uint::rand::{random_bits_core, random_mod_core}, NonZero, RandomBits, RandomBitsError, RandomMod, }; -use rand_core::CryptoRngCore; +use rand_core::RngCore; impl RandomBits for BoxedUint { - fn try_random_bits( - rng: &mut impl CryptoRngCore, - bit_length: u32, - ) -> Result { + fn try_random_bits(rng: &mut impl RngCore, bit_length: u32) -> Result { Self::try_random_bits_with_precision(rng, bit_length, bit_length) } fn try_random_bits_with_precision( - rng: &mut impl CryptoRngCore, + rng: &mut impl RngCore, bit_length: u32, bits_precision: u32, ) -> Result { @@ -34,16 +31,17 @@ impl RandomBits for BoxedUint { } impl RandomMod for BoxedUint { - /// Generate a cryptographically secure random [`BoxedUint`] which is less than a given - /// `modulus`. + /// Generate a random [`BoxedUint`] which is less than a given `modulus`. /// - /// This function uses rejection sampling, a method which produces an unbiased distribution of - /// in-range values provided the underlying CSRNG is unbiased, but runs in variable-time. + /// This function uses rejection sampling, a method which produces an + /// unbiased distribution of in-range values provided the underlying + /// RNG is unbiased, but runs in variable-time. /// - /// The variable-time nature of the algorithm should not pose a security issue so long as the - /// underlying random number generator is truly a CSRNG, where previous outputs are unrelated to - /// subsequent outputs and do not reveal information about the RNG's internal state. - fn random_mod(rng: &mut impl CryptoRngCore, modulus: &NonZero) -> Self { + /// The variable-time nature of the algorithm should not pose a security + /// issue so long as the underlying random number generator is a + /// CSRNG, where previous outputs are unrelated to subsequent + /// outputs and do not reveal information about the RNG's internal state. + fn random_mod(rng: &mut impl RngCore, modulus: &NonZero) -> Self { let mut n = BoxedUint::zero_with_precision(modulus.bits_precision()); random_mod_core(rng, &mut n, modulus, modulus.bits()); n diff --git a/src/uint/rand.rs b/src/uint/rand.rs index ce6b41de8..b3ee11033 100644 --- a/src/uint/rand.rs +++ b/src/uint/rand.rs @@ -2,12 +2,11 @@ use super::{Uint, Word}; use crate::{Encoding, Limb, NonZero, Random, RandomBits, RandomBitsError, RandomMod, Zero}; -use rand_core::CryptoRngCore; +use rand_core::RngCore; use subtle::ConstantTimeLess; impl Random for Uint { - /// Generate a cryptographically secure random [`Uint`]. - fn random(mut rng: &mut impl CryptoRngCore) -> Self { + fn random(mut rng: &mut impl RngCore) -> Self { let mut limbs = [Limb::ZERO; LIMBS]; for limb in &mut limbs { @@ -22,7 +21,7 @@ impl Random for Uint { /// /// NOTE: Assumes that the limbs in the given slice are zeroed! pub(crate) fn random_bits_core( - rng: &mut impl CryptoRngCore, + rng: &mut impl RngCore, zeroed_limbs: &mut [Limb], bit_length: u32, ) -> Result<(), RandomBitsError> { @@ -51,15 +50,12 @@ pub(crate) fn random_bits_core( } impl RandomBits for Uint { - fn try_random_bits( - rng: &mut impl CryptoRngCore, - bit_length: u32, - ) -> Result { + fn try_random_bits(rng: &mut impl RngCore, bit_length: u32) -> Result { Self::try_random_bits_with_precision(rng, bit_length, Self::BITS) } fn try_random_bits_with_precision( - rng: &mut impl CryptoRngCore, + rng: &mut impl RngCore, bit_length: u32, bits_precision: u32, ) -> Result { @@ -82,18 +78,17 @@ impl RandomBits for Uint { } impl RandomMod for Uint { - /// Generate a cryptographically secure random [`Uint`] which is less than - /// a given `modulus`. + /// Generate a random number which is less than a given `modulus`. /// /// This function uses rejection sampling, a method which produces an /// unbiased distribution of in-range values provided the underlying - /// CSRNG is unbiased, but runs in variable-time. + /// RNG is unbiased, but runs in variable-time. /// /// The variable-time nature of the algorithm should not pose a security - /// issue so long as the underlying random number generator is truly a + /// issue so long as the underlying random number generator is a /// CSRNG, where previous outputs are unrelated to subsequent /// outputs and do not reveal information about the RNG's internal state. - fn random_mod(rng: &mut impl CryptoRngCore, modulus: &NonZero) -> Self { + fn random_mod(rng: &mut impl RngCore, modulus: &NonZero) -> Self { let mut n = Self::ZERO; random_mod_core(rng, &mut n, modulus, modulus.bits_vartime()); n @@ -103,7 +98,7 @@ impl RandomMod for Uint { /// Generic implementation of `random_mod` which can be shared with `BoxedUint`. // TODO(tarcieri): obtain `n_bits` via a trait like `Integer` pub(super) fn random_mod_core( - rng: &mut impl CryptoRngCore, + rng: &mut impl RngCore, n: &mut T, modulus: &NonZero, n_bits: u32, diff --git a/src/wrapping.rs b/src/wrapping.rs index 86640246c..c49378b0c 100644 --- a/src/wrapping.rs +++ b/src/wrapping.rs @@ -8,7 +8,7 @@ use core::{ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; #[cfg(feature = "rand_core")] -use {crate::Random, rand_core::CryptoRngCore}; +use {crate::Random, rand_core::RngCore}; #[cfg(feature = "serde")] use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -259,7 +259,7 @@ impl fmt::UpperHex for Wrapping { #[cfg(feature = "rand_core")] impl Random for Wrapping { - fn random(rng: &mut impl CryptoRngCore) -> Self { + fn random(rng: &mut impl RngCore) -> Self { Wrapping(Random::random(rng)) } }