1use rand_core::{CryptoRng, RngCore};
21
22use crate::utils::cell::RefCell;
23use crate::utils::init::{init, Init};
24use crate::utils::sync::blocking::Mutex;
25
26pub struct SharedRand<T> {
31 shared: Mutex<RefCell<T>>,
32}
33
34impl<T> SharedRand<T> {
35 pub const fn new(rand: T) -> Self {
37 Self {
38 shared: Mutex::new(RefCell::new(rand)),
39 }
40 }
41
42 pub fn init(rand: impl Init<T>) -> impl Init<Self> {
44 init!(Self {
45 shared <- Mutex::init(RefCell::init(rand)),
46 })
47 }
48}
49
50impl<T> rand_core::RngCore for &SharedRand<T>
51where
52 T: rand_core::RngCore,
53{
54 fn next_u32(&mut self) -> u32 {
55 self.shared.lock(|rand| rand.borrow_mut().next_u32())
56 }
57
58 fn next_u64(&mut self) -> u64 {
59 self.shared.lock(|rand| rand.borrow_mut().next_u64())
60 }
61
62 fn fill_bytes(&mut self, dest: &mut [u8]) {
63 self.shared.lock(|rand| rand.borrow_mut().fill_bytes(dest))
64 }
65
66 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
67 self.shared
68 .lock(|rand| rand.borrow_mut().try_fill_bytes(dest))
69 }
70}
71
72impl<T> CryptoRng for &SharedRand<T> where T: CryptoRng {}
73
74pub struct WeakTestOnlyRand(u32);
78
79impl WeakTestOnlyRand {
80 const SEED: u32 = 2463534242;
82
83 pub const fn new_default() -> Self {
85 Self(Self::SEED)
86 }
87
88 pub const fn new(seed: u32) -> Self {
90 Self(seed)
91 }
92}
93
94impl RngCore for WeakTestOnlyRand {
95 fn next_u32(&mut self) -> u32 {
96 self.0 = self.0 ^ (self.0 << 13);
97 self.0 = self.0 ^ (self.0 >> 17);
98 self.0 = self.0 ^ (self.0 << 5);
99
100 self.0
101 }
102
103 fn next_u64(&mut self) -> u64 {
104 rand_core::impls::next_u64_via_u32(self)
105 }
106
107 fn fill_bytes(&mut self, dest: &mut [u8]) {
108 rand_core::impls::fill_bytes_via_next(self, dest)
109 }
110
111 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
112 rand_core::impls::fill_bytes_via_next(self, dest);
113
114 Ok(())
115 }
116}
117
118impl CryptoRng for WeakTestOnlyRand {}