ableos_userland/libraries/cryptography/src/random/mod.rs

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)
}
}