#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::print_stdout,
clippy::print_stderr
)]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(feature = "alloc")]
use lib_q_random::{
new_deterministic_rng,
new_secure_rng,
};
#[cfg(not(feature = "alloc"))]
use lib_q_random::{
new_deterministic_rng_no_std,
new_secure_rng_no_std,
};
use rand_core::Rng;
#[test]
fn test_no_std_rng_creation() {
#[cfg(all(not(feature = "alloc"), feature = "getrandom"))]
{
let rng = new_secure_rng_no_std();
assert!(rng.is_ok());
let mut rng = rng.unwrap();
let mut bytes = [0u8; 32];
rng.fill_bytes(&mut bytes);
let all_zeros = bytes.iter().all(|&b| b == 0);
assert!(!all_zeros, "RNG generated all zeros");
}
#[cfg(feature = "alloc")]
{
let rng = new_secure_rng();
assert!(rng.is_ok());
let mut rng = rng.unwrap();
let mut bytes = [0u8; 32];
rng.fill_bytes(&mut bytes);
let all_zeros = bytes.iter().all(|&b| b == 0);
assert!(!all_zeros, "RNG generated all zeros");
}
}
#[test]
fn test_deterministic_rng() {
let mut seed = [0u8; 32];
seed[..16].copy_from_slice(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
#[cfg(not(feature = "alloc"))]
{
let mut rng1 = new_deterministic_rng_no_std(seed);
let mut rng2 = new_deterministic_rng_no_std(seed);
let mut bytes1 = [0u8; 32];
let mut bytes2 = [0u8; 32];
rng1.fill_bytes(&mut bytes1);
rng2.fill_bytes(&mut bytes2);
assert_eq!(
bytes1, bytes2,
"Deterministic RNG should produce same output"
);
assert!(
rng1.is_deterministic(),
"RNG should be marked as deterministic"
);
}
#[cfg(feature = "alloc")]
{
let mut rng1 = new_deterministic_rng(seed);
let mut rng2 = new_deterministic_rng(seed);
let mut bytes1 = [0u8; 32];
let mut bytes2 = [0u8; 32];
rng1.fill_bytes(&mut bytes1);
rng2.fill_bytes(&mut bytes2);
assert_eq!(
bytes1, bytes2,
"Deterministic RNG should produce same output"
);
}
}
#[test]
fn test_rng_reseeding() {
#[cfg(all(not(feature = "alloc"), feature = "getrandom"))]
{
let mut rng = new_secure_rng_no_std().unwrap();
let _initial_counter = rng.reseed_counter();
let initial_bytes = rng.bytes_generated();
let mut bytes = [0u8; 1024];
rng.fill_bytes(&mut bytes);
assert!(
rng.bytes_generated() > initial_bytes,
"Bytes generated should increase"
);
}
#[cfg(feature = "alloc")]
{
let mut rng = new_secure_rng().unwrap();
let mut bytes = [0u8; 1024];
rng.fill_bytes(&mut bytes);
let all_zeros = bytes.iter().all(|&b| b == 0);
assert!(!all_zeros, "RNG generated all zeros");
}
}
#[test]
fn test_rng_error_handling() {
#[cfg(all(not(feature = "alloc"), feature = "getrandom"))]
{
assert!(new_secure_rng_no_std().is_ok());
}
#[cfg(all(not(feature = "alloc"), not(feature = "getrandom")))]
{
assert!(new_secure_rng_no_std().is_err());
}
}
#[test]
fn test_rng_traits() {
#[cfg(all(not(feature = "alloc"), feature = "getrandom"))]
{
use rand_core::{
CryptoRng,
Rng,
};
let mut rng = new_secure_rng_no_std().unwrap();
let u32_val = rng.next_u32();
let u64_val = rng.next_u64();
fn test_crypto_rng<T: CryptoRng>(rng: &mut T) {
let mut test_bytes = [0u8; 16];
rng.fill_bytes(&mut test_bytes);
assert!(!test_bytes.iter().all(|&b| b == 0));
}
test_crypto_rng(&mut rng);
let mut bytes = [0u8; 16];
rng.fill_bytes(&mut bytes);
assert!(u32_val != 0 || u64_val != 0 || !bytes.iter().all(|&b| b == 0));
}
}
#[test]
fn test_no_std_specific() {
#[cfg(all(not(feature = "alloc"), feature = "getrandom"))]
{
let rng = new_secure_rng_no_std().unwrap();
assert!(
!rng.is_deterministic(),
"Secure RNG should not be deterministic"
);
assert_eq!(
rng.bytes_generated(),
0,
"Initial bytes generated should be 0"
);
assert_eq!(
rng.reseed_counter(),
0,
"Initial reseed counter should be 0"
);
let mut det_seed = [0u8; 32];
det_seed[..4].copy_from_slice(&[1, 2, 3, 4]);
let det_rng = new_deterministic_rng_no_std(det_seed);
assert!(
det_rng.is_deterministic(),
"Deterministic RNG should be marked as such"
);
}
}
#[test]
fn test_memory_safety() {
#[cfg(all(not(feature = "alloc"), feature = "getrandom"))]
{
let mut rng = new_secure_rng_no_std().unwrap();
let mut small_bytes = [0u8; 1];
let mut medium_bytes = [0u8; 64];
let mut large_bytes = [0u8; 1024];
rng.fill_bytes(&mut small_bytes);
rng.fill_bytes(&mut medium_bytes);
rng.fill_bytes(&mut large_bytes);
assert!(!small_bytes.iter().all(|&b| b == 0));
assert!(!medium_bytes.iter().all(|&b| b == 0));
assert!(!large_bytes.iter().all(|&b| b == 0));
}
}
#[test]
fn test_edge_cases() {
#[cfg(all(not(feature = "alloc"), feature = "getrandom"))]
{
let mut rng = new_secure_rng_no_std().unwrap();
let mut empty_bytes = [];
rng.fill_bytes(&mut empty_bytes);
let mut single_byte = [0u8; 1];
rng.fill_bytes(&mut single_byte);
let mut large_bytes = [0u8; 65536];
rng.fill_bytes(&mut large_bytes);
}
}