use digest::Digest;
use serde::{Deserialize, Serialize};
use sha3::Sha3_512;
use std::fmt::Debug;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct RandomOracle {
prefix: String,
}
impl RandomOracle {
pub fn new(initial_prefix: &str) -> Self {
debug_assert!(!initial_prefix.contains('-'));
assert!(initial_prefix.len() < u32::MAX as usize);
Self {
prefix: initial_prefix.into(),
}
}
pub fn evaluate<T: Serialize>(&self, obj: &T) -> [u8; 64] {
let mut hasher = Sha3_512::default();
let len: u32 = self
.prefix
.len()
.try_into()
.expect("prefix length should be less than u32::MAX, checked when set");
hasher.update(len.to_be_bytes());
hasher.update(&self.prefix);
let serialized = bcs::to_bytes(obj).expect("serialize should never fail");
hasher.update(&serialized);
hasher.finalize().into()
}
pub fn extend(&self, extension: &str) -> Self {
debug_assert!(!extension.contains('-'));
assert!(self.prefix.len() + extension.len() + 1 < u32::MAX as usize);
Self {
prefix: self.prefix.clone() + "-" + extension,
}
}
}