openvm_circuit/arch/hasher/
mod.rspub mod poseidon2;
use openvm_stark_backend::p3_field::Field;
pub trait Hasher<const CHUNK: usize, F: Field> {
fn compress(&self, left: &[F; CHUNK], right: &[F; CHUNK]) -> [F; CHUNK];
fn hash(&self, values: &[F; CHUNK]) -> [F; CHUNK] {
self.compress(values, &[F::ZERO; CHUNK])
}
fn merkle_root(&self, values: &[F]) -> [F; CHUNK] {
let mut leaves: Vec<_> = chunk_public_values(values)
.into_iter()
.map(|c| self.hash(&c))
.collect();
while leaves.len() > 1 {
leaves = leaves
.chunks_exact(2)
.map(|c| self.compress(&c[0], &c[1]))
.collect();
}
leaves[0]
}
}
pub trait HasherChip<const CHUNK: usize, F: Field>: Hasher<CHUNK, F> {
fn compress_and_record(&mut self, left: &[F; CHUNK], right: &[F; CHUNK]) -> [F; CHUNK];
fn hash_and_record(&mut self, values: &[F; CHUNK]) -> [F; CHUNK] {
self.compress_and_record(values, &[F::ZERO; CHUNK])
}
}
fn chunk_public_values<const CHUNK: usize, F: Field>(public_values: &[F]) -> Vec<[F; CHUNK]> {
public_values
.chunks_exact(CHUNK)
.map(|c| c.try_into().unwrap())
.collect()
}