openvm_continuations/
utils.rs

1use 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}