1#![cfg_attr(feature = "tco", allow(incomplete_features))]
2#![cfg_attr(feature = "tco", feature(explicit_tail_calls))]
3
4use std::{
5 fs::read,
6 marker::PhantomData,
7 path::Path,
8 sync::{Arc, OnceLock},
9};
10
11use config::AppConfig;
12use getset::Getters;
13use keygen::{AppProvingKey, AppVerifyingKey};
14use openvm_build::{
15 build_guest_package, find_unique_executable, get_package, GuestOptions, TargetFilter,
16};
17pub use openvm_build::{cargo_command, get_rustup_toolchain_name};
19pub use openvm_circuit;
20use openvm_circuit::{
21 arch::{
22 execution_mode::Segment, instructions::exe::VmExe, Executor, InitFileGenerator,
23 MeteredExecutor, PreflightExecutor, VirtualMachineError, VmBuilder, VmExecutionConfig,
24 VmExecutor,
25 },
26 system::memory::merkle::public_values::extract_public_values,
27};
28use openvm_continuations::CommitBytes;
29use openvm_sdk_config::{SdkVmConfig, SdkVmCpuBuilder, TranspilerConfig};
30use openvm_stark_backend::{keygen::types::MultiStarkVerifyingKey, StarkEngine, SystemParams};
31use openvm_stark_sdk::config::baby_bear_poseidon2::{
32 BabyBearPoseidon2CpuEngine as BabyBearPoseidon2Engine, Digest,
33};
34#[cfg(feature = "evm-prove")]
35use openvm_static_verifier::StaticVerifierShape;
36use openvm_transpiler::{
37 elf::Elf, openvm_platform::memory::MEM_SIZE, transpiler::Transpiler, FromElf,
38};
39use openvm_verify_stark_host::{
40 verify_vm_stark_proof_decoded,
41 vk::{VerificationBaseline, VmStarkVerifyingKey},
42 VmStarkProof,
43};
44
45use crate::{
46 config::{AggregationConfig, AggregationSystemParams, AggregationTreeConfig},
47 keygen::{AggPrefixProvingKey, AggProvingKey, SdkCachedProvingKey},
48 prover::{AggProver, AppProver, DeferralAggProver, DeferralHookCommits, StarkProver},
49 types::{AppExecutionCommit, ExecutableFormat},
50};
51#[cfg(feature = "evm-prove")]
52use crate::{halo2_params::CacheHalo2ParamsReader, keygen::Halo2ProvingKey, prover::Halo2Prover};
53#[cfg(feature = "root-prover")]
54use crate::{
55 keygen::{dummy::compute_root_proof_heights, RootProvingKey},
56 prover::{EvmProver, RootProver},
57};
58
59cfg_if::cfg_if! {
60 if #[cfg(feature = "cuda")] {
61 use openvm_sdk_config::SdkVmGpuBuilder;
62 use openvm_cuda_backend::BabyBearPoseidon2GpuEngine as GpuBabyBearPoseidon2Engine;
63 pub use GpuSdk as Sdk;
64 pub type DefaultStarkEngine = GpuBabyBearPoseidon2Engine;
65 } else {
66 pub use CpuSdk as Sdk;
67 pub type DefaultStarkEngine = BabyBearPoseidon2Engine;
68 }
69}
70
71pub use openvm_stark_sdk::config::baby_bear_poseidon2::{BabyBearPoseidon2Config as SC, F};
72
73pub mod builder;
74pub mod config;
75pub mod fs;
76#[cfg(feature = "evm-prove")]
77pub mod halo2_params;
78pub mod keygen;
79pub mod prover;
80#[cfg(feature = "evm-verify")]
81mod solidity;
82pub mod types;
83pub mod util;
84
85#[cfg(test)]
86mod tests;
87
88mod error;
89mod stdin;
90pub use error::SdkError;
91pub use stdin::*;
92
93pub const OPENVM_VERSION: &str = concat!(
94 env!("CARGO_PKG_VERSION_MAJOR"),
95 ".",
96 env!("CARGO_PKG_VERSION_MINOR")
97);
98
99#[derive(Getters)]
117pub struct GenericSdk<E, VB>
118where
119 E: StarkEngine<SC = SC>,
120 VB: VmBuilder<E>,
121 VB::VmConfig: VmExecutionConfig<F>,
122{
123 #[getset(get = "pub")]
124 app_config: AppConfig<VB::VmConfig>,
125 #[getset(get = "pub")]
126 agg_config: AggregationConfig,
127 #[getset(get = "pub")]
128 agg_tree_config: AggregationTreeConfig,
129 #[cfg(feature = "root-prover")]
130 #[getset(get = "pub")]
131 root_params: SystemParams,
132 #[cfg(feature = "evm-prove")]
133 #[getset(get = "pub")]
134 halo2_shape: StaticVerifierShape,
135 #[cfg(feature = "evm-prove")]
136 #[getset(get = "pub")]
137 halo2_config: config::Halo2Config,
138
139 #[getset(get = "pub")]
140 app_vm_builder: VB,
141
142 transpiler: Option<Transpiler<F>>,
143
144 #[getset(get = "pub")]
148 executor: VmExecutor<F, VB::VmConfig>,
149
150 app_pk: OnceLock<AppProvingKey<VB::VmConfig>>,
151 agg_prover: OnceLock<Arc<AggProver>>,
152 #[cfg(feature = "root-prover")]
153 root_prover: OnceLock<Arc<RootProver>>,
154
155 deferral_setup: DeferralSetup,
156
157 #[cfg(feature = "evm-prove")]
158 #[getset(get = "pub")]
159 halo2_params_reader: CacheHalo2ParamsReader,
160 #[cfg(feature = "evm-prove")]
161 halo2_prover: OnceLock<Halo2Prover>,
162
163 _phantom: PhantomData<E>,
164}
165
166#[derive(Clone, Default)]
167pub enum DeferralSetup {
168 #[default]
169 Disabled,
172 Aware(DeferralHookCommits),
176 Active(Arc<DeferralAggProver>),
179}
180
181impl DeferralSetup {
182 pub fn hook_cached_commit(&self) -> Option<Digest> {
183 match self {
184 Self::Disabled => None,
185 Self::Aware(commits) => Some(commits.hook_cached_commit),
186 Self::Active(prover) => Some(prover.def_hook_cached_commit()),
187 }
188 }
189
190 pub fn hook_commit(&self) -> Option<Digest> {
191 match self {
192 Self::Disabled => None,
193 Self::Aware(commits) => Some(commits.hook_commit),
194 Self::Active(prover) => Some(prover.def_hook_commit()),
195 }
196 }
197
198 pub fn prover(&self) -> Option<Arc<DeferralAggProver>> {
199 match self {
200 Self::Active(prover) => Some(prover.clone()),
201 Self::Disabled | Self::Aware(_) => None,
202 }
203 }
204}
205
206pub type CpuSdk = GenericSdk<BabyBearPoseidon2Engine, SdkVmCpuBuilder>;
207
208#[cfg(feature = "cuda")]
209pub type GpuSdk = GenericSdk<GpuBabyBearPoseidon2Engine, SdkVmGpuBuilder>;
210
211impl<E, VB> GenericSdk<E, VB>
212where
213 E: StarkEngine<SC = SC>,
214 VB: VmBuilder<E, VmConfig = SdkVmConfig> + Clone + Default,
215{
216 pub fn standard(app_params: SystemParams, agg_params: AggregationSystemParams) -> Self {
224 GenericSdk::new(AppConfig::standard(app_params), agg_params).unwrap()
225 }
226
227 pub fn riscv32(app_params: SystemParams, agg_params: AggregationSystemParams) -> Self {
233 GenericSdk::new(AppConfig::riscv32(app_params), agg_params).unwrap()
234 }
235}
236
237impl<E, VB> GenericSdk<E, VB>
238where
239 E: StarkEngine<SC = SC>,
240 VB: VmBuilder<E>,
241{
242 pub fn new(
244 app_config: AppConfig<VB::VmConfig>,
245 agg_params: AggregationSystemParams,
246 ) -> Result<Self, SdkError>
247 where
248 VB: Default,
249 VB::VmConfig: TranspilerConfig<F>,
250 {
251 Self::builder()
252 .app_config(app_config)
253 .agg_params(agg_params)
254 .build()
255 }
256
257 pub fn new_without_transpiler(
262 app_config: AppConfig<VB::VmConfig>,
263 agg_params: AggregationSystemParams,
264 ) -> Result<Self, SdkError>
265 where
266 VB: Default,
267 {
268 Self::builder()
269 .app_config(app_config)
270 .agg_params(agg_params)
271 .build_without_transpiler()
272 }
273
274 pub fn def_hook_cached_commit(&self) -> Option<Digest> {
276 self.deferral_setup.hook_cached_commit()
277 }
278
279 pub fn def_hook_commit(&self) -> Option<Digest> {
281 self.deferral_setup.hook_commit()
282 }
283
284 pub fn deferral_agg_prover(&self) -> Option<Arc<DeferralAggProver>> {
286 self.deferral_setup.prover()
287 }
288
289 pub fn deferral_circuit_cached_commits(
292 &self,
293 def_idx: usize,
294 ) -> Result<Vec<CommitBytes>, SdkError> {
295 let deferral_prover = self.deferral_setup.prover().ok_or_else(|| {
296 SdkError::Other(eyre::eyre!(
297 "deferral circuit cached commits require an active deferral prover"
298 ))
299 })?;
300 deferral_prover
301 .multi_deferral_circuit_prover
302 .single_circuit_provers
303 .get(def_idx)
304 .map(|prover| prover.def_circuit_prover.cached_commits())
305 .ok_or_else(|| {
306 SdkError::Other(eyre::eyre!(
307 "deferral circuit index {def_idx} is not configured"
308 ))
309 })
310 }
311
312 pub fn cached_proving_key(&self) -> Result<SdkCachedProvingKey<VB::VmConfig>, SdkError> {
320 let app_pk = self
321 .app_pk
322 .get()
323 .ok_or_else(|| SdkError::Other(eyre::eyre!("app_pk is not generated")))?
324 .clone();
325 let agg_prover = self
326 .agg_prover
327 .get()
328 .ok_or_else(|| SdkError::Other(eyre::eyre!("agg_pk is not generated")))?;
329 let deferral_prover = self.deferral_setup.prover();
330 Ok(SdkCachedProvingKey {
331 app_pk,
332 agg_pk: AggProvingKey {
333 prefix: AggPrefixProvingKey {
334 leaf: agg_prover.leaf_prover.get_pk(),
335 internal_for_leaf: agg_prover.internal_for_leaf_prover.get_pk(),
336 },
337 internal_recursive: agg_prover.internal_recursive_prover.get_pk(),
338 },
339 deferral_pk: deferral_prover
340 .as_ref()
341 .map(|def_agg_prover| def_agg_prover.multi_deferral_circuit_prover.get_pk()),
342 deferral_agg_pk: deferral_prover
343 .as_ref()
344 .map(|def_agg_prover| def_agg_prover.get_pk()),
345 #[cfg(feature = "root-prover")]
346 root_pk: self.root_prover.get().map(|root_prover| RootProvingKey {
347 root_pk: root_prover.0.get_pk(),
348 trace_heights: root_prover.0.get_trace_heights().unwrap_or_default(),
349 }),
350 })
351 }
352
353 pub fn build<P: AsRef<Path>>(
356 &self,
357 guest_opts: GuestOptions,
358 pkg_dir: P,
359 target_filter: &Option<TargetFilter>,
360 init_file_name: Option<&str>, ) -> Result<Elf, SdkError> {
362 self.app_config
363 .app_vm_config
364 .write_to_init_file(pkg_dir.as_ref(), init_file_name)?;
365 let pkg = get_package(pkg_dir.as_ref());
366 let target_dir = match build_guest_package(&pkg, &guest_opts, None, target_filter) {
367 Ok(target_dir) => target_dir,
368 Err(Some(code)) => {
369 return Err(SdkError::BuildFailedWithCode(code));
370 }
371 Err(None) => {
372 return Err(SdkError::BuildFailed);
373 }
374 };
375
376 let elf_path =
377 find_unique_executable(pkg_dir, target_dir, target_filter).map_err(SdkError::Other)?;
378 let data = read(&elf_path)?;
379 Elf::decode(&data, MEM_SIZE as u32).map_err(SdkError::Other)
380 }
381
382 pub fn transpiler(&self) -> Result<&Transpiler<F>, SdkError> {
384 self.transpiler
385 .as_ref()
386 .ok_or(SdkError::TranspilerNotAvailable)
387 }
388
389 pub fn convert_to_exe(
391 &self,
392 executable: impl Into<ExecutableFormat>,
393 ) -> Result<Arc<VmExe<F>>, SdkError> {
394 let executable = executable.into();
395 let exe = match executable {
396 ExecutableFormat::Elf(elf) => {
397 let transpiler = self.transpiler()?.clone();
398 Arc::new(VmExe::from_elf(elf, transpiler)?)
399 }
400 ExecutableFormat::VmExe(exe) => Arc::new(exe),
401 ExecutableFormat::SharedVmExe(exe) => exe,
402 };
403 Ok(exe)
404 }
405}
406
407impl<E, VB> GenericSdk<E, VB>
410where
411 E: StarkEngine<SC = SC>,
412 VB: VmBuilder<E> + Clone,
413 <VB::VmConfig as VmExecutionConfig<F>>::Executor:
414 Executor<F> + MeteredExecutor<F> + PreflightExecutor<F, VB::RecordArena>,
415{
416 pub fn execute(
418 &self,
419 app_exe: impl Into<ExecutableFormat>,
420 inputs: StdIn,
421 ) -> Result<Vec<u8>, SdkError> {
422 let exe = self.convert_to_exe(app_exe)?;
423 let instance = self
424 .executor
425 .instance(&exe)
426 .map_err(VirtualMachineError::from)?;
427 let final_memory = instance
428 .execute(inputs, None)
429 .map_err(VirtualMachineError::from)?
430 .memory;
431 let public_values = extract_public_values(
432 self.executor.config.as_ref().num_public_values,
433 &final_memory.memory,
434 );
435 Ok(public_values)
436 }
437
438 pub fn execute_metered(
441 &self,
442 app_exe: impl Into<ExecutableFormat>,
443 inputs: StdIn,
444 ) -> Result<(Vec<u8>, Vec<Segment>), SdkError> {
445 let app_prover = self.app_prover(app_exe)?;
446
447 let vm = app_prover.vm();
448 let exe = app_prover.exe();
449
450 let ctx = vm.build_metered_ctx(&exe);
451 let interpreter = vm
452 .metered_interpreter(&exe)
453 .map_err(VirtualMachineError::from)?;
454
455 let (segments, final_state) = interpreter
456 .execute_metered(inputs, ctx)
457 .map_err(VirtualMachineError::from)?;
458 let public_values = extract_public_values(
459 self.executor.config.as_ref().num_public_values,
460 &final_state.memory.memory,
461 );
462
463 Ok((public_values, segments))
464 }
465
466 pub fn execute_metered_cost(
469 &self,
470 app_exe: impl Into<ExecutableFormat>,
471 inputs: StdIn,
472 ) -> Result<(Vec<u8>, (u64, u64)), SdkError> {
473 let app_prover = self.app_prover(app_exe)?;
474
475 let vm = app_prover.vm();
476 let exe = app_prover.exe();
477
478 let ctx = vm.build_metered_cost_ctx();
479 let interpreter = vm
480 .metered_cost_interpreter(&exe)
481 .map_err(VirtualMachineError::from)?;
482
483 let (ctx, final_state) = interpreter
484 .execute_metered_cost(inputs, ctx)
485 .map_err(VirtualMachineError::from)?;
486 let instret = ctx.instret;
487 let cost = ctx.cost;
488
489 let public_values = extract_public_values(
490 self.executor.config.as_ref().num_public_values,
491 &final_state.memory.memory,
492 );
493
494 Ok((public_values, (cost, instret)))
495 }
496
497 pub fn prove(
512 &self,
513 app_exe: impl Into<ExecutableFormat>,
514 inputs: StdIn,
515 def_inputs: &[DeferralInput],
516 ) -> Result<(VmStarkProof, VerificationBaseline), SdkError> {
517 let mut prover = self.prover(app_exe)?;
518 let proof = prover.prove(inputs, def_inputs)?.0;
519 let baseline = prover.generate_baseline();
520 Ok((proof, baseline))
521 }
522
523 #[cfg(feature = "evm-prove")]
524 pub fn prove_evm(
526 &self,
527 app_exe: impl Into<ExecutableFormat>,
528 inputs: StdIn,
529 def_inputs: &[DeferralInput],
530 ) -> Result<types::EvmProof, SdkError> {
531 let app_exe = self.convert_to_exe(app_exe)?;
532 let mut evm_prover = self.evm_prover(app_exe)?;
533 let evm_proof = evm_prover.prove_evm(inputs, def_inputs)?;
534 Ok(evm_proof)
535 }
536
537 pub fn app_prover(
547 &self,
548 exe: impl Into<ExecutableFormat>,
549 ) -> Result<AppProver<E, VB>, SdkError> {
550 let exe = self.convert_to_exe(exe)?;
551 let app_pk = self.app_pk();
552 let prover = AppProver::<E, VB>::new(self.app_vm_builder.clone(), &app_pk.app_vm_pk, exe)?;
553 Ok(prover)
554 }
555
556 pub fn prover(
560 &self,
561 app_exe: impl Into<ExecutableFormat>,
562 ) -> Result<StarkProver<E, VB>, SdkError> {
563 let app_exe = self.convert_to_exe(app_exe)?;
564 let app_pk = self.app_pk();
565 let stark_prover = StarkProver::<E, _>::new(
566 self.app_vm_builder.clone(),
567 &app_pk.app_vm_pk,
568 app_exe,
569 self.agg_prover(),
570 self.deferral_setup.clone(),
571 )?;
572 Ok(stark_prover)
573 }
574
575 #[cfg(feature = "root-prover")]
576 pub fn evm_prover_without_halo2(
579 &self,
580 app_exe: impl Into<ExecutableFormat>,
581 ) -> Result<EvmProver<E, VB>, SdkError> {
582 let app_exe = self.convert_to_exe(app_exe)?;
583 let app_pk = self.app_pk();
584 let evm_prover = EvmProver::<E, _>::new(
585 self.app_vm_builder.clone(),
586 &app_pk.app_vm_pk,
587 app_exe,
588 self.agg_prover(),
589 self.deferral_setup.clone(),
590 self.root_prover(),
591 #[cfg(feature = "evm-prove")]
592 None,
593 )?;
594 Ok(evm_prover)
595 }
596
597 #[cfg(feature = "root-prover")]
598 pub fn evm_prover(
600 &self,
601 app_exe: impl Into<ExecutableFormat>,
602 ) -> Result<EvmProver<E, VB>, SdkError> {
603 #[allow(unused_mut)]
604 let mut evm_prover = self.evm_prover_without_halo2(app_exe)?;
605 #[cfg(feature = "evm-prove")]
606 {
607 evm_prover.halo2_prover = Some(self.halo2_prover());
608 }
609 Ok(evm_prover)
610 }
611
612 pub fn agg_prover(&self) -> Arc<AggProver> {
616 let app_pk = self.app_pk();
617 self.agg_prover
618 .get_or_init(|| {
619 Arc::new(AggProver::new(
620 Arc::new(app_pk.app_vm_pk.vm_pk.get_vk()),
621 self.agg_config.clone(),
622 self.agg_tree_config,
623 self.def_hook_cached_commit(),
624 ))
625 })
626 .clone()
627 }
628
629 #[cfg(feature = "root-prover")]
630 pub fn root_prover(&self) -> Arc<RootProver> {
632 self.root_prover
633 .get_or_init(|| {
634 let system_config = self.app_config.app_vm_config.as_ref();
635 let root_params = self.root_params.clone();
636 let agg_prover = self.agg_prover();
637
638 let (trace_heights, root_pk) = compute_root_proof_heights(
639 system_config.clone(),
640 self.agg_config.params.clone(),
641 self.agg_tree_config,
642 root_params.clone(),
643 self.deferral_setup.clone(),
644 )
645 .expect("Trace heights did not generate properly");
646
647 let memory_dimensions = system_config.memory_config.memory_dimensions();
648 let num_user_pvs = system_config.num_public_values;
649
650 Arc::new(RootProver::from_pk(
651 agg_prover.internal_recursive_prover.get_vk(),
652 agg_prover
653 .internal_recursive_prover
654 .get_self_vk_pcs_data()
655 .unwrap()
656 .commitment
657 .into(),
658 root_pk,
659 memory_dimensions,
660 num_user_pvs,
661 self.def_hook_commit(),
662 Some(trace_heights),
663 ))
664 })
665 .clone()
666 }
667
668 #[cfg(feature = "evm-prove")]
669 pub fn halo2_prover(&self) -> Halo2Prover {
671 self.halo2_prover
672 .get_or_init(|| {
673 use crate::keygen::static_verifier::keygen_halo2;
674
675 let root_prover = self.root_prover();
676 let root_vk = root_prover.0.get_vk().as_ref().clone();
677 let agg_prover = self.agg_prover();
678
679 let dummy_root_proof = keygen::dummy::generate_dummy_root_proof::<E, _>(
681 self.app_vm_builder.clone(),
682 &self.app_pk().app_vm_pk,
683 agg_prover.clone(),
684 self.deferral_setup.clone(),
685 root_prover,
686 );
687
688 let halo2_pk = keygen_halo2(
689 &self.halo2_config,
690 &self.halo2_params_reader,
691 self.halo2_shape,
692 &agg_prover.internal_recursive_prover.get_vk(),
693 &root_vk,
694 &dummy_root_proof,
695 );
696
697 Halo2Prover::new(self.halo2_params_reader(), halo2_pk)
698 })
699 .clone()
700 }
701
702 pub fn app_keygen(&self) -> (AppProvingKey<VB::VmConfig>, AppVerifyingKey) {
709 let pk = self.app_pk().clone();
710 let vk = pk.get_app_vk();
711 (pk, vk)
712 }
713
714 pub fn app_pk(&self) -> &AppProvingKey<VB::VmConfig> {
719 self.app_pk.get_or_init(|| {
721 AppProvingKey::keygen(self.app_config.clone()).expect("app_keygen failed")
722 })
723 }
724
725 pub fn app_vk(&self) -> AppVerifyingKey {
727 self.app_pk().get_app_vk()
728 }
729
730 pub fn agg_keygen(&self) -> (AggProvingKey, MultiStarkVerifyingKey<SC>) {
732 let pk = self.agg_pk();
733 let vk = self.agg_vk().as_ref().clone();
734 (pk, vk)
735 }
736
737 pub fn agg_prefix_pk(&self) -> AggPrefixProvingKey {
740 if let Some(agg_prover) = self.agg_prover.get() {
741 return AggPrefixProvingKey {
742 leaf: agg_prover.leaf_prover.get_pk(),
743 internal_for_leaf: agg_prover.internal_for_leaf_prover.get_pk(),
744 };
745 }
746
747 let app_pk = self.app_pk();
748 AggProver::keygen_prefix(
749 Arc::new(app_pk.app_vm_pk.vm_pk.get_vk()),
750 self.agg_config.clone(),
751 self.def_hook_cached_commit(),
752 )
753 }
754
755 pub fn agg_pk(&self) -> AggProvingKey {
757 let agg_prover = self.agg_prover();
758 AggProvingKey {
759 prefix: AggPrefixProvingKey {
760 leaf: agg_prover.leaf_prover.get_pk(),
761 internal_for_leaf: agg_prover.internal_for_leaf_prover.get_pk(),
762 },
763 internal_recursive: agg_prover.internal_recursive_prover.get_pk(),
764 }
765 }
766
767 pub fn agg_vk(&self) -> Arc<MultiStarkVerifyingKey<SC>> {
769 self.agg_prover().internal_recursive_prover.get_vk()
770 }
771
772 #[cfg(feature = "root-prover")]
773 pub fn root_pk(&self) -> RootProvingKey {
775 let root_prover = self.root_prover();
776 RootProvingKey {
777 root_pk: root_prover.0.get_pk(),
778 trace_heights: root_prover.0.get_trace_heights().unwrap_or_default(),
779 }
780 }
781
782 #[cfg(feature = "evm-prove")]
791 pub fn halo2_pk(&self) -> Halo2ProvingKey {
792 self.halo2_prover().pk()
793 }
794
795 pub fn app_commit(
799 &self,
800 app_exe: impl Into<ExecutableFormat>,
801 ) -> Result<AppExecutionCommit, SdkError> {
802 let prover = self.prover(app_exe)?;
803 Ok(AppExecutionCommit {
804 app_exe_commit: CommitBytes::from(prover.generate_baseline().app_exe_commit),
805 app_vm_commit: CommitBytes::from(prover.app_vm_commit()),
806 })
807 }
808
809 pub fn verify_proof(
816 agg_vk: MultiStarkVerifyingKey<SC>,
817 baseline: VerificationBaseline,
818 proof: &VmStarkProof,
819 ) -> Result<(), SdkError> {
820 let vk = VmStarkVerifyingKey {
821 mvk: agg_vk,
822 baseline,
823 };
824 verify_vm_stark_proof_decoded(&vk, proof)?;
825 Ok(())
826 }
827
828 #[cfg(feature = "evm-verify")]
829 pub fn generate_halo2_verifier_solidity(&self) -> Result<types::EvmHalo2Verifier, SdkError> {
831 solidity::generate_halo2_verifier_solidity(&self.halo2_pk(), &self.halo2_params_reader)
832 }
833
834 #[cfg(feature = "evm-verify")]
835 pub fn generate_halo2_verifier_solidity_with_version_name(
840 &self,
841 version_name: &str,
842 ) -> Result<types::EvmHalo2Verifier, SdkError> {
843 solidity::generate_halo2_verifier_solidity_with_version_name(
844 &self.halo2_pk(),
845 &self.halo2_params_reader,
846 version_name,
847 )
848 }
849
850 #[cfg(feature = "evm-verify")]
851 pub fn verify_evm_halo2_proof(
857 openvm_verifier: &types::EvmHalo2Verifier,
858 evm_proof: types::EvmProof,
859 expected_app_commit: Option<AppExecutionCommit>,
860 ) -> Result<u64, SdkError> {
861 if let Some(expected_app_commit) = expected_app_commit {
862 if expected_app_commit != evm_proof.app_commit {
863 return Err(
864 eyre::eyre!("EVM proof verification failed: mismatching app commits").into(),
865 );
866 }
867 }
868 solidity::verify_evm_halo2_proof(openvm_verifier, evm_proof)
869 }
870}