clock_rand/traits.rs
1//! Core traits for RNG implementations
2
3use crate::error::Result;
4
5/// Core trait for random number generators
6///
7/// This trait provides the basic interface for generating random values.
8/// It's compatible with the `rand` crate's `RngCore` trait for interoperability.
9pub trait Rng {
10 /// Generate the next `u32` random value
11 fn next_u32(&mut self) -> u32;
12
13 /// Generate the next `u64` random value
14 fn next_u64(&mut self) -> u64;
15
16 /// Fill a byte buffer with random data
17 fn fill_bytes(&mut self, dest: &mut [u8]);
18
19 /// Try to fill a byte buffer with random data (may fail)
20 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<()> {
21 self.fill_bytes(dest);
22 Ok(())
23 }
24}
25
26/// Marker trait for cryptographically secure random number generators
27///
28/// Types implementing this trait are suitable for cryptographic operations
29/// such as key generation, nonce generation, and signature operations.
30pub trait CryptoRng: Rng {
31 // Marker trait - no additional methods required
32 // The security guarantee is provided by the implementation
33}
34
35/// Trait for deterministic random number generators
36///
37/// RNGs implementing this trait produce reproducible sequences when seeded
38/// with the same seed value.
39pub trait DeterministicRng: Rng {
40 /// Check if the RNG is in a deterministic state
41 fn is_deterministic(&self) -> bool;
42}
43
44/// Trait for RNGs that can be seeded
45pub trait SeedableRng: Rng {
46 /// Seed type for this RNG
47 type Seed: AsRef<[u8]> + Clone;
48
49 /// Create a new RNG from a seed
50 fn from_seed(seed: Self::Seed) -> Self;
51
52 /// Reseed the RNG with a new seed
53 fn reseed(&mut self, seed: Self::Seed) -> Result<()>;
54}
55
56/// Compatibility trait with `rand` crate's `RngCore`
57///
58/// This allows clock-rand RNGs to be used with the `rand` crate ecosystem.
59pub trait RngCore: Rng {
60 /// Generate the next `u32` random value
61 fn next_u32(&mut self) -> u32;
62
63 /// Generate the next `u64` random value
64 fn next_u64(&mut self) -> u64;
65
66 /// Fill a byte buffer with random data
67 fn fill_bytes(&mut self, dest: &mut [u8]);
68
69 /// Try to fill a byte buffer with random data (may fail)
70 #[cfg(feature = "std")]
71 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> core::result::Result<(), std::io::Error>;
72}
73
74/// Helper trait for generating random values of specific types
75pub trait RngExt: Rng {
76 /// Generate a random `u8`
77 #[inline]
78 fn gen_u8(&mut self) -> u8 {
79 (self.next_u32() >> 24) as u8
80 }
81
82 /// Generate a random `u16`
83 #[inline]
84 fn gen_u16(&mut self) -> u16 {
85 (self.next_u32() >> 16) as u16
86 }
87
88 /// Generate a random `u32`
89 #[inline]
90 fn gen_u32(&mut self) -> u32 {
91 self.next_u32()
92 }
93
94 /// Generate a random `u64`
95 #[inline]
96 fn gen_u64(&mut self) -> u64 {
97 self.next_u64()
98 }
99
100 /// Generate a random `f32` in [0, 1)
101 fn gen_f32(&mut self) -> f32 {
102 // Generate 24 random bits for mantissa
103 let bits = (self.next_u32() >> 8) | 0x3f80_0000;
104 f32::from_bits(bits) - 1.0
105 }
106
107 /// Generate a random `f64` in [0, 1)
108 fn gen_f64(&mut self) -> f64 {
109 // Generate 53 random bits for mantissa
110 let bits = (self.next_u64() >> 11) | 0x3ff0_0000_0000_0000;
111 f64::from_bits(bits) - 1.0
112 }
113}
114
115impl<T: Rng> RngExt for T {}
116
117// Blanket implementation for RngCore compatibility
118impl<T: Rng> RngCore for T {
119 fn next_u32(&mut self) -> u32 {
120 Rng::next_u32(self)
121 }
122
123 fn next_u64(&mut self) -> u64 {
124 Rng::next_u64(self)
125 }
126
127 fn fill_bytes(&mut self, dest: &mut [u8]) {
128 Rng::fill_bytes(self, dest)
129 }
130
131 #[cfg(feature = "std")]
132 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> core::result::Result<(), std::io::Error> {
133 Rng::try_fill_bytes(self, dest).map_err(std::io::Error::other)
134 }
135}