crypto_bigint/limb/
rand.rs
1use super::Limb;
4use crate::{Encoding, NonZero, Random, RandomMod};
5use rand_core::CryptoRngCore;
6use subtle::ConstantTimeLess;
7
8impl Random for Limb {
9 #[cfg(target_pointer_width = "32")]
10 fn random(rng: &mut impl CryptoRngCore) -> Self {
11 Self(rng.next_u32())
12 }
13
14 #[cfg(target_pointer_width = "64")]
15 fn random(rng: &mut impl CryptoRngCore) -> Self {
16 Self(rng.next_u64())
17 }
18}
19
20impl RandomMod for Limb {
21 fn random_mod(rng: &mut impl CryptoRngCore, modulus: &NonZero<Self>) -> Self {
22 let mut bytes = <Self as Encoding>::Repr::default();
23
24 let n_bits = modulus.bits();
25 let n_bytes = (n_bits + 7) / 8;
26 let mask = 0xff >> (8 * n_bytes - n_bits);
27
28 loop {
29 rng.fill_bytes(&mut bytes[..n_bytes]);
30 bytes[n_bytes - 1] &= mask;
31
32 let n = Limb::from_le_bytes(bytes);
33 if n.ct_lt(modulus).into() {
34 return n;
35 }
36 }
37 }
38}