gadget_std/
rand_helper.rs1use rand::RngCore;
2
3#[cfg(not(feature = "std"))]
4use rand::prelude::StdRng;
5
6pub use rand::{
7 self,
8 distributions::{Distribution, Standard},
9 CryptoRng, Rng,
10};
11
12pub trait UniformRand: Sized {
14 fn rand<R: Rng + ?Sized>(rng: &mut R) -> Self;
15}
16
17impl<T> UniformRand for T
18where
19 Standard: Distribution<T>,
20{
21 #[inline]
22 fn rand<R: Rng + ?Sized>(rng: &mut R) -> Self {
23 rng.sample(Standard)
24 }
25}
26
27pub struct GadgetRng(RngImpl);
29
30#[cfg(feature = "std")]
31type RngImpl = rand::rngs::OsRng;
32
33#[cfg(not(feature = "std"))]
34type RngImpl = StdRng;
35
36impl GadgetRng {
37 pub fn new() -> Self {
39 #[cfg(feature = "std")]
40 {
41 Self(rand::rngs::OsRng)
42 }
43 #[cfg(not(feature = "std"))]
44 {
45 test_rng()
46 }
47 }
48
49 #[allow(unused_variables)]
51 pub fn from_seed(seed: [u8; 32]) -> Self {
52 #[cfg(feature = "std")]
53 {
54 Self(rand::rngs::OsRng)
56 }
57 #[cfg(not(feature = "std"))]
58 {
59 use rand::SeedableRng;
60 Self(StdRng::from_seed(seed))
61 }
62 }
63}
64
65impl Default for GadgetRng {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70
71impl CryptoRng for GadgetRng {}
72
73#[cfg(feature = "std")]
74impl RngCore for GadgetRng {
75 fn next_u32(&mut self) -> u32 {
76 self.0.next_u32()
77 }
78 fn next_u64(&mut self) -> u64 {
79 self.0.next_u64()
80 }
81 fn fill_bytes(&mut self, dest: &mut [u8]) {
82 self.0.fill_bytes(dest)
83 }
84 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
85 self.0.try_fill_bytes(dest)
86 }
87}
88
89#[cfg(not(feature = "std"))]
90impl RngCore for GadgetRng {
91 fn next_u32(&mut self) -> u32 {
92 self.0.gen()
93 }
94 fn next_u64(&mut self) -> u64 {
95 self.0.gen()
96 }
97 fn fill_bytes(&mut self, dest: &mut [u8]) {
98 self.0.fill_bytes(dest)
99 }
100 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
101 self.0.fill_bytes(dest);
102 Ok(())
103 }
104}
105
106pub fn test_rng() -> GadgetRng {
108 const TEST_SEED: [u8; 32] = [
109 1, 0, 0, 0, 23, 0, 0, 0, 200, 1, 0, 0, 210, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0,
111 ];
112 GadgetRng::from_seed(TEST_SEED)
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn test_rng_generates_different_values() {
121 let mut rng = GadgetRng::new();
122 assert_ne!(rng.next_u64(), rng.next_u64());
123 }
124
125 #[test]
126 fn test_deterministic_rng() {
127 #[cfg(not(feature = "std"))]
128 {
129 let mut rng1 = GadgetRng::from_seed([1u8; 32]);
130 let mut rng2 = GadgetRng::from_seed([1u8; 32]);
131 assert_eq!(rng1.next_u64(), rng2.next_u64());
132 }
133 }
134}