use rustreexo::mem_forest::MemForest;
use rustreexo::node_hash::AccumulatorHash;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
enum CustomHash {
Hash([u8; 32]),
Placeholder,
#[default]
Empty,
}
impl std::fmt::Display for CustomHash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Hash(h) => write!(f, "Hash({h:?})"),
Self::Placeholder => write!(f, "Placeholder"),
Self::Empty => write!(f, "Empty"),
}
}
}
impl AccumulatorHash for CustomHash {
fn placeholder() -> Self {
Self::Placeholder
}
fn empty() -> Self {
Self::Empty
}
fn is_placeholder(&self) -> bool {
matches!(self, Self::Placeholder)
}
fn is_empty(&self) -> bool {
matches!(self, Self::Empty)
}
fn write<W>(&self, writer: &mut W) -> std::io::Result<()>
where
W: std::io::Write,
{
match self {
Self::Hash(h) => writer.write_all(h),
Self::Placeholder => writer.write_all(&[0u8; 32]),
Self::Empty => writer.write_all(&[0u8; 32]),
}
}
fn read<R>(reader: &mut R) -> std::io::Result<Self>
where
R: std::io::Read,
{
let mut h = [0u8; 32];
reader.read_exact(&mut h)?;
if h.iter().all(|&x| x == 0) {
Ok(Self::Placeholder)
} else {
Ok(Self::Hash(h))
}
}
fn parent_hash(left: &Self, right: &Self) -> Self {
match (left, right) {
(Self::Hash(l), Self::Hash(r)) => {
let mut h = [0u8; 32];
for i in 0..32 {
h[i] = l[i] ^ r[i];
}
Self::Hash(h)
}
_ => unreachable!(),
}
}
}
fn main() {
let elements = vec![CustomHash::Hash([1; 32]), CustomHash::Hash([2; 32])];
let mut p = MemForest::<CustomHash>::new_with_hash();
p.modify(&elements, &[]).unwrap();
let proof = p.prove(&[elements[0]]).unwrap();
assert_eq!(proof.n_targets(), 1);
assert!(p.verify(&proof, &[elements[0]]).unwrap());
}