openvm_circuit/arch/hasher/
mod.rs
1pub mod poseidon2;
2
3use openvm_stark_backend::p3_field::Field;
4
5pub trait Hasher<const CHUNK: usize, F: Field> {
6 fn compress(&self, left: &[F; CHUNK], right: &[F; CHUNK]) -> [F; CHUNK];
8 fn hash(&self, values: &[F; CHUNK]) -> [F; CHUNK] {
9 self.compress(values, &[F::ZERO; CHUNK])
10 }
11 fn merkle_root(&self, values: &[F]) -> [F; CHUNK] {
14 let mut leaves: Vec<_> = chunk_public_values(values)
15 .into_iter()
16 .map(|c| self.hash(&c))
17 .collect();
18 while leaves.len() > 1 {
19 leaves = leaves
20 .chunks_exact(2)
21 .map(|c| self.compress(&c[0], &c[1]))
22 .collect();
23 }
24 leaves[0]
25 }
26}
27pub trait HasherChip<const CHUNK: usize, F: Field>: Hasher<CHUNK, F> {
28 fn compress_and_record(&mut self, left: &[F; CHUNK], right: &[F; CHUNK]) -> [F; CHUNK];
30 fn hash_and_record(&mut self, values: &[F; CHUNK]) -> [F; CHUNK] {
31 self.compress_and_record(values, &[F::ZERO; CHUNK])
32 }
33}
34
35fn chunk_public_values<const CHUNK: usize, F: Field>(public_values: &[F]) -> Vec<[F; CHUNK]> {
36 public_values
37 .chunks_exact(CHUNK)
38 .map(|c| c.try_into().unwrap())
39 .collect()
40}