feat: benchmarks (#3)
* add benchmark * chore: add complex circuit * feat: enable parallel / asm * bench: use pre-calculated matrices/constraints * chore: bump ethers-rs * chore: fmt * feat: add benches for differently sized circuits (#6) * feat: update bench circuit * feat: add benches for many sizes * fix: adjust bench parameters * fix: remove sym * chore: fmt * fix: point to correct commit of groth16 * fix: update function names to upstream * fix: update function names to upstream Co-authored-by: Kobi Gurkan <kobigurk@gmail.com>
This commit is contained in:
parent
11e6d04f3b
commit
bb0f5429fc
|
@ -1,2 +1 @@
|
|||
/target
|
||||
Cargo.lock
|
||||
|
|
File diff suppressed because it is too large
Load Diff
15
Cargo.toml
15
Cargo.toml
|
@ -12,10 +12,10 @@ num-bigint = { version = "0.4", default-features = false, features = ["rand"] }
|
|||
|
||||
# ZKP Generation
|
||||
ark-ec = { version = "0.3.0", default-features = false, features = ["parallel"] }
|
||||
ark-ff = { version = "0.3.0", default-features = false, features = ["asm", "parallel"] }
|
||||
ark-std = { version = "0.3.0", default-features = false }
|
||||
ark-ff = { version = "0.3.0", default-features = false, features = ["parallel", "asm"] }
|
||||
ark-std = { version = "0.3.0", default-features = false, features = ["parallel"] }
|
||||
ark-bn254 = { version = "0.3.0" }
|
||||
ark-groth16 = { git = "https://github.com/gakonst/groth16", version = "0.3.0", branch = "calculate-matrices", features = ["parallel"] }
|
||||
ark-groth16 = { git = "https://github.com/arkworks-rs/groth16", rev = "765817f", features = ["parallel"] }
|
||||
ark-poly = { version = "^0.3.0", default-features = false, features = ["parallel"] }
|
||||
ark-relations = { version = "0.3.0", default-features = false }
|
||||
ark-serialize = { version = "0.3.0", default-features = false }
|
||||
|
@ -30,9 +30,18 @@ ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features =
|
|||
# error handling
|
||||
thiserror = "1.0.26"
|
||||
color-eyre = "0.5"
|
||||
criterion = "0.3.4"
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal = "0.2.1"
|
||||
tokio = { version = "1.7.1", features = ["macros"] }
|
||||
serde_json = "1.0.64"
|
||||
ethers = { git = "https://github.com/gakonst/ethers-rs", features = ["abigen"] }
|
||||
cfg-if = "1.0"
|
||||
|
||||
[[bench]]
|
||||
name = "groth16"
|
||||
harness = false
|
||||
|
||||
[features]
|
||||
bench-complex-all = []
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
|
||||
use ark_circom::{read_zkey, CircomReduction, WitnessCalculator};
|
||||
use ark_std::rand::thread_rng;
|
||||
|
||||
use ark_bn254::Bn254;
|
||||
use ark_groth16::{create_proof_with_reduction_and_matrices, prepare_verifying_key, verify_proof};
|
||||
|
||||
use std::{collections::HashMap, fs::File};
|
||||
|
||||
fn bench_groth(c: &mut Criterion, num_validators: u32, num_constraints: u32) {
|
||||
let i = num_validators;
|
||||
let j = num_constraints;
|
||||
let path = format!(
|
||||
"./test-vectors/complex-circuit/complex-circuit-{}-{}.zkey",
|
||||
i, j
|
||||
);
|
||||
let mut file = File::open(&path).unwrap();
|
||||
let (params, matrices) = read_zkey(&mut file).unwrap();
|
||||
let num_inputs = matrices.num_instance_variables;
|
||||
let num_constraints = matrices.num_constraints;
|
||||
|
||||
let inputs = {
|
||||
let mut inputs: HashMap<String, Vec<num_bigint::BigInt>> = HashMap::new();
|
||||
let values = inputs.entry("a".to_string()).or_insert_with(Vec::new);
|
||||
values.push(3.into());
|
||||
|
||||
inputs
|
||||
};
|
||||
|
||||
let mut wtns = WitnessCalculator::new(&format!(
|
||||
"./test-vectors/complex-circuit/complex-circuit-{}-{}.wasm",
|
||||
i, j
|
||||
))
|
||||
.unwrap();
|
||||
let full_assignment = wtns
|
||||
.calculate_witness_element::<Bn254, _>(inputs, false)
|
||||
.unwrap();
|
||||
|
||||
let mut rng = thread_rng();
|
||||
use ark_std::UniformRand;
|
||||
let rng = &mut rng;
|
||||
|
||||
let r = ark_bn254::Fr::rand(rng);
|
||||
let s = ark_bn254::Fr::rand(rng);
|
||||
|
||||
let proof = create_proof_with_reduction_and_matrices::<_, CircomReduction>(
|
||||
¶ms,
|
||||
r,
|
||||
s,
|
||||
&matrices,
|
||||
num_inputs,
|
||||
num_constraints,
|
||||
full_assignment.as_slice(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let pvk = prepare_verifying_key(¶ms.vk);
|
||||
let inputs = &full_assignment[1..num_inputs];
|
||||
let verified = verify_proof(&pvk, &proof, inputs).unwrap();
|
||||
|
||||
assert!(verified);
|
||||
|
||||
c.bench_function(&format!("groth proof {} {}", i, j), |b| {
|
||||
b.iter(|| {
|
||||
black_box(
|
||||
create_proof_with_reduction_and_matrices::<_, CircomReduction>(
|
||||
¶ms,
|
||||
r,
|
||||
s,
|
||||
&matrices,
|
||||
num_inputs,
|
||||
num_constraints,
|
||||
full_assignment.as_slice(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "bench-complex-all")] {
|
||||
const MIN_NUM_VARIABLES_POWER: u32 = 3;
|
||||
const MAX_NUM_VARIABLES_POWER: u32 = 5;
|
||||
const MAX_NUM_CONSTRAINTS_POWER: u32 = 5;
|
||||
fn groth_all(c: &mut Criterion) {
|
||||
for i in MIN_NUM_VARIABLES_POWER..=MAX_NUM_VARIABLES_POWER {
|
||||
for j in i..=MAX_NUM_CONSTRAINTS_POWER {
|
||||
let i = 10_u32.pow(i);
|
||||
let j = 10_u32.pow(j);
|
||||
bench_groth(c, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
criterion_group!(benches, groth_all);
|
||||
} else {
|
||||
fn groth(c: &mut Criterion) {
|
||||
bench_groth(c, 10000, 10000);
|
||||
}
|
||||
criterion_group!(benches, groth);
|
||||
}
|
||||
}
|
||||
|
||||
criterion_main!(benches);
|
|
@ -2,6 +2,7 @@
|
|||
//!
|
||||
//! Provides bindings to Circom's R1CS, for Groth16 Proof and Witness generation in Rust.
|
||||
mod witness;
|
||||
pub use witness::WitnessCalculator;
|
||||
|
||||
pub mod circom;
|
||||
pub use circom::{CircomBuilder, CircomCircuit, CircomConfig, CircomReduction};
|
||||
|
|
|
@ -361,7 +361,7 @@ mod tests {
|
|||
use crate::witness::WitnessCalculator;
|
||||
use crate::{circom::CircomReduction, CircomBuilder, CircomConfig};
|
||||
use ark_groth16::{
|
||||
create_proof_with_qap_and_matrices, create_random_proof_with_reduction as prove,
|
||||
create_proof_with_reduction_and_matrices, create_random_proof_with_reduction as prove,
|
||||
prepare_verifying_key, verify_proof,
|
||||
};
|
||||
use ark_std::rand::thread_rng;
|
||||
|
@ -881,7 +881,7 @@ mod tests {
|
|||
let full_assignment = wtns
|
||||
.calculate_witness_element::<Bn254, _>(inputs, false)
|
||||
.unwrap();
|
||||
let proof = create_proof_with_qap_and_matrices::<_, CircomReduction>(
|
||||
let proof = create_proof_with_reduction_and_matrices::<_, CircomReduction>(
|
||||
¶ms,
|
||||
r,
|
||||
s,
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
*.swp
|
||||
complex-circuit-*-*.*
|
||||
powersOfTau*
|
||||
!complex-circuit-10000-10000.*
|
||||
proof.json
|
||||
public.json
|
||||
verification_key.json
|
||||
witness.wtns
|
|
@ -0,0 +1,20 @@
|
|||
MIN_NUM_VARIABLES=$1
|
||||
MAX_NUM_VARIABLES=$2
|
||||
MAX_NUM_CONSTRAINTS=$3
|
||||
|
||||
for i in `seq 10 19`; do wget https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_$i.ptau; done
|
||||
|
||||
./prepare.sh $MIN_NUM_VARIABLES $MAX_NUM_VARIABLES $MAX_NUM_CONSTRAINTS
|
||||
|
||||
for i in `seq $MIN_NUM_VARIABLES $MAX_NUM_VARIABLES`
|
||||
do
|
||||
for j in `seq $i $MAX_NUM_CONSTRAINTS`
|
||||
do
|
||||
NUM_VARIABLES=$(echo 10^$i | bc)
|
||||
NUM_CONSTRAINTS=$(echo 10^$j | bc)
|
||||
echo "**** START benchmarking $NUM_VARIABLES $NUM_CONSTRAINTS ****"
|
||||
./prove.sh $NUM_VARIABLES $NUM_CONSTRAINTS
|
||||
perf stat -r5 rapidsnark complex-circuit-$NUM_VARIABLES-$NUM_CONSTRAINTS.zkey witness.wtns proof.json public.json
|
||||
echo "**** END benchmarking $NUM_VARIABLES $NUM_CONSTRAINTS ****"
|
||||
done
|
||||
done
|
|
@ -0,0 +1,11 @@
|
|||
NUM_VARIABLES=$1
|
||||
NUM_CONSTRAINTS=$2
|
||||
PTAU_POWER=$(echo "l($NUM_CONSTRAINTS)/l(2)" | bc -l | xargs -I{} awk "BEGIN{printf(\"%.f\n\", {}+0.5)}")
|
||||
|
||||
export NODE_OPTIONS=--max-old-space-size=8192
|
||||
|
||||
echo "compiling"
|
||||
circom -f complex-circuit-$NUM_VARIABLES-$NUM_CONSTRAINTS.circom --r1cs --wasm
|
||||
|
||||
echo "zkey"
|
||||
snarkjs zkey new complex-circuit-$NUM_VARIABLES-$NUM_CONSTRAINTS.r1cs powersOfTau28_hez_final_$PTAU_POWER.ptau complex-circuit-$NUM_VARIABLES-$NUM_CONSTRAINTS.zkey
|
|
@ -0,0 +1,21 @@
|
|||
template ManyConstraints(NUM_VARIABLES, NUM_CONSTRAINTS) {
|
||||
signal private input a;
|
||||
signal output c;
|
||||
|
||||
assert(NUM_VARIABLES <= NUM_CONSTRAINTS)
|
||||
|
||||
signal b[NUM_VARIABLES];
|
||||
|
||||
b[0] <== a*a;
|
||||
var i;
|
||||
for (i = 1; i < NUM_VARIABLES; i++) {
|
||||
b[i] <== b[i-1]*b[i-1];
|
||||
}
|
||||
i = i-1;
|
||||
for (var j = NUM_VARIABLES; j < NUM_CONSTRAINTS; j++) {
|
||||
b[i] === b[i-1]*b[i-1];
|
||||
}
|
||||
c <== b[i];
|
||||
}
|
||||
|
||||
component main = ManyConstraints(10000, 10000);
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,21 @@
|
|||
template ManyConstraints(NUM_VARIABLES, NUM_CONSTRAINTS) {
|
||||
signal private input a;
|
||||
signal output c;
|
||||
|
||||
assert(NUM_VARIABLES <= NUM_CONSTRAINTS)
|
||||
|
||||
signal b[NUM_VARIABLES];
|
||||
|
||||
b[0] <== a*a;
|
||||
var i;
|
||||
for (i = 1; i < NUM_VARIABLES; i++) {
|
||||
b[i] <== b[i-1]*b[i-1];
|
||||
}
|
||||
i = i-1;
|
||||
for (var j = NUM_VARIABLES; j < NUM_CONSTRAINTS; j++) {
|
||||
b[i] === b[i-1]*b[i-1];
|
||||
}
|
||||
c <== b[i];
|
||||
}
|
||||
|
||||
component main = ManyConstraints(NUM_VARIABLES_TEMPLATE, NUM_CONSTRAINTS_TEMPLATE);
|
|
@ -0,0 +1 @@
|
|||
{ "a": "3" }
|
|
@ -0,0 +1,10 @@
|
|||
for i in `seq 3 5`
|
||||
do
|
||||
for j in `seq $i 5`
|
||||
do
|
||||
NUM_VARIABLES=$(echo 10^$i | bc)
|
||||
NUM_CONSTRAINTS=$(echo 10^$j | bc)
|
||||
sed "s/NUM_VARIABLES_TEMPLATE/$NUM_VARIABLES/g;s/NUM_CONSTRAINTS_TEMPLATE/$NUM_CONSTRAINTS/g" complex-circuit.circom.template > complex-circuit-$NUM_VARIABLES-$NUM_CONSTRAINTS.circom
|
||||
./build.sh $NUM_VARIABLES $NUM_CONSTRAINTS
|
||||
done
|
||||
done
|
|
@ -0,0 +1,8 @@
|
|||
NUM_VARIABLES=$1
|
||||
NUM_CONSTRAINTS=$2
|
||||
|
||||
snarkjs wtns calculate complex-circuit-$NUM_VARIABLES-$NUM_CONSTRAINTS.wasm input.json witness.wtns
|
||||
snarkjs groth16 prove complex-circuit-$NUM_VARIABLES-$NUM_CONSTRAINTS.zkey witness.wtns proof.json public.json
|
||||
snarkjs zkey export verificationkey complex-circuit-$NUM_VARIABLES-$NUM_CONSTRAINTS.zkey
|
||||
snarkjs groth16 verify verification_key.json proof.json public.json
|
||||
|
Binary file not shown.
|
@ -1,17 +1,17 @@
|
|||
{
|
||||
"pi_a": [
|
||||
"21820242516822140966541162377276968686232843738113587401096982992192344668894",
|
||||
"11813319305207505272935972628809616933491158390363636948064175237855995334902",
|
||||
"6235746210673106891683313862449025023627555115162992763714613342703079170148",
|
||||
"12399711040178466467332477784020211067450597599035925008336813728555144120335",
|
||||
"1"
|
||||
],
|
||||
"pi_b": [
|
||||
[
|
||||
"18917448206777957911519238799204582671273667459570541744718718682284696800644",
|
||||
"21860816634843106300632391943058453169523964990832692292245793512061190952946"
|
||||
"3878778368997395576585378205610237973645840367459368364069435490380759882761",
|
||||
"6372446288114997398874714591076628465205914797783709795970421045876437438845"
|
||||
],
|
||||
[
|
||||
"16561373496530563246294178223057082579479375833438527168631993097749179197198",
|
||||
"19528135117438338906248937077496663741632339371165800510091342591825441786822"
|
||||
"1848758415443668505660007055104065117685874818267116126442518003813688485119",
|
||||
"13151381207181352787620244234186261096498266850828100859417113864178798435289"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
|
@ -19,8 +19,8 @@
|
|||
]
|
||||
],
|
||||
"pi_c": [
|
||||
"16517915790659730733697074034691836627766957980661041574367499432757153082558",
|
||||
"14547307060850695604573432667032315680903080725809615957085938618335278860351",
|
||||
"20702909955866523755177574141774962608204777398014771961964213040023134853917",
|
||||
"11380617408700662148925472638480792573061992967930438232337416544412668869948",
|
||||
"1"
|
||||
],
|
||||
"protocol": "groth16",
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
echo "compiling"
|
||||
circom -f complex-circuit.circom --r1cs --wasm
|
||||
|
||||
echo "wtns"
|
||||
snarkjs wtns calculate complex-circuit.wasm input.json witness.wtns
|
||||
|
||||
echo "zkey"
|
||||
snarkjs zkey new complex-circuit.r1cs powersOfTau28_hez_final_17.ptau complex.zkey
|
||||
|
||||
echo "proving 1"
|
||||
time snarkjs groth16 prove complex.zkey witness.wtns proof.json public.json
|
||||
|
||||
echo "proving 2"
|
||||
time docker run rapidsnark complex.zkey witness.wtns proof.json public.json
|
|
@ -1,3 +1,3 @@
|
|||
[
|
||||
"33"
|
||||
"20227169454906525228014700210166866282343639252280745415680311389428188660505"
|
||||
]
|
Binary file not shown.
Loading…
Reference in New Issue