openvm_sdk/
commit.rs

1use std::sync::Arc;
2
3use openvm_circuit::{
4    arch::{instructions::exe::VmExe, VmConfig},
5    system::program::trace::VmCommittedExe,
6};
7use openvm_continuations::verifier::leaf::LeafVmVerifierConfig;
8use openvm_native_compiler::{conversion::CompilerOptions, ir::DIGEST_SIZE};
9use openvm_stark_backend::{config::StarkGenericConfig, p3_field::PrimeField32};
10use openvm_stark_sdk::{
11    config::{baby_bear_poseidon2::BabyBearPoseidon2Engine, FriParameters},
12    engine::StarkFriEngine,
13    openvm_stark_backend::p3_field::FieldAlgebra,
14    p3_baby_bear::BabyBear,
15    p3_bn254_fr::Bn254Fr,
16};
17
18use crate::{keygen::AppProvingKey, NonRootCommittedExe, F, SC};
19
20/// `AppExecutionCommit` has all the commitments users should check against the final proof.
21pub struct AppExecutionCommit<T> {
22    /// Commitment of the leaf VM verifier program which commits the VmConfig of App VM.
23    /// Internal verifier will verify `leaf_vm_verifier_commit`.
24    pub leaf_vm_verifier_commit: [T; DIGEST_SIZE],
25    /// Commitment of the executable. It's computed as
26    /// compress(
27    ///     compress(
28    ///         hash(app_program_commit),
29    ///         hash(init_memory_commit)
30    ///     ),
31    ///     hash(right_pad(pc_start, 0))
32    /// )
33    /// `right_pad` example, if pc_start = 123, right_pad(pc_start, 0) = \[123,0,0,0,0,0,0,0\]
34    pub exe_commit: [T; DIGEST_SIZE],
35}
36
37impl AppExecutionCommit<F> {
38    /// Users should use this function to compute `AppExecutionCommit` and check it against the final
39    /// proof.
40    pub fn compute<VC: VmConfig<F>>(
41        app_vm_config: &VC,
42        app_exe: &NonRootCommittedExe,
43        leaf_vm_verifier_exe: &NonRootCommittedExe,
44    ) -> Self {
45        assert!(
46            app_exe.exe.program.max_num_public_values <= app_vm_config.system().num_public_values
47        );
48        let exe_commit = app_exe
49            .compute_exe_commit(&app_vm_config.system().memory_config)
50            .into();
51        let leaf_vm_verifier_commit: [F; DIGEST_SIZE] =
52            leaf_vm_verifier_exe.committed_program.commitment.into();
53
54        Self {
55            leaf_vm_verifier_commit,
56            exe_commit,
57        }
58    }
59
60    pub fn app_config_commit_to_bn254(&self) -> Bn254Fr {
61        babybear_digest_to_bn254(&self.leaf_vm_verifier_commit)
62    }
63
64    pub fn exe_commit_to_bn254(&self) -> Bn254Fr {
65        babybear_digest_to_bn254(&self.exe_commit)
66    }
67}
68
69pub(crate) fn babybear_digest_to_bn254(digest: &[F; DIGEST_SIZE]) -> Bn254Fr {
70    let mut ret = Bn254Fr::ZERO;
71    let order = Bn254Fr::from_canonical_u32(BabyBear::ORDER_U32);
72    let mut base = Bn254Fr::ONE;
73    digest.iter().for_each(|&x| {
74        ret += base * Bn254Fr::from_canonical_u32(x.as_canonical_u32());
75        base *= order;
76    });
77    ret
78}
79
80pub fn generate_leaf_committed_exe<VC: VmConfig<F>>(
81    leaf_fri_params: FriParameters,
82    compiler_options: CompilerOptions,
83    app_pk: &AppProvingKey<VC>,
84) -> Arc<NonRootCommittedExe> {
85    let app_vm_vk = app_pk.app_vm_pk.vm_pk.get_vk();
86    let leaf_engine = BabyBearPoseidon2Engine::new(leaf_fri_params);
87    let leaf_program = LeafVmVerifierConfig {
88        app_fri_params: app_pk.app_vm_pk.fri_params,
89        app_system_config: app_pk.app_vm_pk.vm_config.system().clone(),
90        compiler_options,
91    }
92    .build_program(&app_vm_vk);
93    Arc::new(VmCommittedExe::commit(
94        leaf_program.into(),
95        leaf_engine.config.pcs(),
96    ))
97}
98
99pub fn commit_app_exe(
100    app_fri_params: FriParameters,
101    app_exe: impl Into<VmExe<F>>,
102) -> Arc<NonRootCommittedExe> {
103    let exe: VmExe<_> = app_exe.into();
104    let app_engine = BabyBearPoseidon2Engine::new(app_fri_params);
105    Arc::new(VmCommittedExe::<SC>::commit(exe, app_engine.config.pcs()))
106}
107
108pub fn committed_exe_as_bn254(committed_exe: &NonRootCommittedExe) -> Bn254Fr {
109    babybear_digest_to_bn254(&committed_exe.get_program_commit().into())
110}