openvm_continuations/verifier/internal/
types.rs

1use std::{array, borrow::BorrowMut};
2
3use derivative::Derivative;
4use openvm_circuit::circuit_derive::AlignedBorrow;
5use openvm_native_compiler::{
6    ir::{Builder, Config, Felt},
7    prelude::DIGEST_SIZE,
8};
9use openvm_stark_sdk::{
10    config::baby_bear_poseidon2::BabyBearPoseidon2Config,
11    openvm_stark_backend::{
12        config::{Com, StarkGenericConfig, Val},
13        p3_field::PrimeField32,
14        proof::Proof,
15    },
16};
17use serde::{de::DeserializeOwned, Deserialize, Serialize};
18use static_assertions::assert_impl_all;
19
20use crate::{verifier::common::types::VmVerifierPvs, SC};
21
22/// Input for the leaf VM verifier.
23#[derive(Serialize, Deserialize, Derivative)]
24#[serde(bound = "")]
25#[derivative(Clone(bound = "Com<SC>: Clone"))]
26pub struct InternalVmVerifierInput<SC: StarkGenericConfig> {
27    pub self_program_commit: [Val<SC>; DIGEST_SIZE],
28    /// The proofs of leaf verifier or internal verifier in the execution order.
29    pub proofs: Vec<Proof<SC>>,
30}
31assert_impl_all!(InternalVmVerifierInput<BabyBearPoseidon2Config>: Serialize, DeserializeOwned);
32
33/// A proof which can prove OpenVM program execution.
34///
35/// The `inner` field contains the raw STARK proof, including the public values of each AIR. The
36/// `user_public_values` are special user-defined values that are only committed to in the `inner`
37/// public values: one can verify using a Merkle proof that the former are committed to in the
38/// latter.
39///
40/// This struct may be serialized using the `Encode` trait in the `openvm_sdk` crate.
41#[derive(Derivative)]
42#[derivative(Clone(bound = "Com<SC>: Clone"))]
43pub struct VmStarkProof<SC: StarkGenericConfig> {
44    /// STARK backend proof
45    pub inner: Proof<SC>,
46    pub user_public_values: Vec<Val<SC>>,
47}
48
49/// Aggregated state of all segments
50#[derive(Debug, Clone, Copy, AlignedBorrow)]
51#[repr(C)]
52pub struct InternalVmVerifierPvs<T> {
53    pub vm_verifier_pvs: VmVerifierPvs<T>,
54    pub extra_pvs: InternalVmVerifierExtraPvs<T>,
55}
56
57/// Extra PVs for internal VM verifier except VmVerifierPvs.
58#[derive(Debug, Clone, Copy, AlignedBorrow)]
59#[repr(C)]
60pub struct InternalVmVerifierExtraPvs<T> {
61    /// The commitment of the leaf verifier program.
62    pub leaf_verifier_commit: [T; DIGEST_SIZE],
63    /// For recursion verification, a program need its own commitment, but its own commitment
64    /// cannot be hardcoded inside the program itself. So the commitment has to be read from
65    /// external and be committed.
66    pub internal_program_commit: [T; DIGEST_SIZE],
67}
68
69impl InternalVmVerifierInput<SC> {
70    pub fn chunk_leaf_or_internal_proofs(
71        self_program_commit: [Val<SC>; DIGEST_SIZE],
72        proofs: &[Proof<SC>],
73        chunk: usize,
74    ) -> Vec<Self> {
75        proofs
76            .chunks(chunk)
77            .map(|chunk| Self {
78                self_program_commit,
79                proofs: chunk.to_vec(),
80            })
81            .collect()
82    }
83}
84
85impl<F: PrimeField32> InternalVmVerifierPvs<Felt<F>> {
86    pub fn uninit<C: Config<F = F>>(builder: &mut Builder<C>) -> Self {
87        Self {
88            vm_verifier_pvs: VmVerifierPvs::<Felt<F>>::uninit(builder),
89            extra_pvs: InternalVmVerifierExtraPvs::<Felt<F>>::uninit(builder),
90        }
91    }
92}
93
94impl<F: Default + Clone> InternalVmVerifierPvs<Felt<F>> {
95    pub fn flatten(self) -> Vec<Felt<F>> {
96        let mut v = vec![Felt(0, Default::default()); InternalVmVerifierPvs::<u8>::width()];
97        *v.as_mut_slice().borrow_mut() = self;
98        v
99    }
100}
101
102impl<F: PrimeField32> InternalVmVerifierExtraPvs<Felt<F>> {
103    pub fn uninit<C: Config<F = F>>(builder: &mut Builder<C>) -> Self {
104        Self {
105            leaf_verifier_commit: array::from_fn(|_| builder.uninit()),
106            internal_program_commit: array::from_fn(|_| builder.uninit()),
107        }
108    }
109}
110
111impl<F: Default + Clone> InternalVmVerifierExtraPvs<Felt<F>> {
112    pub fn flatten(self) -> Vec<Felt<F>> {
113        let mut v = vec![Felt(0, Default::default()); InternalVmVerifierExtraPvs::<u8>::width()];
114        *v.as_mut_slice().borrow_mut() = self;
115        v
116    }
117}