openvm_sdk/verifier/internal/
types.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use std::{array, borrow::BorrowMut};

use derivative::Derivative;
use openvm_circuit::circuit_derive::AlignedBorrow;
use openvm_native_compiler::{
    ir::{Builder, Config, Felt},
    prelude::DIGEST_SIZE,
};
use openvm_stark_sdk::{
    config::baby_bear_poseidon2::BabyBearPoseidon2Config,
    openvm_stark_backend::{
        config::{Com, StarkGenericConfig, Val},
        p3_field::PrimeField32,
        prover::types::Proof,
    },
};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use static_assertions::assert_impl_all;

use crate::{verifier::common::types::VmVerifierPvs, SC};

/// Input for the leaf VM verifier.
#[derive(Serialize, Deserialize, Derivative)]
#[serde(bound = "")]
#[derivative(Clone(bound = "Com<SC>: Clone"))]
pub struct InternalVmVerifierInput<SC: StarkGenericConfig> {
    pub self_program_commit: [Val<SC>; DIGEST_SIZE],
    /// The proofs of leaf verifier or internal verifier in the execution order.
    pub proofs: Vec<Proof<SC>>,
}
assert_impl_all!(InternalVmVerifierInput<BabyBearPoseidon2Config>: Serialize, DeserializeOwned);

impl InternalVmVerifierInput<SC> {
    pub fn chunk_leaf_or_internal_proofs(
        self_program_commit: [Val<SC>; DIGEST_SIZE],
        proofs: &[Proof<SC>],
        chunk: usize,
    ) -> Vec<Self> {
        proofs
            .chunks(chunk)
            .map(|chunk| Self {
                self_program_commit,
                proofs: chunk.to_vec(),
            })
            .collect()
    }
}
/// Aggregated state of all segments
#[derive(Debug, Clone, Copy, AlignedBorrow)]
#[repr(C)]
pub struct InternalVmVerifierPvs<T> {
    pub vm_verifier_pvs: VmVerifierPvs<T>,
    pub extra_pvs: InternalVmVerifierExtraPvs<T>,
}

impl<F: PrimeField32> InternalVmVerifierPvs<Felt<F>> {
    pub fn uninit<C: Config<F = F>>(builder: &mut Builder<C>) -> Self {
        Self {
            vm_verifier_pvs: VmVerifierPvs::<Felt<F>>::uninit(builder),
            extra_pvs: InternalVmVerifierExtraPvs::<Felt<F>>::uninit(builder),
        }
    }
}

impl<F: Default + Clone> InternalVmVerifierPvs<Felt<F>> {
    pub fn flatten(self) -> Vec<Felt<F>> {
        let mut v = vec![Felt(0, Default::default()); InternalVmVerifierPvs::<u8>::width()];
        *v.as_mut_slice().borrow_mut() = self;
        v
    }
}

/// Extra PVs for internal VM verifier except VmVerifierPvs.
#[derive(Debug, Clone, Copy, AlignedBorrow)]
#[repr(C)]
pub struct InternalVmVerifierExtraPvs<T> {
    /// The commitment of the leaf verifier program.
    pub leaf_verifier_commit: [T; DIGEST_SIZE],
    /// For recursion verification, a program need its own commitment, but its own commitment cannot
    /// be hardcoded inside the program itself. So the commitment has to be read from external and
    /// be committed.
    pub internal_program_commit: [T; DIGEST_SIZE],
}

impl<F: PrimeField32> InternalVmVerifierExtraPvs<Felt<F>> {
    pub fn uninit<C: Config<F = F>>(builder: &mut Builder<C>) -> Self {
        Self {
            leaf_verifier_commit: array::from_fn(|_| builder.uninit()),
            internal_program_commit: array::from_fn(|_| builder.uninit()),
        }
    }
}

impl<F: Default + Clone> InternalVmVerifierExtraPvs<Felt<F>> {
    pub fn flatten(self) -> Vec<Felt<F>> {
        let mut v = vec![Felt(0, Default::default()); InternalVmVerifierExtraPvs::<u8>::width()];
        *v.as_mut_slice().borrow_mut() = self;
        v
    }
}