arnaucube
arnaucube/hyperplonkPublic Self-hosted repository
hyperplonk/hyperplonk/benches/bench.rs
hyperplonk/benches/bench.rsRaw
  1use std::{env, fs::File, time::Instant};
  2
  3use ark_bls12_381::{Bls12_381, Fr};
  4use ark_serialize::Write;
  5use ark_std::test_rng;
  6use hyperplonk::{
  7    prelude::{CustomizedGates, HyperPlonkErrors, MockCircuit},
  8    HyperPlonkSNARK,
  9};
 10use rayon::ThreadPoolBuilder;
 11use subroutines::{
 12    pcs::{
 13        prelude::{MultilinearKzgPCS, MultilinearUniversalParams},
 14        PolynomialCommitmentScheme,
 15    },
 16    poly_iop::PolyIOP,
 17};
 18
 19const SUPPORTED_SIZE: usize = 15;
 20const MIN_NUM_VARS: usize = 8;
 21const MAX_NUM_VARS: usize = 15;
 22const MIN_CUSTOM_DEGREE: usize = 1;
 23const MAX_CUSTOM_DEGREE: usize = 32;
 24const MAX_NUM_THREADS: usize = 24;
 25
 26fn main() -> Result<(), HyperPlonkErrors> {
 27    let args: Vec<String> = env::args().collect();
 28    let thread = args[1].parse().unwrap_or(MAX_NUM_THREADS);
 29    let mut rng = test_rng();
 30    let pcs_srs = MultilinearKzgPCS::<Bls12_381>::gen_srs_for_testing(&mut rng, SUPPORTED_SIZE)?;
 31    ThreadPoolBuilder::new()
 32        .num_threads(thread)
 33        .build()
 34        .unwrap();
 35    bench_vanilla_plonk(&pcs_srs, thread)?;
 36    for degree in MIN_CUSTOM_DEGREE..MAX_CUSTOM_DEGREE {
 37        bench_high_degree_plonk(&pcs_srs, degree, thread)?;
 38    }
 39
 40    Ok(())
 41}
 42
 43fn bench_vanilla_plonk(
 44    pcs_srs: &MultilinearUniversalParams<Bls12_381>,
 45    thread: usize,
 46) -> Result<(), HyperPlonkErrors> {
 47    let filename = format!("vanilla threads {}.txt", thread);
 48    let mut file = File::create(filename).unwrap();
 49    for nv in MIN_NUM_VARS..MAX_NUM_VARS {
 50        let vanilla_gate = CustomizedGates::vanilla_plonk_gate();
 51        bench_mock_circuit_zkp_helper(&mut file, nv, &vanilla_gate, &pcs_srs)?;
 52    }
 53
 54    Ok(())
 55}
 56
 57fn bench_high_degree_plonk(
 58    pcs_srs: &MultilinearUniversalParams<Bls12_381>,
 59    degree: usize,
 60    thread: usize,
 61) -> Result<(), HyperPlonkErrors> {
 62    let filename = format!("high degree {} thread {}.txt", degree, thread);
 63    let mut file = File::create(filename).unwrap();
 64    for nv in MIN_NUM_VARS..MAX_NUM_VARS {
 65        let vanilla_gate = CustomizedGates::mock_gate(2, degree);
 66        bench_mock_circuit_zkp_helper(&mut file, nv, &vanilla_gate, &pcs_srs)?;
 67    }
 68
 69    Ok(())
 70}
 71
 72fn bench_mock_circuit_zkp_helper(
 73    file: &mut File,
 74    nv: usize,
 75    gate: &CustomizedGates,
 76    pcs_srs: &MultilinearUniversalParams<Bls12_381>,
 77) -> Result<(), HyperPlonkErrors> {
 78    let repetition = if nv < 10 {
 79        5
 80    } else if nv < 20 {
 81        2
 82    } else {
 83        1
 84    };
 85
 86    //==========================================================
 87    let start = Instant::now();
 88    for _ in 0..repetition {
 89        let circuit = MockCircuit::<Fr>::new(1 << nv, gate);
 90        assert!(circuit.is_satisfied());
 91    }
 92    println!(
 93        "mock circuit gen for {} variables: {} ns",
 94        nv,
 95        start.elapsed().as_nanos() / repetition as u128
 96    );
 97
 98    let circuit = MockCircuit::<Fr>::new(1 << nv, gate);
 99    assert!(circuit.is_satisfied());
100    let index = circuit.index;
101    //==========================================================
102    // generate pk and vks
103    let start = Instant::now();
104    for _ in 0..repetition {
105        let (_pk, _vk) = <PolyIOP<Fr> as HyperPlonkSNARK<
106            Bls12_381,
107            MultilinearKzgPCS<Bls12_381>,
108        >>::preprocess(&index, &pcs_srs)?;
109    }
110    println!(
111        "key extraction for {} variables: {} us",
112        nv,
113        start.elapsed().as_micros() / repetition as u128
114    );
115    let (pk, vk) =
116        <PolyIOP<Fr> as HyperPlonkSNARK<Bls12_381, MultilinearKzgPCS<Bls12_381>>>::preprocess(
117            &index, &pcs_srs,
118        )?;
119    //==========================================================
120    // generate a proof
121    let start = Instant::now();
122    for _ in 0..repetition {
123        let _proof =
124            <PolyIOP<Fr> as HyperPlonkSNARK<Bls12_381, MultilinearKzgPCS<Bls12_381>>>::prove(
125                &pk,
126                &circuit.witnesses[0].coeff_ref(),
127                &circuit.witnesses,
128            )?;
129    }
130    let t = start.elapsed().as_micros() / repetition as u128;
131
132    file.write_all(format!("{} {}\n", nv, t).as_ref()).unwrap();
133
134    let proof = <PolyIOP<Fr> as HyperPlonkSNARK<Bls12_381, MultilinearKzgPCS<Bls12_381>>>::prove(
135        &pk,
136        &circuit.witnesses[0].coeff_ref(),
137        &circuit.witnesses,
138    )?;
139    //==========================================================
140    // verify a proof
141    let start = Instant::now();
142    for _ in 0..repetition {
143        let verify =
144            <PolyIOP<Fr> as HyperPlonkSNARK<Bls12_381, MultilinearKzgPCS<Bls12_381>>>::verify(
145                &vk,
146                &circuit.witnesses[0].coeff_ref(),
147                &proof,
148            )?;
149        assert!(verify);
150    }
151    println!(
152        "verifying for {} variables: {} us",
153        nv,
154        start.elapsed().as_micros() / repetition as u128
155    );
156    Ok(())
157}