openvm_verify_stark_guest/
lib.rs1#![cfg_attr(target_os = "zkvm", no_std)]
2
3extern crate alloc;
4
5use alloc::{vec, vec::Vec};
6
7use openvm_deferral_guest::{deferred_compute, get_deferred_output, Commit, COMMIT_NUM_BYTES};
8
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct ProofOutput {
11 pub app_exe_commit: Commit,
12 pub app_vm_commit: Commit,
13 pub user_public_values: Vec<u8>,
14}
15
16pub fn verify_stark_unchecked<const DEF_IDX: u16>(input_commit: &Commit) -> ProofOutput {
17 let output_key = deferred_compute::<DEF_IDX>(input_commit);
18 let output_len = output_key.output_len as usize;
19 let mut output_bytes = vec![0u8; output_len];
20 get_deferred_output::<DEF_IDX>(&mut output_bytes, &output_key);
21
22 const MIN_OUTPUT_BYTES: usize = 2 * COMMIT_NUM_BYTES;
23 if output_len < MIN_OUTPUT_BYTES {
24 panic!("output_len too small for a ProofOutput");
25 }
26
27 let app_exe_commit = output_bytes[..COMMIT_NUM_BYTES].try_into().unwrap();
28 let app_vm_commit = output_bytes[COMMIT_NUM_BYTES..MIN_OUTPUT_BYTES]
29 .try_into()
30 .unwrap();
31 let user_public_values = collapse_user_public_values(&output_bytes[MIN_OUTPUT_BYTES..]);
32
33 ProofOutput {
34 app_exe_commit,
35 app_vm_commit,
36 user_public_values,
37 }
38}
39
40pub fn verify_stark<const DEF_IDX: u16>(input_commit: &Commit, expected: &ProofOutput) {
41 let actual = verify_stark_unchecked::<DEF_IDX>(input_commit);
42 if actual != *expected {
43 panic!("Proof verification failed for commit {:?}", input_commit);
44 }
45}
46
47fn collapse_user_public_values(expanded: &[u8]) -> Vec<u8> {
48 const F_NUM_BYTES: usize = 4;
49
50 if !expanded.len().is_multiple_of(F_NUM_BYTES) {
51 panic!("User public values output length is not a multiple of {F_NUM_BYTES}");
52 }
53
54 let mut user_public_values = Vec::with_capacity(expanded.len() / F_NUM_BYTES);
55 for bytes in expanded.chunks_exact(F_NUM_BYTES) {
56 if bytes[1..].iter().any(|&byte| byte != 0) {
57 panic!("User public value has non-zero high bytes");
58 }
59 user_public_values.push(bytes[0]);
60 }
61 user_public_values
62}