// Copyright (c) 2023 Espresso Systems (espressosys.com) // This file is part of the HyperPlonk library. // You should have received a copy of the MIT License // along with the HyperPlonk library. If not, see . use arithmetic::{identity_permutation_mles, VPAuxInfo, VirtualPolynomial}; use ark_bls12_381::{Bls12_381, Fr}; use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; use ark_std::test_rng; use std::{marker::PhantomData, sync::Arc, time::Instant}; use subroutines::{ pcs::{prelude::MultilinearKzgPCS, PolynomialCommitmentScheme}, poly_iop::prelude::{ PermutationCheck, PolyIOP, PolyIOPErrors, ProductCheck, SumCheck, ZeroCheck, }, }; type KZG = MultilinearKzgPCS; fn main() -> Result<(), PolyIOPErrors> { bench_permutation_check()?; println!("\n\n"); bench_sum_check()?; println!("\n\n"); bench_prod_check()?; println!("\n\n"); bench_zero_check() } fn bench_sum_check() -> Result<(), PolyIOPErrors> { let mut rng = test_rng(); for degree in 2..4 { for nv in 4..25 { let repetition = if nv < 10 { 100 } else if nv < 20 { 50 } else { 10 }; let (poly, asserted_sum) = VirtualPolynomial::rand(nv, (degree, degree + 1), 2, &mut rng)?; let poly_info = poly.aux_info.clone(); let proof = { let start = Instant::now(); for _ in 0..repetition { let mut transcript = as SumCheck>::init_transcript(); let _proof = as SumCheck>::prove(&poly, &mut transcript)?; } println!( "sum check proving time for {} variables and {} degree: {} ns", nv, degree, start.elapsed().as_nanos() / repetition as u128 ); let mut transcript = as SumCheck>::init_transcript(); as SumCheck>::prove(&poly, &mut transcript)? }; { let start = Instant::now(); for _ in 0..repetition { let mut transcript = as SumCheck>::init_transcript(); let _subclaim = as SumCheck>::verify( asserted_sum, &proof, &poly_info, &mut transcript, )?; } println!( "sum check verification time for {} variables and {} degree: {} ns", nv, degree, start.elapsed().as_nanos() / repetition as u128 ); } println!("===================================="); } } Ok(()) } fn bench_zero_check() -> Result<(), PolyIOPErrors> { let mut rng = test_rng(); for degree in 2..4 { for nv in 4..20 { let repetition = if nv < 10 { 100 } else if nv < 20 { 50 } else { 10 }; let poly = VirtualPolynomial::rand_zero(nv, (degree, degree + 1), 2, &mut rng)?; let poly_info = poly.aux_info.clone(); let proof = { let start = Instant::now(); let mut transcript = as ZeroCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; let proof = as ZeroCheck>::prove(&poly, &mut transcript)?; println!( "zero check proving time for {} variables and {} degree: {} ns", nv, degree, start.elapsed().as_nanos() / repetition as u128 ); proof }; { let start = Instant::now(); let mut transcript = as ZeroCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; let _zero_subclaim = as ZeroCheck>::verify(&proof, &poly_info, &mut transcript)?; println!( "zero check verification time for {} variables and {} degree: {} ns", nv, degree, start.elapsed().as_nanos() / repetition as u128 ); } println!("===================================="); } } Ok(()) } fn bench_permutation_check() -> Result<(), PolyIOPErrors> { let mut rng = test_rng(); for nv in 4..20 { let srs = KZG::gen_srs_for_testing(&mut rng, nv + 1)?; let (pcs_param, _) = KZG::trim(&srs, None, Some(nv + 1))?; let repetition = if nv < 10 { 100 } else if nv < 20 { 50 } else { 10 }; let ws = vec![Arc::new(DenseMultilinearExtension::rand(nv, &mut rng))]; // identity map let perms = identity_permutation_mles(nv, 1); let proof = { let start = Instant::now(); let mut transcript = as PermutationCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; let (proof, _q_x, _frac_poly) = as PermutationCheck< Bls12_381, KZG, >>::prove( &pcs_param, &ws, &ws, &perms, &mut transcript )?; println!( "permutation check proving time for {} variables: {} ns", nv, start.elapsed().as_nanos() / repetition as u128 ); proof }; { let poly_info = VPAuxInfo { max_degree: 2, num_variables: nv, phantom: PhantomData::default(), }; let start = Instant::now(); let mut transcript = as PermutationCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; let _perm_check_sum_claim = as PermutationCheck>::verify( &proof, &poly_info, &mut transcript, )?; println!( "permutation check verification time for {} variables: {} ns", nv, start.elapsed().as_nanos() / repetition as u128 ); } println!("===================================="); } Ok(()) } fn bench_prod_check() -> Result<(), PolyIOPErrors> { let mut rng = test_rng(); for nv in 4..20 { let srs = KZG::gen_srs_for_testing(&mut rng, nv + 1)?; let (pcs_param, _) = KZG::trim(&srs, None, Some(nv + 1))?; let repetition = if nv < 10 { 100 } else if nv < 20 { 50 } else { 10 }; let f: DenseMultilinearExtension = DenseMultilinearExtension::rand(nv, &mut rng); let mut g = f.clone(); g.evaluations.reverse(); let fs = vec![Arc::new(f)]; let gs = vec![Arc::new(g)]; let proof = { let start = Instant::now(); let mut transcript = as ProductCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; let (proof, _prod_x, _frac_poly) = as ProductCheck>::prove( &pcs_param, &fs, &gs, &mut transcript, )?; println!( "product check proving time for {} variables: {} ns", nv, start.elapsed().as_nanos() / repetition as u128 ); proof }; { let poly_info = VPAuxInfo { max_degree: 2, num_variables: nv, phantom: PhantomData::default(), }; let start = Instant::now(); let mut transcript = as ProductCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; let _perm_check_sum_claim = as ProductCheck>::verify( &proof, &poly_info, &mut transcript, )?; println!( "product check verification time for {} variables: {} ns", nv, start.elapsed().as_nanos() / repetition as u128 ); } println!("===================================="); } Ok(()) }