Generating Proofs: Basics

An end-to-end flow of proving f(x) = y with the SP1 zkVM involves the following steps:

  • Define f using normal Rust code and compile it to an ELF (covered in the writing programs section).
  • Generate a proof π using the SP1 zkVM that f(x) = y with prove(ELF, x).
  • Verify the proof π using verify(ELF, x, y, π).

To make this more concrete, let's walk through a simple example of generating a proof for a Fiboancci program inside the zkVM.


use sha2::{Digest, Sha256};
use sp1_sdk::{utils, ProverClient, SP1PublicValues, SP1Stdin};

/// The ELF we want to execute inside the zkVM.
const ELF: &[u8] = include_bytes!("../../program/elf/riscv32im-succinct-zkvm-elf");

fn main() {
    // Setup a tracer for logging.

    // Create an input stream and write '500' to it.
    let n = 500u32;

    // The expected result of the fibonacci calculation
    let expected_a = 1926u32;
    let expected_b: u32 = 3194u32;

    let mut stdin = SP1Stdin::new();

    // Generate the proof for the given program and input.
    let client = ProverClient::new();
    let mut proof = client.prove(ELF, stdin).unwrap();

    println!("generated proof");

    // Read and verify the output.
    let n: u32 =<u32>();
    let a =<u32>();
    let b =<u32>();
    assert_eq!(a, expected_a);
    assert_eq!(b, expected_b);

    println!("a: {}", a);
    println!("b: {}", b);

    // Verify proof and public values
    client.verify(ELF, &proof).expect("verification failed");

    // Save the proof.
        .expect("saving proof failed");

    println!("successfully generated and verified proof for the program!")

You can run the above script with RUST_LOG=info cargo run --release.

Build Script

If you want your program crate to be built automatically whenever you build/run your script crate, you can add a file inside of script/ (at the same level as Cargo.toml):

use sp1_helper::build_program;

fn main() {

Make sure to also add sp1-helper as a build dependency in script/Cargo.toml:

sp1-helper = { git = "" }

If you run RUST_LOG=info cargo run --release -vv, you will see the following output from the build script if the program has changed, indicating that the program was rebuilt:

[fibonacci-script 0.1.0] cargo:rerun-if-changed=../program/src
[fibonacci-script 0.1.0] cargo:rerun-if-changed=../program/Cargo.toml
[fibonacci-script 0.1.0] cargo:rerun-if-changed=../program/Cargo.lock
[fibonacci-script 0.1.0] cargo:warning=fibonacci-program built at 2024-03-02 22:01:26
[fibonacci-script 0.1.0] [sp1]    Compiling fibonacci-program v0.1.0 (/Users/umaroy/Documents/fibonacci/program)
[fibonacci-script 0.1.0] [sp1]     Finished release [optimized] target(s) in 0.15s
warning: fibonacci-script@0.1.0: fibonacci-program built at 2024-03-02 22:01:26```