openvm_continuations/
utils.rs1use std::array::from_fn;
2
3use openvm_circuit::arch::POSEIDON2_WIDTH;
4use openvm_stark_sdk::config::baby_bear_poseidon2::{
5 poseidon2_compress_with_capacity, DIGEST_SIZE, F,
6};
7use p3_field::PrimeCharacteristicRing;
8
9pub fn digests_to_poseidon2_input<T: Clone>(
10 x: [T; DIGEST_SIZE],
11 y: [T; DIGEST_SIZE],
12) -> [T; POSEIDON2_WIDTH] {
13 from_fn(|i| {
14 if i < DIGEST_SIZE {
15 x[i].clone()
16 } else {
17 y[i - DIGEST_SIZE].clone()
18 }
19 })
20}
21
22pub fn poseidon2_input_to_digests<T>(
23 x: [T; POSEIDON2_WIDTH],
24) -> ([T; DIGEST_SIZE], [T; DIGEST_SIZE]) {
25 let mut it = x.into_iter();
26 let commit = from_fn(|_| it.next().unwrap());
27 let len = from_fn(|_| it.next().unwrap());
28 (commit, len)
29}
30
31pub fn pad_slice_to_poseidon2_input<T: Clone>(x: &[T], fill: T) -> [T; POSEIDON2_WIDTH] {
32 from_fn(|i| {
33 if i < x.len() {
34 x[i].clone()
35 } else {
36 fill.clone()
37 }
38 })
39}
40
41pub fn zero_hash(depth: usize) -> [F; DIGEST_SIZE] {
42 let mut ret = [F::ZERO; DIGEST_SIZE];
43 for _ in 0..depth {
44 ret = poseidon2_compress_with_capacity(ret, ret).0;
45 }
46 ret
47}
48
49pub fn zero_hashes_from_depth_one<const MAX_DEPTH: usize>() -> [[F; DIGEST_SIZE]; MAX_DEPTH] {
50 let mut zero_hash = [F::ZERO; DIGEST_SIZE];
51 from_fn(|_| {
52 zero_hash = poseidon2_compress_with_capacity(zero_hash, zero_hash).0;
53 zero_hash
54 })
55}