diff --git a/workflow/Cargo.toml b/workflow/Cargo.toml index 90cf0b7..787fc09 100644 --- a/workflow/Cargo.toml +++ b/workflow/Cargo.toml @@ -68,4 +68,8 @@ harness = false [[bench]] name = "simple_tree_recursion" +harness = false + +[[bench]] +name = "hybrid_recursion" harness = false \ No newline at end of file diff --git a/workflow/benches/hybrid_recursion.rs b/workflow/benches/hybrid_recursion.rs new file mode 100644 index 0000000..5fcd908 --- /dev/null +++ b/workflow/benches/hybrid_recursion.rs @@ -0,0 +1,91 @@ +use criterion::{Criterion, criterion_group, criterion_main}; +use plonky2::iop::witness::PartialWitness; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use plonky2::plonk::circuit_data::{CircuitConfig}; +use plonky2::plonk::config::GenericConfig; +use plonky2::plonk::proof::ProofWithPublicInputs; +use codex_plonky2_circuits::circuits::sample_cells::{SampleCircuit}; +use codex_plonky2_circuits::recursion::circuits::leaf_circuit::LeafCircuit; +use codex_plonky2_circuits::recursion::circuits::sampling_inner_circuit::SamplingRecursion; +use codex_plonky2_circuits::recursion::hybrid::tree_circuit::HybridTreeRecursion; +use proof_input::params::{C, D, F,HF}; +use proof_input::gen_input::gen_testing_circuit_input; +use proof_input::params::Params; + +/// Benchmark for building, proving, and verifying the Plonky2 tree recursion circuit. +fn bench_hybrid_recursion(c: &mut Criterion) -> anyhow::Result<()>{ + + let mut group = c.benchmark_group(format!("Tree Recursion - Approach 2 Benchmark for N={}",K)); + + //------------ sampling inner circuit ---------------------- + // Circuit that does the sampling - default input + let config = CircuitConfig::standard_recursion_config(); + let mut sampling_builder = CircuitBuilder::::new(config); + let mut params = Params::default(); + let one_circ_input = gen_testing_circuit_input::(¶ms.input_params); + let samp_circ = SampleCircuit::::new(params.circuit_params); + let inner_tar = samp_circ.sample_slot_circuit_with_public_input(&mut sampling_builder)?; + // get generate a sampling proof + let mut pw = PartialWitness::::new(); + samp_circ.sample_slot_assign_witness(&mut pw,&inner_tar,&one_circ_input); + let inner_data = sampling_builder.build::(); + let inner_proof = inner_data.prove(pw.clone())?; + + // ------------------- leaf -------------------- + let inner_circ = SamplingRecursion::::new(Params::default().circuit_params); + let leaf_circuit = LeafCircuit::::new(inner_circ); + + + // ------------- Node/tree circuit ------------------ + // node circuit that verifies leafs or itself + + let mut tree = HybridTreeRecursion::::new(leaf_circuit); + + // prepare input + let input_proofs: Vec> = (0..K) + .map(|_| { + inner_proof.clone() + }) + .collect::>(); + + // Building phase + group.bench_function("prove tree", |b| { + b.iter(|| { + let _ = tree.prove_tree::(&input_proofs, inner_data.verifier_data()); + + }) + }); + + let (tree_root_proof, verifier_data) = tree.prove_tree::(&input_proofs, inner_data.verifier_data())?; + + println!("tree circuit - num of public input = {}", tree_root_proof.public_inputs.len()); + println!("Proof size: {} bytes", tree_root_proof.to_bytes().len()); + + // Verifying Phase + group.bench_function("verify tree circuit", |b| { + b.iter(|| { + verifier_data.verify(tree_root_proof.clone()).expect("verify fail"); + }) + }); + + + group.finish(); + Ok(()) +} + +fn bench_tree_recursion_approach2(c: &mut Criterion){ + const N: usize = 2; // number of child nodes - binary here + const M: usize = 64; // number of proofs aggregated in leaves + const K: usize = 128; // number of proofs to be aggregated in the tree + bench_hybrid_recursion::(c); + bench_hybrid_recursion::(c); + // bench_hybrid_recursion::(c); +} + +/// Criterion benchmark group +criterion_group!{ + name = recursion; + config = Criterion::default().sample_size(10); + targets = bench_tree_recursion_approach2 +} +criterion_main!(recursion); diff --git a/workflow/benches/simple_recursion.rs b/workflow/benches/simple_recursion.rs index b6389a6..4a28f6a 100644 --- a/workflow/benches/simple_recursion.rs +++ b/workflow/benches/simple_recursion.rs @@ -21,8 +21,6 @@ fn bench_simple_recursion(c: &mut Criterion) -> Result<()> // params let mut circ_params = Params::default().circuit_params; circ_params.n_samples = n_samples; - // number of inner proofs: - // const N_INNER: usize = 16; let (data, pw) = build_circuit(n_samples, 3)?; let proof = prove_circuit(&data, &pw)?; diff --git a/workflow/benches/simple_recursion_hashed_pi.rs b/workflow/benches/simple_recursion_hashed_pi.rs index 9f3da82..d1715fe 100644 --- a/workflow/benches/simple_recursion_hashed_pi.rs +++ b/workflow/benches/simple_recursion_hashed_pi.rs @@ -19,8 +19,6 @@ fn bench_recursion(c: &mut Criterion) -> Result<()>{ // params let mut circ_params = Params::default().circuit_params; circ_params.n_samples = n_samples; - // number of inner proofs: - // const N_INNER: usize = 16; let (data, pw) = build_circuit(n_samples, 3)?; let proof = prove_circuit(&data, &pw)?; diff --git a/workflow/benches/simple_tree_recursion.rs b/workflow/benches/simple_tree_recursion.rs index 6014ac3..193cd39 100644 --- a/workflow/benches/simple_tree_recursion.rs +++ b/workflow/benches/simple_tree_recursion.rs @@ -16,9 +16,6 @@ fn bench_tree_recursion(c: &mut Criterion) -> anyhow::Resul // params let mut circ_params = Params::default().circuit_params; circ_params.n_samples = n_samples; - // number of inner proofs: - // const N_INNER: usize = 4; - // let mut data: Option> = None; let (data, pw) = build_circuit(n_samples, 3)?; let proof = prove_circuit(&data, &pw)?; diff --git a/workflow/benches/tree_recursion1.rs b/workflow/benches/tree_recursion1.rs index 0f1255a..efa6a6a 100644 --- a/workflow/benches/tree_recursion1.rs +++ b/workflow/benches/tree_recursion1.rs @@ -81,12 +81,6 @@ fn bench_node_recursion(c: &mut Criterion) -> Re fn bench_tree_recursion(c: &mut Criterion) -> Result<()>{ let mut group = c.benchmark_group(format!("bench tree recursion - approach 1 for N={}",TOTAL_INPUT)); - // const M: usize = 1; - // const N: usize = 2; - // const DEPTH: usize = 3; - - // const TOTAL_INPUT: usize = T; - // number of samples in each proof let n_samples = 5; // params @@ -140,7 +134,6 @@ fn bench_tree_recursion_approach1(c: &mut Criterion){ const M: usize = 1; const N: usize = 2; bench_node_recursion::(c); - // bench_tree_recursion(c); } fn bench_multiple_params(c: &mut Criterion){ diff --git a/workflow/benches/tree_recursion2.rs b/workflow/benches/tree_recursion2.rs index 1b04a24..52c6738 100644 --- a/workflow/benches/tree_recursion2.rs +++ b/workflow/benches/tree_recursion2.rs @@ -5,7 +5,8 @@ use plonky2::plonk::circuit_data::{CircuitConfig}; use plonky2::plonk::config::GenericConfig; use plonky2::plonk::proof::ProofWithPublicInputs; use codex_plonky2_circuits::circuits::sample_cells::{SampleCircuit}; -use codex_plonky2_circuits::recursion::tree2::leaf_circuit::{LeafCircuit, LeafInput}; +use codex_plonky2_circuits::circuits::utils::vec_to_array; +use codex_plonky2_circuits::recursion::circuits::leaf_circuit::{LeafCircuit, LeafInput}; use codex_plonky2_circuits::recursion::circuits::sampling_inner_circuit::SamplingRecursion; use codex_plonky2_circuits::recursion::tree2::{tree_circuit::TreeRecursion}; use proof_input::params::{C, D, F,HF}; @@ -14,7 +15,7 @@ use proof_input::params::Params; /// Benchmark for building, proving, and verifying the Plonky2 tree recursion circuit. -fn bench_tree_recursion(c: &mut Criterion) -> anyhow::Result<()>{ +fn bench_leaf(c: &mut Criterion) -> anyhow::Result<()>{ let mut group = c.benchmark_group(format!("Tree Recursion - Approach 2 Benchmark for N={}",K)); @@ -55,10 +56,13 @@ fn bench_tree_recursion(c: &mut Criterion) -> an // ------------------- leaf -------------------- // leaf circuit that verifies the sampling proof let inner_circ = SamplingRecursion::::new(Params::default().circuit_params); - let leaf_circuit = LeafCircuit::::new(inner_circ); + let leaf_circuit = LeafCircuit::::new(inner_circ); - let leaf_in = LeafInput{ - inner_proof, + let leafs: Vec> = (0..M).map(|i| inner_proof.clone()).collect::>(); + let leafs_arr = vec_to_array::>(leafs)?; + + let leaf_in = LeafInput::{ + inner_proof: leafs_arr, verifier_data: inner_data.verifier_data(), }; let config = CircuitConfig::standard_recursion_config(); @@ -90,56 +94,13 @@ fn bench_tree_recursion(c: &mut Criterion) -> an println!("leaf circuit - Circuit size (degree bits): {:?}", leaf_circ_data.common.degree_bits() ); println!("leaf proof - num of public input = {}", leaf_proof.public_inputs.len()); - // ------------- Node/tree circuit ------------------ - // node circuit that verifies leafs or itself - - let mut tree = TreeRecursion::::build::<_,HF>(leaf_circuit.clone())?; - - // Building phase - group.bench_function("build tree circuit", |b| { - b.iter(|| { - let _tree = TreeRecursion::::build::<_,HF>(leaf_circuit.clone()); - }) - }); - - - let leaf_proofs: Vec> = (0..K) - .map(|_| { - leaf_proof.clone() - }) - .collect::>(); - - let tree_root_proof = tree.prove_tree(leaf_proofs.clone()).unwrap(); - - // Proving Phase - group.bench_function("prove tree circuit", |b| { - b.iter(|| { - let _tree_root_proof = tree.prove_tree(leaf_proofs.clone()); - }) - }); - - println!("tree circuit - Circuit size (degree bits): {:?}", tree.node.node_data.node_circuit_data.common.degree_bits()); - println!("tree circuit - num of public input = {}", tree_root_proof.public_inputs.len()); - - assert!( - tree.verify_proof(tree_root_proof.clone(), N==K).is_ok(), - "proof verification failed" - ); - - // Verifying Phase - group.bench_function("verify tree circuit", |b| { - b.iter(|| { - tree.verify_proof(tree_root_proof.clone(), N==K).expect("verify fail"); - }) - }); - group.finish(); Ok(()) } /// Benchmark for building, proving, and verifying the Plonky2 tree recursion circuit. -fn bench_tree_recursion_node_only(c: &mut Criterion) -> anyhow::Result<()>{ +fn bench_tree_recursion(c: &mut Criterion) -> anyhow::Result<()>{ let mut group = c.benchmark_group(format!("Tree Recursion - Approach 2 Benchmark for N={}",K)); @@ -160,10 +121,13 @@ fn bench_tree_recursion_node_only(c: &mut Criter // ------------------- leaf -------------------- // leaf circuit that verifies the sampling proof let inner_circ = SamplingRecursion::::new(Params::default().circuit_params); - let leaf_circuit = LeafCircuit::::new(inner_circ); + let leaf_circuit = LeafCircuit::::new(inner_circ); + + let leafs: Vec> = (0..M).map(|i| inner_proof.clone()).collect::>(); + let leafs_arr = vec_to_array::>(leafs)?; - let leaf_in = LeafInput{ - inner_proof, + let leaf_in = LeafInput::{ + inner_proof: leafs_arr, verifier_data: inner_data.verifier_data(), }; let config = CircuitConfig::standard_recursion_config(); @@ -179,12 +143,12 @@ fn bench_tree_recursion_node_only(c: &mut Criter // ------------- Node/tree circuit ------------------ // node circuit that verifies leafs or itself - let mut tree = TreeRecursion::::build::<_,HF>(leaf_circuit.clone())?; + let mut tree = TreeRecursion::::build::<_,HF, M>(leaf_circuit.clone())?; // Building phase group.bench_function("build tree circuit", |b| { b.iter(|| { - let _tree = TreeRecursion::::build::<_,HF>(leaf_circuit.clone()); + let _tree = TreeRecursion::::build::<_,HF, M>(leaf_circuit.clone()); }) }); @@ -225,11 +189,12 @@ fn bench_tree_recursion_node_only(c: &mut Criter } fn bench_tree_recursion_approach2(c: &mut Criterion){ + const M:usize = 1; // number of inner proofs in each leaf const N: usize = 2; // number of child nodes const K: usize = 4; // number of proofs to be aggregated in the tree - bench_tree_recursion_node_only::(c); - bench_tree_recursion_node_only::(c); - bench_tree_recursion_node_only::(c); + bench_tree_recursion::(c); + // bench_tree_recursion::(c); + // bench_leaf::<2,N,8>(c); } /// Criterion benchmark group