Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: plonk prover #795

Merged
merged 20 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ concurrency:
cancel-in-progress: true

jobs:
groth16:
name: Groth16
plonk:
name: Plonk
runs-on: runs-on,cpu=64,ram=256,family=m7i+m7a,hdd=80,image=ubuntu22-full-x64
env:
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
Expand All @@ -35,7 +35,7 @@ jobs:
with:
command: test
toolchain: nightly-2024-04-17
args: --release -p sp1-sdk --features groth16 -- test_e2e_prove_groth16 --nocapture
args: --release -p sp1-sdk --features plonk_bn254 -- test_e2e_prove_plonk_bn254 --nocapture
env:
RUSTFLAGS: -Copt-level=3 -Cdebug-assertions -Coverflow-checks=y -Cdebuginfo=0 -C target-cpu=native
RUST_BACKTRACE: 1
4 changes: 2 additions & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
with:
command: test
toolchain: nightly-2024-04-17
args: --release --features groth16
args: --release --features plonk_bn254
env:
RUSTFLAGS: -Copt-level=3 -Cdebug-assertions -Coverflow-checks=y -Cdebuginfo=0 -C target-cpu=native
RUST_BACKTRACE: 1
Expand Down Expand Up @@ -76,7 +76,7 @@ jobs:
with:
command: test
toolchain: nightly-2024-04-17
args: --release --features groth16
args: --release --features plonk_bn254
env:
RUSTFLAGS: -Copt-level=3 -Cdebug-assertions -Coverflow-checks=y -Cdebuginfo=0 -C target-cpu=native
RUST_BACKTRACE: 1
Expand Down
2 changes: 1 addition & 1 deletion book/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@

- [Recommended Settings](./developers/recommended-settings.md)

- [Building Groth16 Artifacts](./developers/building-groth16-artifacts.md)
jtguibas marked this conversation as resolved.
Show resolved Hide resolved
- [Building Plonk Bn254 Artifacts](./developers/building-groth16-artifacts.md)
6 changes: 3 additions & 3 deletions book/developers/building-groth16-artifacts.md
jtguibas marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Building Groth16 Artifacts
# Building Plonk BN254 Artifacts

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

```shell,noplayground
RUST_LOG=info make groth16
RUST_LOG=info make plonk-bn254
```
2 changes: 1 addition & 1 deletion book/developers/recommended-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
For developers contributing to the SP1 project, we recommend the following settings:

- `FRI_QUERIES=1`: Makes the prover use less bits of security to generate proofs more quickly.
- `SP1_DEV=1`: This will rebuild the Groth16 artifacts everytime they are necessary.
- `SP1_DEV=1`: This will rebuild the Plonk Bn254 artifacts everytime they are necessary.
16 changes: 8 additions & 8 deletions book/verifying-proofs/solidity-and-evm.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@
SP1 recently added support for verifying proofs for onchain usecases. To see an end-to-end example
of using SP1 for on-chain usecases, refer to the [SP1 Project Template](https://github.com/succinctlabs/sp1-project-template/tree/main).

## Generating a Groth16 Proof
## Generating a Plonk Bn254 Proof

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 function for this called `prove_groth16`. 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 Groth16.
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 function for this called `prove_plonk_bn254`. 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.

**Due to the fact that Groth16 proofs require a trusted setup, the Groth16 prover is only guaranteed to work on official releases of SP1 (i.e., `v.1.0.0-testnet`).**
**Due to the fact that PLONK Bn254 proofs require a trusted setup, the PLONK Bn254 prover is only guaranteed to work on official releases of SP1 (i.e., `v.1.0.0-testnet`).**
jtguibas marked this conversation as resolved.
Show resolved Hide resolved

To use Groth16 proving & verification locally, enable the `groth16` feature flag in the sp1-sdk and ensure that Go >1.22.1 is installed.
To use PLONK proving & verification locally, enable the `plonk_bn254` feature flag in the sp1-sdk and ensure that Go >1.22.1 is installed.
```toml
sp1-sdk = { features = ["groth16"] }
sp1-sdk = { features = ["plonk_bn254"] }
```


### Example

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

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

## Exporting the Verifier Contract

Expand All @@ -41,7 +41,7 @@ use std::path::PathBuf;

fn main() {
let contracts_src_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../contracts/src");
sp1_sdk::artifacts::export_solidity_groth16_verifier(contracts_src_dir)
sp1_sdk::artifacts::export_solidity_plonk_bn254_verifier(contracts_src_dir)
.expect("failed to export verifier");
}
```
2 changes: 1 addition & 1 deletion examples/aggregation/script/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ default-run = "sp1-aggregation-example-script"

[dependencies]
hex = "0.4.3"
sp1-sdk = { path = "../../../sdk", features = ["groth16"] }
sp1-sdk = { path = "../../../sdk", features = ["plonk_bn254"] }
tracing = "0.1.40"

[build-dependencies]
Expand Down
8 changes: 4 additions & 4 deletions examples/aggregation/script/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const FIBONACCI_ELF: &[u8] =
include_bytes!("../../programs/fibonacci/elf/riscv32im-succinct-zkvm-elf");

/// An input to the aggregation program.
///
///
/// Consists of a proof and a verification key.
struct AggregationInput {
pub proof: SP1CompressedProof,
Expand Down Expand Up @@ -93,9 +93,9 @@ fn main() {
stdin.write_proof(input.proof.proof, input.vk.vk);
}

// Generate the groth16 proof.
// Generate the plonk bn254 proof.
client
.prove_groth16(&aggregation_pk, stdin)
.prove_plonk_bn254(&aggregation_pk, stdin)
.expect("proving failed");
});
});
}
4 changes: 2 additions & 2 deletions examples/fibonacci/script/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ sha2 = "0.10.8"
sp1-helper = { path = "../../../helper" }

[[bin]]
name = "groth16"
path = "bin/groth16.rs"
name = "plonk_bn254"
path = "bin/plonk_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 mut proof = client.prove_groth16(&pk, stdin).unwrap();
let mut proof = client.prove_plonk_bn254(&pk, stdin).unwrap();

println!("generated proof");

Expand All @@ -29,7 +29,7 @@ fn main() {

// Verify proof and public values
client
.verify_groth16(&proof, &vk)
.verify_plonk_bn254(&proof, &vk)
.expect("verification failed");

// Save the proof.
Expand Down
8 changes: 4 additions & 4 deletions prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ num-bigint = "0.4.5"
thiserror = "1.0.60"

[[bin]]
name = "build_groth16"
path = "scripts/build_groth16.rs"
name = "build_plonk_bn254"
path = "scripts/build_plonk_bn254.rs"

[[bin]]
name = "e2e"
path = "scripts/e2e.rs"

[features]
default = ["groth16"]
default = ["plonk_bn254"]

neon = ["sp1-core/neon"]
groth16 = ["sp1-recursion-gnark-ffi/groth16"]
plonk_bn254 = ["sp1-recursion-gnark-ffi/plonk_bn254"]
4 changes: 2 additions & 2 deletions prover/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ all:
make tendermint-sweep
make fibonacci-groth16

build-groth16:
build-plonk-bn254:
mkdir -p build && \
RUSTFLAGS='-C target-cpu=native' \
cargo run -p sp1-prover --release --bin build_groth16 -- \
jtguibas marked this conversation as resolved.
Show resolved Hide resolved
cargo run -p sp1-prover --release --bin build_plonk_bn254 -- \
--build-dir=./build

release-groth16:
jtguibas marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::path::PathBuf;

use clap::Parser;
use sp1_core::utils::setup_logger;
use sp1_prover::build::build_groth16_artifacts_with_dummy;
use sp1_prover::build::build_plonk_bn254_artifacts_with_dummy;

#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
Expand All @@ -17,5 +17,5 @@ struct Args {
pub fn main() {
setup_logger();
let args = Args::parse();
build_groth16_artifacts_with_dummy(args.build_dir);
build_plonk_bn254_artifacts_with_dummy(args.build_dir);
}
12 changes: 6 additions & 6 deletions prover/scripts/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use sp1_recursion_circuit::stark::build_wrap_circuit;
use sp1_recursion_circuit::witness::Witnessable;
use sp1_recursion_compiler::ir::Witness;
use sp1_recursion_core::air::RecursionPublicValues;
use sp1_recursion_gnark_ffi::Groth16Prover;
use sp1_recursion_gnark_ffi::PlonkBn254Prover;
use subtle_encoding::hex;

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -70,19 +70,19 @@ pub fn main() {
witness.write_vkey_hash(vkey_hash);

tracing::info!("sanity check gnark test");
Groth16Prover::test(constraints.clone(), witness.clone());
PlonkBn254Prover::test(constraints.clone(), witness.clone());

tracing::info!("sanity check gnark build");
Groth16Prover::build(constraints.clone(), witness.clone(), build_dir.clone());
PlonkBn254Prover::build(constraints.clone(), witness.clone(), build_dir.clone());

tracing::info!("sanity check gnark prove");
let groth16_prover = Groth16Prover::new();
let plonk_bn254_prover = PlonkBn254Prover::new();

tracing::info!("gnark prove");
let proof = groth16_prover.prove(witness.clone(), build_dir.clone());
let proof = plonk_bn254_prover.prove(witness.clone(), build_dir.clone());

tracing::info!("verify gnark proof");
groth16_prover.verify(
plonk_bn254_prover.verify(
&proof,
&vkey_hash.as_canonical_biguint(),
&committed_values_digest.as_canonical_biguint(),
Expand Down
2 changes: 1 addition & 1 deletion prover/scripts/fibonacci_groth16.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Tests end-to-end performance of wrapping a recursion proof to Groth16.
//! Tests end-to-end performance of wrapping a recursion proof to PLONK.

#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
Expand Down
57 changes: 30 additions & 27 deletions prover/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,83 +10,86 @@ pub use sp1_recursion_compiler::ir::Witness;
use sp1_recursion_compiler::{config::OuterConfig, constraints::Constraint};
use sp1_recursion_core::air::RecursionPublicValues;
pub use sp1_recursion_core::stark::utils::sp1_dev_mode;
use sp1_recursion_gnark_ffi::Groth16Prover;
use sp1_recursion_gnark_ffi::PlonkBn254Prover;

use crate::install::{install_groth16_artifacts, GROTH16_ARTIFACTS_COMMIT};
use crate::install::{install_plonk_bn254_artifacts, PLONK_BN254_ARTIFACTS_COMMIT};
use crate::utils::{babybear_bytes_to_bn254, babybears_to_bn254, words_to_bytes};
use crate::{OuterSC, SP1Prover};

/// Tries to install the Groth16 artifacts if they are not already installed.
pub fn try_install_groth16_artifacts() -> PathBuf {
let build_dir = groth16_artifacts_dir();
/// Tries to install the PLONK artifacts if they are not already installed.
pub fn try_install_plonk_bn254_artifacts() -> PathBuf {
let build_dir = plonk_bn254_artifacts_dir();

if build_dir.exists() {
println!("[sp1] groth16 artifacts already seem to exist at {}. if you want to re-download them, delete the directory", build_dir.display());
println!(
"[sp1] plonk bn254 artifacts already seem to exist at {}. if you want to re-download them, delete the directory",
build_dir.display()
);
} else {
println!(
"[sp1] groth16 artifacts for commit {} do not exist at {}. downloading...",
GROTH16_ARTIFACTS_COMMIT,
"[sp1] plonk bn254 artifacts for commit {} do not exist at {}. downloading...",
PLONK_BN254_ARTIFACTS_COMMIT,
build_dir.display()
);
install_groth16_artifacts(build_dir.clone());
install_plonk_bn254_artifacts(build_dir.clone());
}
build_dir
}

/// Tries to build the Groth16 artifacts inside the development directory.
/// Tries to build the PLONK artifacts inside the development directory.
///
/// TODO: Maybe add some additional logic here to handle rebuilding the artifacts if they are
/// already built.
pub fn try_build_groth16_artifacts_dev(
pub fn try_build_plonk_bn254_artifacts_dev(
template_vk: &StarkVerifyingKey<OuterSC>,
template_proof: &ShardProof<OuterSC>,
) -> PathBuf {
let build_dir = groth16_artifacts_dev_dir();
println!("[sp1] building groth16 artifacts in development mode");
build_groth16_artifacts(template_vk, template_proof, &build_dir);
let build_dir = plonk_bn254_artifacts_dev_dir();
println!("[sp1] building plonk bn254 artifacts in development mode");
build_plonk_bn254_artifacts(template_vk, template_proof, &build_dir);
build_dir
}

/// Gets the directory where the Groth16 artifacts are installed.
pub fn groth16_artifacts_dir() -> PathBuf {
/// Gets the directory where the PLONK artifacts are installed.
pub fn plonk_bn254_artifacts_dir() -> PathBuf {
dirs::home_dir()
.unwrap()
.join(".sp1")
.join("circuits")
.join("groth16")
.join(GROTH16_ARTIFACTS_COMMIT)
.join("plonk_bn254")
.join(PLONK_BN254_ARTIFACTS_COMMIT)
}

/// Gets the directory where the Groth16 artifacts are installed in development mode.
pub fn groth16_artifacts_dev_dir() -> PathBuf {
/// Gets the directory where the PLONK artifacts are installed in development mode.
pub fn plonk_bn254_artifacts_dev_dir() -> PathBuf {
dirs::home_dir()
.unwrap()
.join(".sp1")
.join("circuits")
.join("groth16")
.join("plonk_bn254")
.join("dev")
}

/// Build the groth16 artifacts to the given directory for the given verification key and template
/// Build the plonk bn254 artifacts to the given directory for the given verification key and template
/// proof.
pub fn build_groth16_artifacts(
pub fn build_plonk_bn254_artifacts(
template_vk: &StarkVerifyingKey<OuterSC>,
template_proof: &ShardProof<OuterSC>,
build_dir: impl Into<PathBuf>,
) {
let build_dir = build_dir.into();
std::fs::create_dir_all(&build_dir).expect("failed to create build directory");
let (constraints, witness) = build_constraints_and_witness(template_vk, template_proof);
Groth16Prover::build(constraints, witness, build_dir);
PlonkBn254Prover::build(constraints, witness, build_dir);
}

/// Builds the groth16 artifacts to the given directory.
/// Builds the plonk bn254 artifacts to the given directory.
///
/// This may take a while as it needs to first generate a dummy proof and then it needs to compile
/// the circuit.
pub fn build_groth16_artifacts_with_dummy(build_dir: impl Into<PathBuf>) {
pub fn build_plonk_bn254_artifacts_with_dummy(build_dir: impl Into<PathBuf>) {
let (wrap_vk, wrapped_proof) = dummy_proof();
crate::build::build_groth16_artifacts(&wrap_vk, &wrapped_proof, build_dir.into());
crate::build::build_plonk_bn254_artifacts(&wrap_vk, &wrapped_proof, build_dir.into());
}

/// Build the verifier constraints and template witness for the circuit.
Expand Down
Loading
Loading