use nebu::Goldilocks;
pub type Digest = [Goldilocks; 4];
pub fn hash_atom(value: Goldilocks) -> Digest {
let mut data = [0u8; 8];
data[0..8].copy_from_slice(&value.as_u64().to_le_bytes());
let h = hemera::tree::hash_leaf(&data, 0, false);
extract_digest(&h)
}
pub fn hash_pair(left: &Digest, right: &Digest) -> Digest {
let lh = pack_digest(left);
let rh = pack_digest(right);
let h = hemera::tree::hash_node(&lh, &rh, false);
extract_digest(&h)
}
pub fn digest_bytes(d: &Digest) -> [u8; 32] {
let mut out = [0u8; 32];
for i in 0..4 {
out[i * 8..(i + 1) * 8].copy_from_slice(&d[i].as_u64().to_le_bytes());
}
out
}
pub fn digest_from_bytes(b: &[u8; 32]) -> Digest {
let mut d = [Goldilocks::ZERO; 4];
for i in 0..4 {
let mut buf = [0u8; 8];
buf.copy_from_slice(&b[i * 8..(i + 1) * 8]);
d[i] = Goldilocks::new(u64::from_le_bytes(buf)).canonicalize();
}
d
}
fn pack_digest(d: &Digest) -> hemera::Hash {
hemera::Hash::from_bytes(digest_bytes(d))
}
fn extract_digest(h: &hemera::Hash) -> Digest {
let bytes = h.as_bytes();
let mut digest = [Goldilocks::ZERO; 4];
for i in 0..4 {
let mut buf = [0u8; 8];
buf.copy_from_slice(&bytes[i * 8..(i + 1) * 8]);
digest[i] = Goldilocks::new(u64::from_le_bytes(buf)).canonicalize();
}
digest
}