openvm_native_recursion/
types.rs

1use openvm_native_compiler::{
2    asm::AsmConfig,
3    ir::{Config, DIGEST_SIZE},
4};
5use openvm_stark_backend::{
6    air_builders::symbolic::SymbolicExpressionDag,
7    config::{Com, StarkGenericConfig, Val},
8    keygen::types::{LinearConstraint, MultiStarkVerifyingKey, StarkVerifyingKey, TraceWidth},
9    p3_util::log2_strict_usize,
10};
11
12use crate::{
13    digest::DigestVal,
14    hints::{InnerChallenge, InnerVal},
15};
16
17pub type InnerConfig = AsmConfig<InnerVal, InnerChallenge>;
18
19/// Constants determined by AIRs.
20pub struct StarkVerificationAdvice<C: Config> {
21    /// Preprocessed trace data, if any
22    pub preprocessed_data: Option<VerifierSinglePreprocessedDataInProgram<C>>,
23    /// Trace sub-matrix widths
24    pub width: TraceWidth,
25    /// The factor to multiply the trace degree by to get the degree of the quotient polynomial. Determined from the max constraint degree of the AIR constraints.
26    /// This is equivalently the number of chunks the quotient polynomial is split into.
27    pub quotient_degree: usize,
28    /// Number of public values for this STARK only
29    pub num_public_values: usize,
30    /// For only this RAP, how many challenges are needed in each trace challenge phase
31    pub num_challenges_to_sample: Vec<usize>,
32    /// Number of values to expose to verifier in each trace challenge phase
33    pub num_exposed_values_after_challenge: Vec<usize>,
34    /// Symbolic representation of all AIR constraints, including logup constraints
35    pub symbolic_constraints: SymbolicExpressionDag<C::F>,
36}
37
38/// Create StarkVerificationAdvice for an inner config.
39pub(crate) fn new_from_inner_vk<SC: StarkGenericConfig, C: Config<F = Val<SC>>>(
40    vk: StarkVerifyingKey<Val<SC>, Com<SC>>,
41) -> StarkVerificationAdvice<C>
42where
43    Com<SC>: Into<[C::F; DIGEST_SIZE]>,
44{
45    let StarkVerifyingKey {
46        preprocessed_data,
47        params,
48        quotient_degree,
49        symbolic_constraints,
50        rap_phase_seq_kind: _,
51    } = vk;
52    StarkVerificationAdvice {
53        preprocessed_data: preprocessed_data.map(|data| VerifierSinglePreprocessedDataInProgram {
54            commit: DigestVal::F(data.commit.clone().into().to_vec()),
55        }),
56        width: params.width,
57        quotient_degree: quotient_degree as usize,
58        num_public_values: params.num_public_values,
59        num_challenges_to_sample: params.num_challenges_to_sample,
60        num_exposed_values_after_challenge: params.num_exposed_values_after_challenge,
61        symbolic_constraints: symbolic_constraints.constraints,
62    }
63}
64
65/// Constants determined by multiple AIRs.
66pub struct MultiStarkVerificationAdvice<C: Config> {
67    pub per_air: Vec<StarkVerificationAdvice<C>>,
68    pub num_challenges_to_sample: Vec<usize>,
69    pub trace_height_constraints: Vec<LinearConstraint>,
70    pub log_up_pow_bits: usize,
71    pub pre_hash: DigestVal<C>,
72}
73
74/// Create MultiStarkVerificationAdvice for an inner config.
75pub fn new_from_inner_multi_vk<SC: StarkGenericConfig, C: Config<F = Val<SC>>>(
76    vk: &MultiStarkVerifyingKey<SC>,
77) -> MultiStarkVerificationAdvice<C>
78where
79    Com<SC>: Into<[C::F; DIGEST_SIZE]>,
80{
81    let num_challenges_to_sample = vk.num_challenges_per_phase();
82    MultiStarkVerificationAdvice {
83        per_air: vk
84            .inner
85            .per_air
86            .iter()
87            .map(|vk| new_from_inner_vk::<SC, C>(vk.clone()))
88            .collect(),
89        num_challenges_to_sample,
90        trace_height_constraints: vk.inner.trace_height_constraints.clone(),
91        log_up_pow_bits: vk.inner.log_up_pow_bits,
92        pre_hash: DigestVal::F(vk.pre_hash.clone().into().to_vec()),
93    }
94}
95
96impl<C: Config> StarkVerificationAdvice<C> {
97    pub fn log_quotient_degree(&self) -> usize {
98        log2_strict_usize(self.quotient_degree)
99    }
100}
101
102pub struct VerifierSinglePreprocessedDataInProgram<C: Config> {
103    pub commit: DigestVal<C>,
104}