openvm_continuations/circuit/deferral/
utils.rs

1use std::array::from_fn;
2
3use openvm_stark_sdk::config::baby_bear_poseidon2::{
4    poseidon2_compress_with_capacity, DIGEST_SIZE, F,
5};
6use p3_field::PrimeCharacteristicRing;
7
8use crate::circuit::deferral::{DEF_INTERNAL_TAG, DEF_LEAF_TAG};
9
10pub(crate) fn def_tagged_compress(
11    tag: [u8; DIGEST_SIZE],
12    left: [F; DIGEST_SIZE],
13    right: [F; DIGEST_SIZE],
14) -> ([F; DIGEST_SIZE], [F; DIGEST_SIZE]) {
15    let tagged_left = poseidon2_compress_with_capacity(tag.map(F::from_u8), left).0;
16    let parent = poseidon2_compress_with_capacity(tagged_left, right).0;
17    (tagged_left, parent)
18}
19
20pub fn def_leaf_compress(
21    left: [F; DIGEST_SIZE],
22    right: [F; DIGEST_SIZE],
23) -> ([F; DIGEST_SIZE], [F; DIGEST_SIZE]) {
24    def_tagged_compress(DEF_LEAF_TAG, left, right)
25}
26
27pub(crate) fn def_internal_compress(
28    left: [F; DIGEST_SIZE],
29    right: [F; DIGEST_SIZE],
30) -> ([F; DIGEST_SIZE], [F; DIGEST_SIZE]) {
31    def_tagged_compress(DEF_INTERNAL_TAG, left, right)
32}
33
34pub(crate) fn def_zero_hash(depth: usize) -> [F; DIGEST_SIZE] {
35    let mut zero_hash = [F::ZERO; DIGEST_SIZE];
36    for level in 0..depth {
37        zero_hash = if level == 0 {
38            def_leaf_compress(zero_hash, zero_hash).1
39        } else {
40            def_internal_compress(zero_hash, zero_hash).1
41        };
42    }
43    zero_hash
44}
45
46pub(crate) fn def_zero_hashes_from_depth_one<const MAX_DEPTH: usize>(
47) -> [[F; DIGEST_SIZE]; MAX_DEPTH] {
48    let mut zero_hash = [F::ZERO; DIGEST_SIZE];
49    from_fn(|depth| {
50        zero_hash = if depth == 0 {
51            def_leaf_compress(zero_hash, zero_hash).1
52        } else {
53            def_internal_compress(zero_hash, zero_hash).1
54        };
55        zero_hash
56    })
57}