Skip to content

Commit

Permalink
docs: add groth16 (#1503)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattstam authored Sep 13, 2024
1 parent 2480345 commit 4791740
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 51 deletions.
18 changes: 8 additions & 10 deletions book/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@

- [Proof Aggregation](./writing-programs/proof-aggregation.md)


# Generating Proofs

- [Setup](./generating-proofs/setup.md)
Expand All @@ -46,13 +45,15 @@
- [Recommended Workflow](./generating-proofs/recommended-workflow.md)

- [Prover Network Beta](./generating-proofs/prover-network.md)
- [Key Setup](./generating-proofs/prover-network/key-setup.md)
- [Usage](./generating-proofs/prover-network/usage.md)
- [Supported Versions](./generating-proofs/prover-network/versions.md)

- [Key Setup](./generating-proofs/prover-network/key-setup.md)
- [Usage](./generating-proofs/prover-network/usage.md)
- [Supported Versions](./generating-proofs/prover-network/versions.md)

- [Hardware Acceleration](./generating-proofs/hardware-acceleration.md)
- [AVX](./generating-proofs/hardware-acceleration/avx.md)
- [CUDA](./generating-proofs/hardware-acceleration/cuda.md)

- [AVX](./generating-proofs/hardware-acceleration/avx.md)
- [CUDA](./generating-proofs/hardware-acceleration/cuda.md)

- [FAQ](./generating-proofs/sp1-sdk-faq.md)

Expand All @@ -64,7 +65,6 @@

- [Contract Addresses](./onchain-verification/contract-addresses.md)


# Developers

- [Common Issues](./developers/common-issues.md)
Expand All @@ -73,6 +73,4 @@

- [RV32IM Specification](./developers/rv32im-specification.md)

- [Building PLONK Artifacts](./developers/building-plonk-artifacts.md)


- [Building Circuit Artifacts](./developers/building-circuit-artifacts.md)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Building Circuit Artifacts

To build the production PLONK and Groth16 Bn254 artifacts from scratch, you can use the `Makefile` inside the `prover` directory.
To build the production Groth16 and PLONK Bn254 artifacts from scratch, you can use the `Makefile` inside the `prover` directory.

```shell,noplayground
cd prover
Expand Down
6 changes: 3 additions & 3 deletions book/generating-proofs/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ To make this more concrete, let's walk through a simple example of generating a
{{#include ../../examples/fibonacci/script/src/main.rs}}
```

You can run the above script in the `script` directory with `RUST_LOG=info cargo run --release`. Note that running the above script will generate a proof locally.
You can run the above script in the `script` directory with `RUST_LOG=info cargo run --release`. Note that running the above script will generate a proof locally.

<div class="warning">
WARNING: Local proving often is much slower than the prover network and for certain proof types (e.g. PLONK) requires a significant amount of RAM and will likely not work on a laptop.
WARNING: Local proving often is much slower than the prover network and for certain proof types (e.g. Groth16, PLONK) require a significant amount of RAM and will likely not work on a laptop.
</div>

We recommend using the [prover network](./prover-network.md) to generate proofs. Read more about the [recommended workflow](./recommended-workflow.md) for developing with SP1.
We recommend using the [prover network](./prover-network.md) to generate proofs. Read more about the [recommended workflow](./recommended-workflow.md) for developing with SP1.
24 changes: 21 additions & 3 deletions book/generating-proofs/proof-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,32 @@ let client = ProverClient::new();
client.prove(&pk, stdin).compressed().run().unwrap();
```

## Groth16 (testnet only)

<div class="warning">
WARNING: Groth16 proofs are currently only verifiable on testnets & are not production-ready
</div>

<div class="warning">
WARNING: The Groth16 prover requires around 64GB of RAM and are only guaranteed to work on official releases of SP1. We recommend using the prover network to generate these proofs.
</div>

The Groth16 prover mode generate a SNARK proof with extremely small proof size and low verification cost.
This mode generates proofs that can be verified onchain for around ~270k gas.

```rust,noplayground
let client = ProverClient::new();
client.prove(&pk, stdin).groth16().run().unwrap();
```

## PLONK

<div class="warning">
WARNING: The PLONK prover requires around 64GB of RAM and is only guaranteed to work on official releases of SP1. We recommend using the prover network to generate PLONK proofs.
WARNING: The PLONK prover requires around 64GB of RAM and are only guaranteed to work on official releases of SP1. We recommend using the prover network to generate these proofs.
</div>

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.
The Groth16 and PLONK prover modes generate a SNARK proof with extremely small proof size and low verification cost.
This mode generates proofs that can be verified onchain for around ~300k gas.

```rust,noplayground
let client = ProverClient::new();
Expand Down
18 changes: 9 additions & 9 deletions book/generating-proofs/recommended-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

We recommend the following workflow for developing with SP1.

## Step 1: Iterate on your program with execution only
## Step 1: Iterate on your program with execution only

While iterating on your SP1 program, you should **only execute** the program with the RISC-V runtime. This will allow you to verify the correctness of your program and test the `SP1Stdin` as well as the `SP1PublicValues` that are returned, without having to generate a proof (which can be slow and/or expensive). If the execution of your program succeeds, then proof generation should succeed as well!

Expand All @@ -14,7 +14,7 @@ Note that printing out the total number of executed cycles and the full executio

**Crate Setup:** We recommend that your program crate that defines the `main` function (around which you wrap the `sp1_zkvm::entrypoint!` macro) should be kept minimal. Most of your business logic should be in a separate crate (in the same repo/workspace) that can be tested independently and that is not tied to the SP1 zkVM. This will allow you to unit test your program logic without having to worry about the `zkvm` compilation target. This will also allow you to efficient reuse types between your program crate and your crate that generates proofs.

## Step 2: Generate proofs
## Step 2: Generate proofs

After you have iterated on your program and finalized that it works correctly, you can generate proofs for your program for final end to end testing or production use.

Expand All @@ -28,7 +28,7 @@ There are a few things to keep in mind when using the prover network.

#### Benchmarking latency on the prover network

The prover network currently parallelizes proof generation across multiple machines. This means the latency of proof generation does not scale linearly with the number of cycles of your program, but rather with the number of cycles of your program divided by the number of currently available machines on the prover network.
The prover network currently parallelizes proof generation across multiple machines. This means the latency of proof generation does not scale linearly with the number of cycles of your program, but rather with the number of cycles of your program divided by the number of currently available machines on the prover network.

Our prover network currently has limited capacity because it is still in beta. If you have an extremely latency sensitive use-case and you want to figure out the **minimal latency possible** for your program, you should [reach out to us](https://partner.succinct.xyz/) and we can onboard you to our reserved capacity cluster that has a dedicated instances that can significantly reduce latency.

Expand All @@ -40,18 +40,18 @@ Note that **latency is not the same as cost**, because we parallelize proof gene

#### Benchmarking on small vs. large programs

In SP1, there is a fixed overhead for proving that is independent of your program's cycle count. This means that benchmarking on *small programs* is not representative of the performance of larger programs. To get an idea of the scale of programs for real-world workloads, you can refer to our [benchmarking blog post](https://blog.succinct.xyz/sp1-production-benchmarks) and also some numbers below:
In SP1, there is a fixed overhead for proving that is independent of your program's cycle count. This means that benchmarking on _small programs_ is not representative of the performance of larger programs. To get an idea of the scale of programs for real-world workloads, you can refer to our [benchmarking blog post](https://blog.succinct.xyz/sp1-production-benchmarks) and also some numbers below:

* An average Ethereum block can be between 100-500M cycles (including merkle proof verification for storage and execution of transactions) with our `keccak` and `secp256k1` precompiles.
* For a Tendermint light client, the average cycle count can be between 10M and 50M cycles (including our ed25519 precompiles).
* We consider programs with <2M cycles to be "small" and by default, the fixed overhead of proving will dominate the proof latency. If latency is incredibly important for your use-case, we can specialize the prover network for your program if you reach out to us.
- An average Ethereum block can be between 100-500M cycles (including merkle proof verification for storage and execution of transactions) with our `keccak` and `secp256k1` precompiles.
- For a Tendermint light client, the average cycle count can be between 10M and 50M cycles (including our ed25519 precompiles).
- We consider programs with <2M cycles to be "small" and by default, the fixed overhead of proving will dominate the proof latency. If latency is incredibly important for your use-case, we can specialize the prover network for your program if you reach out to us.

Note that if you generate PLONK proofs on the prover network, you will encounter a fixed overhead of 90 seconds for the STARK -> SNARK wrapping step. We're actively working on reducing this overhead in our next release.
Note that if you generate Groth16 or PLONK proofs on the prover network, you will encounter a fixed overhead for the STARK -> SNARK wrapping step. We're actively working on reducing this overhead in future releases.

#### On-Demand vs. Reserved Capacity

The prover network is currently in beta and has limited capacity. For high volume use-cases, we can offer discounted pricing and a reserved capacity cluster that has a dedicated instances that can significantly reduce latency and have higher throughput and guaranteed SLAs.

### Generating proofs locally

If you want to generate proofs locally, you can use the `sp1_sdk` crate to generate proofs locally as outlined in the [Basics](./basics.md) section. By default, the `ProverClient` will generate proofs locally using your CPU. Check out the hardware requirements for locally proving [here](../getting-started/hardware-requirements.md#local-proving).
If you want to generate proofs locally, you can use the `sp1_sdk` crate to generate proofs locally as outlined in the [Basics](./basics.md) section. By default, the `ProverClient` will generate proofs locally using your CPU. Check out the hardware requirements for locally proving [here](../getting-started/hardware-requirements.md#local-proving).
26 changes: 13 additions & 13 deletions book/getting-started/hardware-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
We recommend that developers who want to use SP1 for non-trivial programs generate proofs on our prover network. The prover network generates SP1 proofs across multiple machines, reducing latency and also runs SP1 on optimized hardware instances that result in faster + cheaper proof generation times.

We recommend that for any production benchmarking, you use the prover network to estimate latency and costs of proof generation.

</div>

## Local Proving
Expand All @@ -12,16 +13,16 @@ If you want to generate SP1 proofs locally, this section has an overview of the

**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 | 64GB+ (for PLONK) |
| Disk | 20GB+ | 20GB+ | 100GB+ (for trusted setup) |
| EVM Compatible | | | |
| | Mock / Network | Core / Compress | Groth16 and 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 | 64GB+, more is better |
| Disk | 20GB+ | 20GB+ | 12GB+ |
| EVM Compatible ||||

### CPU

The execution & trace generation of the zkVM is mostly CPU bound, having a high single-core
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.

Expand All @@ -30,13 +31,12 @@ which can be parallelized with multiple cores.
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 SNARKs like Groth16 require. We have future optimizations planned to reduce
the memory requirements of the PLONK prover substantially.
This effect is most noticeable when using the Groth16 or PLONK provers, which requires around 128GB
of RAM to generate a proof.

### 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.
Disk is required to install the SP1 zkVM toolchain and to install the circuit artifacts, if you
plan to locally build the Groth16 or PLONK provers.

Furthermore, disk is used to checkpoint the state of the program execution, which is required to generate the proofs.
14 changes: 8 additions & 6 deletions book/onchain-verification/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,22 @@ Refer to the section on [Contract Addresses](./contract-addresses.md) for the ad

By default, the proofs generated by SP1 are not verifiable onchain, as they are non-constant size and STARK verification on Ethereum is very expensive. To generate a proof that can be verified onchain, we use performant STARK recursion to combine SP1 shard proofs into a single STARK proof and then wrap that in a SNARK proof. Our `ProverClient` has a prover option for this called `plonk`. Behind the scenes, this function will first generate a normal SP1 proof, then recursively combine all of them into a single proof using the STARK recursion protocol. Finally, the proof is wrapped in a SNARK proof using PLONK.

> WARNING: The PLONK prover is only guaranteed to work on official releases of SP1. To use PLONK proving & verification locally, ensure that you have Docker installed and have at least 128GB of RAM.
> WARNING: The Groth16 and PLONK provers are only guaranteed to work on official releases of SP1. To
> use Groth16 or PLONK proving & verification locally, ensure that you have Docker installed and have
> at least 128GB of RAM.
### Example

```rust,noplayground
{{#include ../../examples/fibonacci/script/bin/plonk_bn254.rs}}
{{#include ../../examples/fibonacci/script/bin/groth16_bn254.rs}}
```

You can run the above script with `RUST_LOG=info cargo run --bin plonk_bn254 --release` in `examples/fibonacci/script`.
You can run the above script with `RUST_LOG=info cargo run --bin groth16_bn254 --release` in `examples/fibonacci/script`.

#### Using PLONK without Docker (Advanced)
#### Using Groth16 and PLONK without Docker (Advanced)

If you would like to run the PLONK prover directly without Docker, you must have Go 1.22 installed and enable the `native-plonk` feature in `sp1-sdk`. This path is not recommended and may require additional native dependencies.
If you would like to run the Groth16 or PLONK prover directly without Docker, you must have Go 1.22 installed and enable the `native-gnark` feature in `sp1-sdk`. This path is not recommended and may require additional native dependencies.

```toml
sp1-sdk = { version = "2.0.0", features = ["native-plonk"] }
sp1-sdk = { version = "2.0.0", features = ["native-gnark"] }
```
4 changes: 2 additions & 2 deletions examples/fibonacci/script/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ sha2 = "0.10.8"
sp1-build = { workspace = true }

[[bin]]
name = "plonk_bn254"
path = "bin/plonk_bn254.rs"
name = "groth16_bn254"
path = "bin/groth16_bn254.rs"

[[bin]]
name = "compressed"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn main() {
// Generate the proof for the given program and input.
let client = ProverClient::new();
let (pk, vk) = client.setup(ELF);
let proof = client.prove(&pk, stdin).plonk().run().unwrap();
let proof = client.prove(&pk, stdin).groth16().run().unwrap();

println!("generated proof");

Expand All @@ -32,9 +32,7 @@ fn main() {
client.verify(&proof, &vk).expect("verification failed");

// Save the proof.
proof
.save("proof-with-pis.bin")
.expect("saving proof failed");
proof.save("proof-with-pis.bin").expect("saving proof failed");

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

0 comments on commit 4791740

Please sign in to comment.