Skip to content

Commit

Permalink
Feat: benches solvency circuit (#81)
Browse files Browse the repository at this point in the history
* fix: modify `init` api of MerkleSumTree and Solvency circuits to take initialized tree as input #54

* bench: added benches for `MstInclusionCircuit`
  • Loading branch information
enricobottazzi authored Jul 5, 2023
1 parent bfa9e03 commit 56d4917
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 85 deletions.
5 changes: 5 additions & 0 deletions zk_prover/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,10 @@ For Merkle Sum Tree Proof of Inclusion circuit
| ------ | ------ | ---------------- | ------------------ | ------------------ |
| 172.09 ms (+33.3%) | 63.307 ms (+2.496%)| 285.14 ms (-72.45%) | 4.7232 ms (-40.07%) | 2752 (-73.61%) |

For Proof of Solvency circuit

| VK Gen | Pk Gen | Proof Generation | Proof Verification | Proof Size (bytes) |
| ------ | ------ | ---------------- | ------------------ | ------------------ |
| 109.64 ms | 57.848 ms| 1.3231s | 6.9582 ms | 11520 |


139 changes: 129 additions & 10 deletions zk_prover/benches/full_solvency_flow.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
use criterion::{criterion_group, criterion_main, Criterion};
use halo2_proofs::{
halo2curves::bn256::Bn256,
halo2curves::bn256::{Bn256, Fr as Fp},
plonk::{keygen_pk, keygen_vk},
poly::kzg::commitment::ParamsKZG,
};
use snark_verifier_sdk::CircuitExt;
use summa_solvency::{
circuits::merkle_sum_tree::MstInclusionCircuit,
circuits::utils::{full_prover, full_verifier, generate_setup_params},
merkle_sum_tree::MerkleSumTree,
circuits::{
solvency::SolvencyCircuit,
utils::{full_prover, full_verifier, generate_setup_params},
},
merkle_sum_tree::{MerkleSumTree, MOD_BITS},
};

const SAMPLE_SIZE: usize = 10;
const LEVELS: usize = 15;
const N_ASSETS: usize = 2;
const PATH_NAME: &str = "two_assets";
const L: usize = 2 + (N_ASSETS * 2);
const N_BYTES: usize = MOD_BITS / 8;

fn build_mstree(_c: &mut Criterion) {
let mut criterion = Criterion::default().sample_size(SAMPLE_SIZE);
Expand Down Expand Up @@ -45,7 +49,7 @@ fn verification_key_gen_mst_inclusion_circuit(_c: &mut Criterion) {
let empty_circuit = MstInclusionCircuit::<LEVELS, L, N_ASSETS>::init_empty();

let bench_name = format!(
"gen verification key for 2 power of {} entries with {} assets",
"gen verification key for 2 power of {} entries with {} assets mst inclusion circuit",
LEVELS, N_ASSETS
);
criterion.bench_function(&bench_name, |b| {
Expand All @@ -64,7 +68,7 @@ fn proving_key_gen_mst_inclusion_circuit(_c: &mut Criterion) {

let vk = keygen_vk(&params, &empty_circuit).expect("vk generation should not fail");
let bench_name = format!(
"gen proving key for 2 power of {} entries with {} assets",
"gen proving key for 2 power of {} entries with {} assets mst inclusion circuit",
LEVELS, N_ASSETS
);
criterion.bench_function(&bench_name, |b| {
Expand All @@ -89,11 +93,13 @@ fn generate_zk_proof_mst_inclusion_circuit(_c: &mut Criterion) {
PATH_NAME, PATH_NAME, LEVELS
);

let merkle_sum_tree = MerkleSumTree::<N_ASSETS>::new(&csv_file).unwrap();

// Only now we can instantiate the circuit with the actual inputs
let circuit = MstInclusionCircuit::<LEVELS, L, N_ASSETS>::init(&csv_file, 0);
let circuit = MstInclusionCircuit::<LEVELS, L, N_ASSETS>::init(merkle_sum_tree, 0);

let bench_name = format!(
"generate zk proof - tree of 2 power of {} entries with {} assets",
"generate zk proof - tree of 2 power of {} entries with {} assets mst inclusion circuit",
LEVELS, N_ASSETS
);
criterion.bench_function(&bench_name, |b| {
Expand All @@ -118,15 +124,124 @@ fn verify_zk_proof_mst_inclusion_circuit(_c: &mut Criterion) {
PATH_NAME, PATH_NAME, LEVELS
);

let merkle_sum_tree = MerkleSumTree::<N_ASSETS>::new(&csv_file).unwrap();

// Only now we can instantiate the circuit with the actual inputs
let circuit = MstInclusionCircuit::<LEVELS, L, N_ASSETS>::init(merkle_sum_tree, 0);

let proof = full_prover(&params, &pk, circuit.clone(), circuit.instances());

println!("proof size in bytes: {}", proof.len());

let bench_name = format!(
"verify zk proof - tree of 2 power of {} entries with {} assets mst inclusion circuit",
LEVELS, N_ASSETS
);
criterion.bench_function(&bench_name, |b| {
b.iter(|| {
full_verifier(&params, &vk, proof.clone(), circuit.instances());
})
});
}

fn verification_key_gen_solvency_circuit(_c: &mut Criterion) {
let mut criterion = Criterion::default().sample_size(SAMPLE_SIZE);

let params: ParamsKZG<Bn256> = generate_setup_params(12);

let empty_circuit = SolvencyCircuit::<L, N_ASSETS, N_BYTES>::init_empty();

let bench_name = format!(
"gen verification key for 2 power of {} entries with {} assets solvency circuit",
LEVELS, N_ASSETS
);
criterion.bench_function(&bench_name, |b| {
b.iter(|| {
keygen_vk(&params, &empty_circuit).expect("vk generation should not fail");
})
});
}

fn proving_key_gen_solvency_circuit(_c: &mut Criterion) {
let mut criterion = Criterion::default().sample_size(SAMPLE_SIZE);

let params: ParamsKZG<Bn256> = generate_setup_params(12);

let empty_circuit = SolvencyCircuit::<L, N_ASSETS, N_BYTES>::init_empty();

let vk = keygen_vk(&params, &empty_circuit).expect("vk generation should not fail");
let bench_name = format!(
"gen proving key for 2 power of {} entries with {} assets solvency circuit",
LEVELS, N_ASSETS
);
criterion.bench_function(&bench_name, |b| {
b.iter(|| {
keygen_pk(&params, vk.clone(), &empty_circuit).expect("pk generation should not fail");
})
});
}

fn generate_zk_proof_solvency_circuit(_c: &mut Criterion) {
let mut criterion = Criterion::default().sample_size(SAMPLE_SIZE);

let params: ParamsKZG<Bn256> = generate_setup_params(12);

let empty_circuit = SolvencyCircuit::<L, N_ASSETS, N_BYTES>::init_empty();

let vk = keygen_vk(&params, &empty_circuit).expect("vk generation should not fail");
let pk = keygen_pk(&params, vk, &empty_circuit).expect("pk generation should not fail");

let csv_file = format!(
"benches/csv/{}/{}_entry_2_{}.csv",
PATH_NAME, PATH_NAME, LEVELS
);

let merkle_sum_tree = MerkleSumTree::<N_ASSETS>::new(&csv_file).unwrap();

let assets_sum = merkle_sum_tree.root().balances.map(|x| x + Fp::from(1));

// Only now we can instantiate the circuit with the actual inputs
let circuit = SolvencyCircuit::<L, N_ASSETS, N_BYTES>::init(merkle_sum_tree, assets_sum);

let bench_name = format!(
"generate zk proof - tree of 2 power of {} entries with {} assets solvency circuit",
LEVELS, N_ASSETS
);
criterion.bench_function(&bench_name, |b| {
b.iter(|| {
full_prover(&params, &pk, circuit.clone(), circuit.instances());
})
});
}

fn verify_zk_proof_solvency_circuit(_c: &mut Criterion) {
let mut criterion = Criterion::default().sample_size(SAMPLE_SIZE);

let params: ParamsKZG<Bn256> = generate_setup_params(12);

let empty_circuit = SolvencyCircuit::<L, N_ASSETS, N_BYTES>::init_empty();

let vk = keygen_vk(&params, &empty_circuit).expect("vk generation should not fail");
let pk = keygen_pk(&params, vk.clone(), &empty_circuit).expect("pk generation should not fail");

let csv_file = format!(
"benches/csv/{}/{}_entry_2_{}.csv",
PATH_NAME, PATH_NAME, LEVELS
);

let merkle_sum_tree = MerkleSumTree::<N_ASSETS>::new(&csv_file).unwrap();

let assets_sum = merkle_sum_tree.root().balances.map(|x| x + Fp::from(1));

// Only now we can instantiate the circuit with the actual inputs
let circuit = MstInclusionCircuit::<LEVELS, L, N_ASSETS>::init(&csv_file, 0);
let circuit = SolvencyCircuit::<L, N_ASSETS, N_BYTES>::init(merkle_sum_tree, assets_sum);

let proof = full_prover(&params, &pk, circuit.clone(), circuit.instances());

println!("proof size in bytes: {}", proof.len());

let bench_name = format!(
"verify zk proof - tree of 2 power of {} entries with {} assets",
"verify zk proof - tree of 2 power of {} entries with {} assets solvency circuit",
LEVELS, N_ASSETS
);
criterion.bench_function(&bench_name, |b| {
Expand All @@ -142,6 +257,10 @@ criterion_group!(
verification_key_gen_mst_inclusion_circuit,
proving_key_gen_mst_inclusion_circuit,
generate_zk_proof_mst_inclusion_circuit,
verify_zk_proof_mst_inclusion_circuit
verify_zk_proof_mst_inclusion_circuit,
verification_key_gen_solvency_circuit,
proving_key_gen_solvency_circuit,
generate_zk_proof_solvency_circuit,
verify_zk_proof_solvency_circuit
);
criterion_main!(benches);
Binary file modified zk_prover/prints/mst-inclusion-layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 2 additions & 4 deletions zk_prover/src/circuits/merkle_sum_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,10 @@ impl<const LEVELS: usize, const L: usize, const N_ASSETS: usize>
}
}

/// Initializes the circuit with the data of the merkle sum tree (identified by its path) and the index of the user of which the inclusion is to be verified.
pub fn init(path: &str, user_index: usize) -> Self {
/// Initializes the circuit with the merkle sum tree and the index of the user of which the inclusion is to be verified.
pub fn init(merkle_sum_tree: MerkleSumTree<N_ASSETS>, user_index: usize) -> Self {
assert_eq!((N_ASSETS * 2) + 2, L);

let merkle_sum_tree = MerkleSumTree::new(path).unwrap();

let proof = merkle_sum_tree.generate_proof(user_index).unwrap();

assert_eq!(proof.path_indices.len(), LEVELS);
Expand Down
6 changes: 2 additions & 4 deletions zk_prover/src/circuits/solvency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,10 @@ impl<const L: usize, const N_ASSETS: usize, const N_BYTES: usize>
}
}

/// Initializes the circuit with the data of the merkle sum tree (identified by its path) and the assets sum
pub fn init(path: &str, assets_sum: [Fp; N_ASSETS]) -> Self {
/// Initializes the circuit with the merkle sum tree and the assets sum
pub fn init(merkle_sum_tree: MerkleSumTree<N_ASSETS>, assets_sum: [Fp; N_ASSETS]) -> Self {
assert_eq!((N_ASSETS * 2) + 2, L);

let merkle_sum_tree = MerkleSumTree::<N_ASSETS>::new(path).unwrap();

let (penultimate_node_left, penultimate_node_right) = merkle_sum_tree
.penultimate_level_data()
.expect("Failed to retrieve penultimate level data");
Expand Down
Loading

0 comments on commit 56d4917

Please sign in to comment.