openvm_sdk/keygen/
mod.rs

1#[cfg(feature = "evm-prove")]
2use std::io::{self, Read, Write};
3use std::sync::Arc;
4
5use openvm_circuit::{
6    arch::{AirInventoryError, SystemConfig, VmCircuitConfig},
7    system::memory::dimensions::MemoryDimensions,
8};
9use openvm_continuations::prover::DeferralCircuitProverKey;
10#[cfg(feature = "root-prover")]
11use openvm_continuations::RootSC;
12#[cfg(feature = "evm-prove")]
13use openvm_stark_backend::codec::{Decode, Encode};
14use openvm_stark_backend::{
15    keygen::types::{MultiStarkProvingKey, MultiStarkVerifyingKey},
16    StarkEngine,
17};
18use openvm_stark_sdk::config::baby_bear_poseidon2::{BabyBearPoseidon2CpuEngine, DuplexSponge};
19use serde::{Deserialize, Serialize};
20
21use crate::{config::AppConfig, prover::vm::types::VmProvingKey, SC};
22
23#[cfg(feature = "root-prover")]
24pub mod dummy;
25#[cfg(feature = "evm-prove")]
26pub mod static_verifier;
27
28/// This is lightweight to clone as it contains smart pointers to the proving keys.
29#[derive(Clone, Serialize, Deserialize)]
30pub struct AppProvingKey<VC> {
31    pub app_vm_pk: Arc<VmProvingKey<VC>>,
32}
33
34#[derive(Clone, Serialize, Deserialize)]
35pub struct AppVerifyingKey {
36    pub vk: MultiStarkVerifyingKey<SC>,
37    pub memory_dimensions: MemoryDimensions,
38    pub num_user_pvs: usize,
39}
40
41#[derive(Clone, Serialize, Deserialize)]
42pub struct AggPrefixProvingKey {
43    pub leaf: Arc<MultiStarkProvingKey<SC>>,
44    pub internal_for_leaf: Arc<MultiStarkProvingKey<SC>>,
45}
46
47#[derive(Clone, Serialize, Deserialize)]
48pub struct AggProvingKey {
49    pub prefix: AggPrefixProvingKey,
50    pub internal_recursive: Arc<MultiStarkProvingKey<SC>>,
51}
52
53#[derive(Clone, Serialize, Deserialize)]
54pub struct DeferralCircuitProvingKey {
55    pub def_circuit_pk: Arc<DeferralCircuitProverKey<SC>>,
56    pub agg_prefix_pk: AggPrefixProvingKey,
57}
58
59#[derive(Clone, Serialize, Deserialize)]
60pub struct DeferralProvingKey {
61    pub circuits: Vec<DeferralCircuitProvingKey>,
62    pub def_internal_recursive_pk: Arc<MultiStarkProvingKey<SC>>,
63    pub def_hook_pk: Arc<MultiStarkProvingKey<SC>>,
64}
65
66#[cfg(feature = "root-prover")]
67#[derive(Clone, Serialize, Deserialize)]
68pub struct RootProvingKey {
69    pub root_pk: Arc<MultiStarkProvingKey<RootSC>>,
70    pub trace_heights: Vec<usize>,
71}
72
73impl<VC> AppProvingKey<VC>
74where
75    VC: Clone + VmCircuitConfig<SC> + AsRef<SystemConfig>,
76{
77    pub fn keygen(config: AppConfig<VC>) -> Result<Self, AirInventoryError> {
78        let app_engine = BabyBearPoseidon2CpuEngine::<DuplexSponge>::new(config.system_params);
79        let app_vm_pk = {
80            let vm_pk = config
81                .app_vm_config
82                .create_airs()?
83                .keygen(app_engine.config());
84            VmProvingKey {
85                vm_config: config.app_vm_config.clone(),
86                vm_pk: Arc::new(vm_pk),
87            }
88        };
89        Ok(Self {
90            app_vm_pk: Arc::new(app_vm_pk),
91        })
92    }
93
94    pub fn num_public_values(&self) -> usize {
95        self.app_vm_pk.vm_config.as_ref().num_public_values
96    }
97
98    pub fn get_app_vk(&self) -> AppVerifyingKey {
99        let system_config = self.app_vm_pk.vm_config.as_ref();
100        AppVerifyingKey {
101            vk: self.app_vm_pk.vm_pk.get_vk(),
102            memory_dimensions: system_config.memory_config.memory_dimensions(),
103            num_user_pvs: system_config.num_public_values,
104        }
105    }
106
107    pub fn vm_config(&self) -> &VC {
108        &self.app_vm_pk.vm_config
109    }
110
111    pub fn app_config(&self) -> AppConfig<VC> {
112        AppConfig {
113            app_vm_config: self.vm_config().clone(),
114            system_params: self.app_vm_pk.vm_pk.params.clone(),
115        }
116    }
117}
118
119/// Proving keys that have already been generated by an SDK.
120///
121/// Optional fields mean the SDK has not generated or been seeded with that key yet. Constructing
122/// this type should not trigger key generation.
123///
124/// Halo2 proving keys use a separate codec path; use `write_halo2_pk_to_file` and
125/// `read_halo2_pk_from_file` for those.
126#[derive(Clone, Serialize, Deserialize)]
127pub struct SdkCachedProvingKey<VC> {
128    pub app_pk: AppProvingKey<VC>,
129    pub agg_pk: AggProvingKey,
130    pub deferral_pk: Option<DeferralProvingKey>,
131    pub deferral_agg_pk: Option<AggProvingKey>,
132    #[cfg(feature = "root-prover")]
133    pub root_pk: Option<RootProvingKey>,
134}
135
136#[cfg(feature = "evm-prove")]
137#[derive(Clone)]
138pub struct Halo2ProvingKey {
139    /// Static verifier to verify a stark proof of the root verifier.
140    pub verifier: Arc<openvm_static_verifier::StaticVerifierProvingKey>,
141    /// Wrapper circuit to verify static verifier and reduce the verification costs in the final
142    /// proof.
143    pub wrapper: Arc<openvm_static_verifier::Halo2WrapperProvingKey>,
144    /// Whether to collect detailed profiling metrics.
145    pub profiling: bool,
146}
147
148#[cfg(feature = "evm-prove")]
149impl Encode for Halo2ProvingKey {
150    fn encode<W: Write>(&self, writer: &mut W) -> io::Result<()> {
151        self.profiling.encode(writer)?;
152        self.verifier.encode(writer)?;
153        self.wrapper.encode(writer)
154    }
155}
156
157#[cfg(feature = "evm-prove")]
158impl Decode for Halo2ProvingKey {
159    fn decode<R: Read>(reader: &mut R) -> io::Result<Self> {
160        Ok(Self {
161            profiling: bool::decode(reader)?,
162            verifier: Arc::new(openvm_static_verifier::StaticVerifierProvingKey::decode(
163                reader,
164            )?),
165            wrapper: Arc::new(openvm_static_verifier::Halo2WrapperProvingKey::decode(
166                reader,
167            )?),
168        })
169    }
170}