openvm_continuations/verifier/leaf/
types.rs

1use derivative::Derivative;
2use openvm_circuit::{
3    arch::ContinuationVmProof, system::memory::merkle::public_values::UserPublicValuesProof,
4};
5use openvm_native_compiler::ir::DIGEST_SIZE;
6use openvm_stark_sdk::{
7    config::baby_bear_poseidon2::BabyBearPoseidon2Config,
8    openvm_stark_backend::{
9        config::{Com, StarkGenericConfig, Val},
10        proof::Proof,
11    },
12    p3_baby_bear::BabyBear,
13};
14use serde::{de::DeserializeOwned, Deserialize, Serialize};
15use static_assertions::assert_impl_all;
16
17/// Input for the leaf VM verifier.
18#[derive(Serialize, Deserialize, Derivative)]
19#[serde(bound = "")]
20#[derivative(Clone(bound = "Com<SC>: Clone"))]
21pub struct LeafVmVerifierInput<SC: StarkGenericConfig> {
22    /// The proofs of the VM execution segments in the execution order.
23    pub proofs: Vec<Proof<SC>>,
24    /// The public values root proof. Leaf VM verifier only needs this when verifying the last
25    /// segment.
26    pub public_values_root_proof: Option<UserPublicValuesRootProof<Val<SC>>>,
27}
28assert_impl_all!(LeafVmVerifierInput<BabyBearPoseidon2Config>: Serialize, DeserializeOwned);
29
30/// Proof that the merkle root of public values is in the memory state. Can be extracted from
31/// `openvm_circuit::system::memory::public_values::UserPublicValuesProof`.
32#[derive(Serialize, Deserialize, Clone, Debug)]
33pub struct UserPublicValuesRootProof<F> {
34    /// Sibling hashes for proving the merkle root of public values. For a specific VM, the path
35    /// is constant. So we don't need the boolean which indicates if a node is a left child or
36    /// right child.
37    pub sibling_hashes: Vec<[F; DIGEST_SIZE]>,
38    pub public_values_commit: [F; DIGEST_SIZE],
39}
40assert_impl_all!(UserPublicValuesRootProof<BabyBear>: Serialize, DeserializeOwned);
41
42impl<SC: StarkGenericConfig> LeafVmVerifierInput<SC> {
43    pub fn chunk_continuation_vm_proof(proof: &ContinuationVmProof<SC>, chunk: usize) -> Vec<Self> {
44        let ContinuationVmProof {
45            per_segment,
46            user_public_values,
47        } = proof;
48        let mut ret: Vec<Self> = per_segment
49            .chunks(chunk)
50            .map(|proof| Self {
51                proofs: proof.to_vec(),
52                public_values_root_proof: None,
53            })
54            .collect();
55        ret.last_mut().unwrap().public_values_root_proof =
56            Some(UserPublicValuesRootProof::extract(user_public_values));
57        ret
58    }
59}
60
61impl<F: Clone> UserPublicValuesRootProof<F> {
62    pub fn extract(pvs_proof: &UserPublicValuesProof<{ DIGEST_SIZE }, F>) -> Self {
63        Self {
64            sibling_hashes: pvs_proof.proof.clone(),
65            public_values_commit: pvs_proof.public_values_commit.clone(),
66        }
67    }
68}