libsodium_rs/random.rs
1//! # Secure Random Number Generation
2//!
3//! This module provides functions for generating cryptographically secure random numbers
4//! and bytes. It uses libsodium's random number generator, which is designed to be
5//! suitable for cryptographic operations.
6//!
7//! ## Security Considerations
8//!
9//! - The random number generator is automatically seeded with sufficient entropy during
10//! library initialization.
11//! - The implementation is designed to be resistant to side-channel attacks.
12//! - The generator is suitable for generating cryptographic keys, nonces, and other
13//! security-sensitive values.
14//!
15//! ## Available Functions
16//!
17//! - [`bytes`]: Generate a vector of random bytes
18//! - [`fill_bytes`]: Fill an existing buffer with random bytes
19//! - [`u32()`]: Generate a random 32-bit unsigned integer
20//! - [`uniform`]: Generate a random 32-bit unsigned integer within a range
21//!
22//! ## Example
23//!
24//! ```rust
25//! use libsodium_rs as sodium;
26//! use sodium::random;
27//! use sodium::ensure_init;
28//!
29//! fn main() -> Result<(), Box<dyn std::error::Error>> {
30//! ensure_init()?;
31//!
32//! // Generate 32 random bytes (suitable for a key)
33//! let random_bytes = random::bytes(32);
34//! assert_eq!(random_bytes.len(), 32);
35//!
36//! // Fill an existing buffer with random bytes
37//! let mut buffer = [0u8; 16];
38//! random::fill_bytes(&mut buffer);
39//!
40//! // Generate a random 32-bit unsigned integer
41//! let random_u32 = random::u32();
42//!
43//! // Generate a random integer between 0 and 99 (inclusive)
44//! let dice_roll = random::uniform(100);
45//! assert!(dice_roll < 100);
46//!
47//! Ok(())
48//! }
49//! ```
50//!
51
52use libsodium_sys;
53
54/// Generate random bytes
55pub fn bytes(size: usize) -> Vec<u8> {
56 let mut buf = vec![0u8; size];
57 unsafe {
58 libsodium_sys::randombytes_buf(buf.as_mut_ptr() as *mut _, size);
59 }
60 buf
61}
62
63/// Fill a buffer with random bytes
64///
65/// This function fills the provided buffer with random bytes.
66/// It cannot fail and does not return a Result.
67pub fn fill_bytes(buf: &mut [u8]) {
68 unsafe {
69 libsodium_sys::randombytes_buf(buf.as_mut_ptr() as *mut _, buf.len());
70 }
71}
72
73/// Generate a random 32-bit unsigned integer
74pub fn u32() -> u32 {
75 unsafe { libsodium_sys::randombytes_random() }
76}
77
78/// Generate a random 32-bit unsigned integer between 0 and upper_bound (exclusive)
79pub fn uniform(upper_bound: u32) -> u32 {
80 unsafe { libsodium_sys::randombytes_uniform(upper_bound) }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn test_random_bytes() {
89 let bytes1 = bytes(32);
90 let bytes2 = bytes(32);
91 assert_eq!(bytes1.len(), 32);
92 assert_eq!(bytes2.len(), 32);
93 assert_ne!(bytes1, bytes2); // Extremely unlikely to be equal
94 }
95
96 #[test]
97 fn test_random_u32() {
98 let _ = u32(); // Just ensure it doesn't panic
99 }
100
101 #[test]
102 fn test_uniform() {
103 let bound = 100;
104 for _ in 0..1000 {
105 let n = uniform(bound);
106 assert!(n < bound);
107 }
108 }
109}