use std::{
hash::{Hash, Hasher},
io,
};
use crate::{GuardedLandfill, Substructure};
use bytemuck_derive::*;
use rand::Rng;
use seahash::SeaHasher;
#[repr(C)]
#[derive(Clone, Copy, Zeroable, Pod, Debug)]
pub struct Entropy([u64; 4]);
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq, Zeroable, Pod)]
pub struct Tag(u32);
impl Substructure for Entropy {
fn init(lf: GuardedLandfill) -> io::Result<Self> {
lf.get_static_or_init(|| {
let mut rng = rand::thread_rng();
Entropy(rng.gen())
})
}
fn flush(&self) -> io::Result<()> {
Ok(())
}
}
impl Entropy {
pub fn checksum<T: Hash>(&self, t: &T) -> u64 {
let mut hasher =
SeaHasher::with_seeds(self.0[0], self.0[1], self.0[2], self.0[3]);
t.hash(&mut hasher);
hasher.finish()
}
pub fn nonce(&self) -> u64 {
rand::thread_rng().gen()
}
pub fn tag(&self) -> Tag {
Tag(self.checksum(&()) as u32)
}
}