Skip to content

Latest commit

 

History

History
144 lines (98 loc) · 5.27 KB

File metadata and controls

144 lines (98 loc) · 5.27 KB

RISC-Zero Verifier

CI License

A no-std verifier for RISC-Zero STARK proofs.

Overview

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.

Usage

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.

Working with Proofs, Keys, and Journals

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());

Development

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.info file with the coverage data.

Utilities

Proof Generation

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.

Convert Legacy ZkVerify Proofs

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 convert

The 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 information

License

This crate is released under the Apache 2.0 License.

Disclaimer: no-std Compatibility

Due to an issue in the upstream risc0-circuit-rv32im@2.0.x 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.