openvm_continuations/verifier/leaf/
vars.rs

1use std::array;
2
3use openvm_native_compiler::prelude::*;
4use openvm_native_recursion::hints::Hintable;
5use openvm_stark_sdk::openvm_stark_backend::{
6    config::{StarkGenericConfig, Val},
7    p3_field::FieldAlgebra,
8    proof::Proof,
9};
10
11use crate::{
12    verifier::{
13        leaf::types::{LeafVmVerifierInput, UserPublicValuesRootProof},
14        utils,
15    },
16    C, F,
17};
18
19#[derive(DslVariable, Clone)]
20pub struct UserPublicValuesRootProofVariable<const CHUNK: usize, C: Config> {
21    /// Sibling hashes for proving the merkle root of public values. For a specific VM, the path
22    /// is constant. So we don't need the boolean which indicates if a node is a left child or
23    /// right child.
24    pub sibling_hashes: Array<C, [Felt<C::F>; CHUNK]>,
25    pub public_values_commit: [Felt<C::F>; CHUNK],
26}
27
28impl<SC: StarkGenericConfig> LeafVmVerifierInput<SC> {
29    pub fn write_to_stream<C: Config<N = Val<SC>>>(&self) -> Vec<Vec<Val<SC>>>
30    where
31        Vec<Proof<SC>>: Hintable<C>,
32        UserPublicValuesRootProof<Val<SC>>: Hintable<C>,
33    {
34        let mut ret = Hintable::<C>::write(&self.proofs);
35        if let Some(pvs_root_proof) = &self.public_values_root_proof {
36            ret.extend(Hintable::<C>::write(pvs_root_proof));
37        }
38        ret
39    }
40}
41
42impl Hintable<C> for UserPublicValuesRootProof<F> {
43    type HintVariable = UserPublicValuesRootProofVariable<{ DIGEST_SIZE }, C>;
44    fn read(builder: &mut Builder<C>) -> Self::HintVariable {
45        let len = builder.hint_var();
46        let sibling_hashes = builder.array(len);
47        builder.range(0, len).for_each(|i_vec, builder| {
48            let hash = array::from_fn(|_| builder.hint_felt());
49            builder.set_value(&sibling_hashes, i_vec[0], hash);
50        });
51        let public_values_commit = array::from_fn(|_| builder.hint_felt());
52        Self::HintVariable {
53            sibling_hashes,
54            public_values_commit,
55        }
56    }
57    fn write(&self) -> Vec<Vec<<C as Config>::N>> {
58        let len = <<C as Config>::N>::from_canonical_usize(self.sibling_hashes.len());
59        let mut stream = len.write();
60        stream.extend(
61            self.sibling_hashes
62                .iter()
63                .flat_map(utils::write_field_slice),
64        );
65        stream.extend(utils::write_field_slice(&self.public_values_commit));
66        stream
67    }
68}