Skip to main content

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}