A no-std verifier for RISC-Zero STARK proofs.
This crate provides the necessary tools to deserialize and verify RISC-Zero proofs in a no-std context. It allows you to work with:
Proof: The RISC-Zero receipt.Vk: The verification key, also known as the RISC-Zero image ID.Journal: The public inputs, also known as the RISC-Zero journal.
After deserializing these components, you can verify a proof against its corresponding verification key and public inputs, ensuring it was generated by a specific RISC-Zero VM version.
To verify a proof, you need to select the VerifierContext that matches the RISC-Zero VM version used for proof generation. The following example assumes the proof was generated with VM version 1.2.
use risc0_verifier::*;
use std::path::PathBuf;
use serde::Deserialize;
use std::fs::File;
#[derive(Deserialize)]
pub struct Case {
pub receipt_path: PathBuf,
pub journal: Journal,
pub vk: Vk,
}
// Load the proof, journal, and verification key.
let Case { receipt_path, journal, vk } =
serde_json::from_reader(
std::fs::File::open("./resources/cases/prover_1.2.0/vm_1.2.0/poseidon2_22.json").unwrap()
).unwrap();
// Deserialize the RISC-Zero receipt, which was serialized using `ciborium`.
let proof: Proof = ciborium::from_reader(File::open(receipt_path).unwrap()).unwrap();
// Verify the proof using the context for VM v1.2.
assert!(verify(&v1_2(), vk.clone(), proof.clone(), journal.clone()).is_ok());
// Alternatively, use dynamic dispatching for the verifier.
let verifier_1_2 = v1_2().boxed();
let verifier_1_1 = v1_1().boxed();
assert!(verifier_1_2.verify(vk.clone().into(), proof.clone(), journal.clone()).is_ok());
// This will fail as the proof was not generated with VM v1.1.
assert!(!verifier_1_1.verify(vk.into(), proof, journal).is_ok());For proofs generated with 2.x.y versions of the VM, use the v2() context.
risc0-verifier can handle any serde-serialized RISC-Zero Receipt that does not contain a Groth16 proof. If you have a RISC-Zero Receipt, simply serialize it using your preferred format (e.g., ciborium, json) and then deserialize it into a risc0_verifier::Proof to use with the verify function.
The same applies to the Journal. For the Vk, you can construct it directly from the RISC-Zero image key bytes:
use risc0_verifier::Vk;
// Create a Vk from its hex representation.
let vk: Vk = hex_literal::hex!("9db9988d9fbcacadf2bd29fc7c60b98bc4234342fe536eb983169eb6cc248009").into();
// For comparison, here is the equivalent risc0_zkp_v1::core::digest::Digest.
let r0: risc0_zkp_v1::core::digest::Digest = [
2375596445,
2913778847,
4230594034,
2344181884,
1111696324,
3111015422,
3063813763,
159392972
].into();
assert_eq!(vk.as_words(), r0.as_words());
assert_eq!(vk.as_bytes(), r0.as_bytes());This project uses cargo-make for task automation. To get started, install it with cargo install cargo-make.
-
Run all CI checks:
cargo make ci
-
Generate test coverage:
cargo make coverage
This will create a
lcov.infofile with the coverage data.
The generate_proofs directory contains a simple RISC-Zero method and a program to generate multiple proofs with different configurations. For more details, see generate_proofs/notes.md.
Versions of this crate prior to 0.2.0 used bincode for serialization, which is not no-std compatible. The format has since been updated to use CBOR for proofs to ensure no-std support.
A command-line tool is provided to convert proofs from the old format to the new one. Build it with:
cargo build --bin convert_old --release --features convertThe resulting binary at ./target/release/convert_old can convert both Proof and Journal data. By default, it reads from stdin and writes to stdout.
./target/release/convert_old --help
Usage: convert_old [-x] [-X] [-j] [-i <input>] [-o <output>]
Perform conversion.
Options:
-x, --hex-input hex input format
-X, --hex-output hex output format
-j, --journal convert journal
-i, --input input data (none for stdin)
-o, --output output data (none for stdout)
--help, help display usage informationThis crate is released under the Apache 2.0 License.
Due to an issue in the upstream [email protected] crate, this crate is not strictly no-std at the moment. It transitively includes bit-vec without gating the std feature. While this prevents compilation for some bare-metal targets (e.g., thumbv7em-none-eabi), it remains compatible with many other no-std environments. The CI checks for this are temporarily disabled until the upstream issue is resolved.