Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion .github/workflows/end-to-end.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ jobs:
working-directory: noir-examples/noir-passport/merkle_age_check
run: |
cargo run --release --bin provekit-cli generate-gnark-inputs \
./benchmark-inputs/t_attest-prover.pkp \
./benchmark-inputs/t_attest-verifier.pkv \
./benchmark-inputs/t_attest-proof.np

- name: Run Gnark verifier
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
params_for_recursive_verifier
params
artifacts/
spartan_vm_debug/
mavros_debug/

# Don't ignore benchmarking artifacts
!tooling/provekit-bench/benches/*
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ anyhow = "1.0.93"
argh = "0.1.12"
axum = "0.8.4"
base64 = "0.22.1"
bincode = "1.3"
bytes = "1.10.1"
chrono = "0.4.41"
# On CI divan get replaced by divan = { package = "codspeed-divan-compat", version = "3.0.1" } for benchmark tracking.
Expand Down Expand Up @@ -162,6 +163,8 @@ ark-ff = { version = "0.5", features = ["asm", "std"] }
ark-poly = "0.5"
ark-serialize = "0.5"
ark-std = { version = "0.5", features = ["std"] }
mavros-vm = { git = "https://github.com/reilabs/mavros", branch = "split_main"}
mavros-artifacts = { git = "https://github.com/reilabs/mavros", branch = "split_main"}
spongefish = { git = "https://github.com/arkworks-rs/spongefish", features = [
"ark-ff", "sha2",
], rev = "fcc277f8a857fdeeadd7cca92ab08de63b1ff1a1" }
Expand Down
128 changes: 127 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ cargo run --release --bin provekit-cli verify ./verifier.pkv ./proof.np
Generate inputs for Gnark circuit:

```sh
cargo run --release --bin provekit-cli generate-gnark-inputs ./prover.pkp ./proof.np
cargo run --release --bin provekit-cli generate-gnark-inputs ./verifier.pkv ./proof.np
```

Analyze circuit statistics and R1CS complexity:
Expand Down Expand Up @@ -70,6 +70,132 @@ cd ../../recursive-verifier
go run cmd/cli/main.go --config ../noir-examples/poseidon-rounds/params_for_recursive_verifier --r1cs ../noir-examples/poseidon-rounds/r1cs.json
```

### Benchmarking

Benchmark against Barretenberg:

> _Note_: You can install Barretenberg from [here](https://github.com/AztecProtocol/aztec-packages/blob/master/barretenberg/bbup/README.md).

> _Note_: You can install [hyperfine](https://github.com/sharkdp/hyperfine) using brew on OSX: `brew install hyperfine`.

```sh
cd noir-examples/poseidon-rounds
cargo run --release --bin provekit-cli prepare ./target/basic.json --pkp ./prover.pkp --pkv ./verifier.pkv
hyperfine 'nargo execute && bb prove -b ./target/basic.json -w ./target/basic.gz -o ./target' '../../target/release/provekit-cli prove ./prover.pkp ./Prover.toml'
```

### Profiling

#### Custom built-in profile (Memory usage)

The `provekit-cli` application has written custom memory profiler that prints basic info about memory usage when application
runs. To run binary with profiling enabled run it with cargo `--features profiling` param or compile with it.

```sh
cargo run --release --bin provekit-cli --features profiling prove ./prover.pkp ./Prover.toml -o ./proof.np
```

#### Using tracy (CPU and Memory usage)

Tracy tool [website](https://github.com/wolfpld/tracy). To install tracy tool on OSX use brew: `brew install tracy`.

> **Important**: integration is done with `Tracy Profiler 0.11.1`. It is newest version available from brew. Newer
> version may require updating dependencies as tracy is using its own protocol between app and tracy tool that changes
> with each major version.

TLDR; Tracy is an interactive tool to profile application. There is integration plugin for rust that works with
standard tracing annotation. For now it is integrated into `provekit-cli` binary only. Collecting profiling data requires
tracy to run during application profiling. You may noticed that it makes application to run much longer but mostly
due to data transfer between the application and the tracy running along.

Usage:

1. Start tracy from command line
```sh
tracy
```
2. Leave all fields with defaults and just click `Connect` button. It will cause tracy to start listening on the
localhost for incoming data.
3. Compile `noir-r1cs-profiled` binary.
```sh
cargo build --release --bin provekit-cli --features profiling
```
4. (OSX only) If you want to check call stacks additional command needs to be run (base on tracy instruction). The
command must be run against each binary that is being profiled by tracy. This will create directory next to the
binary provided with `.dSYM` suffix (ex. `../../target/profiled-cli.dSYM`). Directory will contain the
debug symbols and paths extracted with different format that is compatible with tracy tool. It must be rerun after
each changes made to `provekit-cli` app.
```sh
dsymutil ../../target/release/provekit-cli
```
5. Now start the application to profile:
```sh
../../target/release/provekit-cli prove ./prover.pkp ./Prover.toml -o ./proof.np
```
6. Go back to tracy tool. You should see that it receives data. App is interactive.

#### Using samply (CPU usage)

Samply tool [website](https://github.com/mstange/samply/) with instructions to install. It will start local server and
open a webpage with interactive app to view results. This does not require to run binary
with profiling enabled.

```sh
samply record -r 10000 -- ./../../target/release/provekit-cli prove ./prover.pkp ./Prover.toml -o ./proof.np
```

#### Using instruments (Memory usage) - OSX only

Cargo instruments tool [website](https://crates.io/crates/cargo-instruments) with instructions to install. It will open
results using built-in Instruments app. Results are interactive.

```sh
cargo instruments --template Allocations --release --bin provekit-cli prove ./prover.pkp ./Prover.toml -o ./proof.np
```

Samply tool [website](https://github.com/mstange/samply/) with instructions to install. It will start local server and
open a webpage with interactive app to view results. This does not require to run binary
with profiling enabled.

```sh
samply record -r 10000 -- ./../../target/release/provekit-cli prove ./prover.pkp ./Prover.toml -o ./proof.np
```

## Demo instructions for Mavros

> _NOTE:_ The example below is being run for single example `poseidon-rounds`. You can use different example to run same commands.

Compile the Noir circuit:

mavros bin is a prerequisite. You should follow the build instructions in the Mavros repository at

https://github.com/reilabs/mavros


```sh
cd noir-examples/poseidon-rounds
mavros compile
```

Prepare the Noir program (generates prover and verifier files):

```sh
cargo run --release --bin provekit-cli prepare --compiler mavros ./target/basic.json --r1cs ./target/r1cs.bin --pkp ./prover.pkp --pkv ./verifier.pkv
```

Generate the Noir Proof using the input Toml:

```sh
cargo run --release --bin provekit-cli prove ./prover.pkp ./Prover.toml -o ./proof.np
```

Verify the Noir Proof:

```sh
cargo run --release --bin provekit-cli verify ./verifier.pkv ./proof.np
```


### Benchmarking

Benchmark against Barretenberg:
Expand Down
7 changes: 7 additions & 0 deletions noir-examples/many_poseidons/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "basic"
type = "bin"
authors = [""]

[dependencies]
poseidon = { tag = "v0.1.1", git = "https://github.com/noir-lang/poseidon" }
2 changes: 2 additions & 0 deletions noir-examples/many_poseidons/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
input = "2"
out = "17988182159117295307234504899192092167905999116349671907177110574981469137649"
8 changes: 8 additions & 0 deletions noir-examples/many_poseidons/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use poseidon::poseidon::bn254;

fn main(mut input: Field, out: pub Field) {
for i in 0..10000 {
input = bn254::hash_1([input]);
}
assert_eq(input, out);
}
7 changes: 7 additions & 0 deletions noir-examples/power/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "basic"
type = "bin"
authors = [""]
compiler_version = ">=0.22.0"

[dependencies]
2 changes: 2 additions & 0 deletions noir-examples/power/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x = "1"
y = "1"
8 changes: 8 additions & 0 deletions noir-examples/power/prove.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
nargo compile
nargo check
nargo execute my-witness
bb prove -b ./target/power.json -w ./target/my-witness.gz -o ./target/proof
echo "✅ Proof generated at ./target/proof"
bb write_vk -b ./target/power.json -o ./target/vk
bb verify -k ./target/vk -p ./target/proof
echo "✅ Verified the proof at ./target/proof"
7 changes: 7 additions & 0 deletions noir-examples/power/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main(mut x: Field, y: pub Field) {
let mut r = 1;
for i in 0..10 {
r *= x;
}
assert(r == y);
}
6 changes: 6 additions & 0 deletions noir-examples/rangechecks/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "basic"
type = "bin"
authors = [""]

[dependencies]
1 change: 1 addition & 0 deletions noir-examples/rangechecks/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "0"
7 changes: 7 additions & 0 deletions noir-examples/rangechecks/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main(x: Field) {
for i in 0..10000 {
let r = x + i as Field;
r.assert_max_bit_size::<32>();
}
}

5 changes: 5 additions & 0 deletions provekit/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ license.workspace = true
homepage.workspace = true
repository.workspace = true

[features]
default = []

[dependencies]
# Workspace crates
skyscraper.workspace = true
Expand Down Expand Up @@ -41,6 +44,8 @@ tracing.workspace = true
xz2.workspace = true
zerocopy.workspace = true
zeroize.workspace = true
mavros-vm.workspace = true
mavros-artifacts.workspace = true
zstd.workspace = true

[lints]
Expand Down
4 changes: 2 additions & 2 deletions provekit/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ use crate::{
pub use {
acir::FieldElement as NoirElement,
ark_bn254::Fr as FieldElement,
noir_proof_scheme::{NoirProof, NoirProofScheme},
noir_proof_scheme::{MavrosSchemeData, NoirProof, NoirProofScheme, NoirSchemeData},
prefix_covector::{OffsetCovector, PrefixCovector},
prover::Prover,
prover::{MavrosProver, NoirProver, Prover},
r1cs::R1CS,
verifier::Verifier,
whir_r1cs::{
Expand Down
45 changes: 41 additions & 4 deletions provekit/common/src/noir_proof_scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,39 @@ use {
NoirElement, PublicInputs, R1CS,
},
acir::circuit::Program,
mavros_vm::{ConstraintsLayout, WitnessLayout},
noirc_abi::Abi,
serde::{Deserialize, Serialize},
};

/// A scheme for proving a Noir program.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NoirProofScheme {
pub struct NoirSchemeData {
pub program: Program<NoirElement>,
pub r1cs: R1CS,
pub split_witness_builders: SplitWitnessBuilders,
pub witness_generator: NoirWitnessGenerator,
pub whir_for_witness: WhirR1CSScheme,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MavrosSchemeData {
#[serde(with = "crate::utils::serde_jsonify")]
pub abi: Abi,
pub num_public_inputs: usize,
pub r1cs: R1CS,
pub whir_for_witness: WhirR1CSScheme,
pub witgen_binary: Vec<u64>,
pub ad_binary: Vec<u64>,
pub constraints_layout: ConstraintsLayout,
pub witness_layout: WitnessLayout,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NoirProofScheme {
Noir(NoirSchemeData),
Mavros(MavrosSchemeData),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct NoirProof {
pub public_inputs: PublicInputs,
Expand All @@ -26,7 +46,24 @@ pub struct NoirProof {

impl NoirProofScheme {
#[must_use]
pub const fn size(&self) -> (usize, usize) {
(self.r1cs.num_constraints(), self.r1cs.num_witnesses())
pub fn r1cs(&self) -> &R1CS {
match self {
NoirProofScheme::Noir(d) => &d.r1cs,
NoirProofScheme::Mavros(d) => &d.r1cs,
}
}

#[must_use]
pub fn whir_for_witness(&self) -> &WhirR1CSScheme {
match self {
NoirProofScheme::Noir(d) => &d.whir_for_witness,
NoirProofScheme::Mavros(d) => &d.whir_for_witness,
}
}

#[must_use]
pub fn size(&self) -> (usize, usize) {
let r1cs = self.r1cs();
(r1cs.num_constraints(), r1cs.num_witnesses())
}
}
Loading
Loading