mirror of
https://github.com/logos-storage/proof-aggregation.git
synced 2026-01-02 13:53:13 +00:00
fix and improve the workflow scripts and bench.
This commit is contained in:
parent
950cd6bd0d
commit
5e7d210322
@ -1,13 +1,14 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use plonky2::gates::noop::NoopGate;
|
||||
use plonky2::hash::hash_types::HashOut;
|
||||
use plonky2::iop::witness::{PartialWitness, WitnessWrite};
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::plonk::circuit_data::CircuitConfig;
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use plonky2::plonk::circuit_data::{CircuitConfig, VerifierCircuitData};
|
||||
use codex_plonky2_circuits::circuit_helper::Plonky2Circuit;
|
||||
|
||||
use codex_plonky2_circuits::recursion::uniform::compress::CompressionCircuit;
|
||||
use codex_plonky2_circuits::recursion::uniform::compress::{CompressionCircuit, CompressionInput};
|
||||
use codex_plonky2_circuits::recursion::uniform::tree::get_hash_of_verifier_data;
|
||||
use proof_input::params::{D, C, F, HF};
|
||||
|
||||
/// Benchmark for building, proving, and verifying the Plonky2 circuit.
|
||||
@ -33,24 +34,23 @@ fn bench_compression_runtime(c: &mut Criterion, circuit_size: usize) -> Result<(
|
||||
|
||||
// 2 virtual hashes (8 field elems) as public input - same as in the recursion tree
|
||||
let mut pi = vec![];
|
||||
for i in 0..2{
|
||||
for _i in 0..2{
|
||||
pi.push(builder.add_virtual_hash_public_input());
|
||||
}
|
||||
|
||||
let inner_data = builder.build::<C>();
|
||||
println!("inner circuit size = {:?}", inner_data.common.degree_bits());
|
||||
|
||||
let inner_verifier_data: VerifierCircuitData<F,C,D> = inner_data.verifier_data();
|
||||
// prove with dummy public input
|
||||
let mut pw = PartialWitness::<F>::new();
|
||||
pw.set_hash_target(pi[0], HashOut::<F>::ZERO)?;
|
||||
pw.set_hash_target(pi[1], HashOut::<F>::ZERO)?;
|
||||
pw.set_hash_target(pi[1], get_hash_of_verifier_data::<F,D,C,HF>(&inner_verifier_data))?;
|
||||
let inner_proof = inner_data.prove(pw)?;
|
||||
|
||||
// Compression circuit
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
let compression_circ = CompressionCircuit::<F,D,C,HF>::new(inner_data.common.clone());
|
||||
let compression_targets = compression_circ.build(&mut builder)?;
|
||||
let compression_circ = CompressionCircuit::<F,D,C,HF>::new(inner_data.common.clone(), inner_data.verifier_only.clone());
|
||||
let (compression_targets, compression_circ_data) = compression_circ.build_with_standard_config()?;
|
||||
|
||||
// Benchmark Group
|
||||
let mut group = c.benchmark_group(format!("Compression Circuit Benchmark for inner-proof size = {}", circuit_size));
|
||||
@ -58,33 +58,30 @@ fn bench_compression_runtime(c: &mut Criterion, circuit_size: usize) -> Result<(
|
||||
// Benchmark the Circuit Building Phase
|
||||
group.bench_function("Build Circuit", |b| {
|
||||
b.iter(|| {
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut local_builder = CircuitBuilder::<F, D>::new(config);
|
||||
let _compression_targets = compression_circ.build(&mut local_builder);
|
||||
let _data = local_builder.build::<C>();
|
||||
let _compression_targets = compression_circ.build_with_standard_config();
|
||||
})
|
||||
});
|
||||
|
||||
// Build the circuit once for proving and verifying benchmarks
|
||||
let compression_circ_data = builder.build::<C>();
|
||||
println!("compress circuit size = {:?}", compression_circ_data.common.degree_bits());
|
||||
|
||||
let mut pw = PartialWitness::<F>::new();
|
||||
compression_circ.assign_targets(&mut pw, &compression_targets, inner_proof, &inner_data.verifier_only)?;
|
||||
let compression_input = CompressionInput{
|
||||
inner_proof,
|
||||
};
|
||||
|
||||
let verifier_data: VerifierCircuitData<F,C,D> = compression_circ_data.verifier_data();
|
||||
let prover_data = compression_circ_data.prover_data();
|
||||
|
||||
group.bench_function("Prove Circuit", |b| {
|
||||
b.iter_batched(
|
||||
|| pw.clone(),
|
||||
|local_pw| compression_circ_data.prove(local_pw).expect("Failed to prove circuit"),
|
||||
BatchSize::SmallInput,
|
||||
)
|
||||
b.iter( ||
|
||||
{
|
||||
let _ = compression_circ.prove(&compression_targets, &compression_input, &prover_data);
|
||||
})
|
||||
});
|
||||
|
||||
let proof = compression_circ_data.prove(pw)?;
|
||||
let proof = compression_circ.prove(&compression_targets, &compression_input, &prover_data)?;
|
||||
println!("Proof size: {} bytes", proof.to_bytes().len());
|
||||
|
||||
let verifier_data = compression_circ_data.verifier_data();
|
||||
|
||||
// Benchmark the Verifying Phase
|
||||
group.bench_function("Verify Proof", |b| {
|
||||
b.iter(|| {
|
||||
@ -96,10 +93,9 @@ fn bench_compression_runtime(c: &mut Criterion, circuit_size: usize) -> Result<(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn bench_compression(c: &mut Criterion) -> Result<()>{
|
||||
bench_compression_runtime(c, 13)?;
|
||||
bench_compression_runtime(c, 14)?;
|
||||
Ok(())
|
||||
fn bench_compression(c: &mut Criterion){
|
||||
bench_compression_runtime(c, 13).expect("bench failed");
|
||||
bench_compression_runtime(c, 14).expect("bench failed");
|
||||
}
|
||||
|
||||
/// Criterion benchmark group
|
||||
|
||||
@ -2,7 +2,6 @@ use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use anyhow::Result;
|
||||
|
||||
use proof_input::merkle_tree::merkle_safe::{MerkleTree};
|
||||
use plonky2::field::types::Field;
|
||||
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData};
|
||||
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher, PoseidonGoldilocksConfig};
|
||||
use plonky2::iop::witness::{PartialWitness, WitnessWrite};
|
||||
@ -28,13 +27,13 @@ fn prepare_data<
|
||||
const D: usize,
|
||||
C: GenericConfig<D, F = F>,
|
||||
H: Hasher<F> + AlgebraicHasher<F>,
|
||||
>(N: usize, max_depth: usize) -> Result<(
|
||||
>(n: usize, max_depth: usize) -> Result<(
|
||||
Vec<MerkleTreeCircuitInput<F, D>>,
|
||||
HashOut<F>,
|
||||
)> {
|
||||
// Generate random leaf data
|
||||
let nleaves = 16; // Number of leaves
|
||||
let data = (0..nleaves)
|
||||
let n_leaves = 16; // Number of leaves
|
||||
let data = (0..n_leaves)
|
||||
.map(|i| F::from_canonical_u64(i))
|
||||
.collect::<Vec<_>>();
|
||||
// Hash the data to obtain leaf hashes
|
||||
@ -53,7 +52,7 @@ fn prepare_data<
|
||||
let tree = MerkleTree::<F, D>::new(&leaves, zero_hash)?;
|
||||
|
||||
// Select N leaf indices to prove
|
||||
let leaf_indices: Vec<usize> = (0..N).collect();
|
||||
let leaf_indices: Vec<usize> = (0..n).collect();
|
||||
|
||||
// Get the Merkle proofs for the selected leaves
|
||||
let proofs: Vec<_> = leaf_indices
|
||||
@ -63,9 +62,9 @@ fn prepare_data<
|
||||
|
||||
let mut circ_inputs = vec![];
|
||||
|
||||
for i in 0..N{
|
||||
for i in 0..n {
|
||||
let path_bits = usize_to_bits_le(leaf_indices[i], max_depth);
|
||||
let last_index = (nleaves - 1) as usize;
|
||||
let last_index = (n_leaves - 1) as usize;
|
||||
let last_bits = usize_to_bits_le(last_index, max_depth);
|
||||
let mask_bits = usize_to_bits_le(last_index, max_depth+1);
|
||||
|
||||
@ -118,7 +117,7 @@ fn build_circuit<
|
||||
|
||||
//assign input
|
||||
assign_witness(&mut pw, &mut targets, circ_inputs[i].clone())?;
|
||||
pw.set_hash_target(expected_root_target, expected_root);
|
||||
pw.set_hash_target(expected_root_target, expected_root)?;
|
||||
}
|
||||
|
||||
// Build the circuit
|
||||
@ -136,9 +135,9 @@ fn merkle_proof_benchmark<
|
||||
let mut group = c.benchmark_group("Merkle Proof Benchmark");
|
||||
|
||||
// Prepare the data that will be used in all steps
|
||||
let N = 5; // Number of leaves to prove
|
||||
let n = 5; // Number of leaves to prove
|
||||
let max_depth = 4;
|
||||
let (circ_input, expected_root) = prepare_data::<F, D,C,H>(N, max_depth).unwrap();
|
||||
let (circ_input, expected_root) = prepare_data::<F, D,C,H>(n, max_depth).unwrap();
|
||||
|
||||
// Benchmark the circuit building
|
||||
group.bench_function("Merkle Proof Build", |b| {
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
use anyhow::Result;
|
||||
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;
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use plonky2::plonk::circuit_data::{CircuitData, VerifierCircuitData};
|
||||
use codex_plonky2_circuits::circuit_helper::Plonky2Circuit;
|
||||
|
||||
use codex_plonky2_circuits::circuits::sample_cells::SampleCircuit;
|
||||
use proof_input::gen_input::gen_testing_circuit_input;
|
||||
@ -12,14 +10,12 @@ use proof_input::params::{D, C, F, HF, Params};
|
||||
/// Benchmark for building, proving, and verifying the Plonky2 circuit.
|
||||
fn bench_prove_verify<const N: usize>(c: &mut Criterion) -> Result<()>{
|
||||
|
||||
let n_samples = N;
|
||||
// get default parameters
|
||||
let params = Params::default();
|
||||
let mut test_params = params.input_params;
|
||||
test_params.n_samples = n_samples;
|
||||
let mut params = Params::default();
|
||||
params.set_n_samples(N);
|
||||
|
||||
let mut circuit_params = params.circuit_params;
|
||||
circuit_params.n_samples = n_samples;
|
||||
let test_params = params.input_params;
|
||||
let circuit_params = params.circuit_params;
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
println!("Parallel feature is ENABLED");
|
||||
@ -27,62 +23,33 @@ fn bench_prove_verify<const N: usize>(c: &mut Criterion) -> Result<()>{
|
||||
// gen the circuit input
|
||||
let circ_input = gen_testing_circuit_input::<F,D>(&test_params);
|
||||
|
||||
// Create the circuit configuration
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
// Initialize the SampleCircuit with the parameters
|
||||
let circ = SampleCircuit::<F,D,HF>::new(circuit_params.clone());
|
||||
let targets = circ.sample_slot_circuit_with_public_input(&mut builder)?;
|
||||
|
||||
// Create a PartialWitness and assign the circuit input
|
||||
let mut pw = PartialWitness::new();
|
||||
circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input.clone());
|
||||
let (targets, data) = circ.build_with_standard_config()?;
|
||||
let verifier_data:VerifierCircuitData<F,C,D> = data.verifier_data();
|
||||
let prover_data = data.prover_data();
|
||||
|
||||
// Benchmark Group: Separate benchmarks for building, proving, and verifying
|
||||
let mut group = c.benchmark_group(format!("Sampling Circuit Benchmark for N= {}", N));
|
||||
let mut group = c.benchmark_group(format!("Sampling Circuit Benchmark for N= {} Samples", N));
|
||||
|
||||
// Benchmark the Circuit Building Phase
|
||||
group.bench_function("Build Circuit", |b| {
|
||||
b.iter(|| {
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut local_builder = CircuitBuilder::<F, D>::new(config);
|
||||
let _targets = circ.sample_slot_circuit_with_public_input(&mut local_builder);
|
||||
let _data = local_builder.build::<C>();
|
||||
let _: (_, CircuitData<F, C, D>) = circ.build_with_standard_config().unwrap();
|
||||
})
|
||||
});
|
||||
|
||||
// Build the circuit once for proving and verifying benchmarks
|
||||
let build_start = std::time::Instant::now();
|
||||
let data = builder.build::<C>();
|
||||
let build_duration = build_start.elapsed();
|
||||
println!("Build time: {:?}", build_duration);
|
||||
println!("Circuit size (degree bits): {:?}", data.common.degree_bits());
|
||||
|
||||
// let num_constr: usize = data.common
|
||||
// .gates
|
||||
// .iter()
|
||||
// .map(|gate| gate.0.num_constraints())
|
||||
// .sum();
|
||||
//
|
||||
// println!("Number of constraints: {}", num_constr);
|
||||
// println!("Number of gates used: {}", data.common.gates.len());
|
||||
// circuit size
|
||||
println!("Circuit size (degree bits): {:?}", prover_data.common.degree_bits());
|
||||
|
||||
group.bench_function("Prove Circuit", |b| {
|
||||
b.iter_batched(
|
||||
|| pw.clone(),
|
||||
|local_pw| data.prove(local_pw).expect("Failed to prove circuit"),
|
||||
BatchSize::SmallInput,
|
||||
)
|
||||
b.iter(|| {
|
||||
let _ = circ.prove(&targets, &circ_input, &prover_data);
|
||||
})
|
||||
});
|
||||
|
||||
// Generate the proof once for verification benchmarking
|
||||
let prove_start = std::time::Instant::now();
|
||||
let proof_with_pis = data.prove(pw.clone()).expect("Failed to prove circuit");
|
||||
let prove_duration = prove_start.elapsed();
|
||||
println!("prove time: {:?}", prove_duration);
|
||||
let verifier_data = data.verifier_data();
|
||||
|
||||
let proof_with_pis = circ.prove(&targets, &circ_input, &prover_data)?;
|
||||
println!("Proof size: {} bytes", proof_with_pis.to_bytes().len());
|
||||
|
||||
// Benchmark the Verifying Phase
|
||||
@ -96,11 +63,10 @@ fn bench_prove_verify<const N: usize>(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(())
|
||||
fn bench_sampling(c: &mut Criterion){
|
||||
bench_prove_verify::<10>(c).expect("bench failed");
|
||||
bench_prove_verify::<50>(c).expect("bench failed");
|
||||
bench_prove_verify::<100>(c).expect("bench failed");
|
||||
}
|
||||
|
||||
/// Criterion benchmark group
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
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};
|
||||
use proof_input::params::{D, C, F, HF};
|
||||
use proof_input::serialization::file_paths::{PROOF_JSON, TREE_PROOF_JSON, VERIFIER_CIRC_DATA_JSON};
|
||||
use proof_input::serialization::json::{export_tree_proof_with_pi, import_proof_with_pi, import_verifier_circuit_data};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// load the parameters from environment variables
|
||||
let params = Params::from_env()?;
|
||||
const N: usize = 1;
|
||||
const M: usize = 2;
|
||||
|
||||
@ -26,31 +21,24 @@ fn main() -> Result<()> {
|
||||
4
|
||||
};
|
||||
|
||||
// generate circuit input with given parameters
|
||||
let circ_input = gen_testing_circuit_input::<F,D>(¶ms.input_params);
|
||||
// Read the proof
|
||||
let proof_with_pi = import_proof_with_pi::<F,C,D>()?;
|
||||
println!("Proof with public input imported from: {}", PROOF_JSON);
|
||||
|
||||
// create the circuit
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
let circ = SampleCircuit::<F,D,HF>::new(params.circuit_params);
|
||||
let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder)?;
|
||||
// read the circuit data
|
||||
let verifier_data = import_verifier_circuit_data::<F,C,D>()?;
|
||||
println!("Verifier circuit data imported from: {}", VERIFIER_CIRC_DATA_JSON);
|
||||
|
||||
// create a PartialWitness and assign
|
||||
let mut pw = PartialWitness::new();
|
||||
circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input)?;
|
||||
// duplicate the proof to get k proofs
|
||||
// this is just for testing - in real scenario we would need to load k proofs
|
||||
let proofs: Vec<ProofWithPublicInputs<F, C, D>> = (0..k).map(|_i| proof_with_pi.clone()).collect();
|
||||
|
||||
// Build the circuit
|
||||
let data = builder.build::<C>();
|
||||
|
||||
// Prove the inner-circuit with the assigned witness
|
||||
let inner_proof = data.prove(pw)?;
|
||||
|
||||
// dummy proofs
|
||||
let proofs: Vec<ProofWithPublicInputs<F, C, D>> = (0..k).map(|i| inner_proof.clone()).collect();
|
||||
|
||||
let mut tree = TreeRecursion::<F,D,C,HF, N, M>::build_with_standard_config(data.common.clone(), data.verifier_only.clone()).unwrap();
|
||||
let mut tree = TreeRecursion::<F,D,C,HF, N, M>::build_with_standard_config(verifier_data.common.clone(), verifier_data.verifier_only.clone()).unwrap();
|
||||
|
||||
let tree_proof = tree.prove_tree(&proofs).unwrap();
|
||||
//export the proof to json file
|
||||
export_tree_proof_with_pi(&tree_proof)?;
|
||||
println!("Tree proof written to: {}", TREE_PROOF_JSON);
|
||||
|
||||
let inner_pi: Vec<Vec<F>> = proofs.iter().map(|p| p.public_inputs.clone()).collect();
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use std::time::Instant;
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use anyhow::Result;
|
||||
use proof_input::serialization::circuit_input::export_circ_input_to_json;
|
||||
use proof_input::gen_input::gen_testing_circuit_input;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use anyhow::Result;
|
||||
use std::time::Instant;
|
||||
use codex_plonky2_circuits::circuit_helper::Plonky2Circuit;
|
||||
@ -6,7 +5,7 @@ use proof_input::serialization::circuit_input::import_circ_input_from_json;
|
||||
use codex_plonky2_circuits::circuits::sample_cells::{SampleCircuit, SampleCircuitInput, SampleTargets};
|
||||
use codex_plonky2_circuits::circuits::params::CircuitParams;
|
||||
use proof_input::params::{D, C, F, HF};
|
||||
use proof_input::serialization::file_paths::{CIRC_INPUT_JSON, PROVER_CIRC_DATA_JSON, TARGETS_JSON};
|
||||
use proof_input::serialization::file_paths::{CIRC_INPUT_JSON, PROVER_CIRC_DATA_JSON, TARGETS_JSON, TREE_PROOF_JSON};
|
||||
use proof_input::serialization::json::{export_proof_with_pi, import_prover_circuit_data, import_targets};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
@ -34,6 +33,7 @@ fn main() -> Result<()> {
|
||||
|
||||
//export the proof to json file
|
||||
export_proof_with_pi(&proof_with_pis)?;
|
||||
println!("Tree proof written to: {}", TREE_PROOF_JSON);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
use std::time::Instant;
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use anyhow::Result;
|
||||
use codex_plonky2_circuits::circuits::params::CircuitParams;
|
||||
use proof_input::params::{D, C, F};
|
||||
use proof_input::serialization::file_paths::{PROOF_JSON, VERIFIER_CIRC_DATA_JSON};
|
||||
use proof_input::serialization::json::{import_proof_with_pi, import_verifier_circuit_data};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// Load the parameters from environment variables
|
||||
let circuit_params = CircuitParams::from_env()?;
|
||||
|
||||
// read the circuit data
|
||||
let verifier_data = import_verifier_circuit_data::<F,C,D>()?;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user