arnaucube
arnaucube/hyperplonkPublic Self-hosted repository
hyperplonk/hyperplonk/benches/bench.rs
hyperplonk/benches/bench.rsRaw
  1// Copyright (c) 2023 Espresso Systems (espressosys.com)
  2// This file is part of the HyperPlonk library.
  3
  4// You should have received a copy of the MIT License
  5// along with the HyperPlonk library. If not, see <https://mit-license.org/>.
  6
  7use std::{fs::File, io, time::Instant};
  8
  9use ark_bls12_381::{Bls12_381, Fr};
 10use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Write};
 11use ark_std::test_rng;
 12use hyperplonk::{
 13    prelude::{CustomizedGates, HyperPlonkErrors, MockCircuit},
 14    HyperPlonkSNARK,
 15};
 16use subroutines::{
 17    pcs::{
 18        prelude::{MultilinearKzgPCS, MultilinearUniversalParams},
 19        PolynomialCommitmentScheme,
 20    },
 21    poly_iop::PolyIOP,
 22};
 23
 24const SUPPORTED_SIZE: usize = 20;
 25const MIN_NUM_VARS: usize = 8;
 26const MAX_NUM_VARS: usize = 20;
 27const MIN_CUSTOM_DEGREE: usize = 1;
 28const MAX_CUSTOM_DEGREE: usize = 32;
 29const HIGH_DEGREE_TEST_NV: usize = 15;
 30
 31fn main() -> Result<(), HyperPlonkErrors> {
 32    let thread = rayon::current_num_threads();
 33    println!("start benchmark with #{} threads", thread);
 34    let mut rng = test_rng();
 35    let pcs_srs = {
 36        match read_srs() {
 37            Ok(p) => p,
 38            Err(_e) => {
 39                let srs =
 40                    MultilinearKzgPCS::<Bls12_381>::gen_srs_for_testing(&mut rng, SUPPORTED_SIZE)?;
 41                write_srs(&srs);
 42                srs
 43            },
 44        }
 45    };
 46    bench_jellyfish_plonk(&pcs_srs, thread)?;
 47    println!();
 48    bench_vanilla_plonk(&pcs_srs, thread)?;
 49    println!();
 50    for degree in MIN_CUSTOM_DEGREE..=MAX_CUSTOM_DEGREE {
 51        bench_high_degree_plonk(&pcs_srs, degree, thread)?;
 52        println!();
 53    }
 54    println!();
 55
 56    Ok(())
 57}
 58
 59fn read_srs() -> Result<MultilinearUniversalParams<Bls12_381>, io::Error> {
 60    let mut f = File::open("srs.params")?;
 61    Ok(MultilinearUniversalParams::<Bls12_381>::deserialize_compressed_unchecked(&mut f).unwrap())
 62}
 63
 64fn write_srs(pcs_srs: &MultilinearUniversalParams<Bls12_381>) {
 65    let mut f = File::create("srs.params").unwrap();
 66    pcs_srs.serialize_uncompressed(&mut f).unwrap();
 67}
 68
 69fn bench_vanilla_plonk(
 70    pcs_srs: &MultilinearUniversalParams<Bls12_381>,
 71    thread: usize,
 72) -> Result<(), HyperPlonkErrors> {
 73    let filename = format!("vanilla threads {}.txt", thread);
 74    let mut file = File::create(filename).unwrap();
 75    for nv in MIN_NUM_VARS..=MAX_NUM_VARS {
 76        let vanilla_gate = CustomizedGates::vanilla_plonk_gate();
 77        bench_mock_circuit_zkp_helper(&mut file, nv, &vanilla_gate, pcs_srs)?;
 78    }
 79
 80    Ok(())
 81}
 82
 83fn bench_jellyfish_plonk(
 84    pcs_srs: &MultilinearUniversalParams<Bls12_381>,
 85    thread: usize,
 86) -> Result<(), HyperPlonkErrors> {
 87    let filename = format!("jellyfish threads {}.txt", thread);
 88    let mut file = File::create(filename).unwrap();
 89    for nv in MIN_NUM_VARS..=MAX_NUM_VARS {
 90        let jf_gate = CustomizedGates::jellyfish_turbo_plonk_gate();
 91        bench_mock_circuit_zkp_helper(&mut file, nv, &jf_gate, pcs_srs)?;
 92    }
 93
 94    Ok(())
 95}
 96
 97fn bench_high_degree_plonk(
 98    pcs_srs: &MultilinearUniversalParams<Bls12_381>,
 99    degree: usize,
100    thread: usize,
101) -> Result<(), HyperPlonkErrors> {
102    let filename = format!("high degree {} thread {}.txt", degree, thread);
103    let mut file = File::create(filename).unwrap();
104    println!("custom gate of degree {}", degree);
105    let vanilla_gate = CustomizedGates::mock_gate(2, degree);
106    bench_mock_circuit_zkp_helper(&mut file, HIGH_DEGREE_TEST_NV, &vanilla_gate, pcs_srs)?;
107
108    Ok(())
109}
110
111fn bench_mock_circuit_zkp_helper(
112    file: &mut File,
113    nv: usize,
114    gate: &CustomizedGates,
115    pcs_srs: &MultilinearUniversalParams<Bls12_381>,
116) -> Result<(), HyperPlonkErrors> {
117    let repetition = if nv < 10 {
118        5
119    } else if nv < 20 {
120        2
121    } else {
122        1
123    };
124
125    //==========================================================
126    let circuit = MockCircuit::<Fr>::new(1 << nv, gate);
127    assert!(circuit.is_satisfied());
128    let index = circuit.index;
129    //==========================================================
130    // generate pk and vks
131    let start = Instant::now();
132    for _ in 0..repetition {
133        let (_pk, _vk) = <PolyIOP<Fr> as HyperPlonkSNARK<
134            Bls12_381,
135            MultilinearKzgPCS<Bls12_381>,
136        >>::preprocess(&index, pcs_srs)?;
137    }
138    println!(
139        "key extraction for {} variables: {} us",
140        nv,
141        start.elapsed().as_micros() / repetition as u128
142    );
143    let (pk, vk) =
144        <PolyIOP<Fr> as HyperPlonkSNARK<Bls12_381, MultilinearKzgPCS<Bls12_381>>>::preprocess(
145            &index, pcs_srs,
146        )?;
147    //==========================================================
148    // generate a proof
149    let start = Instant::now();
150    for _ in 0..repetition {
151        let _proof =
152            <PolyIOP<Fr> as HyperPlonkSNARK<Bls12_381, MultilinearKzgPCS<Bls12_381>>>::prove(
153                &pk,
154                &circuit.public_inputs,
155                &circuit.witnesses,
156            )?;
157    }
158    let t = start.elapsed().as_micros() / repetition as u128;
159    println!(
160        "proving for {} variables: {} us",
161        nv,
162        start.elapsed().as_micros() / repetition as u128
163    );
164    file.write_all(format!("{} {}\n", nv, t).as_ref()).unwrap();
165
166    let proof = <PolyIOP<Fr> as HyperPlonkSNARK<Bls12_381, MultilinearKzgPCS<Bls12_381>>>::prove(
167        &pk,
168        &circuit.public_inputs,
169        &circuit.witnesses,
170    )?;
171    //==========================================================
172    // verify a proof
173    let start = Instant::now();
174    for _ in 0..repetition {
175        let verify =
176            <PolyIOP<Fr> as HyperPlonkSNARK<Bls12_381, MultilinearKzgPCS<Bls12_381>>>::verify(
177                &vk,
178                &circuit.public_inputs,
179                &proof,
180            )?;
181        assert!(verify);
182    }
183    println!(
184        "verifying for {} variables: {} us",
185        nv,
186        start.elapsed().as_micros() / repetition as u128
187    );
188    Ok(())
189}