-
Notifications
You must be signed in to change notification settings - Fork 276
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
306 additions
and
233 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,8 @@ | ||
# Building Plonk BN254 Artifacts | ||
# Building PLONK Artifacts | ||
|
||
To build the production Plonk Bn254 artifacts from scratch, you can use the `Makefile` inside the `prover` directory. | ||
|
||
```shell,noplayground | ||
cd prover | ||
RUST_LOG=info make build-plonk-bn254 | ||
``` | ||
|
||
## Non-production builds | ||
|
||
For quickly building the plonk artifacts, you can run `cargo test` with additional flags to speed up the build process. | ||
|
||
```shell,noplayground | ||
SP1_DEV=true FRI_QUERIES=1 cargo test --release test_e2e_prove_plonk | ||
``` | ||
|
||
The generated artifacts should only be used for development and testing purposes. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,13 @@ | ||
# 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](../writing-programs/basics.md) section). | ||
- Setup a proving key (`pk`) and verifying key (`vk`) for the program given the ELF. The proving key contains all the information needed to generate a proof and includes some post-processing on top of the ELF, while the verifying key is a compact representation of the ELF that contains all the information needed to verify a proof and is much smaller than the ELF itself. | ||
- Generate a proof `π` using the SP1 zkVM that `f(x) = y` with `prove(pk, x)`. | ||
- Verify the proof `π` using `verify(vk, x, y, π)`. | ||
All the methods you'll need for generating proofs are included in the `sp1_sdk` crate. Most importantly, you'll need to use the `ProverClient` to setup a proving key and verifying key for your program and then use the `prove` and `verify` methods to generate and verify proofs. | ||
|
||
To make this more concrete, let's walk through a simple example of generating a proof for a Fiboancci program inside the zkVM. | ||
|
||
## Fibonacci | ||
## Example: Fibonacci | ||
|
||
```rust,noplayground | ||
{{#include ../../examples/fibonacci/script/src/main.rs}} | ||
``` | ||
|
||
You can run the above script in the `script` directory with `RUST_LOG=info cargo run --release`. | ||
|
||
## Build Script | ||
|
||
> WARNING: This may not generate a reproducible ELF which is necessary for verifying that your binary corresponds to given source code. | ||
> | ||
> When building a ELF that will be used in production, make sure to use the [reproduction build system](../writing-programs/setup.md#build-with-docker-production). | ||
If you want your program crate to be built automatically whenever you build/run your script crate, you can add a `build.rs` file inside of `script/` (at the same level as `Cargo.toml`): | ||
|
||
```rust,noplayground | ||
{{#include ../../examples/fibonacci/script/build.rs}} | ||
``` | ||
|
||
Make sure to also add `sp1-helper` as a build dependency in `script/Cargo.toml`: | ||
|
||
```toml | ||
[build-dependencies] | ||
sp1-helper = { git = "https://github.com/succinctlabs/sp1.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``` | ||
```` | ||
You can run the above script in the `script` directory with `RUST_LOG=info cargo run --release`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Development Options | ||
|
||
## Execution Only | ||
|
||
We recommend that during the development of large programs (> 1 million cycles) you do not generate proofs each time. | ||
Instead, you should have your script only execute the program with the RISC-V runtime and read `public_values`. Here is an example: | ||
|
||
```rust,noplayground | ||
{{#include ../../examples/fibonacci/script/bin/execute.rs}} | ||
``` | ||
|
||
If the execution of your program succeeds, then proof generation should succeed as well! (Unless there is a bug in our zkVM implementation.) | ||
|
||
## Logging and Tracing Information | ||
|
||
You can use `sp1_sdk::utils::setup_logger()` to enable logging information respectively. You can set the logging level with the `RUST_LOG` environment variable. | ||
|
||
```rust,noplayground | ||
sp1_sdk::utils::setup_logger(); | ||
``` | ||
|
||
Example of setting the logging level to `info` (other options are `debug`, `trace`, and `warn`): | ||
|
||
```bash | ||
RUST_LOG=info cargo run --release | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Optimizing Performance | ||
|
||
## CPU Acceleration | ||
|
||
SP1 supports CPU hardware acceleration using AVX256/512 and NEON SIMD instructions. To enable the acceleration, you can use the `RUSTFLAGS` environment variable to generate code that is optimized for your CPU. | ||
|
||
**AVX256 / NEON**: | ||
```bash | ||
RUSTFLAGS='-C target-cpu=native' cargo run --release | ||
``` | ||
|
||
**AVX512**: | ||
```bash | ||
RUSTFLAGS='-C target-cpu=native -C target_feature=+avx512ifma,+avx512vl' cargo run --release | ||
``` | ||
|
||
## Enviroment Variables (Advanced) | ||
|
||
`SHARD_SIZE`: The number of cycles that will be proven in each "shard" in the SP1 zkVM. This value | ||
must be set to a power of two. | ||
|
||
`SHARD_BATCH_SIZE`: The number of shards that will be proven in parallel. This value can be tuned | ||
depending on how much memory your machine has to improve performance. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Prover Options | ||
|
||
The prover options can be configured using a "builder" pattern after creating a `ProverClient` and | ||
calling `prove` on it. | ||
|
||
For a full list of options, see the [SP1 SDK](https://github.com/succinctlabs/sp1/blob/dev/sdk/src/action.rs). | ||
|
||
## Core (Default) | ||
|
||
The default prover mode generates a list of STARK proofs that in aggregate have size proportional to | ||
the size of the execution. Use this in settings where you don't care about **verification cost / proof size**. | ||
|
||
```rust,noplayground | ||
let client = ProverClient::new(); | ||
client.prove(&pk, stdin).run().unwrap(); | ||
``` | ||
|
||
## Compressed | ||
|
||
The compressed prover mode generates STARK proofs that have constant size. Use this in settings where you | ||
care about **verification cost / proof size**. | ||
|
||
```rust,noplayground | ||
let client = ProverClient::new(); | ||
client.prove(&pk, stdin).compressed().run().unwrap(); | ||
``` | ||
|
||
## PLONK | ||
|
||
> WARNING: The PLONK prover requires around 128GB of RAM and is only guaranteed to work on official releases of SP1. | ||
The PLONK prover mode generates a SNARK proof with extremely small proof size and low verification cost. | ||
This mode is necessary for generating proofs that can be verified onchain for around ~300k gas. | ||
|
||
```rust,noplayground | ||
let client = ProverClient::new(); | ||
client.prove(&pk, stdin).plonk().run().unwrap(); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Hardware Requirements | ||
|
||
The hardware requirements for SP1 depend on what features you want to use. These requirements can also | ||
change over time as the design of the zKVM evolves. | ||
|
||
**The most important requirement is CPU for performance/latency and RAM to prevent running out of memory.** | ||
|
||
| | Mock / Network | Core / Compress | PLONK (EVM) | | ||
|----------------|------------------------------|------------------------------------|----------------------------| | ||
| CPU | 1+, single-core perf matters | 16+, more is better | 32+, more is better | | ||
| Memory | 8GB+, more is better | 32GB+, more if you have more cores | 128GB+ (for PLONK) | | ||
| Disk | 20GB+ | 20GB+ | 100GB+ (for trusted setup) | | ||
| EVM Compatible | ✅ | ❌ | ✅ | | ||
|
||
### CPU | ||
|
||
The execution & trace generation of the zkVM is mostly CPU bound, having a high single-core | ||
performance is recommended to accelerate these steps. The rest of the prover is mostly bound by hashing/field operations | ||
which can be parallelized with multiple cores. | ||
|
||
### Memory | ||
|
||
Our prover requires keeping large matrices (i.e., traces) in memory to generate the proofs. Certain steps of the prover | ||
have a minimum memory requirement, meaning that if you have less than this amount of memory, the process will OOM. | ||
|
||
This effect is most noticeable when using the PLONK prover, which requires around 128GB of RAM to generate a proof. We use PLONK to avoid | ||
having to perform a trusted setup, which other SNARK provers like Groth16 require. We have future optimizations planned to reduce | ||
the memory requirements of the PLONK prover substantially. | ||
|
||
### Disk | ||
|
||
Disk is required to install the SP1 zkVM toolchain and to install the trused setup artifacts, if you plan to locally build the PLONK prover. | ||
|
||
Furthermore, disk is used to checkpoint the state of the program execution, which is required to generate the proofs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# What is a zkVM? | ||
|
||
A zero-knowledge virtual machine (zkVM) is zero-knowledge proof system that allows developers to prove the execution of arbitrary Rust (or other LLVM-compiled language) programs. | ||
|
||
Conceptually, you can think of the SP1 zkVM as proving the evaluation of a function `f(x) = y` by following the steps below: | ||
|
||
- Define `f` using normal Rust code and compile it to an ELF (covered in the [writing programs](../writing-programs/setup.md) section). | ||
- Setup a proving key (`pk`) and verifying key (`vk`) for the program given the ELF. | ||
- Generate a proof `π` using the SP1 zkVM that `f(x) = y` with `prove(pk, x)`. | ||
- Verify the proof `π` using `verify(vk, x, y, π)`. | ||
|
||
As a practical example, `f` could be a simple Fibonacci [program](https://github.com/succinctlabs/sp1/blob/main/examples/fibonacci/program/src/main.rs). The process of generating a proof and verifying it can be seen [here](https://github.com/succinctlabs/sp1/blob/main/examples/fibonacci/script/src/main.rs). | ||
|
||
For blockchain applications, the verification usually happens inside of a [smart contract](https://github.com/succinctlabs/sp1-project-template/blob/main/contracts/src/Fibonacci.sol). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Why use SP1? | ||
|
||
Zero-knowledge proofs (ZKPs) are a powerful primitive that enable developers to outsource verifiable computation to provers. But ZKP adoption has been held back because it is “moon math”, requiring specialized knowledge in obscure ZKP frameworks and hard to maintain one-off deployments. | ||
|
||
Performant, general-purpose zkVMs, like SP1, will obsolete the current paradigm of specialized teams hand rolling their own custom ZK stack and create a future where all blockchain infrastructure, including rollups, bridges, coprocessors, and more, utilize ZKPs **via maintainable software written in Rust (or other LLVM-compiled languages)**. | ||
|
||
SP1 is especially powerful in blockchain contexts which rely on verifiable computation. Example applications include: | ||
- [Rollups](https://ethereum.org/en/developers/docs/scaling/zk-rollups/): SP1 can be used in combination with existing node infrastructure like [Reth](https://github.com/paradigmxyz/reth) to build rollups with fraud proofs based on zero-knowledge proofs. | ||
- [Coprocessors](https://crypto.mirror.xyz/BFqUfBNVZrqYau3Vz9WJ-BACw5FT3W30iUX3mPlKxtA): SP1 can be used to outsource onchain computation to offchain provers to enable use cases such as accessing historical state and onchain machine learning, dramatically reducing gas costs. | ||
- [Light Clients](https://ethereum.org/en/developers/docs/nodes-and-clients/light-clients/): SP1 can be used to build light clients that can verify the state of other chains, facilitating interoperability between different blockchains without relying on any trusted third parties. | ||
|
||
SP1 has already been integrated in many of these applications, including but not limited to: | ||
|
||
- [SP1 Reth](https://github.com/succinctlabs/sp1-reth): A performant, type-1 zkEVM written in Rust & SP1. | ||
- [SP1 Tendermint](https://github.com/succinctlabs/sp1-tendermint-example): An example of a ZK Tendermint light client on Ethereum powered by SP1. | ||
- and many more! | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Build Script | ||
|
||
> WARNING: This may not generate a reproducible ELF which is necessary for verifying that your binary corresponds to given source code. | ||
> | ||
> When building a ELF that will be used in production, make sure to use the [reproduction build system](../writing-programs/setup.md#build-with-docker-production). | ||
If you want your program crate to be built automatically whenever you build/run your script crate, you can add a `build.rs` file inside of `script/` (at the same level as `Cargo.toml`): | ||
|
||
```rust,noplayground | ||
{{#include ../../examples/fibonacci/script/build.rs}} | ||
``` | ||
|
||
Make sure to also add `sp1-helper` as a build dependency in `script/Cargo.toml`: | ||
|
||
```toml | ||
[build-dependencies] | ||
sp1-helper = { git = "https://github.com/succinctlabs/sp1.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``` | ||
```` |
Oops, something went wrong.