Skip to content

Commit 818a05e

Browse files
committed
Helper function for verify_openvm_stark
1 parent 7b2dd5c commit 818a05e

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,10 +32,10 @@ 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>>(
@@ -45,26 +46,28 @@ impl AppExecutionCommit<F> {
4546
assert!(
4647
app_exe.exe.program.max_num_public_values <= app_vm_config.system().num_public_values
4748
);
48-
let exe_commit = app_exe
49+
let exe_commit: [F; DIGEST_SIZE] = app_exe
4950
.compute_exe_commit(&app_vm_config.system().memory_config)
5051
.into();
51-
let leaf_vm_verifier_commit: [F; DIGEST_SIZE] =
52-
leaf_vm_verifier_exe.committed_program.commitment.into();
52+
let vm_commit: [F; DIGEST_SIZE] = leaf_vm_verifier_exe.committed_program.commitment.into();
5353

5454
Self {
55-
leaf_vm_verifier_commit,
56-
exe_commit,
55+
vm_commit: vm_commit.map(|x| x.as_canonical_u32()),
56+
exe_commit: exe_commit.map(|x| x.as_canonical_u32()),
5757
}
5858
}
5959

60-
pub fn app_config_commit_to_bn254(&self) -> Bn254Fr {
61-
babybear_digest_to_bn254(&self.leaf_vm_verifier_commit)
60+
pub fn vm_commit_to_bn254(&self) -> Bn254Fr {
61+
babybear_u32_digest_to_bn254(&self.vm_commit)
6262
}
6363

6464
pub fn exe_commit_to_bn254(&self) -> Bn254Fr {
65-
babybear_digest_to_bn254(&self.exe_commit)
65+
babybear_u32_digest_to_bn254(&self.exe_commit)
6666
}
6767
}
68+
fn babybear_u32_digest_to_bn254(digest: &[u32; DIGEST_SIZE]) -> Bn254Fr {
69+
babybear_digest_to_bn254(&digest.map(F::from_canonical_u32))
70+
}
6871

6972
pub(crate) fn babybear_digest_to_bn254(digest: &[F; DIGEST_SIZE]) -> Bn254Fr {
7073
let mut ret = Bn254Fr::ZERO;
@@ -77,25 +80,6 @@ pub(crate) fn babybear_digest_to_bn254(digest: &[F; DIGEST_SIZE]) -> Bn254Fr {
7780
ret
7881
}
7982

80-
pub 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-
9983
pub fn commit_app_exe(
10084
app_fri_params: FriParameters,
10185
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},
@@ -362,7 +361,7 @@ fn test_static_verifier_custom_pv_handler() {
362361
&app_pk.leaf_committed_exe,
363362
);
364363
let exe_commit = commits.exe_commit_to_bn254();
365-
let leaf_verifier_commit = commits.app_config_commit_to_bn254();
364+
let leaf_verifier_commit = commits.vm_commit_to_bn254();
366365

367366
let pv_handler = CustomPvHandler {
368367
exe_commit,
@@ -649,42 +648,23 @@ fn test_verify_openvm_stark_e2e() -> Result<()> {
649648
sdk.transpile(elf, vm_config.transpiler())?
650649
};
651650

651+
// app_exe publishes 7th and 8th fibonacci numbers.
652652
let pvs = [13u32, 21, 0, 0, 0, 0, 0, 0];
653+
let pvs_u32 = encode_rv32_public_values(&pvs);
653654

654-
let exe_commit_u32: Vec<_> = commits
655-
.exe_commit
656-
.iter()
657-
.map(|x| x.as_canonical_u32())
658-
.collect();
659-
let vm_commit_u32: Vec<_> = commits
660-
.leaf_vm_verifier_commit
661-
.iter()
662-
.map(|x| x.as_canonical_u32())
663-
.collect();
664-
let pvs_u32: Vec<_> = pvs
665-
.iter()
666-
.flat_map(|x| x.to_le_bytes())
667-
.map(|x| x as u32)
668-
.collect();
669-
670-
let key = ASM_FILENAME
671-
.as_bytes()
672-
.iter()
673-
.cloned()
674-
.chain(exe_commit_u32.iter().flat_map(|x| x.to_le_bytes()))
675-
.chain(vm_commit_u32.iter().flat_map(|x| x.to_le_bytes()))
676-
.chain(pvs_u32.iter().flat_map(|x| x.to_le_bytes()))
677-
.collect();
678655
let mut stdin = StdIn::default();
656+
let key = compute_hint_key_for_verify_openvm_stark(
657+
ASM_FILENAME,
658+
&commits.exe_commit,
659+
&commits.vm_commit,
660+
&pvs_u32,
661+
);
679662
let to_encode: Vec<Vec<F>> = e2e_stark_proof.proof.write();
680663
let value = hint_load_by_key_encode(&to_encode);
681664
stdin.add_key_value(key, value);
682665

683-
let exe_commit_u32_8: [u32; 8] = exe_commit_u32.try_into().unwrap();
684-
let vm_commit_u32_8: [u32; 8] = vm_commit_u32.try_into().unwrap();
685-
686-
stdin.write(&exe_commit_u32_8);
687-
stdin.write(&vm_commit_u32_8);
666+
stdin.write(&commits.exe_commit);
667+
stdin.write(&commits.vm_commit);
688668
stdin.write(&pvs_u32);
689669

690670
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)