forked from AbleOS/ableos_userland
144 lines
4.0 KiB
Rust
144 lines
4.0 KiB
Rust
use core::fmt::Display;
|
|
|
|
pub struct Csprng {
|
|
state: [u8; 256],
|
|
dirty: bool,
|
|
}
|
|
|
|
impl Csprng {
|
|
pub fn new() -> Self {
|
|
// Initialize the state with a seed.
|
|
let mut state = [0; 256];
|
|
for i in 0..256 {
|
|
state[i] = 0;
|
|
}
|
|
|
|
Self {
|
|
state,
|
|
dirty: false,
|
|
}
|
|
}
|
|
|
|
pub fn mix_in_data(&mut self, data: &[u8]) {
|
|
self.dirty = true;
|
|
|
|
// TODO: Mix the data into the state using a secure hashing function.
|
|
|
|
// Mix the data into the state using a simple hash function.
|
|
let mut result = [0; 256];
|
|
for (i, byte) in data.iter().enumerate() {
|
|
result[i % 256] ^= byte;
|
|
}
|
|
|
|
// XOR the result of the hashing function with the current state.
|
|
for i in 0..256 {
|
|
self.state[i] ^= result[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Csprng {
|
|
pub fn get_random_u8(&mut self) -> Result<u8, RandError> {
|
|
self.dirty = true;
|
|
let random_bytes = self.state[0];
|
|
Ok(random_bytes)
|
|
}
|
|
|
|
pub fn get_random_u16(&mut self) -> Result<u16, RandError> {
|
|
self.dirty = true;
|
|
|
|
let random_byte_1 = self.state[0];
|
|
let random_byte_2 = self.state[1];
|
|
|
|
let random_number = u16::from_le_bytes([random_byte_1, random_byte_2]);
|
|
Ok(random_number)
|
|
}
|
|
|
|
pub fn get_random_u32(&mut self) -> Result<u32, RandError> {
|
|
self.dirty = true;
|
|
|
|
// Generate a random number using the current state of the CSPRNG.
|
|
let random_byte_1 = self.state[0];
|
|
let random_byte_2 = self.state[1];
|
|
let random_byte_3 = self.state[2];
|
|
let random_byte_4 = self.state[3];
|
|
|
|
let random_number =
|
|
u32::from_le_bytes([random_byte_1, random_byte_2, random_byte_3, random_byte_4]);
|
|
Ok(random_number)
|
|
}
|
|
|
|
pub fn get_random_u64(&mut self) -> Result<u64, RandError> {
|
|
self.dirty = true;
|
|
|
|
// Generate a random number using the current state of the CSPRNG.
|
|
let random_byte_1 = self.state[0];
|
|
let random_byte_2 = self.state[1];
|
|
let random_byte_3 = self.state[2];
|
|
let random_byte_4 = self.state[3];
|
|
let random_byte_5 = self.state[4];
|
|
let random_byte_6 = self.state[5];
|
|
let random_byte_7 = self.state[6];
|
|
let random_byte_8 = self.state[7];
|
|
|
|
let random_number = u64::from_le_bytes([
|
|
random_byte_1,
|
|
random_byte_2,
|
|
random_byte_3,
|
|
random_byte_4,
|
|
random_byte_5,
|
|
random_byte_6,
|
|
random_byte_7,
|
|
random_byte_8,
|
|
]);
|
|
Ok(random_number)
|
|
}
|
|
|
|
pub fn get_random_u128(&mut self) -> Result<u128, RandError> {
|
|
let random_byte_1 = self.state[0];
|
|
let random_byte_2 = self.state[1];
|
|
let random_byte_3 = self.state[2];
|
|
let random_byte_4 = self.state[3];
|
|
let random_byte_5 = self.state[4];
|
|
let random_byte_6 = self.state[5];
|
|
let random_byte_7 = self.state[6];
|
|
let random_byte_8 = self.state[8];
|
|
let random_byte_9 = self.state[9];
|
|
let random_byte_10 = self.state[10];
|
|
let random_byte_11 = self.state[11];
|
|
let random_byte_12 = self.state[12];
|
|
let random_byte_15 = self.state[13];
|
|
let random_byte_16 = self.state[14];
|
|
let random_byte_17 = self.state[15];
|
|
|
|
let random_number = u128::from_le_bytes([
|
|
random_byte_1,
|
|
random_byte_2,
|
|
random_byte_3,
|
|
random_byte_4,
|
|
random_byte_5,
|
|
random_byte_6,
|
|
random_byte_7,
|
|
random_byte_8,
|
|
random_byte_8,
|
|
random_byte_9,
|
|
random_byte_10,
|
|
random_byte_11,
|
|
random_byte_12,
|
|
random_byte_15,
|
|
random_byte_16,
|
|
random_byte_17,
|
|
]);
|
|
|
|
Ok(random_number)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum RandError {}
|
|
impl Display for RandError {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
write!(f, "{}", self)
|
|
}
|
|
}
|