Writing Programs: Basics
A zero-knowledge proof generally proves that some function f
when applied to some input x
produces some output y
(i.e. f(x) = y
).
In the context of the SP1 zkVM:
f
is written in normal Rust code.x
are bytes that can be serialized / deserialized into objectsy
are bytes that can be serialized / deserialized into objects
To make this more concrete, let's walk through a simple example of writing a Fibonacci program inside the zkVM.
Fibonacci
This program is from the examples
directory in the SP1 repo which contains several example programs of varying complexity.
//! A simple program that takes a number `n` as input, and writes the `n-1`th and `n`th fibonacci
//! number as an output.
// These two lines are necessary for the program to properly compile.
//
// Under the hood, we wrap your main function with some extra code so that it behaves properly
// inside the zkVM.
#![no_main]
sp1_zkvm::entrypoint!(main);
pub fn main() {
// Read an input to the program.
//
// Behind the scenes, this compiles down to a custom system call which handles reading inputs
// from the prover.
let n = sp1_zkvm::io::read::<u32>();
// Write n to public input
sp1_zkvm::io::commit(&n);
// Compute the n'th fibonacci number, using normal Rust code.
let mut a = 0;
let mut b = 1;
for _ in 0..n {
let mut c = a + b;
c %= 7919; // Modulus to prevent overflow.
a = b;
b = c;
}
// Write the output of the program.
//
// Behind the scenes, this also compiles down to a custom system call which handles writing
// outputs to the prover.
sp1_zkvm::io::commit(&a);
sp1_zkvm::io::commit(&b);
}
As you can see, writing programs is as simple as writing normal Rust. To read more about how inputs and outputs work, refer to the section on Inputs & Outputs.