1use core::fmt;
7
8#[cfg_attr(not(all(feature = "rand", feature = "std")), allow(unused_imports))]
11use rand_core::{
12 Rng,
13 TryCryptoRng,
14 TryRng,
15};
16
17#[cfg(feature = "hash")]
18use crate::Error;
19
20#[derive(Clone, Debug, PartialEq)]
25pub struct ClassicalMcElieceRng {
26 state: u64,
28 counter: u64,
30 deterministic: bool,
32 reseed_counter: u32,
34}
35
36impl ClassicalMcElieceRng {
37 #[must_use]
43 pub fn new() -> Self {
44 Self {
45 state: 0,
46 counter: 0,
47 deterministic: false,
48 reseed_counter: 0,
49 }
50 }
51
52 #[must_use]
57 pub fn new_deterministic(seed: u64) -> Self {
58 Self {
59 state: seed
60 .wrapping_mul(6_364_136_223_846_793_005_u64)
61 .wrapping_add(1_442_695_040_888_963_407_u64),
62 counter: 0,
63 deterministic: true,
64 reseed_counter: 0,
65 }
66 }
67
68 #[must_use]
73 pub fn new_deterministic_from_bytes(seed_bytes: &[u8]) -> Self {
74 let mut hash = 0u64;
75 for (i, &byte) in seed_bytes.iter().enumerate() {
76 hash = hash.wrapping_add(u64::from(byte) << (i % 8));
77 }
78 Self::new_deterministic(hash)
79 }
80
81 pub fn randombytes_init(&mut self, entropy_input: [u8; 48]) {
87 if self.deterministic {
88 let mut hash = 0u64;
90 for (i, &byte) in entropy_input.iter().enumerate() {
91 hash = hash.wrapping_add(u64::from(byte) << (i % 8));
92 }
93 self.state = self.state.wrapping_add(hash);
94 self.counter = 0;
95 self.reseed_counter = 1;
96 }
97 }
100
101 fn generate_bytes(&mut self, dest: &mut [u8]) {
103 if self.deterministic {
104 self.generate_deterministic_bytes(dest);
105 } else {
106 self.generate_secure_bytes(dest);
107 }
108 }
109
110 fn generate_deterministic_bytes(&mut self, dest: &mut [u8]) {
115 for chunk in dest.chunks_mut(8) {
116 for _ in 0..3 {
121 self.state = self
122 .state
123 .wrapping_mul(6_364_136_223_846_793_005_u64)
124 .wrapping_add(1_442_695_040_888_963_407_u64);
125 }
126
127 self.counter = self.counter.wrapping_add(1);
128
129 let mut value = self.state ^
132 self.counter ^
133 (u64::from(self.reseed_counter) << 32) ^
134 (u64::from(self.reseed_counter) << 16);
135
136 value = value.wrapping_mul(0x9E37_79B9_7F4A_7C15_u64); value ^= value >> 33;
140 value = value.wrapping_mul(0x9E37_79B9_7F4A_7C15_u64);
141 value ^= value >> 29;
142 value = value.wrapping_mul(0xC4CE_B9FE_1A85_EC53_u64);
143 value ^= value >> 32;
144
145 let bytes = value.to_le_bytes();
146
147 let len = chunk.len().min(8);
148 chunk[..len].copy_from_slice(&bytes[..len]);
149 }
150
151 self.reseed_counter = self.reseed_counter.wrapping_add(1);
152 }
153
154 fn generate_secure_bytes(&mut self, dest: &mut [u8]) {
160 #[cfg(feature = "getrandom")]
161 {
162 assert!(
164 getrandom::fill(dest).is_ok(),
165 "lib_q_random::ClassicalMcElieceRng: getrandom::fill failed; \
166 refusing non-OS RNG output (enable `custom-entropy` or fix the environment)"
167 );
168 }
169
170 #[cfg(not(feature = "getrandom"))]
171 {
172 let _ = dest;
173 panic!(
177 "lib_q_random: ClassicalMcElieceRng requires the `getrandom` crate feature for secure output; \
178 enable `getrandom`/`secure`/`classical-mceliece`, or use `new_deterministic` for tests"
179 );
180 }
181
182 self.reseed_counter = self.reseed_counter.wrapping_add(1);
183 }
184}
185
186impl Default for ClassicalMcElieceRng {
187 fn default() -> Self {
188 Self::new()
189 }
190}
191
192impl Eq for ClassicalMcElieceRng {}
193
194impl fmt::Display for ClassicalMcElieceRng {
195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196 writeln!(f, "ClassicalMcElieceRng {{")?;
197 writeln!(f, " state = {}", self.state)?;
198 writeln!(f, " counter = {}", self.counter)?;
199 writeln!(f, " deterministic = {}", self.deterministic)?;
200 writeln!(f, " reseed_counter = {}", self.reseed_counter)?;
201 writeln!(f, "}}")
202 }
203}
204
205impl TryRng for ClassicalMcElieceRng {
206 type Error = core::convert::Infallible;
207
208 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
209 let mut bytes = [0u8; 4];
210 self.try_fill_bytes(&mut bytes)?;
211 Ok(u32::from_le_bytes(bytes))
212 }
213
214 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
215 let mut bytes = [0u8; 8];
216 self.try_fill_bytes(&mut bytes)?;
217 Ok(u64::from_le_bytes(bytes))
218 }
219
220 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
221 self.generate_bytes(dest);
222 Ok(())
223 }
224}
225
226impl TryCryptoRng for ClassicalMcElieceRng {}
227
228#[cfg(feature = "hash")]
234#[derive(Clone, Debug)]
235pub struct Kt128Rng {
236 expander: crate::kt128_expander::Kt128Expander,
237}
238
239#[cfg(feature = "hash")]
240impl Kt128Rng {
241 pub fn new() -> crate::Result<Self> {
247 #[cfg(feature = "getrandom")]
248 {
249 let mut seed = [0u8; 32];
251 getrandom::fill(&mut seed).map_err(|_| Error::EntropySourceUnavailable {
252 source: "system",
253 context: Some("getrandom failed"),
254 })?;
255 Ok(Self::from_seed(&seed))
256 }
257 #[cfg(not(feature = "getrandom"))]
258 {
259 Err(Error::FeatureNotAvailable {
261 feature: "secure entropy",
262 required_features: &["getrandom"],
263 })
264 }
265 }
266
267 #[must_use]
269 pub fn from_seed(seed: &[u8]) -> Self {
270 Self {
271 expander: crate::kt128_expander::Kt128Expander::from_seed(
272 crate::kt128_expander::DOMAIN_HPKE_RNG,
273 seed,
274 ),
275 }
276 }
277
278 pub fn refill(&mut self) {
280 self.expander.refill();
281 }
282}
283
284#[cfg(feature = "hash")]
285impl TryRng for Kt128Rng {
286 type Error = core::convert::Infallible;
287
288 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
289 let mut bytes = [0u8; 4];
290 self.try_fill_bytes(&mut bytes)?;
291 Ok(u32::from_le_bytes(bytes))
292 }
293
294 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
295 let mut bytes = [0u8; 8];
296 self.try_fill_bytes(&mut bytes)?;
297 Ok(u64::from_le_bytes(bytes))
298 }
299
300 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
301 self.expander.fill_bytes(dest);
302 Ok(())
303 }
304}
305
306#[cfg(feature = "hash")]
307#[cfg(test)]
308mod kt128_rng_tests {
309 use super::*;
310 use crate::kt128_expander::Kt128Expander;
311
312 #[test]
314 fn test_kt128_rng_matches_hpke_domain_expander() {
315 let seed = [9u8; 32];
316 let mut rng = Kt128Rng::from_seed(&seed);
317 let mut exp = Kt128Expander::from_seed(crate::kt128_expander::DOMAIN_HPKE_RNG, &seed);
318 let mut a = [0u8; 128];
319 let mut b = [0u8; 128];
320 rng.fill_bytes(&mut a);
321 exp.fill_bytes(&mut b);
322 assert_eq!(a, b);
323 }
324}
325
326#[cfg(feature = "hash")]
327impl TryCryptoRng for Kt128Rng {}
328
329pub struct FnDsaRng {
334 #[cfg(all(feature = "rand", feature = "std"))]
337 rng: Option<rand::rngs::ThreadRng>,
338}
339
340impl Default for FnDsaRng {
341 fn default() -> Self {
342 Self::new()
343 }
344}
345
346impl FnDsaRng {
347 #[must_use]
349 pub fn new() -> Self {
350 #[cfg(all(feature = "rand", feature = "std"))]
351 {
352 Self {
353 rng: Some(rand::rng()),
354 }
355 }
356 #[cfg(not(all(feature = "rand", feature = "std")))]
357 {
358 Self {}
359 }
360 }
361}
362
363impl TryRng for FnDsaRng {
364 type Error = core::convert::Infallible;
365
366 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
367 #[cfg(all(feature = "rand", feature = "std"))]
368 {
369 if let Some(ref mut rng) = self.rng {
370 Ok(rng.next_u32())
371 } else {
372 let mut bytes = [0u8; 4];
373 self.try_fill_bytes(&mut bytes)?;
374 Ok(u32::from_le_bytes(bytes))
375 }
376 }
377 #[cfg(not(all(feature = "rand", feature = "std")))]
378 {
379 #[cfg(feature = "getrandom")]
380 {
381 let mut bytes = [0u8; 4];
382 getrandom::fill(&mut bytes).expect("Failed to get random bytes from getrandom");
383 Ok(u32::from_le_bytes(bytes))
384 }
385 #[cfg(not(feature = "getrandom"))]
386 {
387 panic!(
388 "FnDsaRng requires the 'std' (ThreadRng) or 'getrandom' feature. \
389 Use deterministic RNG for testing without these features."
390 );
391 }
392 }
393 }
394
395 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
396 #[cfg(all(feature = "getrandom", not(all(feature = "rand", feature = "std"))))]
397 {
398 let mut bytes = [0u8; 8];
399 getrandom::fill(&mut bytes).expect("Failed to get random bytes from getrandom");
400 Ok(u64::from_le_bytes(bytes))
401 }
402
403 #[cfg(not(all(feature = "getrandom", not(all(feature = "rand", feature = "std")))))]
404 {
405 let upper = u64::from(self.try_next_u32()?);
406 let lower = u64::from(self.try_next_u32()?);
407 Ok((upper << 32) | lower)
408 }
409 }
410
411 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
412 #[cfg(all(feature = "getrandom", not(all(feature = "rand", feature = "std"))))]
416 {
417 getrandom::fill(dest).expect("Failed to get random bytes from getrandom");
418 Ok(())
419 }
420
421 #[cfg(not(all(feature = "getrandom", not(all(feature = "rand", feature = "std")))))]
422 {
423 for chunk in dest.chunks_mut(4) {
424 let bytes = self.try_next_u32()?.to_le_bytes();
425 let len = chunk.len().min(4);
426 chunk[..len].copy_from_slice(&bytes[..len]);
427 }
428 Ok(())
429 }
430 }
431}
432
433impl TryCryptoRng for FnDsaRng {}
434
435#[cfg(test)]
436mod tests {
437 use rand_core::Rng;
438
439 use super::*;
440
441 #[test]
442 fn test_classical_mceliece_rng_creation() {
443 let rng = ClassicalMcElieceRng::new();
444 assert!(!rng.deterministic);
445 assert_eq!(rng.state, 0);
446 assert_eq!(rng.counter, 0);
447 }
448
449 #[test]
450 fn test_classical_mceliece_deterministic_rng_creation() {
451 let rng = ClassicalMcElieceRng::new_deterministic(12345);
452 assert!(rng.deterministic);
453 assert_ne!(rng.state, 0);
455 assert_eq!(rng.counter, 0);
456 }
457
458 #[test]
459 fn test_classical_mceliece_deterministic_rng_consistency() {
460 let mut rng1 = ClassicalMcElieceRng::new_deterministic(42);
461 let mut rng2 = ClassicalMcElieceRng::new_deterministic(42);
462
463 let mut bytes1 = [0u8; 32];
464 let mut bytes2 = [0u8; 32];
465
466 rng1.fill_bytes(&mut bytes1);
467 rng2.fill_bytes(&mut bytes2);
468
469 assert_eq!(bytes1, bytes2);
470 }
471
472 #[test]
473 fn test_classical_mceliece_rng_interface() {
474 let mut rng = ClassicalMcElieceRng::new_deterministic(100);
475
476 let mut bytes = [0u8; 16];
478 rng.fill_bytes(&mut bytes);
479 assert_ne!(bytes, [0u8; 16]); let val1 = rng.next_u32();
483 let val2 = rng.next_u32();
484 assert_ne!(val1, val2); let val3 = rng.next_u64();
488 let val4 = rng.next_u64();
489 assert_ne!(val3, val4); }
491
492 #[test]
493 fn test_classical_mceliece_randombytes_init() {
494 let mut rng = ClassicalMcElieceRng::new_deterministic(0);
495 let entropy = [1u8; 48];
496
497 rng.randombytes_init(entropy);
498
499 assert_ne!(rng.state, 0);
501 assert_eq!(rng.reseed_counter, 1);
502 }
503
504 #[test]
505 fn test_fn_dsa_rng_creation() {
506 let _rng = FnDsaRng::new();
507 }
510
511 #[test]
512 #[cfg(any(feature = "rand", feature = "getrandom"))]
513 fn test_fn_dsa_rng_interface() {
514 let mut rng = FnDsaRng::new();
515
516 let mut bytes = [0u8; 16];
518 rng.fill_bytes(&mut bytes);
519 let val1 = rng.next_u32();
523 let val2 = rng.next_u32();
524 assert_ne!(val1, val2);
526
527 let val3 = rng.next_u64();
529 let val4 = rng.next_u64();
530 assert_ne!(val3, val4);
532 }
533
534 #[test]
537 #[cfg(all(feature = "getrandom", not(feature = "rand")))]
538 fn test_fn_dsa_rng_fill_bytes_getrandom_only_odd_length() {
539 let mut rng = FnDsaRng::new();
540 let mut buf = [0u8; 1281];
541 rng.fill_bytes(&mut buf);
542 }
543}