Quick Start

First, create a new powdrVM project with

cargo-powdr new my-host
  • Your new crate my-host is the host of the virtual machine's execution, and is responsible for preparing data and running the prover.
  • The guest crate in your new project contains the Rust code whose execution will be proven.

Most of these details are abstracted by the powdr library.

Now that your project is set up, just run

cargo run -r

The host manages a powdr::Session which can be used to share data with the guest, test the execution, and generate ZK proofs.

use powdr::Session;

fn main() {
    env_logger::init();

    let some_data = vec![1, 2, 3, 4, 5];

    // Create a new powdr session to make proofs for the `guest` crate.
    // Store all temporary and final artifacts in `powdr-target`.
    let mut session = Session::builder()
        .guest_path("./guest")
        .out_path("powdr-target")
        // powdrVM splits long execution traces into chunks
        // which are proven individually.
        // The default size of a chunk is 2^20 = 1048576 rows.
        // For experiments and smaller traces/proofs, it may be beneficial to reduce the chunk size.
        // Create a new powdr session with a custom chunk size.
        // 2^18 = 262144 rows per chunk.
        .chunk_size_log2(18)
        .build()
        // Write `some_data` to channel 1 and the sum of `some_data` to channel 2.
        // Any serde-serializable type can be written to a channel.
        .write(1, &some_data)
        .write(2, &some_data.iter().sum::<u32>());

    // Fast dry run to test execution.
    session.run();

    // Uncomment to compute the proof.
    //session.prove();
}

The guest contains the custom logic that should be proved.

use powdr_riscv_runtime;
use powdr_riscv_runtime::io::read;

fn main() {
    // Any serde-deserializable type can be read from a channel.
    // Read some data from channel 1.
    let data: Vec<u32> = read(1);
    // Read the claimed sum from channel 2.
    let sum: u32 = read(2);

    // Check that the claimed sum is correct.
    assert_eq!(data.iter().sum::<u32>(), sum);
}