Skip to content

Commit

Permalink
remove MAX_DEGREE stuff from cargo-powdr (#1992)
Browse files Browse the repository at this point in the history
This PR fixes line breaks for some md files and adjusts the code and
README of cargo-powdr to not talk about the MAX_DEGREE_LOG stuff

---------

Co-authored-by: Lucas Clemente Vella <[email protected]>
  • Loading branch information
leonardoalt and lvella authored Oct 30, 2024
1 parent 5b0d9a0 commit 1b27183
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 43 deletions.
2 changes: 1 addition & 1 deletion cargo-powdr/template/Cargo.toml.template
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ default = []
simd = ["powdr/plonky3-simd"]

[dependencies]
powdr = { git = "https://github.com/powdr-labs/powdr", features = ["plonky3"] }
powdr = { git = "https://github.com/powdr-labs/powdr", tag = "v0.1.0", features = ["plonky3"] }

serde = { version = "1.0", default-features = false, features = [
"alloc",
Expand Down
77 changes: 50 additions & 27 deletions cargo-powdr/template/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# powdrVM Usage Template

This is a foundational template for generating zero-knowledge proofs with powdrVM. You write the code to be proven as a guest program for the zkVM host. This template includes a structure for host/guest interaction, ZKP setup, and artifact generation.

Guest programs are written in Rust. When creating your guest program, you can write Rust code in the usual way, including using std and importing packages others have written. We provide some additional powdrVM specific functionalities via system calls, such as IO operations for host <-> guest communication and precompiles to accelerate complex programs via optimized circuits.
This is a foundational template for generating zero-knowledge proofs with powdrVM.
You write the code to be proven as a guest program for the zkVM host.
This template includes a structure for host/guest interaction, ZKP setup,
and artifact generation.

Guest programs are written in Rust.
When creating your guest program, you can write Rust code in the usual way,
including using std and importing packages others have written.
We provide some additional powdrVM specific functionalities via system calls,
such as IO operations for host <-> guest communication and precompiles to
accelerate complex programs via optimized circuits.

## Dependencies

Expand All @@ -18,28 +26,22 @@ cargo run -r

## AVX / Neon

You can enable AVX or Neon support by using the `simd` feature and running the host with extra flags:
You can enable AVX or Neon support by using the `simd` feature and running
the host with extra flags:

```bash
RUSTFLAGS='-C target-cpu=native' cargo run --features simd -r
```

## Structure

- `src/main.rs`: the host code. This is where you create a powdr `Session`, prepare data to be shared with the guest, and run the prover.
- `guest`: this is the guest crate. It contains the code that will be run inside the powdrVM.
- `powdr-target`: this is where all generated artifacts reside. This includes the compiled guest code to powdr-asm, the compiled PIL constraints, setup artifacts such as proving and verifying keys, and the final ZK proofs.

## Troubleshooting

powdrVM uses a default chunk size of 2^20 cycles for production cases. In some machines, key generation can run out-of-memory. To solve this, use

```bash
export MAX_DEGREE_LOG=20
```

and use a chunk size of 2^18 in the host, as explained in the section below.
This is being improved at the moment.
- `src/main.rs`: the host code. This is where you create a powdr `Session`,
prepare data to be shared with the guest, and run the prover.
- `guest`: this is the guest crate. It contains the code that will be
run inside the powdrVM.
- `powdr-target`: this is where all generated artifacts reside.
This includes the compiled guest code to powdr-asm, the compiled PIL constraints,
setup artifacts such as proving and verifying keys, and the final ZK proofs.

## Workflow

Expand All @@ -53,39 +55,60 @@ let some_data = vec![1, 2, 3, 4, 5];

Create a new powdr session where we'll be running crate `guest` in powdrVM
and all artifacts will be stored in `powdr-target`:

```rust
let mut session = Session::new("./guest", "powdr-target")
let mut session = Session::builder()
.guest_path("./guest")
.out_path("powdr-target")
.build()
```

Write `some_data` to channel 1 and the sum of `some_data` to channel 2.
Note that any `serde` type can be used to share data between host and guest.

The guest will read this data from the channels:

```rust
.write(1, &some_data).write(2, &some_data.iter().sum::<u32>());
.write(1, &some_data)
.write(2, &some_data.iter().sum::<u32>());
```

The line below also creates a powdr `Session`, but tells powdrVM to use 2^18 rows
per chunk, if needed. In that case, make sure to also use `export MAX_DEGREE_LOG=20`.
This tells the powdr compiler to generate smaller circuits than the default production
size of 2^22. This is being improved at the moment.
The lines below also create a powdr `Session`, but tell powdrVM to use 2^18 rows
per chunk, instead of the default 2^20. This is useful to decrease memory usage,
for example, at the expense of proving time.

```rust
let mut session = Session::new_with_chunk_size("./guest", "powdr-target", 18)
let mut session = Session::builder()
.guest_path("./guest")
.out_path("powdr-target")
.chunk_size_log2(18)
```

Run the session without generating a proof. Useful for testing the guest code:

```rust
session.run();
```

Generate the ZK proof:

```rust
session.prove();
```

Before generating a proof, powdrVM has to create the proving and verifying keys (setup) for the given guest program. When run for the first time, this can take a while. Subsequent runs will be faster as the setup only changes if the guest changes.
Before generating a proof, powdrVM has to create the proving and verifying keys (setup)
for the given guest program.
When run for the first time, this can take a while.
Subsequent runs will be faster as the setup only changes if the guest changes.

powdrVM also needs to compute the witnesses for the given execution trace,
needed by the ZK prover.
Currently this is done by an automated constraint solver,
which can be slow for complex programs.
We are working on a more efficient way to generate witnesses.

You can run the host with INFO logs to have a deeper look at what's happening:

You can also run the host with INFO logs to have a deeper look at what's happening:
```bash
RUST_LOG=info cargo run -r
```
4 changes: 2 additions & 2 deletions cargo-powdr/template/guest/Cargo.toml.template
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"

[dependencies]
powdr-riscv-syscalls = { git = "https://github.com/powdr-labs/powdr" }
powdr-riscv-runtime = { git = "https://github.com/powdr-labs/powdr", features = ["std"]}
powdr-riscv-syscalls = { git = "https://github.com/powdr-labs/powdr", tag = "v0.1.0" }
powdr-riscv-runtime = { git = "https://github.com/powdr-labs/powdr", tag = "v0.1.0", features = ["std"]}

[workspace]
23 changes: 12 additions & 11 deletions cargo-powdr/template/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,19 @@ fn main() {
.write(1, &some_data)
.write(2, &some_data.iter().sum::<u32>());

// Create a new powdr session with a custom chunk size for small traces/proofs.
// 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.
// When using this, make sure to also use
// `$ export MAX_DEGREE_LOG=20`
// to get faster setup times.
// let mut session = Session::builder()
// .guest_path("./guest")
// .out_path("powdr-target")
// .chunk_size_log2(18)
// .build()
// .write(1, &some_data)
// .write(2, &some_data.iter().sum::<u32>());
let mut session = Session::builder()
.guest_path("./guest")
.out_path("powdr-target")
.chunk_size_log2(18)
.build()
.write(1, &some_data)
.write(2, &some_data.iter().sum::<u32>());

// Fast dry run to test execution.
session.run();
Expand Down
6 changes: 4 additions & 2 deletions examples/keccak/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# powdrVM tinykeccak example

This example demonstrates how to use the `powdrVM` to run a simple keccak hash function using the `tinykeccak` crate.
This example demonstrates how to use the `powdrVM` to run a simple
keccak hash function using the `tinykeccak` crate.

We want to prove that we know the pre-image of a hash.
The host takes in a 32-byte challenge hash `C` as a hex string, and the pre-image string `P`, such that `Keccak(P) = C`.
The host takes in a 32-byte challenge hash `C` as a hex string,
and the pre-image string `P`, such that `Keccak(P) = C`.

The guest receives the same data from the host and verifies that the claim is true.

Expand Down

0 comments on commit 1b27183

Please sign in to comment.