summaryrefslogtreecommitdiffstats
path: root/vendor/crypto-bigint/src/uint/rand.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/crypto-bigint/src/uint/rand.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/crypto-bigint/src/uint/rand.rs')
-rw-r--r--vendor/crypto-bigint/src/uint/rand.rs45
1 files changed, 15 insertions, 30 deletions
diff --git a/vendor/crypto-bigint/src/uint/rand.rs b/vendor/crypto-bigint/src/uint/rand.rs
index df551c71b..e283e2246 100644
--- a/vendor/crypto-bigint/src/uint/rand.rs
+++ b/vendor/crypto-bigint/src/uint/rand.rs
@@ -1,14 +1,13 @@
//! Random number generator support
-use super::UInt;
+use super::Uint;
use crate::{Limb, NonZero, Random, RandomMod};
-use rand_core::{CryptoRng, RngCore};
+use rand_core::CryptoRngCore;
use subtle::ConstantTimeLess;
-#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
-impl<const LIMBS: usize> Random for UInt<LIMBS> {
- /// Generate a cryptographically secure random [`UInt`].
- fn random(mut rng: impl CryptoRng + RngCore) -> Self {
+impl<const LIMBS: usize> Random for Uint<LIMBS> {
+ /// Generate a cryptographically secure random [`Uint`].
+ fn random(mut rng: &mut impl CryptoRngCore) -> Self {
let mut limbs = [Limb::ZERO; LIMBS];
for limb in &mut limbs {
@@ -19,44 +18,30 @@ impl<const LIMBS: usize> Random for UInt<LIMBS> {
}
}
-#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
-impl<const LIMBS: usize> RandomMod for UInt<LIMBS> {
- /// Generate a cryptographically secure random [`UInt`] which is less than
+impl<const LIMBS: usize> RandomMod for Uint<LIMBS> {
+ /// Generate a cryptographically secure random [`Uint`] 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
- /// [`CryptoRng`] is unbiased, but runs in variable-time.
+ /// CSRNG 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
- /// [`CryptoRng`], where previous outputs are unrelated to subsequent
+ /// CSRNG, where previous outputs are unrelated to subsequent
/// outputs and do not reveal information about the RNG's internal state.
- fn random_mod(mut rng: impl CryptoRng + RngCore, modulus: &NonZero<Self>) -> Self {
+ fn random_mod(mut rng: &mut impl CryptoRngCore, modulus: &NonZero<Self>) -> Self {
let mut n = Self::ZERO;
- // TODO(tarcieri): use `div_ceil` when available
- // See: https://github.com/rust-lang/rust/issues/88581
- let mut n_limbs = modulus.bits_vartime() / Limb::BIT_SIZE;
- if n_limbs < LIMBS {
- n_limbs += 1;
- }
-
- // Compute the highest limb of `modulus` as a `NonZero`.
- // Add one to ensure `Limb::random_mod` returns values inclusive of this limb.
- let modulus_hi =
- NonZero::new(modulus.limbs[n_limbs.saturating_sub(1)].saturating_add(Limb::ONE))
- .unwrap(); // Always at least one due to `saturating_add`
+ let n_bits = modulus.as_ref().bits_vartime();
+ let n_limbs = (n_bits + Limb::BITS - 1) / Limb::BITS;
+ let mask = Limb::MAX >> (Limb::BITS * n_limbs - n_bits);
loop {
for i in 0..n_limbs {
- n.limbs[i] = if (i + 1 == n_limbs) && (*modulus_hi != Limb::MAX) {
- // Highest limb
- Limb::random_mod(&mut rng, &modulus_hi)
- } else {
- Limb::random(&mut rng)
- }
+ n.limbs[i] = Limb::random(&mut rng);
}
+ n.limbs[n_limbs - 1] = n.limbs[n_limbs - 1] & mask;
if n.ct_lt(modulus).into() {
return n;