Skip to content

Commit

Permalink
provide a Random::try_random method
Browse files Browse the repository at this point in the history
  • Loading branch information
baloo committed Feb 21, 2025
1 parent c7a7c81 commit 8c1c6c7
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 30 deletions.
6 changes: 3 additions & 3 deletions src/int/rand.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
//! Random number generator support
use rand_core::{RngCore, TryRngCore};
use rand_core::TryRngCore;

use crate::{Int, Random, RandomBits, RandomBitsError};

use super::Uint;

impl<const LIMBS: usize> Random for Int<LIMBS> {
/// Generate a cryptographically secure random [`Int`].
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
Self(Uint::random(rng))
fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
Ok(Self(Uint::try_random(rng)?))
}
}

Expand Down
15 changes: 7 additions & 8 deletions src/limb/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@
use super::Limb;
use crate::{Encoding, NonZero, Random, RandomMod};
use rand_core::{RngCore, TryRngCore};
use rand_core::TryRngCore;
use subtle::ConstantTimeLess;

impl Random for Limb {
#[cfg(target_pointer_width = "32")]
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
Self(rng.next_u32())
}
fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
#[cfg(target_pointer_width = "32")]
let val = rng.try_next_u32()?;
#[cfg(target_pointer_width = "64")]
let val = rng.try_next_u64()?;

#[cfg(target_pointer_width = "64")]
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
Self(rng.next_u64())
Ok(Self(val))
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/modular/const_monty_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use core::{fmt::Debug, marker::PhantomData};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};

#[cfg(feature = "rand_core")]
use crate::{Random, RandomMod, rand_core::RngCore};
use crate::{Random, RandomMod, rand_core::TryRngCore};

#[cfg(feature = "serde")]
use {
Expand Down Expand Up @@ -204,8 +204,11 @@ where
MOD: ConstMontyParams<LIMBS>,
{
#[inline]
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
Self::new(&Uint::random_mod(rng, MOD::MODULUS.as_nz_ref()))
fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
Ok(Self::new(&Uint::try_random_mod(
rng,
MOD::MODULUS.as_nz_ref(),
)?))
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/non_zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
use crate::{ArrayEncoding, ByteArray};

#[cfg(feature = "rand_core")]
use {crate::Random, rand_core::RngCore};
use {crate::Random, rand_core::TryRngCore};

#[cfg(feature = "serde")]
use serdect::serde::{
Expand Down Expand Up @@ -246,10 +246,10 @@ where
/// As a result, it runs in variable time. If the generator `rng` is
/// cryptographically secure (for example, it implements `CryptoRng`),
/// then this is guaranteed not to leak anything about the output value.
fn random<R: RngCore + ?Sized>(mut rng: &mut R) -> Self {
fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
loop {
if let Some(result) = Self::new(T::random(&mut rng)).into() {
break result;
if let Some(result) = Self::new(T::try_random(rng)?).into() {
break Ok(result);
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/odd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
use crate::BoxedUint;

#[cfg(feature = "rand_core")]
use {crate::Random, rand_core::RngCore};
use crate::{Random, rand_core::TryRngCore};

#[cfg(all(feature = "alloc", feature = "rand_core"))]
use {crate::RandomBits, rand_core::TryRngCore};
use crate::RandomBits;

#[cfg(feature = "serde")]
use crate::Zero;
Expand Down Expand Up @@ -153,10 +153,10 @@ impl PartialOrd<Odd<BoxedUint>> for BoxedUint {
#[cfg(feature = "rand_core")]
impl<const LIMBS: usize> Random for Odd<Uint<LIMBS>> {
/// Generate a random `Odd<Uint<T>>`.
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
let mut ret = Uint::random(rng);
fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
let mut ret = Uint::try_random(rng)?;
ret.limbs[0] |= Limb::ONE;
Odd(ret)
Ok(Odd(ret))
}
}

Expand Down
10 changes: 9 additions & 1 deletion src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,15 @@ pub trait Random: Sized {
/// Generate a random value.
///
/// If `rng` is a CSRNG, the generation is cryptographically secure as well.
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self;
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
let Ok(out) = Self::try_random(rng);
out
}

/// Generate a random value.
///
/// If `rng` is a CSRNG, the generation is cryptographically secure as well.
fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error>;
}

/// Possible errors of the methods in [`RandomBits`] trait.
Expand Down
6 changes: 3 additions & 3 deletions src/uint/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ use rand_core::{RngCore, TryRngCore};
use subtle::ConstantTimeLess;

impl<const LIMBS: usize> Random for Uint<LIMBS> {
fn random<R: RngCore + ?Sized>(mut rng: &mut R) -> Self {
fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
let mut limbs = [Limb::ZERO; LIMBS];

for limb in &mut limbs {
*limb = Limb::random(&mut rng)
*limb = Limb::try_random(rng)?
}

limbs.into()
Ok(limbs.into())
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/wrapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use core::{
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};

#[cfg(feature = "rand_core")]
use {crate::Random, rand_core::RngCore};
use {crate::Random, rand_core::TryRngCore};

#[cfg(feature = "serde")]
use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer};
Expand Down Expand Up @@ -259,8 +259,8 @@ impl<T: fmt::UpperHex> fmt::UpperHex for Wrapping<T> {

#[cfg(feature = "rand_core")]
impl<T: Random> Random for Wrapping<T> {
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
Wrapping(Random::random(rng))
fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
Ok(Wrapping(Random::try_random(rng)?))
}
}

Expand Down

0 comments on commit 8c1c6c7

Please sign in to comment.