diff --git a/Cargo.toml b/Cargo.toml index f244600..219a5bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ resolver = "2" [workspace.dependencies] anyhow = { version = "1.0.89"} unroll = { version = "0.1.5"} -plonky2 = { version = "1.0.0" } +plonky2 = { version = "1.0.0" , default-features = false} plonky2_field = { version = "1.0.0" } plonky2_maybe_rayon = { version = "1.0.0"} itertools = { version = "0.12.1"} diff --git a/workflow/BENCHMARKS.md b/workflow/BENCHMARKS.md index a040173..7212944 100644 --- a/workflow/BENCHMARKS.md +++ b/workflow/BENCHMARKS.md @@ -4,63 +4,30 @@ In here we show the preliminary benchmarks of codex storage proofs circuits. ## Running Benchmarks -To run the benchmarks for safe merkle tree circuit, you can use the following command: +**Runtime Benchmarks** + +To run the benchmarks for sampling circuit and aggregation, you can use the following commands: ```bash -cargo bench --bench safe_circuit +cd bench_scripts +bash ./bench_runtime ``` -To run the benchmarks for sampling circuit, you can use the following command: -Note: make sure to adjust the parameters as need in .... - -```bash -cargo bench --bench sample_cells -``` - -The following operations were benchmarked: +The following operations were benchmarked for sampling and recursion circuits (both single-thread and multi-thread): - **Build Circuit**: Time taken to construct the circuit for the specified params. - **Prove Circuit**: Time taken to generate a proof for the constructed circuit. - **Verify Circuit**: Time taken to verify the generated proof. -## Bench Results -The following is the result of running the codex storage proof circuit (sample_cells). -The bench uses the Goldilocks field and Poseidon2 Hash. All results were run on Mac Mini with M2 Pro and 16GB RAM. - -### Bench params -The benchmark runs with the default params which are the following: +**Memory Benchmarks** +To run the memory benchmarks for sampling circuit and aggregation, you can use the following commands: ```bash -export MAXDEPTH=32 # Maximum depth of the slot tree -export MAXSLOTS=256 # Maximum number of slots -export CELLSIZE=2048 # Cell size in bytes -export BLOCKSIZE=65536 # Block size in bytes -export NSAMPLES=5 # Number of samples to prove - -export ENTROPY=1234567 # External randomness -export SEED=12345 # Seed for creating fake data - -export NSLOTS=11 # Number of slots in the dataset -export SLOTINDEX=3 # Which slot to prove (0..NSLOTS-1) -export NCELLS=512 # Number of cells in this slot +cd bench_scripts +bash ./bench_memory ``` +Note: The memory usage is quite difficult to replicate as it depends on the operating system, +but on macOS look for the "maximum resident set size" to get the peak memory usage. -### Build Time -Build time for plonky2 circuits is 39.644 ms. -Baseline Groth16 with same params: 61 seconds for the circuit specific setup. - -### Prove Time -Prove time for plonky2 circuits is 53.940 ms. -Baseline Groth16 with same params: 4.56 seconds using snarkjs - -improvement: approx 80x - -### Verify Time -To be done once recursion is added to the codebase. - -### Proof Size -Plonky Proof size: 116008 bytes -This is without recursion or Groth16 wrapper. - -### Peak Memory Usage -To be done. +## Bench Results +See this [document](https://hackmd.io/@NQdG6IOmQE6astjwhJ6ACw/Bk-SopNj1g) for full benchmark results. diff --git a/workflow/Cargo.toml b/workflow/Cargo.toml index 9c7f1a5..61a810e 100644 --- a/workflow/Cargo.toml +++ b/workflow/Cargo.toml @@ -22,6 +22,10 @@ proof-input = { path = "../proof-input" } criterion = { version = "0.5.1", default-features = false } tynm = { version = "0.1.6", default-features = false } +[features] +default = [] +parallel = ["plonky2/parallel"] + [[bin]] name = "prove_and_verify" path = "src/bin/prove_and_verify.rs" @@ -38,6 +42,10 @@ path = "src/bin/build_circ.rs" name = "prove" path = "src/bin/prove.rs" +[[bin]] +name = "aggregate" +path = "src/bin/aggregate.rs" + [[bench]] name = "merkle_circuit" harness = false @@ -48,4 +56,8 @@ harness = false [[bench]] name = "uniform_recursion" +harness = false + +[[bench]] +name = "compression" harness = false \ No newline at end of file diff --git a/workflow/README.md b/workflow/README.md index af55a91..2d1722c 100644 --- a/workflow/README.md +++ b/workflow/README.md @@ -22,6 +22,7 @@ This crate can be used to: - [`prove_and_verify`](./src/bin/prove_and_verify.rs) contains the main function to generated input with the given params as environment variables. +- [`aggregate`](./src/bin/aggregate.rs) contains the main function to generate the sampling proofs and aggregate `k` of them. ## Usage @@ -45,7 +46,7 @@ rustup override set nightly The steps to generate circuit input with **fake data** are the following: #### Step 1: Setting Up Parameters -Parameters for generating the circuit input can be defined in [`params.sh`](./params.sh). +Parameters for generating the circuit input can be defined in [`params.sh`](scripts/params.sh). You can customize the test parameters by setting the following environment variables: ```bash @@ -75,13 +76,13 @@ fn main() { Once the params are set, you can run the script to generate the [`JSON file`](./input.json). ```bash -sudo bash ./gen_input.sh +sudo bash ./scripts/gen_input.sh ``` ### Build the Circuit To build the circuit and measure the time to build, you can simply run the script: ```bash -sudo bash ./build_circuit.sh +sudo bash ./scripts/build_circuit.sh ``` To see the source code of how to build the circuit, see [`build_circ`](./src/bin/build_circ.rs). @@ -91,7 +92,7 @@ you can run the circuits to generate the proofs. First make sure you have the [`JSON file`](./input.json), then follow the steps: #### Step 1: Setting Up Circuit Parameters -Parameters for the circuit can be defined in [`circ_params.sh`](./circ_params.sh). +Parameters for the circuit can be defined in [`circ_params.sh`](scripts/circ_params.sh). You can customize the test parameters by setting the following environment variables: ```bash export MAX_DEPTH=32 # maximum depth of the slot tree @@ -106,16 +107,31 @@ Once the params are set, you can run the script to generate the proof. You can also see the time taken to generate the proof. ```bash -sudo bash ./prove.sh +sudo bash ./scripts/prove.sh ``` ### Build, Prove, and Verify To automate the whole process, you can run the following script the script builds the circuit, loads the JSON circuit input, generates the proof, and verifies it. It also shows the time taken for each step. -Make sure that you generate the circuit input prior to this so that you have the [`JSON input file`](./input.json) and set the [`circ_params.sh`](./circ_params.sh). +Make sure that you generate the circuit input prior to this so that you have the [`JSON input file`](./input.json) and set the [`circ_params.sh`](scripts/circ_params.sh). ```bash -sudo bash ./prove_and_verify.sh +sudo bash ./scripts/prove_and_verify.sh ``` To inspect the source code, see [`prove_and_verify`](./src/bin/prove_and_verify.rs). + +### Generate K Proofs and aggregate them +To do this, you can run the following script: + +```bash +sudo bash ./scripts/aggregate.sh +``` + + +or the following if you want to specify the number of proofs to be aggregated +```bash +sudo bash ./scripts/aggregate.sh -- "$K_VALUE" +``` + + diff --git a/workflow/RECURSION_BENCHMARKS.md b/workflow/RECURSION_BENCHMARKS.md deleted file mode 100644 index 7ae23f9..0000000 --- a/workflow/RECURSION_BENCHMARKS.md +++ /dev/null @@ -1,77 +0,0 @@ -## Benchmarks - -In here we show the benchmarks results when using Plonky2 recursion for the codex storage proofs. - -## Running Benchmarks - -To run the benchmarks, you can use the following command with `x` replaced with the benchmark name (for the list of all benchmarks, see [benches](./benches)): - -```bash -cargo bench --bench x -``` - -## Benchmark Results: -We implemented and experimented with various recursion approaches: -- Simple Recursion -- Simple Tree Recursion -- Cyclic Recursion -- Tree Recursion (Approach1) -- Tree Recursion (Approach2) -- Hybrid Recursion (Simple + Tree) - -For more details on each of these approaches see this [writeup](https://hackmd.io/@NQdG6IOmQE6astjwhJ6ACw/rk85D2HX1e) - -Here we show the benchmark results of running Hybrid recursion approaches and compare it to simple recursion. -Based on our experimentation, the hybrid approach gives the best results, compared to others. -The Params for the hybrid approach must be adjusted based on the number of proofs to be aggregated to give optimal results. - -There are various parameters to consider before benchmarking. -First the circuit and test parameters we used are the following: - -```bash -export MAXDEPTH=32 # Maximum depth of the slot tree -export MAXSLOTS=256 # Maximum number of slots -export CELLSIZE=2048 # Cell size in bytes -export BLOCKSIZE=65536 # Block size in bytes -export NSAMPLES=100 # Number of samples to prove - -export ENTROPY=1234567 # External randomness -export SEED=12345 # Seed for creating fake data - -export NSLOTS=11 # Number of slots in the dataset -export SLOTINDEX=3 # Which slot to prove (0..NSLOTS-1) -export NCELLS=512 # Number of cells in this slot -``` - -As can be seen above we set the number of samples (`NSAMPLES=100`) which should be sufficient. - -Additionally, we vary the number of proofs to be aggregated (`P = {4,8,16,32,64,128}`). -There are also the `N` and `M` parameters for the tree-structure recursion. -These params mean different things for each approach (refer to [writeup](https://hackmd.io/@NQdG6IOmQE6astjwhJ6ACw/rk85D2HX1e)) -In the Hybrid approach, these values are -- `M`: Number of proof aggregated in the leaf -- `N`: Number of proofs aggregated in the nodes of the tree - -**Build Circuit** - -| **P** | ** Recursion Build time (s)** | -|---------|-------------------------------| -| **4** | 0.967 | -| **8** | 1.613 | -| **16** | 2.977 | -| **32** | 5.847 | -| **64** | 12.533 | -| **128** | 26.930 | - - -**Prove Circuit** - -| **P** | **Simple Recursion (s)** | **Hybrid Recursion (s)** | -|-------|--------------------------|--------------------------| -| **4** | 0.769 | 0.612 | -| **8** | 1.549 | 1.227 | -| **16** | 3.212 | 2.691 | -| **32** | 6.574 | 6.225 | -| **64** | 15.107 | 14.654 | -| **128** | 34.617 | 29.189 | - diff --git a/workflow/bench_scripts/bench_memory.sh b/workflow/bench_scripts/bench_memory.sh new file mode 100644 index 0000000..413f0a5 --- /dev/null +++ b/workflow/bench_scripts/bench_memory.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Source parameters +source "params.sh" + +# Move to the project root +cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } + +# Build silently +cargo build --release > /dev/null 2>&1 || { echo "cargo build failed"; exit 101; } + +# 1) sampling circuit - build +echo "Running sampling circuit - build..." +/usr/bin/time -l bash -c 'cargo run --bin build_circ --features "parallel" >/dev/null 2>/dev/null' + +# 2) sampling circuit - prove +echo "Running sampling circuit - prove..." +cargo run --bin gen_input >/dev/null 2>/dev/null || { echo "gen_input.sh: cargo run failed"; exit 102; } +/usr/bin/time -l bash -c 'cargo run --bin prove --features "parallel" >/dev/null 2>/dev/null' + +# 3) sampling circuit - aggregate +K_VALUE=${1:-128} +echo "Running sampling circuit - aggregate (${K_VALUE} proofs)..." +/usr/bin/time -l bash -c "cargo run --bin aggregate --features 'parallel' -- '${K_VALUE}' >/dev/null 2>/dev/null" + diff --git a/workflow/bench_scripts/bench_runtime.sh b/workflow/bench_scripts/bench_runtime.sh new file mode 100644 index 0000000..10f750e --- /dev/null +++ b/workflow/bench_scripts/bench_runtime.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Change to the parent directory of the script +cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } + +echo "Running bench for the sampling circuit with multithreading..." +cargo bench --bench sample_cells --features "parallel" || { echo "Benchmark 'sample_cells' with multithreading failed"; exit 101; } + +echo "Running bench for the sampling circuit with single-thread..." +cargo bench --bench sample_cells || { echo "Benchmark 'sample_cells' with single-thread failed"; exit 102; } + +echo "Running bench for the tree recursion circuit with multithreading..." +cargo bench --bench uniform_recursion --features "parallel" || { echo "Benchmark 'uniform_recursion' with multithreading failed"; exit 103; } + +echo "Running bench for the tree recursion circuit with single-thread..." +cargo bench --bench uniform_recursion || { echo "Benchmark 'uniform_recursion' with single-thread failed"; exit 104; } diff --git a/workflow/bench_scripts/circ_params.sh b/workflow/bench_scripts/circ_params.sh new file mode 100755 index 0000000..7eaaec6 --- /dev/null +++ b/workflow/bench_scripts/circ_params.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +export MAX_DEPTH=32 # maximum depth of the slot tree +export MAX_LOG2_N_SLOTS=8 # Depth of the dataset tree = ceiling_log2(max_slots) +export BLOCK_TREE_DEPTH=5 # depth of the mini tree (block tree) +export N_FIELD_ELEMS_PER_CELL=272 # number of field elements per cell +export N_SAMPLES=100 # number of samples to prove \ No newline at end of file diff --git a/workflow/params.sh b/workflow/bench_scripts/params.sh similarity index 89% rename from workflow/params.sh rename to workflow/bench_scripts/params.sh index 12db138..c064bc9 100755 --- a/workflow/params.sh +++ b/workflow/bench_scripts/params.sh @@ -4,7 +4,7 @@ export MAXDEPTH=32 # maximum depth of the slot tree export MAXSLOTS=256 # maximum number of slots export CELLSIZE=2048 # cell size in bytes export BLOCKSIZE=65536 # block size in bytes -export NSAMPLES=5 # number of samples to prove +export NSAMPLES=100 # number of samples to prove export ENTROPY=1234567 # external randomness export SEED=12345 # seed for creating fake data diff --git a/workflow/benches/merkle_circuit.rs b/workflow/benches/merkle_circuit.rs index 5e1481c..bd6c772 100644 --- a/workflow/benches/merkle_circuit.rs +++ b/workflow/benches/merkle_circuit.rs @@ -2,7 +2,6 @@ use criterion::{criterion_group, criterion_main, Criterion}; use anyhow::Result; use proof_input::merkle_tree::merkle_safe::{MerkleTree}; -// use codex_plonky2_circuits::{circuits::merkle_circuit::MerkleTreeCircuit}; use plonky2::field::types::Field; use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData}; use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher, PoseidonGoldilocksConfig}; @@ -13,8 +12,6 @@ use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2_poseidon2::poseidon2_hash::poseidon2::{Poseidon2, Poseidon2Hash}; use plonky2::plonk::circuit_builder::CircuitBuilder; -// use codex_plonky2_circuits::merkle_tree::merkle_safe::MerkleProof; -// use plonky2_field::goldilocks_field::GoldilocksField; use proof_input::merkle_tree::merkle_circuit; use proof_input::merkle_tree::merkle_circuit::{assign_witness, MerkleTreeCircuitInput}; use proof_input::utils::usize_to_bits_le; diff --git a/workflow/benches/sample_cells.rs b/workflow/benches/sample_cells.rs index dac23b2..f360cf5 100644 --- a/workflow/benches/sample_cells.rs +++ b/workflow/benches/sample_cells.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; @@ -10,9 +10,9 @@ use proof_input::gen_input::gen_testing_circuit_input; use proof_input::params::{D, C, F, HF, Params}; /// Benchmark for building, proving, and verifying the Plonky2 circuit. -fn bench_prove_verify(c: &mut Criterion) -> Result<()>{ +fn bench_prove_verify(c: &mut Criterion) -> Result<()>{ - let n_samples = 100; + let n_samples = N; // get default parameters let params = Params::default(); let mut test_params = params.input_params; @@ -21,6 +21,9 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{ let mut circuit_params = params.circuit_params; circuit_params.n_samples = n_samples; + #[cfg(feature = "parallel")] + println!("Parallel feature is ENABLED"); + // gen the circuit input let circ_input = gen_testing_circuit_input::(&test_params); @@ -37,7 +40,7 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{ circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input.clone()); // Benchmark Group: Separate benchmarks for building, proving, and verifying - let mut group = c.benchmark_group("Sampling Circuit Benchmark"); + let mut group = c.benchmark_group(format!("Sampling Circuit Benchmark for N= {}", N)); // Benchmark the Circuit Building Phase group.bench_function("Build Circuit", |b| { @@ -45,9 +48,6 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{ let config = CircuitConfig::standard_recursion_config(); let mut local_builder = CircuitBuilder::::new(config); let _targets = circ.sample_slot_circuit_with_public_input(&mut local_builder); - // let local_targets = targets.clone(); - // let mut local_pw = pw.clone(); - // circ.sample_slot_assign_witness(&mut local_pw, &local_targets, &circ_input.clone()); let _data = local_builder.build::(); }) }); @@ -68,12 +68,12 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{ // println!("Number of constraints: {}", num_constr); // println!("Number of gates used: {}", data.common.gates.len()); - // Benchmark the Proving Phase group.bench_function("Prove Circuit", |b| { - b.iter(|| { - let local_pw = pw.clone(); - data.prove(local_pw).expect("Failed to prove circuit") - }) + b.iter_batched( + || pw.clone(), + |local_pw| data.prove(local_pw).expect("Failed to prove circuit"), + BatchSize::SmallInput, + ) }); // Generate the proof once for verification benchmarking @@ -96,10 +96,17 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{ Ok(()) } +fn bench_sampling(c: &mut Criterion) -> Result<()>{ + bench_prove_verify::<10>(c)?; + bench_prove_verify::<50>(c)?; + bench_prove_verify::<100>(c)?; + Ok(()) +} + /// Criterion benchmark group criterion_group!{ - name = prove_verify_benches; + name = benches; config = Criterion::default().sample_size(10); - targets = bench_prove_verify + targets = bench_sampling } -criterion_main!(prove_verify_benches); +criterion_main!(benches); diff --git a/workflow/benches/uniform_recursion.rs b/workflow/benches/uniform_recursion.rs index eb42613..0f383c1 100644 --- a/workflow/benches/uniform_recursion.rs +++ b/workflow/benches/uniform_recursion.rs @@ -31,7 +31,7 @@ fn bench_uniform_recursion(c: &mu let inner_data = sampling_builder.build::(); let inner_proof = inner_data.prove(pw.clone())?; - let proofs: Vec> = (0..N).map(|i| inner_proof.clone()).collect(); + let proofs: Vec> = (0..K).map(|i| inner_proof.clone()).collect(); // ------------------- tree -------------------- diff --git a/workflow/build_circuit.sh b/workflow/build_circuit.sh deleted file mode 100755 index d85777e..0000000 --- a/workflow/build_circuit.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# Source the parameters from params.sh -source ./params.sh - -# Build -cargo build --release || { echo "build_circuit.sh: cargo build failed"; exit 101; } - -# Run the Rust executable -cargo run --bin build_circ || { echo "build_circuit.sh: cargo run failed"; exit 102; } diff --git a/workflow/scripts/aggregate.sh b/workflow/scripts/aggregate.sh new file mode 100644 index 0000000..f2351e0 --- /dev/null +++ b/workflow/scripts/aggregate.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Source the parameters from the scripts directory +source "params.sh" + +# Change to the parent directory of the script +cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } + +# Build +cargo build --release || { echo "prove.sh: cargo build failed"; exit 101; } + +# Run the Rust executable +K_VALUE=${1:-4} +cargo run --bin aggregate --features "parallel" -- "$K_VALUE" || { echo "prove.sh: cargo run failed"; exit 102; } diff --git a/workflow/scripts/build_circuit.sh b/workflow/scripts/build_circuit.sh new file mode 100755 index 0000000..82828a6 --- /dev/null +++ b/workflow/scripts/build_circuit.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Source the parameters from the scripts directory +source "params.sh" + +# Change to the parent directory of the script +cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } + +# Build +cargo build --release || { echo "build_circuit.sh: cargo build failed"; exit 101; } + +# Run the Rust executable +cargo run --bin build_circ || { echo "build_circuit.sh: cargo run failed"; exit 102; } + diff --git a/workflow/circ_params.sh b/workflow/scripts/circ_params.sh similarity index 100% rename from workflow/circ_params.sh rename to workflow/scripts/circ_params.sh diff --git a/workflow/gen_input.sh b/workflow/scripts/gen_input.sh similarity index 68% rename from workflow/gen_input.sh rename to workflow/scripts/gen_input.sh index 8ef626f..e174f5c 100755 --- a/workflow/gen_input.sh +++ b/workflow/scripts/gen_input.sh @@ -3,6 +3,9 @@ # Source the parameters from params.sh source ./params.sh +# Change to the parent directory of the script +cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } + # Build cargo build --release || { echo "gen_input.sh: cargo build failed"; exit 101; } diff --git a/workflow/scripts/params.sh b/workflow/scripts/params.sh new file mode 100755 index 0000000..c064bc9 --- /dev/null +++ b/workflow/scripts/params.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +export MAXDEPTH=32 # maximum depth of the slot tree +export MAXSLOTS=256 # maximum number of slots +export CELLSIZE=2048 # cell size in bytes +export BLOCKSIZE=65536 # block size in bytes +export NSAMPLES=100 # number of samples to prove + +export ENTROPY=1234567 # external randomness +export SEED=12345 # seed for creating fake data + +export NSLOTS=11 # number of slots in the dataset +export SLOTINDEX=3 # which slot we prove (0..NSLOTS-1) +export NCELLS=512 # number of cells in this slot \ No newline at end of file diff --git a/workflow/prove.sh b/workflow/scripts/prove.sh similarity index 68% rename from workflow/prove.sh rename to workflow/scripts/prove.sh index 87ab3cf..cda727c 100755 --- a/workflow/prove.sh +++ b/workflow/scripts/prove.sh @@ -3,6 +3,9 @@ # Source the parameters from params.sh source ./circ_params.sh +# Change to the parent directory of the script +cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } + # Build cargo build --release || { echo "prove.sh: cargo build failed"; exit 101; } diff --git a/workflow/prove_and_verify.sh b/workflow/scripts/prove_and_verify.sh similarity index 70% rename from workflow/prove_and_verify.sh rename to workflow/scripts/prove_and_verify.sh index 522eee0..5df856d 100755 --- a/workflow/prove_and_verify.sh +++ b/workflow/scripts/prove_and_verify.sh @@ -3,6 +3,9 @@ # Source the parameters from params.sh source ./circ_params.sh +# Change to the parent directory of the script +cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } + # Build cargo build --release || { echo "prove_and_verify.sh: cargo build failed"; exit 101; } diff --git a/workflow/src/bin/aggregate.rs b/workflow/src/bin/aggregate.rs new file mode 100644 index 0000000..a0fbd1b --- /dev/null +++ b/workflow/src/bin/aggregate.rs @@ -0,0 +1,60 @@ +use std::env; +use plonky2::plonk::circuit_data::CircuitConfig; +use plonky2::plonk::config::GenericConfig; +use plonky2::iop::witness::PartialWitness; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use anyhow::Result; +use plonky2::plonk::proof::ProofWithPublicInputs; +use codex_plonky2_circuits::circuits::sample_cells::SampleCircuit; +use codex_plonky2_circuits::recursion::uniform::tree::TreeRecursion; +use proof_input::gen_input::gen_testing_circuit_input; +use proof_input::params::{D, C, F, HF, Params}; + +fn main() -> Result<()> { + // load the parameters from environment variables + let params = Params::from_env()?; + const N: usize = 1; + const M: usize = 2; + + // take k = "number of proofs" from env arguments; default to 4 if not there + let args: Vec = env::args().collect(); + let k: usize = if args.len() > 1 { + args[1] + .parse() + .expect("k not valid") + } else { + 4 + }; + + // generate circuit input with given parameters + let circ_input = gen_testing_circuit_input::(¶ms.input_params); + + // create the circuit + let config = CircuitConfig::standard_recursion_config(); + let mut builder = CircuitBuilder::::new(config); + let circ = SampleCircuit::::new(params.circuit_params); + let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder)?; + + // create a PartialWitness and assign + let mut pw = PartialWitness::new(); + circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input)?; + + // Build the circuit + let data = builder.build::(); + + // Prove the inner-circuit with the assigned witness + let inner_proof = data.prove(pw)?; + + // dummy proofs + let proofs: Vec> = (0..k).map(|i| inner_proof.clone()).collect(); + + let mut tree = TreeRecursion::::build(data.common.clone()).unwrap(); + + let tree_proof = tree.prove_tree(&proofs, &data.verifier_only).unwrap(); + + let inner_pi: Vec> = proofs.iter().map(|p| p.public_inputs.clone()).collect(); + + assert!(tree.verify_proof_and_public_input(tree_proof,inner_pi.clone(),&data.verifier_data(), false).is_ok()); + + Ok(()) +} diff --git a/workflow/src/bin/prove.rs b/workflow/src/bin/prove.rs index 66ed23a..debac54 100644 --- a/workflow/src/bin/prove.rs +++ b/workflow/src/bin/prove.rs @@ -26,7 +26,7 @@ fn main() -> Result<()> { // Create a PartialWitness and assign let mut pw = PartialWitness::new(); - circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input); + circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input)?; // Build the circuit let build_time = Instant::now();