Skip to content

Commit 814a762

Browse files
committed
Helper function for verify_openvm_stark
1 parent c942537 commit 814a762

File tree

5 files changed

+76
-78
lines changed

5 files changed

+76
-78
lines changed

crates/cli/src/commands/prove.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ impl ProveCmd {
103103
sdk.set_agg_tree_config(*agg_tree_config);
104104
let (app_pk, committed_exe, input) =
105105
Self::prepare_execution(&sdk, app_pk, exe, input)?;
106+
let commits = AppExecutionCommit::compute(
107+
&app_pk.app_vm_pk.vm_config,
108+
&committed_exe,
109+
&app_pk.leaf_committed_exe,
110+
);
111+
println!("exe commit: {:?}", commits.exe_commit);
112+
println!("vm commit: {:?}", commits.vm_commit);
106113
let agg_pk = read_agg_pk_from_file(DEFAULT_AGG_PK_PATH).map_err(|e| {
107114
eyre::eyre!("Failed to read aggregation proving key: {}\nPlease run 'cargo openvm setup' first", e)
108115
})?;
@@ -129,6 +136,14 @@ impl ProveCmd {
129136
let params_reader = CacheHalo2ParamsReader::new(DEFAULT_PARAMS_DIR);
130137
let (app_pk, committed_exe, input) =
131138
Self::prepare_execution(&sdk, app_pk, exe, input)?;
139+
let commits = AppExecutionCommit::compute(
140+
&app_pk.app_vm_pk.vm_config,
141+
&committed_exe,
142+
&app_pk.leaf_committed_exe,
143+
);
144+
println!("exe commit: {:?}", commits.exe_commit_to_bn254());
145+
println!("vm commit: {:?}", commits.vm_commit_to_bn254());
146+
132147
println!("Generating EVM proof, this may take a lot of compute and memory...");
133148
let agg_pk = read_agg_pk_from_file(DEFAULT_AGG_PK_PATH).map_err(|e| {
134149
eyre::eyre!("Failed to read aggregation proving key: {}\nPlease run 'cargo openvm setup' first", e)
@@ -155,14 +170,6 @@ impl ProveCmd {
155170
let app_exe = read_exe_from_file(exe)?;
156171
let committed_exe = sdk.commit_app_exe(app_pk.app_fri_params(), app_exe)?;
157172

158-
let commits = AppExecutionCommit::compute(
159-
&app_pk.app_vm_pk.vm_config,
160-
&committed_exe,
161-
&app_pk.leaf_committed_exe,
162-
);
163-
println!("app_pk commit: {:?}", commits.app_config_commit_to_bn254());
164-
println!("exe commit: {:?}", commits.exe_commit_to_bn254());
165-
166173
let input = read_to_stdin(input)?;
167174
Ok((app_pk, committed_exe, input))
168175
}

crates/sdk/src/commit.rs

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use openvm_circuit::{
44
arch::{instructions::exe::VmExe, VmConfig},
55
system::program::trace::VmCommittedExe,
66
};
7-
use openvm_continuations::verifier::leaf::LeafVmVerifierConfig;
8-
use openvm_native_compiler::{conversion::CompilerOptions, ir::DIGEST_SIZE};
7+
use openvm_native_compiler::ir::DIGEST_SIZE;
98
use openvm_stark_backend::{config::StarkGenericConfig, p3_field::PrimeField32};
109
use openvm_stark_sdk::{
1110
config::{baby_bear_poseidon2::BabyBearPoseidon2Engine, FriParameters},
@@ -14,14 +13,16 @@ use openvm_stark_sdk::{
1413
p3_baby_bear::BabyBear,
1514
p3_bn254_fr::Bn254Fr,
1615
};
16+
use serde::{Deserialize, Serialize};
1717

18-
use crate::{keygen::AppProvingKey, NonRootCommittedExe, F, SC};
18+
use crate::{NonRootCommittedExe, F, SC};
1919

2020
/// `AppExecutionCommit` has all the commitments users should check against the final proof.
21-
pub struct AppExecutionCommit<T> {
21+
#[derive(Clone, Debug, Serialize, Deserialize)]
22+
pub struct AppExecutionCommit {
2223
/// Commitment of the leaf VM verifier program which commits the VmConfig of App VM.
2324
/// Internal verifier will verify `leaf_vm_verifier_commit`.
24-
pub leaf_vm_verifier_commit: [T; DIGEST_SIZE],
25+
pub vm_commit: [u32; DIGEST_SIZE],
2526
/// Commitment of the executable. It's computed as
2627
/// compress(
2728
/// compress(
@@ -31,37 +32,39 @@ pub struct AppExecutionCommit<T> {
3132
/// hash(right_pad(pc_start, 0))
3233
/// )
3334
/// `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+
pub exe_commit: [u32; DIGEST_SIZE],
3536
}
3637

37-
impl AppExecutionCommit<F> {
38+
impl AppExecutionCommit {
3839
/// Users should use this function to compute `AppExecutionCommit` and check it against the
3940
/// final proof.
4041
pub fn compute<VC: VmConfig<F>>(
4142
app_vm_config: &VC,
4243
app_exe: &NonRootCommittedExe,
4344
leaf_vm_verifier_exe: &NonRootCommittedExe,
4445
) -> Self {
45-
let exe_commit = app_exe
46+
let exe_commit: [F; DIGEST_SIZE] = app_exe
4647
.compute_exe_commit(&app_vm_config.system().memory_config)
4748
.into();
48-
let leaf_vm_verifier_commit: [F; DIGEST_SIZE] =
49-
leaf_vm_verifier_exe.committed_program.commitment.into();
49+
let vm_commit: [F; DIGEST_SIZE] = leaf_vm_verifier_exe.committed_program.commitment.into();
5050

5151
Self {
52-
leaf_vm_verifier_commit,
53-
exe_commit,
52+
vm_commit: vm_commit.map(|x| x.as_canonical_u32()),
53+
exe_commit: exe_commit.map(|x| x.as_canonical_u32()),
5454
}
5555
}
5656

57-
pub fn app_config_commit_to_bn254(&self) -> Bn254Fr {
58-
babybear_digest_to_bn254(&self.leaf_vm_verifier_commit)
57+
pub fn vm_commit_to_bn254(&self) -> Bn254Fr {
58+
babybear_u32_digest_to_bn254(&self.vm_commit)
5959
}
6060

6161
pub fn exe_commit_to_bn254(&self) -> Bn254Fr {
62-
babybear_digest_to_bn254(&self.exe_commit)
62+
babybear_u32_digest_to_bn254(&self.exe_commit)
6363
}
6464
}
65+
fn babybear_u32_digest_to_bn254(digest: &[u32; DIGEST_SIZE]) -> Bn254Fr {
66+
babybear_digest_to_bn254(&digest.map(F::from_canonical_u32))
67+
}
6568

6669
pub(crate) fn babybear_digest_to_bn254(digest: &[F; DIGEST_SIZE]) -> Bn254Fr {
6770
let mut ret = Bn254Fr::ZERO;
@@ -74,25 +77,6 @@ pub(crate) fn babybear_digest_to_bn254(digest: &[F; DIGEST_SIZE]) -> Bn254Fr {
7477
ret
7578
}
7679

77-
pub fn generate_leaf_committed_exe<VC: VmConfig<F>>(
78-
leaf_fri_params: FriParameters,
79-
compiler_options: CompilerOptions,
80-
app_pk: &AppProvingKey<VC>,
81-
) -> Arc<NonRootCommittedExe> {
82-
let app_vm_vk = app_pk.app_vm_pk.vm_pk.get_vk();
83-
let leaf_engine = BabyBearPoseidon2Engine::new(leaf_fri_params);
84-
let leaf_program = LeafVmVerifierConfig {
85-
app_fri_params: app_pk.app_vm_pk.fri_params,
86-
app_system_config: app_pk.app_vm_pk.vm_config.system().clone(),
87-
compiler_options,
88-
}
89-
.build_program(&app_vm_vk);
90-
Arc::new(VmCommittedExe::commit(
91-
leaf_program.into(),
92-
leaf_engine.config.pcs(),
93-
))
94-
}
95-
9680
pub fn commit_app_exe(
9781
app_fri_params: FriParameters,
9882
app_exe: impl Into<VmExe<F>>,

crates/sdk/tests/integration_test.rs

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{borrow::Borrow, path::PathBuf, sync::Arc};
22

33
use eyre::Result;
4+
use openvm::host::{compute_hint_key_for_verify_openvm_stark, encode_rv32_public_values};
45
use openvm_build::GuestOptions;
56
use openvm_circuit::{
67
arch::{
@@ -44,9 +45,7 @@ use openvm_sdk::{
4445
types::{EvmHalo2Verifier, EvmProof},
4546
DefaultStaticVerifierPvHandler, Sdk, StdIn,
4647
};
47-
use openvm_stark_backend::{
48-
keygen::types::LinearConstraint, p3_field::PrimeField32, p3_matrix::Matrix,
49-
};
48+
use openvm_stark_backend::{keygen::types::LinearConstraint, p3_matrix::Matrix};
5049
use openvm_stark_sdk::{
5150
config::{
5251
baby_bear_poseidon2::{BabyBearPoseidon2Config, BabyBearPoseidon2Engine},
@@ -356,7 +355,7 @@ fn test_static_verifier_custom_pv_handler() {
356355
&app_pk.leaf_committed_exe,
357356
);
358357
let exe_commit = commits.exe_commit_to_bn254();
359-
let leaf_verifier_commit = commits.app_config_commit_to_bn254();
358+
let leaf_verifier_commit = commits.vm_commit_to_bn254();
360359

361360
let pv_handler = CustomPvHandler {
362361
exe_commit,
@@ -643,42 +642,23 @@ fn test_verify_openvm_stark_e2e() -> Result<()> {
643642
sdk.transpile(elf, vm_config.transpiler())?
644643
};
645644

645+
// app_exe publishes 7th and 8th fibonacci numbers.
646646
let pvs = [13u32, 21, 0, 0, 0, 0, 0, 0];
647+
let pvs_u32 = encode_rv32_public_values(&pvs);
647648

648-
let exe_commit_u32: Vec<_> = commits
649-
.exe_commit
650-
.iter()
651-
.map(|x| x.as_canonical_u32())
652-
.collect();
653-
let vm_commit_u32: Vec<_> = commits
654-
.leaf_vm_verifier_commit
655-
.iter()
656-
.map(|x| x.as_canonical_u32())
657-
.collect();
658-
let pvs_u32: Vec<_> = pvs
659-
.iter()
660-
.flat_map(|x| x.to_le_bytes())
661-
.map(|x| x as u32)
662-
.collect();
663-
664-
let key = ASM_FILENAME
665-
.as_bytes()
666-
.iter()
667-
.cloned()
668-
.chain(exe_commit_u32.iter().flat_map(|x| x.to_le_bytes()))
669-
.chain(vm_commit_u32.iter().flat_map(|x| x.to_le_bytes()))
670-
.chain(pvs_u32.iter().flat_map(|x| x.to_le_bytes()))
671-
.collect();
672649
let mut stdin = StdIn::default();
650+
let key = compute_hint_key_for_verify_openvm_stark(
651+
ASM_FILENAME,
652+
&commits.exe_commit,
653+
&commits.vm_commit,
654+
&pvs_u32,
655+
);
673656
let to_encode: Vec<Vec<F>> = e2e_stark_proof.proof.write();
674657
let value = hint_load_by_key_encode(&to_encode);
675658
stdin.add_key_value(key, value);
676659

677-
let exe_commit_u32_8: [u32; 8] = exe_commit_u32.try_into().unwrap();
678-
let vm_commit_u32_8: [u32; 8] = vm_commit_u32.try_into().unwrap();
679-
680-
stdin.write(&exe_commit_u32_8);
681-
stdin.write(&vm_commit_u32_8);
660+
stdin.write(&commits.exe_commit);
661+
stdin.write(&commits.vm_commit);
682662
stdin.write(&pvs_u32);
683663

684664
sdk.execute(verify_exe, vm_config, stdin)?;

crates/toolchain/openvm/src/host.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,33 @@ pub fn read_u32() -> u32 {
9898
u32::from_le_bytes(bytes.try_into().unwrap())
9999
}
100100

101+
/// Compute the hint key for `verify_openvm_stark` function, which reads a stark proof from stream
102+
/// `kv_store`.
103+
pub fn compute_hint_key_for_verify_openvm_stark(
104+
asm_filename: &str,
105+
exe_commit_u32: &[u32; 8],
106+
vm_commit_u32: &[u32; 8],
107+
pvs_u32: &[u32],
108+
) -> Vec<u8> {
109+
asm_filename
110+
.as_bytes()
111+
.iter()
112+
.cloned()
113+
.chain(exe_commit_u32.iter().flat_map(|x| x.to_le_bytes()))
114+
.chain(vm_commit_u32.iter().flat_map(|x| x.to_le_bytes()))
115+
.chain(pvs_u32.iter().flat_map(|x| x.to_le_bytes()))
116+
.collect()
117+
}
118+
119+
/// Encode the public values in guest program(revealed by `reveal_u32`) into the format in proofs.
120+
pub fn encode_rv32_public_values(logic_pvs: &[u32]) -> Vec<u32> {
121+
logic_pvs
122+
.iter()
123+
.flat_map(|x| x.to_le_bytes())
124+
.map(|x| x as u32)
125+
.collect()
126+
}
127+
101128
#[cfg(all(feature = "std", test, not(target_os = "zkvm")))]
102129
mod tests {
103130
use alloc::vec;

crates/toolchain/openvm/src/verify_stark.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
/// program calls `reveal_u32` to publish an u32(e.g. `258`) in the proof, that u32 is decomposed
1111
/// into 4 field elements in byte. In `user_pvs`, it should be an u32 array, `[2, 1, 0, 0]`.
1212
/// 2. Provide the corresponding stark proof in the key-value store in OpenVM streams. The key
13-
/// should
14-
/// be the concatenation of the filename, `app_exe_commit`, `app_vm_commit`, and `user_pvs` in
15-
/// little-endian bytes.
13+
/// should be the concatenation of the filename, `app_exe_commit`, `app_vm_commit`, and `user_pvs`
14+
/// in little-endian bytes. Users can use `openvm::host::compute_hint_key_for_verify_openvm_stark`
15+
/// to compute the hint key.
1616
#[macro_export]
1717
macro_rules! define_verify_openvm_stark {
1818
($fn_name: ident, $asm_folder: expr, $asm_filename: literal) => {

0 commit comments

Comments
 (0)