openvm_verify_stark/
lib.rs

1#[cfg(not(target_os = "zkvm"))]
2pub mod host;
3
4/// Define a function that verifies an OpenVM Stark proof.
5/// To define this function, users need to specify the function name and an ASM file containing the
6/// assembly code for the verification(this ASM file can be generated by
7/// `Sdk.generate_root_verifier_asm` function). To specify the ASM file, users need to provide the
8/// parent folder and filename of the ASM file.
9/// To call this function:
10/// 1. users need to provide `app_exe_commit`/`app_vm_commit`/`user_pvs`(user public values) as the
11///    arguments. CAREFUL: `app_exe_commit`/`app_vm_commit` are in u32 and are interpreted as native
12///    fields. `user_pvs` are the exact public values of that proof. Here we assume all the public
13///    values are `u8`s.
14/// 2. Provide the corresponding stark proof in the key-value store in OpenVM streams. The key
15///    should be the concatenation of the filename, `app_exe_commit`, `app_vm_commit`, and
16///    `user_pvs` in little-endian bytes. Users can use
17///    `openvm::host::compute_hint_key_for_verify_openvm_stark` to compute the hint key.
18#[macro_export]
19macro_rules! define_verify_openvm_stark {
20    ($fn_name: ident, $asm_folder: expr, $asm_filename: literal) => {
21        pub fn $fn_name(app_exe_commit: &[u32; 8], app_vm_commit: &[u32; 8], user_pvs: &[u8]) {
22            // The memory location for the start of the heap.
23            const HEAP_START_ADDRESS: u32 = 1 << 24;
24            const FIELDS_PER_U32: u32 = 4;
25            const FILENAME: &str = $asm_filename;
26            // Construct the hint key
27            let hint_key: alloc::vec::Vec<u8> = FILENAME
28                .as_bytes()
29                .iter()
30                .cloned()
31                .chain(app_exe_commit.iter().flat_map(|x| x.to_le_bytes()))
32                .chain(app_vm_commit.iter().flat_map(|x| x.to_le_bytes()))
33                .chain(user_pvs.iter().cloned())
34                .collect();
35            openvm::io::hint_load_by_key(&hint_key);
36            // Store the expected public values into the beginning of the native heap.
37            let mut native_addr = HEAP_START_ADDRESS;
38            for &x in app_exe_commit {
39                openvm::io::store_u32_to_native(native_addr, x);
40                native_addr += FIELDS_PER_U32;
41            }
42            for &x in app_vm_commit {
43                openvm::io::store_u32_to_native(native_addr, x);
44                native_addr += FIELDS_PER_U32;
45            }
46            for &x in user_pvs {
47                openvm::io::store_u32_to_native(native_addr, x as u32);
48                native_addr += FIELDS_PER_U32;
49            }
50            // Assumption: the asm file should be generated by SDK. The code block should:
51            // 1. Increase the heap pointer in order to avoid overwriting expected public values.
52            // 2. Hint a stark proof from the input stream
53            // 3. Verify the proof
54            // 4. Compare the public values with the expected ones. Panic if not equal.
55            unsafe { core::arch::asm!(include_str!(concat!($asm_folder, "/", $asm_filename)),) }
56        }
57    };
58}