ruint/support/
rand_09.rs

1//! Support for the [`rand`](https://crates.io/crates/rand) crate.
2
3#![cfg(feature = "rand-09")]
4#![cfg_attr(docsrs, doc(cfg(feature = "rand-09")))]
5
6// FEATURE: Implement the Uniform distribution.
7
8use rand_09 as rand;
9
10use crate::Uint;
11use rand::{
12    Rng,
13    distr::{Distribution, StandardUniform},
14};
15
16impl<const BITS: usize, const LIMBS: usize> Distribution<Uint<BITS, LIMBS>> for StandardUniform {
17    #[inline]
18    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Uint<BITS, LIMBS> {
19        <Uint<BITS, LIMBS>>::random_with(rng)
20    }
21}
22
23impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
24    /// Creates a new [`Uint`] with the default cryptographic random number
25    /// generator.
26    ///
27    /// This is currently [`rand::rng()`].
28    #[inline]
29    #[must_use]
30    #[cfg(feature = "std")]
31    pub fn random() -> Self {
32        let mut uint = Self::ZERO;
33        uint.randomize();
34        uint
35    }
36
37    /// Creates a new [`Uint`] with the given random number generator.
38    #[inline]
39    #[doc(alias = "random_using")]
40    #[must_use]
41    pub fn random_with<R: rand::RngCore + ?Sized>(rng: &mut R) -> Self {
42        let mut uint = Self::ZERO;
43        uint.randomize_with(rng);
44        uint
45    }
46
47    /// Fills this [`Uint`] with the default cryptographic random number
48    /// generator.
49    ///
50    /// See [`random`](Self::random) for more details.
51    #[inline]
52    #[cfg(feature = "std")]
53    pub fn randomize(&mut self) {
54        self.randomize_with(&mut rand::rng());
55    }
56
57    /// Fills this [`Uint`] with the given random number generator.
58    #[inline]
59    #[doc(alias = "randomize_using")]
60    pub fn randomize_with<R: rand::RngCore + ?Sized>(&mut self, rng: &mut R) {
61        rng.fill(&mut self.limbs[..]);
62        self.apply_mask();
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use crate::{const_for, nlimbs};
70
71    #[test]
72    fn test_rand() {
73        let mut rng = rand::rng();
74        const_for!(BITS in SIZES {
75            const LIMBS: usize = nlimbs(BITS);
76            for _ in 0..1000 {
77                let _: Uint<BITS, LIMBS> = rng.random();
78            }
79        });
80    }
81}