crypto_bigint/limb/
rand.rs1use super::Limb;
4use crate::{Encoding, NonZero, Random, RandomMod};
5use rand_core::RngCore;
6use subtle::ConstantTimeLess;
7
8impl Random for Limb {
9 #[cfg(target_pointer_width = "32")]
10 fn random(rng: &mut (impl RngCore + ?Sized)) -> Self {
11 Self(rng.next_u32())
12 }
13
14 #[cfg(target_pointer_width = "64")]
15 fn random(rng: &mut (impl RngCore + ?Sized)) -> Self {
16 Self(rng.next_u64())
17 }
18}
19
20impl RandomMod for Limb {
21 fn random_mod(rng: &mut (impl RngCore + ?Sized), modulus: &NonZero<Self>) -> Self {
22 let mut bytes = <Self as Encoding>::Repr::default();
23
24 let n_bits = modulus.bits() as usize;
25 let n_bytes = (n_bits + 7) / 8;
26 let mask = 0xffu8 >> (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}