crypto_bigint_syncless/limb/
rand.rs1use super::Limb;
4use crate::{Encoding, NonZero, Random, RandomMod};
5use rand_core::TryRngCore;
6use subtle::ConstantTimeLess;
7
8impl Random for Limb {
9 fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
10 #[cfg(target_pointer_width = "32")]
11 let val = rng.try_next_u32()?;
12 #[cfg(target_pointer_width = "64")]
13 let val = rng.try_next_u64()?;
14
15 Ok(Self(val))
16 }
17}
18
19impl RandomMod for Limb {
20 fn try_random_mod<R: TryRngCore + ?Sized>(
21 rng: &mut R,
22 modulus: &NonZero<Self>,
23 ) -> Result<Self, R::Error> {
24 let mut bytes = <Self as Encoding>::Repr::default();
25
26 let n_bits = modulus.bits() as usize;
27 let n_bytes = n_bits.div_ceil(8);
28 let mask = 0xffu8 >> (8 * n_bytes - n_bits);
29
30 loop {
31 rng.try_fill_bytes(&mut bytes[..n_bytes])?;
32 bytes[n_bytes - 1] &= mask;
33
34 let n = Limb::from_le_bytes(bytes);
35 if n.ct_lt(modulus).into() {
36 return Ok(n);
37 }
38 }
39 }
40}