From 56b1085c113350d02b31d1b4944fee55e430d7b7 Mon Sep 17 00:00:00 2001 From: Ivan Mikushin Date: Tue, 21 Feb 2023 05:53:49 -0800 Subject: [PATCH] Bump to arkworks-0.4.0 (#126) * Bump to arkworks-0.4.0 * Replace remaining usages of `msm_bigint` with `msm_unchecked` Using `msm_unchecked` instead of `msm_bigint` allows to delete the BigInt conversion code by letting the library take care of it. --- arithmetic/Cargo.toml | 12 +- arithmetic/src/univariate_polynomial.rs | 76 +++------- arithmetic/src/virtual_polynomial.rs | 5 +- hyperplonk/Cargo.toml | 12 +- hyperplonk/benches/bench.rs | 12 +- hyperplonk/src/lib.rs | 10 +- hyperplonk/src/mock.rs | 2 +- hyperplonk/src/snark.rs | 140 ++++++++++-------- hyperplonk/src/structs.rs | 14 +- hyperplonk/src/utils.rs | 14 +- subroutines/Cargo.toml | 12 +- subroutines/benches/iop_bench.rs | 26 ++-- subroutines/src/pcs/mod.rs | 21 ++- .../src/pcs/multilinear_kzg/batching.rs | 58 ++++---- subroutines/src/pcs/multilinear_kzg/mod.rs | 111 ++++++-------- subroutines/src/pcs/multilinear_kzg/srs.rs | 66 ++++----- subroutines/src/pcs/structs.rs | 6 +- subroutines/src/pcs/univariate_kzg/mod.rs | 92 +++++------- subroutines/src/pcs/univariate_kzg/srs.rs | 52 +++---- subroutines/src/poly_iop/perm_check/mod.rs | 68 +++++---- subroutines/src/poly_iop/prod_check/mod.rs | 103 +++++++------ subroutines/src/poly_iop/structs.rs | 2 +- .../src/poly_iop/sum_check/verifier.rs | 2 +- subroutines/src/poly_iop/utils.rs | 4 +- transcript/Cargo.toml | 6 +- transcript/src/lib.rs | 2 +- 26 files changed, 444 insertions(+), 484 deletions(-) diff --git a/arithmetic/Cargo.toml b/arithmetic/Cargo.toml index 2082c7f..209450b 100644 --- a/arithmetic/Cargo.toml +++ b/arithmetic/Cargo.toml @@ -5,17 +5,17 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -ark-bls12-381 = { version = "0.3.0", default-features = false, features = [ "curve" ] } -ark-ff = { version = "^0.3.0", default-features = false } -ark-poly = { version = "^0.3.0", default-features = false } -ark-serialize = { version = "^0.3.0", default-features = false } -ark-std = { version = "^0.3.0", default-features = false } +ark-bls12-381 = { version = "0.4.0", default-features = false, features = [ "curve" ] } +ark-ff = { version = "^0.4.0", default-features = false } +ark-poly = { version = "^0.4.0", default-features = false } +ark-serialize = { version = "^0.4.0", default-features = false } +ark-std = { version = "^0.4.0", default-features = false } displaydoc = { version = "0.2.3", default-features = false } rand_chacha = { version = "0.3.0", default-features = false } rayon = { version = "1.5.2", default-features = false, optional = true } [dev-dependencies] -ark-ec = { version = "^0.3.0", default-features = false } +ark-ec = { version = "^0.4.0", default-features = false } criterion = "0.4.0" [features] diff --git a/arithmetic/src/univariate_polynomial.rs b/arithmetic/src/univariate_polynomial.rs index cb2b88b..674bac9 100644 --- a/arithmetic/src/univariate_polynomial.rs +++ b/arithmetic/src/univariate_polynomial.rs @@ -81,8 +81,8 @@ pub fn get_uni_domain( mod test { use super::*; use ark_bls12_381::Fr; - use ark_ff::{field_new, One}; - use ark_poly::UVPolynomial; + use ark_ff::{MontFp, One}; + use ark_poly::DenseUVPolynomial; #[test] fn test_build_l_with_suffix() -> Result<(), ArithErrors> { @@ -121,7 +121,7 @@ mod test { { let domain = get_uni_domain::(3)?; - let l = build_l(&[point1, point2, point3], &domain, true)?; + let l = build_l::(&[point1, point2, point3], &domain, true)?; // sage: q = 52435875175126190479447740508185965837690552500527637822603658699938581184513 // sage: P. = PolynomialRing(Zmod(q)) @@ -142,20 +142,16 @@ mod test { // 13108968793781547619861935127046491459422638125131909455650914674984645296128*x + // 39326906381344642859585805381139474378267914375395728366952744024953935888385 let l0 = DensePolynomial::from_coefficients_vec(vec![ - field_new!( - Fr, + MontFp!( "39326906381344642859585805381139474378267914375395728366952744024953935888385" ), - field_new!( - Fr, + MontFp!( "13108968793781547619861935127046491459422638125131909455650914674984645296128" ), - field_new!( - Fr, + MontFp!( "39326906381344642859585805381139474378267914375395728366952744024953935888385" ), - field_new!( - Fr, + MontFp!( "13108968793781547619861935127046491459422638125131909455650914674984645296128" ), ]); @@ -170,22 +166,16 @@ mod test { // 52435875175126190478581454301667552757996485117855702128036095582747240693761*x + // 39326906381344642859585805381139474378267914375395728366952744024953935888385 let l1 = DensePolynomial::from_coefficients_vec(vec![ - field_new!( - Fr, + MontFp!( "39326906381344642859585805381139474378267914375395728366952744024953935888385" ), - field_new!( - Fr, + MontFp!( "52435875175126190478581454301667552757996485117855702128036095582747240693761" ), - field_new!( - Fr, + MontFp!( "13108968793781547619861935127046491459422638125131909455650914674984645296128" ), - field_new!( - Fr, - "866286206518413079694067382671935694567563117191340490752" - ), + MontFp!("866286206518413079694067382671935694567563117191340490752"), ]); // ======================== @@ -198,22 +188,16 @@ mod test { // 52435875175126190476848881888630726598608350352511830738900969348364559712256*x + // 39326906381344642859585805381139474378267914375395728366952744024953935888387 let l2 = DensePolynomial::from_coefficients_vec(vec![ - field_new!( - Fr, + MontFp!( "39326906381344642859585805381139474378267914375395728366952744024953935888387" ), - field_new!( - Fr, + MontFp!( "52435875175126190476848881888630726598608350352511830738900969348364559712256" ), - field_new!( - Fr, + MontFp!( "13108968793781547619861935127046491459422638125131909455650914674984645296129" ), - field_new!( - Fr, - "2598858619555239239082202148015807083702689351574021472255" - ), + MontFp!("2598858619555239239082202148015807083702689351574021472255"), ]); // ======================== @@ -227,15 +211,11 @@ mod test { // 3 let l3 = DensePolynomial::from_coefficients_vec(vec![ Fr::from(3u64), - field_new!( - Fr, + MontFp!( "52435875175126190475982595682112313518914282969839895044333406231173219221504" ), Fr::one(), - field_new!( - Fr, - "3465144826073652318776269530687742778270252468765361963007" - ), + MontFp!("3465144826073652318776269530687742778270252468765361963007"), ]); assert_eq!(l0, l[0], "l0 not equal"); @@ -298,22 +278,16 @@ mod test { // 52435875175126190476848881888630726598608350352511830738900969348364559712256*x + // 39326906381344642859585805381139474378267914375395728366952744024953935888387 let l0 = DensePolynomial::from_coefficients_vec(vec![ - field_new!( - Fr, + MontFp!( "39326906381344642859585805381139474378267914375395728366952744024953935888387" ), - field_new!( - Fr, + MontFp!( "52435875175126190476848881888630726598608350352511830738900969348364559712256" ), - field_new!( - Fr, + MontFp!( "13108968793781547619861935127046491459422638125131909455650914674984645296129" ), - field_new!( - Fr, - "2598858619555239239082202148015807083702689351574021472255" - ), + MontFp!("2598858619555239239082202148015807083702689351574021472255"), ]); // ======================== @@ -327,15 +301,11 @@ mod test { // 3 let l1 = DensePolynomial::from_coefficients_vec(vec![ Fr::from(3u64), - field_new!( - Fr, + MontFp!( "52435875175126190475982595682112313518914282969839895044333406231173219221504" ), Fr::one(), - field_new!( - Fr, - "3465144826073652318776269530687742778270252468765361963007" - ), + MontFp!("3465144826073652318776269530687742778270252468765361963007"), ]); assert_eq!(l0, l[0], "l0 not equal"); diff --git a/arithmetic/src/virtual_polynomial.rs b/arithmetic/src/virtual_polynomial.rs index f8a185f..3d3e5d4 100644 --- a/arithmetic/src/virtual_polynomial.rs +++ b/arithmetic/src/virtual_polynomial.rs @@ -10,7 +10,7 @@ use crate::{errors::ArithErrors, multilinear_polynomial::random_zero_mle_list, random_mle_list}; use ark_ff::PrimeField; use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; -use ark_serialize::{CanonicalSerialize, SerializationError, Write}; +use ark_serialize::CanonicalSerialize; use ark_std::{ end_timer, rand::{Rng, RngCore}, @@ -546,7 +546,6 @@ mod test { let mle = DenseMultilinearExtension::from_evaluations_vec(num_var, eval); - let res = Arc::new(mle); - res + Arc::new(mle) } } diff --git a/hyperplonk/Cargo.toml b/hyperplonk/Cargo.toml index 439ac35..90a8cda 100644 --- a/hyperplonk/Cargo.toml +++ b/hyperplonk/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" [dependencies] arithmetic = { path = "../arithmetic" } -ark-ec = { version = "^0.3.0", default-features = false } -ark-ff = { version = "^0.3.0", default-features = false } -ark-poly = { version = "^0.3.0", default-features = false } -ark-serialize = { version = "^0.3.0", default-features = false, features = [ "derive" ] } -ark-std = { version = "^0.3.0", default-features = false } +ark-ec = { version = "^0.4.0", default-features = false } +ark-ff = { version = "^0.4.0", default-features = false } +ark-poly = { version = "^0.4.0", default-features = false } +ark-serialize = { version = "^0.4.0", default-features = false, features = [ "derive" ] } +ark-std = { version = "^0.4.0", default-features = false } displaydoc = { version = "0.2.3", default-features = false } rayon = { version = "1.5.2", default-features = false, optional = true } subroutines = { path = "../subroutines" } @@ -18,7 +18,7 @@ transcript = { path = "../transcript" } util = { path = "../util" } [dev-dependencies] -ark-bls12-381 = { version = "0.3.0", default-features = false, features = [ "curve" ] } +ark-bls12-381 = { version = "0.4.0", default-features = false, features = [ "curve" ] } # Benchmarks [[bench]] name = "hyperplonk-benches" diff --git a/hyperplonk/benches/bench.rs b/hyperplonk/benches/bench.rs index 3649fdd..edd85d4 100644 --- a/hyperplonk/benches/bench.rs +++ b/hyperplonk/benches/bench.rs @@ -58,7 +58,7 @@ fn main() -> Result<(), HyperPlonkErrors> { fn read_srs() -> Result, io::Error> { let mut f = File::open("srs.params")?; - Ok(MultilinearUniversalParams::::deserialize_unchecked(&mut f).unwrap()) + Ok(MultilinearUniversalParams::::deserialize_compressed_unchecked(&mut f).unwrap()) } fn write_srs(pcs_srs: &MultilinearUniversalParams) { @@ -74,7 +74,7 @@ fn bench_vanilla_plonk( let mut file = File::create(filename).unwrap(); for nv in MIN_NUM_VARS..=MAX_NUM_VARS { let vanilla_gate = CustomizedGates::vanilla_plonk_gate(); - bench_mock_circuit_zkp_helper(&mut file, nv, &vanilla_gate, &pcs_srs)?; + bench_mock_circuit_zkp_helper(&mut file, nv, &vanilla_gate, pcs_srs)?; } Ok(()) @@ -88,7 +88,7 @@ fn bench_jellyfish_plonk( let mut file = File::create(filename).unwrap(); for nv in MIN_NUM_VARS..=MAX_NUM_VARS { let jf_gate = CustomizedGates::jellyfish_turbo_plonk_gate(); - bench_mock_circuit_zkp_helper(&mut file, nv, &jf_gate, &pcs_srs)?; + bench_mock_circuit_zkp_helper(&mut file, nv, &jf_gate, pcs_srs)?; } Ok(()) @@ -103,7 +103,7 @@ fn bench_high_degree_plonk( let mut file = File::create(filename).unwrap(); println!("custom gate of degree {}", degree); let vanilla_gate = CustomizedGates::mock_gate(2, degree); - bench_mock_circuit_zkp_helper(&mut file, HIGH_DEGREE_TEST_NV, &vanilla_gate, &pcs_srs)?; + bench_mock_circuit_zkp_helper(&mut file, HIGH_DEGREE_TEST_NV, &vanilla_gate, pcs_srs)?; Ok(()) } @@ -133,7 +133,7 @@ fn bench_mock_circuit_zkp_helper( let (_pk, _vk) = as HyperPlonkSNARK< Bls12_381, MultilinearKzgPCS, - >>::preprocess(&index, &pcs_srs)?; + >>::preprocess(&index, pcs_srs)?; } println!( "key extraction for {} variables: {} us", @@ -142,7 +142,7 @@ fn bench_mock_circuit_zkp_helper( ); let (pk, vk) = as HyperPlonkSNARK>>::preprocess( - &index, &pcs_srs, + &index, pcs_srs, )?; //========================================================== // generate a proof diff --git a/hyperplonk/src/lib.rs b/hyperplonk/src/lib.rs index 5d4c11c..4044a11 100644 --- a/hyperplonk/src/lib.rs +++ b/hyperplonk/src/lib.rs @@ -6,7 +6,7 @@ //! Main module for the HyperPlonk SNARK. -use ark_ec::PairingEngine; +use ark_ec::pairing::Pairing; use errors::HyperPlonkErrors; use subroutines::{pcs::prelude::PolynomialCommitmentScheme, poly_iop::prelude::PermutationCheck}; use witness::WitnessColumn; @@ -25,7 +25,7 @@ mod witness; /// A HyperPlonk is derived from ZeroChecks and PermutationChecks. pub trait HyperPlonkSNARK: PermutationCheck where - E: PairingEngine, + E: Pairing, PCS: PolynomialCommitmentScheme, { type Index; @@ -58,8 +58,8 @@ where /// - The HyperPlonk SNARK proof. fn prove( pk: &Self::ProvingKey, - pub_input: &[E::Fr], - witnesses: &[WitnessColumn], + pub_input: &[E::ScalarField], + witnesses: &[WitnessColumn], ) -> Result; /// Verify the HyperPlonk proof. @@ -72,7 +72,7 @@ where /// - Return a boolean on whether the verification is successful fn verify( vk: &Self::VerifyingKey, - pub_input: &[E::Fr], + pub_input: &[E::ScalarField], proof: &Self::Proof, ) -> Result; } diff --git a/hyperplonk/src/mock.rs b/hyperplonk/src/mock.rs index d68f2f0..e3af594 100644 --- a/hyperplonk/src/mock.rs +++ b/hyperplonk/src/mock.rs @@ -193,7 +193,7 @@ mod test { // generate pk and vks let (pk, vk) = as HyperPlonkSNARK>>::preprocess( - &index, &pcs_srs, + &index, pcs_srs, )?; // generate a proof and verify let proof = diff --git a/hyperplonk/src/snark.rs b/hyperplonk/src/snark.rs index c66230f..18d0689 100644 --- a/hyperplonk/src/snark.rs +++ b/hyperplonk/src/snark.rs @@ -12,7 +12,7 @@ use crate::{ HyperPlonkSNARK, }; use arithmetic::{evaluate_opt, gen_eval_point, VPAuxInfo}; -use ark_ec::PairingEngine; +use ark_ec::pairing::Pairing; use ark_poly::DenseMultilinearExtension; use ark_std::{end_timer, log2, start_timer, One, Zero}; use rayon::iter::IntoParallelRefIterator; @@ -29,22 +29,22 @@ use subroutines::{ }; use transcript::IOPTranscript; -impl HyperPlonkSNARK for PolyIOP +impl HyperPlonkSNARK for PolyIOP where - E: PairingEngine, + E: Pairing, // Ideally we want to access polynomial as PCS::Polynomial, instead of instantiating it here. // But since PCS::Polynomial can be both univariate or multivariate in our implementation // we cannot bound PCS::Polynomial with a property trait bound. PCS: PolynomialCommitmentScheme< E, - Polynomial = Arc>, - Point = Vec, - Evaluation = E::Fr, + Polynomial = Arc>, + Point = Vec, + Evaluation = E::ScalarField, Commitment = Commitment, BatchProof = BatchProof, >, { - type Index = HyperPlonkIndex; + type Index = HyperPlonkIndex; type ProvingKey = HyperPlonkProvingKey; type VerifyingKey = HyperPlonkVerifyingKey; type Proof = HyperPlonkProof; @@ -75,7 +75,7 @@ where } // build selector oracles and commit to it - let selector_oracles: Vec>> = index + let selector_oracles: Vec>> = index .selectors .iter() .map(|s| Arc::new(DenseMultilinearExtension::from(s))) @@ -153,11 +153,11 @@ where /// - 5. deferred batch opening fn prove( pk: &Self::ProvingKey, - pub_input: &[E::Fr], - witnesses: &[WitnessColumn], + pub_input: &[E::ScalarField], + witnesses: &[WitnessColumn], ) -> Result { let start = start_timer!(|| "hyperplonk proving"); - let mut transcript = IOPTranscript::::new(b"hyperplonk"); + let mut transcript = IOPTranscript::::new(b"hyperplonk"); prover_sanity_check(&pk.params, pub_input, witnesses)?; @@ -177,7 +177,7 @@ where // ======================================================================= let step = start_timer!(|| "commit witnesses"); - let witness_polys: Vec>> = witnesses + let witness_polys: Vec>> = witnesses .iter() .map(|w| Arc::new(DenseMultilinearExtension::from(w))) .collect(); @@ -212,7 +212,7 @@ where &witness_polys, )?; - let zero_check_proof = >::prove(&fx, &mut transcript)?; + let zero_check_proof = >::prove(&fx, &mut transcript)?; end_timer!(step); // ======================================================================= // 3. Run permutation check on `\{w_i(x)\}` and `permutation_oracle`, and @@ -259,12 +259,20 @@ where let step = start_timer!(|| "opening and evaluations"); // (perm_check_point[2..n], 0) - let perm_check_point_0 = [&[E::Fr::zero()], &perm_check_point[0..num_vars - 1]].concat(); + let perm_check_point_0 = [ + &[E::ScalarField::zero()], + &perm_check_point[0..num_vars - 1], + ] + .concat(); // (perm_check_point[2..n], 1) - let perm_check_point_1 = [&[E::Fr::one()], &perm_check_point[0..num_vars - 1]].concat(); + let perm_check_point_1 = + [&[E::ScalarField::one()], &perm_check_point[0..num_vars - 1]].concat(); // (1, ..., 1, 0) - let prod_final_query_point = - [vec![E::Fr::zero()], vec![E::Fr::one(); num_vars - 1]].concat(); + let prod_final_query_point = [ + vec![E::ScalarField::zero()], + vec![E::ScalarField::one(); num_vars - 1], + ] + .concat(); // prod(x)'s points pcs_acc.insert_poly_and_points(&prod_x, &perm_check_proof.prod_x_comm, perm_check_point); @@ -319,7 +327,7 @@ where // - pi_poly(r_pi) where r_pi is sampled from transcript let r_pi = transcript.get_and_append_challenge_vectors(b"r_pi", ell)?; // padded with zeros - let r_pi_padded = [r_pi, vec![E::Fr::zero(); num_vars - ell]].concat(); + let r_pi_padded = [r_pi, vec![E::ScalarField::zero(); num_vars - ell]].concat(); // Evaluate witness_poly[0] at r_pi||0s which is equal to public_input evaluated // at r_pi. Assumes that public_input is a power of 2 pcs_acc.insert_poly_and_points(&witness_polys[0], &witness_commits[0], &r_pi_padded); @@ -379,12 +387,12 @@ where /// - public input consistency checks fn verify( vk: &Self::VerifyingKey, - pub_input: &[E::Fr], + pub_input: &[E::ScalarField], proof: &Self::Proof, ) -> Result { let start = start_timer!(|| "hyperplonk verification"); - let mut transcript = IOPTranscript::::new(b"hyperplonk"); + let mut transcript = IOPTranscript::::new(b"hyperplonk"); let num_selectors = vk.params.num_selector_columns(); let num_witnesses = vk.params.num_witness_columns(); @@ -429,7 +437,7 @@ where // ======================================================================= let step = start_timer!(|| "verify zero check"); // Zero check and perm check have different AuxInfo - let zero_check_aux_info = VPAuxInfo:: { + let zero_check_aux_info = VPAuxInfo:: { max_degree: vk.params.gate_func.degree(), num_variables: num_vars, phantom: PhantomData::default(), @@ -439,7 +447,7 @@ where transcript.append_serializable_element(b"w", w_com)?; } - let zero_check_sub_claim = >::verify( + let zero_check_sub_claim = >::verify( &proof.zero_check_proof, &zero_check_aux_info, &mut transcript, @@ -462,7 +470,7 @@ where let step = start_timer!(|| "verify permutation check"); // Zero check and perm check have different AuxInfo - let perm_check_aux_info = VPAuxInfo:: { + let perm_check_aux_info = VPAuxInfo:: { // Prod(x) has a max degree of witnesses.len() + 1 max_degree: proof.witness_commits.len() + 1, num_variables: num_vars, @@ -522,10 +530,18 @@ where let mut comms = vec![]; let mut points = vec![]; - let perm_check_point_0 = [&[E::Fr::zero()], &perm_check_point[0..num_vars - 1]].concat(); - let perm_check_point_1 = [&[E::Fr::one()], &perm_check_point[0..num_vars - 1]].concat(); - let prod_final_query_point = - [vec![E::Fr::zero()], vec![E::Fr::one(); num_vars - 1]].concat(); + let perm_check_point_0 = [ + &[E::ScalarField::zero()], + &perm_check_point[0..num_vars - 1], + ] + .concat(); + let perm_check_point_1 = + [&[E::ScalarField::one()], &perm_check_point[0..num_vars - 1]].concat(); + let prod_final_query_point = [ + vec![E::ScalarField::zero()], + vec![E::ScalarField::one(); num_vars - 1], + ] + .concat(); // prod(x)'s points comms.push(proof.perm_check_proof.prod_x_comm); @@ -581,7 +597,7 @@ where pi_eval, expect_pi_eval, ))); } - let r_pi_padded = [r_pi, vec![E::Fr::zero(); num_vars - ell]].concat(); + let r_pi_padded = [r_pi, vec![E::ScalarField::zero(); num_vars - ell]].concat(); comms.push(proof.witness_commits[0]); points.push(r_pi_padded); @@ -638,7 +654,7 @@ mod tests { test_hyperplonk_helper::(gates) } - fn test_hyperplonk_helper( + fn test_hyperplonk_helper( gate_func: CustomizedGates, ) -> Result<(), HyperPlonkErrors> { let mut rng = test_rng(); @@ -656,7 +672,12 @@ mod tests { gate_func, }; let permutation = identity_permutation(nv, num_witnesses); - let q1 = SelectorColumn(vec![E::Fr::one(), E::Fr::one(), E::Fr::one(), E::Fr::one()]); + let q1 = SelectorColumn(vec![ + E::ScalarField::one(), + E::ScalarField::one(), + E::ScalarField::one(), + E::ScalarField::one(), + ]); let index = HyperPlonkIndex { params, permutation, @@ -664,58 +685,59 @@ mod tests { }; // generate pk and vks - let (pk, vk) = as HyperPlonkSNARK>>::preprocess( - &index, &pcs_srs, - )?; + let (pk, vk) = + as HyperPlonkSNARK>>::preprocess( + &index, &pcs_srs, + )?; // w1 := [0, 1, 2, 3] let w1 = WitnessColumn(vec![ - E::Fr::zero(), - E::Fr::one(), - E::Fr::from(2u128), - E::Fr::from(3u128), + E::ScalarField::zero(), + E::ScalarField::one(), + E::ScalarField::from(2u128), + E::ScalarField::from(3u128), ]); // w2 := [0^5, 1^5, 2^5, 3^5] let w2 = WitnessColumn(vec![ - E::Fr::zero(), - E::Fr::one(), - E::Fr::from(32u128), - E::Fr::from(243u128), + E::ScalarField::zero(), + E::ScalarField::one(), + E::ScalarField::from(32u128), + E::ScalarField::from(243u128), ]); // public input = w1 let pi = w1.clone(); // generate a proof and verify - let proof = as HyperPlonkSNARK>>::prove( + let proof = as HyperPlonkSNARK>>::prove( &pk, &pi.0, &[w1.clone(), w2.clone()], )?; - let _verify = as HyperPlonkSNARK>>::verify( - &vk, &pi.0, &proof, - )?; + let _verify = + as HyperPlonkSNARK>>::verify( + &vk, &pi.0, &proof, + )?; // bad path 1: wrong permutation - let rand_perm: Vec = random_permutation(nv, num_witnesses, &mut rng); - let mut bad_index = index.clone(); + let rand_perm: Vec = random_permutation(nv, num_witnesses, &mut rng); + let mut bad_index = index; bad_index.permutation = rand_perm; // generate pk and vks - let (_, bad_vk) = as HyperPlonkSNARK>>::preprocess( - &bad_index, &pcs_srs, - )?; - assert_eq!( - as HyperPlonkSNARK>>::verify( - &bad_vk, &pi.0, &proof, - )?, - false - ); + let (_, bad_vk) = + as HyperPlonkSNARK>>::preprocess( + &bad_index, &pcs_srs, + )?; + assert!(! as HyperPlonkSNARK< + E, + MultilinearKzgPCS, + >>::verify(&bad_vk, &pi.0, &proof,)?); // bad path 2: wrong witness - let mut w1_bad = w1.clone(); - w1_bad.0[0] = E::Fr::one(); + let mut w1_bad = w1; + w1_bad.0[0] = E::ScalarField::one(); assert!( - as HyperPlonkSNARK>>::prove( + as HyperPlonkSNARK>>::prove( &pk, &pi.0, &[w1_bad, w2], diff --git a/hyperplonk/src/structs.rs b/hyperplonk/src/structs.rs index 91496e0..76f9c71 100644 --- a/hyperplonk/src/structs.rs +++ b/hyperplonk/src/structs.rs @@ -7,7 +7,7 @@ //! Main module for the HyperPlonk PolyIOP. use crate::{custom_gate::CustomizedGates, prelude::HyperPlonkErrors, selectors::SelectorColumn}; -use ark_ec::PairingEngine; +use ark_ec::pairing::Pairing; use ark_ff::PrimeField; use ark_poly::DenseMultilinearExtension; use ark_std::log2; @@ -25,7 +25,7 @@ use subroutines::{ #[derive(Clone, Debug, PartialEq)] pub struct HyperPlonkProof where - E: PairingEngine, + E: Pairing, PC: PermutationCheck, PCS: PolynomialCommitmentScheme, { @@ -36,7 +36,7 @@ where // IOP proofs // ======================================================================= // the custom gate zerocheck proof - pub zero_check_proof: >::ZeroCheckProof, + pub zero_check_proof: >::ZeroCheckProof, // the permutation check proof for copy constraints pub perm_check_proof: PC::PermutationProof, } @@ -128,13 +128,13 @@ impl HyperPlonkIndex { /// - the commitment to the selectors and permutations /// - the parameters for polynomial commitment #[derive(Clone, Debug, Default, PartialEq)] -pub struct HyperPlonkProvingKey> { +pub struct HyperPlonkProvingKey> { /// Hyperplonk instance parameters pub params: HyperPlonkParams, /// The preprocessed permutation polynomials - pub permutation_oracles: Vec>>, + pub permutation_oracles: Vec>>, /// The preprocessed selector polynomials - pub selector_oracles: Vec>>, + pub selector_oracles: Vec>>, /// Commitments to the preprocessed selector polynomials pub selector_commitments: Vec, /// Commitments to the preprocessed permutation polynomials @@ -148,7 +148,7 @@ pub struct HyperPlonkProvingKey> { +pub struct HyperPlonkVerifyingKey> { /// Hyperplonk instance parameters pub params: HyperPlonkParams, /// The parameters for PCS commitment diff --git a/hyperplonk/src/utils.rs b/hyperplonk/src/utils.rs index 92901a6..4853c97 100644 --- a/hyperplonk/src/utils.rs +++ b/hyperplonk/src/utils.rs @@ -9,7 +9,7 @@ use crate::{ witness::WitnessColumn, }; use arithmetic::{evaluate_opt, VirtualPolynomial}; -use ark_ec::PairingEngine; +use ark_ec::pairing::Pairing; use ark_ff::PrimeField; use ark_poly::DenseMultilinearExtension; use std::{borrow::Borrow, sync::Arc}; @@ -19,7 +19,7 @@ use transcript::IOPTranscript; /// An accumulator structure that holds a polynomial and /// its opening points #[derive(Debug)] -pub(super) struct PcsAccumulator> { +pub(super) struct PcsAccumulator> { // sequence: // - prod(x) at 5 points // - w_merged at perm check point @@ -35,12 +35,12 @@ pub(super) struct PcsAccumulator PcsAccumulator where - E: PairingEngine, + E: Pairing, PCS: PolynomialCommitmentScheme< E, - Polynomial = Arc>, - Point = Vec, - Evaluation = E::Fr, + Polynomial = Arc>, + Point = Vec, + Evaluation = E::ScalarField, Commitment = Commitment, >, { @@ -78,7 +78,7 @@ where pub(super) fn multi_open( &self, prover_param: impl Borrow, - transcript: &mut IOPTranscript, + transcript: &mut IOPTranscript, ) -> Result { Ok(PCS::multi_open( prover_param.borrow(), diff --git a/subroutines/Cargo.toml b/subroutines/Cargo.toml index 83acd50..354af27 100644 --- a/subroutines/Cargo.toml +++ b/subroutines/Cargo.toml @@ -6,12 +6,12 @@ edition = "2021" [dependencies] arithmetic = { path = "../arithmetic" } -ark-bls12-381 = { version = "0.3.0", default-features = false, features = [ "curve" ] } -ark-ec = { version = "^0.3.0", default-features = false } -ark-ff = { version = "^0.3.0", default-features = false } -ark-poly = { version = "^0.3.0", default-features = false } -ark-serialize = { version = "^0.3.0", default-features = false } -ark-std = { version = "^0.3.0", default-features = false } +ark-bls12-381 = { version = "0.4.0", default-features = false, features = [ "curve" ] } +ark-ec = { version = "^0.4.0", default-features = false } +ark-ff = { version = "^0.4.0", default-features = false } +ark-poly = { version = "^0.4.0", default-features = false } +ark-serialize = { version = "^0.4.0", default-features = false } +ark-std = { version = "^0.4.0", default-features = false } derivative = { version = "2", features = ["use_core"] } displaydoc = { version = "0.2.3", default-features = false } itertools = { version = "0.10.4", optional = true } diff --git a/subroutines/benches/iop_bench.rs b/subroutines/benches/iop_bench.rs index 6b024b8..a5766fb 100644 --- a/subroutines/benches/iop_bench.rs +++ b/subroutines/benches/iop_bench.rs @@ -16,7 +16,7 @@ use subroutines::{ }, }; -type KZG = MultilinearKzgPCS; +type Kzg = MultilinearKzgPCS; fn main() -> Result<(), PolyIOPErrors> { bench_permutation_check()?; @@ -139,8 +139,8 @@ 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 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 @@ -159,12 +159,12 @@ fn bench_permutation_check() -> Result<(), PolyIOPErrors> { { let start = Instant::now(); let mut transcript = - as PermutationCheck>::init_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, + Kzg, >>::prove( &pcs_param, &ws, &ws, &perms, &mut transcript )?; @@ -186,9 +186,9 @@ fn bench_permutation_check() -> Result<(), PolyIOPErrors> { let start = Instant::now(); let mut transcript = - as PermutationCheck>::init_transcript(); + as PermutationCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; - let _perm_check_sum_claim = as PermutationCheck>::verify( + let _perm_check_sum_claim = as PermutationCheck>::verify( &proof, &poly_info, &mut transcript, @@ -210,8 +210,8 @@ 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 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 @@ -229,11 +229,11 @@ fn bench_prod_check() -> Result<(), PolyIOPErrors> { let proof = { let start = Instant::now(); - let mut transcript = as ProductCheck>::init_transcript(); + 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( + as ProductCheck>::prove( &pcs_param, &fs, &gs, @@ -256,9 +256,9 @@ fn bench_prod_check() -> Result<(), PolyIOPErrors> { }; let start = Instant::now(); - let mut transcript = as ProductCheck>::init_transcript(); + 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( + let _perm_check_sum_claim = as ProductCheck>::verify( &proof, &poly_info, &mut transcript, diff --git a/subroutines/src/pcs/mod.rs b/subroutines/src/pcs/mod.rs index deac59e..acbcac9 100644 --- a/subroutines/src/pcs/mod.rs +++ b/subroutines/src/pcs/mod.rs @@ -11,17 +11,17 @@ mod univariate_kzg; pub mod prelude; -use ark_ec::PairingEngine; +use ark_ec::pairing::Pairing; use ark_ff::Field; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::rand::{CryptoRng, RngCore}; +use ark_std::rand::Rng; use errors::PCSError; use std::{borrow::Borrow, fmt::Debug, hash::Hash}; use transcript::IOPTranscript; /// This trait defines APIs for polynomial commitment schemes. /// Note that for our usage of PCS, we do not require the hiding property. -pub trait PolynomialCommitmentScheme { +pub trait PolynomialCommitmentScheme { /// Prover parameters type ProverParam: Clone + Sync; /// Verifier parameters @@ -49,7 +49,7 @@ pub trait PolynomialCommitmentScheme { /// /// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY. /// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION. - fn gen_srs_for_testing( + fn gen_srs_for_testing( rng: &mut R, supported_size: usize, ) -> Result; @@ -99,7 +99,7 @@ pub trait PolynomialCommitmentScheme { _polynomials: &[Self::Polynomial], _points: &[Self::Point], _evals: &[Self::Evaluation], - _transcript: &mut IOPTranscript, + _transcript: &mut IOPTranscript, ) -> Result { // the reason we use unimplemented!() is to enable developers to implement the // trait without always implementing the batching APIs. @@ -112,7 +112,7 @@ pub trait PolynomialCommitmentScheme { verifier_param: &Self::VerifierParam, commitment: &Self::Commitment, point: &Self::Point, - value: &E::Fr, + value: &E::ScalarField, proof: &Self::Proof, ) -> Result; @@ -123,7 +123,7 @@ pub trait PolynomialCommitmentScheme { _commitments: &[Self::Commitment], _points: &[Self::Point], _batch_proof: &Self::BatchProof, - _transcript: &mut IOPTranscript, + _transcript: &mut IOPTranscript, ) -> Result { // the reason we use unimplemented!() is to enable developers to implement the // trait without always implementing the batching APIs. @@ -132,7 +132,7 @@ pub trait PolynomialCommitmentScheme { } /// API definitions for structured reference string -pub trait StructuredReferenceString: Sized { +pub trait StructuredReferenceString: Sized { /// Prover parameters type ProverParam; /// Verifier parameters @@ -165,8 +165,5 @@ pub trait StructuredReferenceString: Sized { /// /// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY. /// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION. - fn gen_srs_for_testing( - rng: &mut R, - supported_size: usize, - ) -> Result; + fn gen_srs_for_testing(rng: &mut R, supported_size: usize) -> Result; } diff --git a/subroutines/src/pcs/multilinear_kzg/batching.rs b/subroutines/src/pcs/multilinear_kzg/batching.rs index f511ade..9a54a46 100644 --- a/subroutines/src/pcs/multilinear_kzg/batching.rs +++ b/subroutines/src/pcs/multilinear_kzg/batching.rs @@ -20,8 +20,8 @@ use crate::{ IOPProof, }; use arithmetic::{build_eq_x_r_vec, DenseMultilinearExtension, VPAuxInfo, VirtualPolynomial}; -use ark_ec::{msm::VariableBaseMSM, PairingEngine, ProjectiveCurve}; -use ark_ff::PrimeField; +use ark_ec::{pairing::Pairing, scalar_mul::variable_base::VariableBaseMSM, CurveGroup}; + use ark_std::{end_timer, log2, start_timer, One, Zero}; use std::{collections::BTreeMap, iter, marker::PhantomData, ops::Deref, sync::Arc}; use transcript::IOPTranscript; @@ -29,13 +29,13 @@ use transcript::IOPTranscript; #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct BatchProof where - E: PairingEngine, + E: Pairing, PCS: PolynomialCommitmentScheme, { /// A sum check proof proving tilde g's sum - pub(crate) sum_check_proof: IOPProof, + pub(crate) sum_check_proof: IOPProof, /// f_i(point_i) - pub f_i_eval_at_point_i: Vec, + pub f_i_eval_at_point_i: Vec, /// proof for g'(a_2) pub(crate) g_prime_proof: PCS::Proof, } @@ -53,15 +53,15 @@ pub(crate) fn multi_open_internal( polynomials: &[PCS::Polynomial], points: &[PCS::Point], evals: &[PCS::Evaluation], - transcript: &mut IOPTranscript, + transcript: &mut IOPTranscript, ) -> Result, PCSError> where - E: PairingEngine, + E: Pairing, PCS: PolynomialCommitmentScheme< E, - Polynomial = Arc>, - Point = Vec, - Evaluation = E::Fr, + Polynomial = Arc>, + Point = Vec, + Evaluation = E::ScalarField, >, { let open_timer = start_timer!(|| format!("multi open {} points", points.len())); @@ -127,11 +127,14 @@ where let step = start_timer!(|| "add mle"); let mut sum_check_vp = VirtualPolynomial::new(num_var); for (merged_tilde_g, tilde_eq) in merged_tilde_gs.iter().zip(tilde_eqs.into_iter()) { - sum_check_vp.add_mle_list([merged_tilde_g.clone(), tilde_eq], E::Fr::one())?; + sum_check_vp.add_mle_list([merged_tilde_g.clone(), tilde_eq], E::ScalarField::one())?; } end_timer!(step); - let proof = match as SumCheck>::prove(&sum_check_vp, transcript) { + let proof = match as SumCheck>::prove( + &sum_check_vp, + transcript, + ) { Ok(p) => p, Err(_e) => { // cannot wrap IOPError with PCSError due to cyclic dependency @@ -182,15 +185,15 @@ pub(crate) fn batch_verify_internal( f_i_commitments: &[Commitment], points: &[PCS::Point], proof: &BatchProof, - transcript: &mut IOPTranscript, + transcript: &mut IOPTranscript, ) -> Result where - E: PairingEngine, + E: Pairing, PCS: PolynomialCommitmentScheme< E, - Polynomial = Arc>, - Point = Vec, - Evaluation = E::Fr, + Polynomial = Arc>, + Point = Vec, + Evaluation = E::ScalarField, Commitment = Commitment, >, { @@ -217,14 +220,14 @@ where for (i, point) in points.iter().enumerate() { let eq_i_a2 = eq_eval(a2, point)?; - scalars.push((eq_i_a2 * eq_t_list[i]).into_repr()); + scalars.push(eq_i_a2 * eq_t_list[i]); bases.push(f_i_commitments[i].0); } - let g_prime_commit = VariableBaseMSM::multi_scalar_mul(&bases, &scalars); + let g_prime_commit = E::G1::msm_unchecked(&bases, &scalars); end_timer!(step); // ensure \sum_i eq(t, ) * f_i_evals matches the sum via SumCheck - let mut sum = E::Fr::zero(); + let mut sum = E::ScalarField::zero(); for (i, &e) in eq_t_list.iter().enumerate().take(k) { sum += e * proof.f_i_eval_at_point_i[i]; } @@ -233,7 +236,7 @@ where num_variables: num_var, phantom: PhantomData, }; - let subclaim = match as SumCheck>::verify( + let subclaim = match as SumCheck>::verify( sum, &proof.sum_check_proof, &aux_info, @@ -271,18 +274,13 @@ mod tests { }; use arithmetic::get_batched_nv; use ark_bls12_381::Bls12_381 as E; - use ark_ec::PairingEngine; + use ark_ec::pairing::Pairing; use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; - use ark_std::{ - rand::{CryptoRng, RngCore}, - test_rng, - vec::Vec, - UniformRand, - }; + use ark_std::{rand::Rng, test_rng, vec::Vec, UniformRand}; - type Fr = ::Fr; + type Fr = ::ScalarField; - fn test_multi_open_helper( + fn test_multi_open_helper( ml_params: &MultilinearUniversalParams, polys: &[Arc>], rng: &mut R, diff --git a/subroutines/src/pcs/multilinear_kzg/mod.rs b/subroutines/src/pcs/multilinear_kzg/mod.rs index c724f0c..47f2f05 100644 --- a/subroutines/src/pcs/multilinear_kzg/mod.rs +++ b/subroutines/src/pcs/multilinear_kzg/mod.rs @@ -16,24 +16,18 @@ use crate::{ }; use arithmetic::evaluate_opt; use ark_ec::{ - msm::{FixedBaseMSM, VariableBaseMSM}, - AffineCurve, PairingEngine, ProjectiveCurve, + pairing::Pairing, + scalar_mul::{fixed_base::FixedBase, variable_base::VariableBaseMSM}, + AffineRepr, CurveGroup, }; use ark_ff::PrimeField; use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::{ - borrow::Borrow, - end_timer, format, - marker::PhantomData, - rand::{CryptoRng, RngCore}, - start_timer, - string::ToString, - sync::Arc, - vec, - vec::Vec, - One, Zero, + borrow::Borrow, end_timer, format, marker::PhantomData, rand::Rng, start_timer, + string::ToString, sync::Arc, vec, vec::Vec, One, Zero, }; +use std::ops::Mul; // use batching::{batch_verify_internal, multi_open_internal}; use srs::{MultilinearProverParam, MultilinearUniversalParams, MultilinearVerifierParam}; use transcript::IOPTranscript; @@ -41,27 +35,27 @@ use transcript::IOPTranscript; use self::batching::{batch_verify_internal, multi_open_internal}; /// KZG Polynomial Commitment Scheme on multilinear polynomials. -pub struct MultilinearKzgPCS { +pub struct MultilinearKzgPCS { #[doc(hidden)] phantom: PhantomData, } #[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] /// proof of opening -pub struct MultilinearKzgProof { +pub struct MultilinearKzgProof { /// Evaluation of quotients pub proofs: Vec, } -impl PolynomialCommitmentScheme for MultilinearKzgPCS { +impl PolynomialCommitmentScheme for MultilinearKzgPCS { // Parameters type ProverParam = MultilinearProverParam; type VerifierParam = MultilinearVerifierParam; type SRS = MultilinearUniversalParams; // Polynomial and its associated types - type Polynomial = Arc>; - type Point = Vec; - type Evaluation = E::Fr; + type Polynomial = Arc>; + type Point = Vec; + type Evaluation = E::ScalarField; // Commitments and proofs type Commitment = Commitment; type Proof = MultilinearKzgProof; @@ -74,10 +68,7 @@ impl PolynomialCommitmentScheme for MultilinearKzgPCS { /// /// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY. /// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION. - fn gen_srs_for_testing( - rng: &mut R, - log_size: usize, - ) -> Result { + fn gen_srs_for_testing(rng: &mut R, log_size: usize) -> Result { MultilinearUniversalParams::::gen_srs_for_testing(rng, log_size) } @@ -121,20 +112,14 @@ impl PolynomialCommitmentScheme for MultilinearKzgPCS { ))); } let ignored = prover_param.num_vars - poly.num_vars; - let scalars: Vec<_> = poly - .to_evaluations() - .into_iter() - .map(|x| x.into_repr()) - .collect(); + let scalars: Vec<_> = poly.to_evaluations(); let msm_timer = start_timer!(|| format!( "msm of size {}", prover_param.powers_of_g[ignored].evals.len() )); - let commitment = VariableBaseMSM::multi_scalar_mul( - &prover_param.powers_of_g[ignored].evals, - scalars.as_slice(), - ) - .into_affine(); + let commitment = + E::G1::msm_unchecked(&prover_param.powers_of_g[ignored].evals, scalars.as_slice()) + .into_affine(); end_timer!(msm_timer); end_timer!(commit_timer); @@ -165,7 +150,7 @@ impl PolynomialCommitmentScheme for MultilinearKzgPCS { polynomials: &[Self::Polynomial], points: &[Self::Point], evals: &[Self::Evaluation], - transcript: &mut IOPTranscript, + transcript: &mut IOPTranscript, ) -> Result, PCSError> { multi_open_internal( prover_param.borrow(), @@ -186,7 +171,7 @@ impl PolynomialCommitmentScheme for MultilinearKzgPCS { verifier_param: &Self::VerifierParam, commitment: &Self::Commitment, point: &Self::Point, - value: &E::Fr, + value: &E::ScalarField, proof: &Self::Proof, ) -> Result { verify_internal(verifier_param, commitment, point, value, proof) @@ -199,7 +184,7 @@ impl PolynomialCommitmentScheme for MultilinearKzgPCS { commitments: &[Self::Commitment], points: &[Self::Point], batch_proof: &Self::BatchProof, - transcript: &mut IOPTranscript, + transcript: &mut IOPTranscript, ) -> Result { batch_verify_internal(verifier_param, commitments, points, batch_proof, transcript) } @@ -213,11 +198,11 @@ impl PolynomialCommitmentScheme for MultilinearKzgPCS { /// G1: /// - it proceeds with `num_var` number of rounds, /// - at round i, we compute an MSM for `2^{num_var - i}` number of G1 elements. -fn open_internal( +fn open_internal( prover_param: &MultilinearProverParam, - polynomial: &DenseMultilinearExtension, - point: &[E::Fr], -) -> Result<(MultilinearKzgProof, E::Fr), PCSError> { + polynomial: &DenseMultilinearExtension, + point: &[E::ScalarField], +) -> Result<(MultilinearKzgProof, E::ScalarField), PCSError> { let open_timer = start_timer!(|| format!("open mle with {} variable", polynomial.num_vars)); if polynomial.num_vars() > prover_param.num_vars { @@ -251,8 +236,8 @@ fn open_internal( let k = nv - 1 - i; let cur_dim = 1 << k; - let mut q = vec![E::Fr::zero(); cur_dim]; - let mut r = vec![E::Fr::zero(); cur_dim]; + let mut q = vec![E::ScalarField::zero(); cur_dim]; + let mut r = vec![E::ScalarField::zero(); cur_dim]; let ith_round_eval = start_timer!(|| format!("{}-th round eval", i)); for b in 0..(1 << k) { @@ -264,12 +249,11 @@ fn open_internal( } f = r; end_timer!(ith_round_eval); - let scalars: Vec<_> = q.iter().map(|x| x.into_repr()).collect(); // this is a MSM over G1 and is likely to be the bottleneck let msm_timer = start_timer!(|| format!("msm of size {} at round {}", gi.evals.len(), i)); - proofs.push(VariableBaseMSM::multi_scalar_mul(&gi.evals, &scalars).into_affine()); + proofs.push(E::G1::msm_unchecked(&gi.evals, &q).into_affine()); end_timer!(msm_timer); end_timer!(ith_round); @@ -285,11 +269,11 @@ fn open_internal( /// This function takes /// - num_var number of pairing product. /// - num_var number of MSM -fn verify_internal( +fn verify_internal( verifier_param: &MultilinearVerifierParam, commitment: &Commitment, - point: &[E::Fr], - value: &E::Fr, + point: &[E::ScalarField], + value: &E::ScalarField, proof: &MultilinearKzgProof, ) -> Result { let verify_timer = start_timer!(|| "verify"); @@ -304,22 +288,18 @@ fn verify_internal( let prepare_inputs_timer = start_timer!(|| "prepare pairing inputs"); - let scalar_size = E::Fr::size_in_bits(); - let window_size = FixedBaseMSM::get_mul_window_size(num_var); + let scalar_size = E::ScalarField::MODULUS_BIT_SIZE as usize; + let window_size = FixedBase::get_mul_window_size(num_var); - let h_table = FixedBaseMSM::get_window_table( - scalar_size, - window_size, - verifier_param.h.into_projective(), - ); - let h_mul: Vec = - FixedBaseMSM::multi_scalar_mul(scalar_size, window_size, &h_table, point); + let h_table = + FixedBase::get_window_table(scalar_size, window_size, verifier_param.h.into_group()); + let h_mul: Vec = FixedBase::msm(scalar_size, window_size, &h_table, point); let ignored = verifier_param.num_vars - num_var; let h_vec: Vec<_> = (0..num_var) - .map(|i| verifier_param.h_mask[ignored + i].into_projective() - h_mul[i]) + .map(|i| verifier_param.h_mask[ignored + i].into_group() - h_mul[i]) .collect(); - let h_vec: Vec = E::G2Projective::batch_normalization_into_affine(&h_vec); + let h_vec: Vec = E::G2::normalize_batch(&h_vec); end_timer!(prepare_inputs_timer); let pairing_product_timer = start_timer!(|| "pairing product"); @@ -333,12 +313,15 @@ fn verify_internal( pairings.push(( E::G1Prepared::from( - (verifier_param.g.mul(*value) - commitment.0.into_projective()).into_affine(), + (verifier_param.g.mul(*value) - commitment.0.into_group()).into_affine(), ), E::G2Prepared::from(verifier_param.h), )); - let res = E::product_of_pairings(pairings.iter()) == E::Fqk::one(); + let ps = pairings.iter().map(|(p, _)| p.clone()); + let hs = pairings.iter().map(|(_, h)| h.clone()); + + let res = E::multi_pairing(ps, hs) == ark_ec::pairing::PairingOutput(E::TargetField::one()); end_timer!(pairing_product_timer); end_timer!(verify_timer); @@ -349,14 +332,14 @@ fn verify_internal( mod tests { use super::*; use ark_bls12_381::Bls12_381; - use ark_ec::PairingEngine; + use ark_ec::pairing::Pairing; use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; - use ark_std::{rand::RngCore, test_rng, vec::Vec, UniformRand}; + use ark_std::{test_rng, vec::Vec, UniformRand}; type E = Bls12_381; - type Fr = ::Fr; + type Fr = ::ScalarField; - fn test_single_helper( + fn test_single_helper( params: &MultilinearUniversalParams, poly: &Arc>, rng: &mut R, diff --git a/subroutines/src/pcs/multilinear_kzg/srs.rs b/subroutines/src/pcs/multilinear_kzg/srs.rs index e6829a1..91687ca 100644 --- a/subroutines/src/pcs/multilinear_kzg/srs.rs +++ b/subroutines/src/pcs/multilinear_kzg/srs.rs @@ -10,31 +10,26 @@ use crate::pcs::{ prelude::PCSError, StructuredReferenceString, }; -use ark_ec::{msm::FixedBaseMSM, AffineCurve, PairingEngine, ProjectiveCurve}; +use ark_ec::{pairing::Pairing, scalar_mul::fixed_base::FixedBase, AffineRepr, CurveGroup}; use ark_ff::{Field, PrimeField, Zero}; use ark_poly::DenseMultilinearExtension; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::{ - collections::LinkedList, - end_timer, format, - rand::{CryptoRng, RngCore}, - start_timer, - string::ToString, - vec::Vec, + collections::LinkedList, end_timer, format, rand::Rng, start_timer, string::ToString, vec::Vec, UniformRand, }; use core::iter::FromIterator; /// Evaluations over {0,1}^n for G1 or G2 #[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)] -pub struct Evaluations { +pub struct Evaluations { /// The evaluations. pub evals: Vec, } /// Universal Parameter #[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)] -pub struct MultilinearUniversalParams { +pub struct MultilinearUniversalParams { /// prover parameters pub prover_param: MultilinearProverParam, /// h^randomness: h^t1, h^t2, ..., **h^{t_nv}** @@ -43,7 +38,7 @@ pub struct MultilinearUniversalParams { /// Prover Parameters #[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)] -pub struct MultilinearProverParam { +pub struct MultilinearProverParam { /// number of variables pub num_vars: usize, /// `pp_{0}`, `pp_{1}`, ...,pp_{nu_vars} defined @@ -58,7 +53,7 @@ pub struct MultilinearProverParam { /// Verifier Parameters #[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)] -pub struct MultilinearVerifierParam { +pub struct MultilinearVerifierParam { /// number of variables pub num_vars: usize, /// generator of G1 @@ -69,7 +64,7 @@ pub struct MultilinearVerifierParam { pub h_mask: Vec, } -impl StructuredReferenceString for MultilinearUniversalParams { +impl StructuredReferenceString for MultilinearUniversalParams { type ProverParam = MultilinearProverParam; type VerifierParam = MultilinearVerifierParam; @@ -130,10 +125,7 @@ impl StructuredReferenceString for MultilinearUniversalPara /// Build SRS for testing. /// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY. /// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION. - fn gen_srs_for_testing( - rng: &mut R, - num_vars: usize, - ) -> Result { + fn gen_srs_for_testing(rng: &mut R, num_vars: usize) -> Result { if num_vars == 0 { return Err(PCSError::InvalidParameters( "constant polynomial not supported".to_string(), @@ -144,15 +136,15 @@ impl StructuredReferenceString for MultilinearUniversalPara let pp_generation_timer = start_timer!(|| "Prover Param generation"); - let g = E::G1Projective::rand(rng); - let h = E::G2Projective::rand(rng); + let g = E::G1::rand(rng); + let h = E::G2::rand(rng); let mut powers_of_g = Vec::new(); - let t: Vec<_> = (0..num_vars).map(|_| E::Fr::rand(rng)).collect(); - let scalar_bits = E::Fr::size_in_bits(); + let t: Vec<_> = (0..num_vars).map(|_| E::ScalarField::rand(rng)).collect(); + let scalar_bits = E::ScalarField::MODULUS_BIT_SIZE as usize; - let mut eq: LinkedList> = + let mut eq: LinkedList> = LinkedList::from_iter(eq_extension(&t).into_iter()); let mut eq_arr = LinkedList::new(); let mut base = eq.pop_back().unwrap().evaluations; @@ -177,12 +169,15 @@ impl StructuredReferenceString for MultilinearUniversalPara pp_powers.extend(pp_k_powers); total_scalars += 1 << (num_vars - i); } - let window_size = FixedBaseMSM::get_mul_window_size(total_scalars); - let g_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, g); - - let pp_g = E::G1Projective::batch_normalization_into_affine( - &FixedBaseMSM::multi_scalar_mul(scalar_bits, window_size, &g_table, &pp_powers), - ); + let window_size = FixedBase::get_mul_window_size(total_scalars); + let g_table = FixedBase::get_window_table(scalar_bits, window_size, g); + + let pp_g = E::G1::normalize_batch(&FixedBase::msm( + scalar_bits, + window_size, + &g_table, + &pp_powers, + )); let mut start = 0; for i in 0..num_vars { @@ -191,8 +186,8 @@ impl StructuredReferenceString for MultilinearUniversalPara evals: pp_g[start..(start + size)].to_vec(), }; // check correctness of pp_k_g - let t_eval_0 = eq_eval(&vec![E::Fr::zero(); num_vars - i], &t[i..num_vars])?; - assert_eq!(g.mul(t_eval_0.into_repr()).into_affine(), pp_k_g.evals[0]); + let t_eval_0 = eq_eval(&vec![E::ScalarField::zero(); num_vars - i], &t[i..num_vars])?; + assert_eq!((g * t_eval_0).into(), pp_k_g.evals[0]); powers_of_g.push(pp_k_g); start += size; } @@ -212,14 +207,9 @@ impl StructuredReferenceString for MultilinearUniversalPara let vp_generation_timer = start_timer!(|| "VP generation"); let h_mask = { - let window_size = FixedBaseMSM::get_mul_window_size(num_vars); - let h_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, h); - E::G2Projective::batch_normalization_into_affine(&FixedBaseMSM::multi_scalar_mul( - scalar_bits, - window_size, - &h_table, - &t, - )) + let window_size = FixedBase::get_mul_window_size(num_vars); + let h_table = FixedBase::get_window_table(scalar_bits, window_size, h); + E::G2::normalize_batch(&FixedBase::msm(scalar_bits, window_size, &h_table, &t)) }; end_timer!(vp_generation_timer); end_timer!(total_timer); diff --git a/subroutines/src/pcs/structs.rs b/subroutines/src/pcs/structs.rs index 73d38d8..3b535db 100644 --- a/subroutines/src/pcs/structs.rs +++ b/subroutines/src/pcs/structs.rs @@ -4,8 +4,8 @@ // You should have received a copy of the MIT License // along with the HyperPlonk library. If not, see . -use ark_ec::PairingEngine; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write}; +use ark_ec::pairing::Pairing; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use derivative::Derivative; #[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)] @@ -19,7 +19,7 @@ use derivative::Derivative; Eq(bound = "") )] /// A commitment is an Affine point. -pub struct Commitment( +pub struct Commitment( /// the actual commitment is an affine point. pub E::G1Affine, ); diff --git a/subroutines/src/pcs/univariate_kzg/mod.rs b/subroutines/src/pcs/univariate_kzg/mod.rs index 32a4fc9..dcf8c8f 100644 --- a/subroutines/src/pcs/univariate_kzg/mod.rs +++ b/subroutines/src/pcs/univariate_kzg/mod.rs @@ -9,49 +9,45 @@ use crate::pcs::{ prelude::Commitment, PCSError, PolynomialCommitmentScheme, StructuredReferenceString, }; -use ark_ec::{msm::VariableBaseMSM, AffineCurve, PairingEngine, ProjectiveCurve}; +use ark_ec::{ + pairing::Pairing, scalar_mul::variable_base::VariableBaseMSM, AffineRepr, CurveGroup, +}; use ark_ff::PrimeField; -use ark_poly::{univariate::DensePolynomial, Polynomial, UVPolynomial}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write}; +use ark_poly::{univariate::DensePolynomial, DenseUVPolynomial, Polynomial}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::{ - borrow::Borrow, - end_timer, format, - marker::PhantomData, - rand::{CryptoRng, RngCore}, - start_timer, - string::ToString, - vec, - vec::Vec, - One, + borrow::Borrow, end_timer, format, marker::PhantomData, rand::Rng, start_timer, + string::ToString, vec, vec::Vec, One, }; use srs::{UnivariateProverParam, UnivariateUniversalParams, UnivariateVerifierParam}; +use std::ops::Mul; pub(crate) mod srs; /// KZG Polynomial Commitment Scheme on univariate polynomial. -pub struct UnivariateKzgPCS { +pub struct UnivariateKzgPCS { #[doc(hidden)] phantom: PhantomData, } #[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] /// proof of opening -pub struct UnivariateKzgProof { +pub struct UnivariateKzgProof { /// Evaluation of quotients pub proof: E::G1Affine, } /// batch proof pub type UnivariateKzgBatchProof = Vec>; -impl PolynomialCommitmentScheme for UnivariateKzgPCS { +impl PolynomialCommitmentScheme for UnivariateKzgPCS { // Parameters type ProverParam = UnivariateProverParam; type VerifierParam = UnivariateVerifierParam; type SRS = UnivariateUniversalParams; // Polynomial and its associated types - type Polynomial = DensePolynomial; - type Point = E::Fr; - type Evaluation = E::Fr; + type Polynomial = DensePolynomial; + type Point = E::ScalarField; + type Evaluation = E::ScalarField; // Polynomial and its associated types type Commitment = Commitment; type Proof = UnivariateKzgProof; @@ -65,7 +61,7 @@ impl PolynomialCommitmentScheme for UnivariateKzgPCS { /// /// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY. /// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION. - fn gen_srs_for_testing( + fn gen_srs_for_testing( rng: &mut R, supported_size: usize, ) -> Result { @@ -107,10 +103,10 @@ impl PolynomialCommitmentScheme for UnivariateKzgPCS { ))); } - let (num_leading_zeros, plain_coeffs) = skip_leading_zeros_and_convert_to_bigints(poly); + let (num_leading_zeros, plain_coeffs) = skip_leading_zeros(poly); let msm_time = start_timer!(|| "MSM to compute commitment to plaintext poly"); - let commitment = VariableBaseMSM::multi_scalar_mul( + let commitment = E::G1::msm_unchecked( &prover_param.powers_of_g[num_leading_zeros..], &plain_coeffs, ) @@ -130,16 +126,15 @@ impl PolynomialCommitmentScheme for UnivariateKzgPCS { ) -> Result<(Self::Proof, Self::Evaluation), PCSError> { let open_time = start_timer!(|| format!("Opening polynomial of degree {}", polynomial.degree())); - let divisor = Self::Polynomial::from_coefficients_vec(vec![-*point, E::Fr::one()]); + let divisor = Self::Polynomial::from_coefficients_vec(vec![-*point, E::ScalarField::one()]); let witness_time = start_timer!(|| "Computing witness polynomial"); let witness_polynomial = polynomial / &divisor; end_timer!(witness_time); - let (num_leading_zeros, witness_coeffs) = - skip_leading_zeros_and_convert_to_bigints(&witness_polynomial); + let (num_leading_zeros, witness_coeffs) = skip_leading_zeros(&witness_polynomial); - let proof = VariableBaseMSM::multi_scalar_mul( + let proof = E::G1::msm_unchecked( &prover_param.borrow().powers_of_g[num_leading_zeros..], &witness_coeffs, ) @@ -157,45 +152,36 @@ impl PolynomialCommitmentScheme for UnivariateKzgPCS { verifier_param: &Self::VerifierParam, commitment: &Self::Commitment, point: &Self::Point, - value: &E::Fr, + value: &E::ScalarField, proof: &Self::Proof, ) -> Result { let check_time = start_timer!(|| "Checking evaluation"); let pairing_inputs: Vec<(E::G1Prepared, E::G2Prepared)> = vec![ ( - (verifier_param.g.mul(value.into_repr()) - - proof.proof.mul(point.into_repr()) - - commitment.0.into_projective()) - .into_affine() - .into(), + (verifier_param.g.mul(value) - proof.proof.mul(point) - commitment.0.into_group()) + .into_affine() + .into(), verifier_param.h.into(), ), (proof.proof.into(), verifier_param.beta_h.into()), ]; - let res = E::product_of_pairings(pairing_inputs.iter()).is_one(); + let p1 = pairing_inputs.iter().map(|(a, _)| a.clone()); + let p2 = pairing_inputs.iter().map(|(_, a)| a.clone()); + + let res = E::multi_pairing(p1, p2).0.is_one(); end_timer!(check_time, || format!("Result: {}", res)); Ok(res) } } -fn skip_leading_zeros_and_convert_to_bigints>( - p: &P, -) -> (usize, Vec) { +fn skip_leading_zeros>(p: &P) -> (usize, &[F]) { let mut num_leading_zeros = 0; while num_leading_zeros < p.coeffs().len() && p.coeffs()[num_leading_zeros].is_zero() { num_leading_zeros += 1; } - let coeffs = convert_to_bigints(&p.coeffs()[num_leading_zeros..]); - (num_leading_zeros, coeffs) -} - -fn convert_to_bigints(p: &[F]) -> Vec { - let to_bigint_time = start_timer!(|| "Converting polynomial coeffs to bigints"); - let coeffs = p.iter().map(|s| s.into_repr()).collect::>(); - end_timer!(to_bigint_time); - coeffs + (num_leading_zeros, &p.coeffs()[num_leading_zeros..]) } #[cfg(test)] @@ -203,13 +189,13 @@ mod tests { use super::*; use crate::StructuredReferenceString; use ark_bls12_381::Bls12_381; - use ark_ec::PairingEngine; + use ark_ec::pairing::Pairing; use ark_poly::univariate::DensePolynomial; use ark_std::{test_rng, UniformRand}; fn end_to_end_test_template() -> Result<(), PCSError> where - E: PairingEngine, + E: Pairing, { let rng = &mut test_rng(); for _ in 0..100 { @@ -219,9 +205,11 @@ mod tests { } let pp = UnivariateKzgPCS::::gen_srs_for_testing(rng, degree)?; let (ck, vk) = pp.trim(degree)?; - let p = as UVPolynomial>::rand(degree, rng); + let p = as DenseUVPolynomial>::rand( + degree, rng, + ); let comm = UnivariateKzgPCS::::commit(&ck, &p)?; - let point = E::Fr::rand(rng); + let point = E::ScalarField::rand(rng); let (proof, value) = UnivariateKzgPCS::::open(&ck, &p, &point)?; assert!( UnivariateKzgPCS::::verify(&vk, &comm, &point, &value, &proof)?, @@ -235,7 +223,7 @@ mod tests { fn linear_polynomial_test_template() -> Result<(), PCSError> where - E: PairingEngine, + E: Pairing, { let rng = &mut test_rng(); for _ in 0..100 { @@ -243,9 +231,11 @@ mod tests { let pp = UnivariateKzgPCS::::gen_srs_for_testing(rng, degree)?; let (ck, vk) = pp.trim(degree)?; - let p = as UVPolynomial>::rand(degree, rng); + let p = as DenseUVPolynomial>::rand( + degree, rng, + ); let comm = UnivariateKzgPCS::::commit(&ck, &p)?; - let point = E::Fr::rand(rng); + let point = E::ScalarField::rand(rng); let (proof, value) = UnivariateKzgPCS::::open(&ck, &p, &point)?; assert!( UnivariateKzgPCS::::verify(&vk, &comm, &point, &value, &proof)?, diff --git a/subroutines/src/pcs/univariate_kzg/srs.rs b/subroutines/src/pcs/univariate_kzg/srs.rs index f15fe4b..9aeaaa8 100644 --- a/subroutines/src/pcs/univariate_kzg/srs.rs +++ b/subroutines/src/pcs/univariate_kzg/srs.rs @@ -7,23 +7,18 @@ //! Implementing Structured Reference Strings for univariate polynomial KZG use crate::pcs::{PCSError, StructuredReferenceString}; -use ark_ec::{msm::FixedBaseMSM, AffineCurve, PairingEngine, ProjectiveCurve}; +use ark_ec::{pairing::Pairing, scalar_mul::fixed_base::FixedBase, AffineRepr, CurveGroup}; use ark_ff::PrimeField; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write}; -use ark_std::{ - end_timer, - rand::{CryptoRng, RngCore}, - start_timer, vec, - vec::Vec, - One, UniformRand, -}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::{end_timer, rand::Rng, start_timer, vec, vec::Vec, One, UniformRand}; use derivative::Derivative; +use std::ops::Mul; /// `UniversalParams` are the universal parameters for the KZG10 scheme. // Adapted from // https://github.com/arkworks-rs/poly-commit/blob/master/src/kzg10/data_structures.rs#L20 #[derive(Debug, Clone, Eq, PartialEq, CanonicalSerialize, CanonicalDeserialize, Default)] -pub struct UnivariateUniversalParams { +pub struct UnivariateUniversalParams { /// Group elements of the form `{ \beta^i G }`, where `i` ranges from 0 to /// `degree`. pub powers_of_g: Vec, @@ -33,7 +28,7 @@ pub struct UnivariateUniversalParams { pub beta_h: E::G2Affine, } -impl UnivariateUniversalParams { +impl UnivariateUniversalParams { /// Returns the maximum supported degree pub fn max_degree(&self) -> usize { self.powers_of_g.len() @@ -42,7 +37,7 @@ impl UnivariateUniversalParams { /// `UnivariateProverParam` is used to generate a proof #[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, Eq, PartialEq, Default)] -pub struct UnivariateProverParam { +pub struct UnivariateProverParam { /// Parameters pub powers_of_g: Vec, } @@ -58,7 +53,7 @@ pub struct UnivariateProverParam { PartialEq(bound = ""), Eq(bound = "") )] -pub struct UnivariateVerifierParam { +pub struct UnivariateVerifierParam { /// The generator of G1. pub g: E::G1Affine, /// The generator of G2. @@ -67,7 +62,7 @@ pub struct UnivariateVerifierParam { pub beta_h: E::G2Affine, } -impl StructuredReferenceString for UnivariateUniversalParams { +impl StructuredReferenceString for UnivariateUniversalParams { type ProverParam = UnivariateProverParam; type VerifierParam = UnivariateVerifierParam; @@ -109,16 +104,13 @@ impl StructuredReferenceString for UnivariateUniversalParam /// Build SRS for testing. /// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY. /// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION. - fn gen_srs_for_testing( - rng: &mut R, - max_degree: usize, - ) -> Result { + fn gen_srs_for_testing(rng: &mut R, max_degree: usize) -> Result { let setup_time = start_timer!(|| format!("KZG10::Setup with degree {}", max_degree)); - let beta = E::Fr::rand(rng); - let g = E::G1Projective::rand(rng); - let h = E::G2Projective::rand(rng); + let beta = E::ScalarField::rand(rng); + let g = E::G1::rand(rng); + let h = E::G2::rand(rng); - let mut powers_of_beta = vec![E::Fr::one()]; + let mut powers_of_beta = vec![E::ScalarField::one()]; let mut cur = beta; for _ in 0..max_degree { @@ -126,21 +118,17 @@ impl StructuredReferenceString for UnivariateUniversalParam cur *= β } - let window_size = FixedBaseMSM::get_mul_window_size(max_degree + 1); + let window_size = FixedBase::get_mul_window_size(max_degree + 1); - let scalar_bits = E::Fr::size_in_bits(); + let scalar_bits = E::ScalarField::MODULUS_BIT_SIZE as usize; let g_time = start_timer!(|| "Generating powers of G"); // TODO: parallelization - let g_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, g); - let powers_of_g = FixedBaseMSM::multi_scalar_mul::( - scalar_bits, - window_size, - &g_table, - &powers_of_beta, - ); + let g_table = FixedBase::get_window_table(scalar_bits, window_size, g); + let powers_of_g = + FixedBase::msm::(scalar_bits, window_size, &g_table, &powers_of_beta); end_timer!(g_time); - let powers_of_g = E::G1Projective::batch_normalization_into_affine(&powers_of_g); + let powers_of_g = E::G1::normalize_batch(&powers_of_g); let h = h.into_affine(); let beta_h = h.mul(beta).into_affine(); diff --git a/subroutines/src/poly_iop/perm_check/mod.rs b/subroutines/src/poly_iop/perm_check/mod.rs index 8a9149d..afff80e 100644 --- a/subroutines/src/poly_iop/perm_check/mod.rs +++ b/subroutines/src/poly_iop/perm_check/mod.rs @@ -11,7 +11,7 @@ use crate::{ pcs::PolynomialCommitmentScheme, poly_iop::{errors::PolyIOPErrors, prelude::ProductCheck, PolyIOP}, }; -use ark_ec::PairingEngine; +use ark_ec::pairing::Pairing; use ark_poly::DenseMultilinearExtension; use ark_std::{end_timer, start_timer}; use std::sync::Arc; @@ -23,14 +23,14 @@ use transcript::IOPTranscript; #[derive(Clone, Debug, Default, PartialEq)] pub struct PermutationCheckSubClaim where - E: PairingEngine, + E: Pairing, PC: ProductCheck, PCS: PolynomialCommitmentScheme, { /// the SubClaim from the ProductCheck pub product_check_sub_claim: PC::ProductCheckSubClaim, /// Challenges beta and gamma - pub challenges: (E::Fr, E::Fr), + pub challenges: (E::ScalarField, E::ScalarField), } pub mod util; @@ -48,7 +48,7 @@ pub mod util; /// - permutation oracles = (p1, ..., pk) pub trait PermutationCheck: ProductCheck where - E: PairingEngine, + E: Pairing, PCS: PolynomialCommitmentScheme, { type PermutationCheckSubClaim; @@ -79,7 +79,7 @@ where fxs: &[Self::MultilinearExtension], gxs: &[Self::MultilinearExtension], perms: &[Self::MultilinearExtension], - transcript: &mut IOPTranscript, + transcript: &mut IOPTranscript, ) -> Result< ( Self::PermutationProof, @@ -98,16 +98,16 @@ where ) -> Result; } -impl PermutationCheck for PolyIOP +impl PermutationCheck for PolyIOP where - E: PairingEngine, - PCS: PolynomialCommitmentScheme>>, + E: Pairing, + PCS: PolynomialCommitmentScheme>>, { type PermutationCheckSubClaim = PermutationCheckSubClaim; type PermutationProof = Self::ProductCheckProof; fn init_transcript() -> Self::Transcript { - IOPTranscript::::new(b"Initializing PermutationCheck transcript") + IOPTranscript::::new(b"Initializing PermutationCheck transcript") } fn prove( @@ -115,7 +115,7 @@ where fxs: &[Self::MultilinearExtension], gxs: &[Self::MultilinearExtension], perms: &[Self::MultilinearExtension], - transcript: &mut IOPTranscript, + transcript: &mut IOPTranscript, ) -> Result< ( Self::PermutationProof, @@ -195,22 +195,25 @@ mod test { }; use arithmetic::{evaluate_opt, identity_permutation_mles, random_permutation_mles, VPAuxInfo}; use ark_bls12_381::Bls12_381; - use ark_ec::PairingEngine; + use ark_ec::pairing::Pairing; use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; use ark_std::test_rng; use std::{marker::PhantomData, sync::Arc}; - type KZG = MultilinearKzgPCS; + type Kzg = MultilinearKzgPCS; fn test_permutation_check_helper( pcs_param: &PCS::ProverParam, - fxs: &[Arc>], - gxs: &[Arc>], - perms: &[Arc>], + fxs: &[Arc>], + gxs: &[Arc>], + perms: &[Arc>], ) -> Result<(), PolyIOPErrors> where - E: PairingEngine, - PCS: PolynomialCommitmentScheme>>, + E: Pairing, + PCS: PolynomialCommitmentScheme< + E, + Polynomial = Arc>, + >, { let nv = fxs[0].num_vars; // what's AuxInfo used for? @@ -221,20 +224,23 @@ mod test { }; // prover - let mut transcript = as PermutationCheck>::init_transcript(); + let mut transcript = + as PermutationCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; - let (proof, prod_x, _frac_poly) = as PermutationCheck>::prove( - pcs_param, - fxs, - gxs, - perms, - &mut transcript, - )?; + let (proof, prod_x, _frac_poly) = + as PermutationCheck>::prove( + pcs_param, + fxs, + gxs, + perms, + &mut transcript, + )?; // verifier - let mut transcript = as PermutationCheck>::init_transcript(); + let mut transcript = + as PermutationCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; - let perm_check_sub_claim = as PermutationCheck>::verify( + let perm_check_sub_claim = as PermutationCheck>::verify( &proof, &poly_info, &mut transcript, @@ -267,7 +273,7 @@ mod test { Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)), ]; // perms is the identity map - test_permutation_check_helper::(&pcs_param, &ws, &ws, &id_perms)?; + test_permutation_check_helper::(&pcs_param, &ws, &ws, &id_perms)?; } { @@ -281,7 +287,7 @@ mod test { // perms is the reverse identity map let mut perms = id_perms.clone(); perms.reverse(); - test_permutation_check_helper::(&pcs_param, &fs, &gs, &perms)?; + test_permutation_check_helper::(&pcs_param, &fs, &gs, &perms)?; } { @@ -294,7 +300,7 @@ mod test { let perms = random_permutation_mles(nv, 2, &mut rng); assert!( - test_permutation_check_helper::(&pcs_param, &ws, &ws, &perms) + test_permutation_check_helper::(&pcs_param, &ws, &ws, &perms) .is_err() ); } @@ -311,7 +317,7 @@ mod test { ]; // s_perm is the identity map - assert!(test_permutation_check_helper::( + assert!(test_permutation_check_helper::( &pcs_param, &fs, &gs, &id_perms ) .is_err()); diff --git a/subroutines/src/poly_iop/prod_check/mod.rs b/subroutines/src/poly_iop/prod_check/mod.rs index 5e18760..2e0225a 100644 --- a/subroutines/src/poly_iop/prod_check/mod.rs +++ b/subroutines/src/poly_iop/prod_check/mod.rs @@ -16,7 +16,7 @@ use crate::{ }, }; use arithmetic::VPAuxInfo; -use ark_ec::PairingEngine; +use ark_ec::pairing::Pairing; use ark_ff::{One, PrimeField, Zero}; use ark_poly::DenseMultilinearExtension; use ark_std::{end_timer, start_timer}; @@ -52,9 +52,9 @@ mod util; /// 2. `generate_challenge` from current transcript (generate alpha) /// 3. `verify` to verify the zerocheck proof and generate the subclaim for /// polynomial evaluations -pub trait ProductCheck: ZeroCheck +pub trait ProductCheck: ZeroCheck where - E: PairingEngine, + E: Pairing, PCS: PolynomialCommitmentScheme, { type ProductCheckSubClaim; @@ -90,7 +90,7 @@ where pcs_param: &PCS::ProverParam, fxs: &[Self::MultilinearExtension], gxs: &[Self::MultilinearExtension], - transcript: &mut IOPTranscript, + transcript: &mut IOPTranscript, ) -> Result< ( Self::ProductCheckProof, @@ -106,7 +106,7 @@ where /// = \prod_{x \in {0,1}^n} g1(x) * ... * gk(x)` fn verify( proof: &Self::ProductCheckProof, - aux_info: &VPAuxInfo, + aux_info: &VPAuxInfo, transcript: &mut Self::Transcript, ) -> Result; } @@ -136,32 +136,32 @@ pub struct ProductCheckSubClaim> { /// - a polynomial commitment for the fractional polynomial #[derive(Clone, Debug, Default, PartialEq)] pub struct ProductCheckProof< - E: PairingEngine, + E: Pairing, PCS: PolynomialCommitmentScheme, - ZC: ZeroCheck, + ZC: ZeroCheck, > { pub zero_check_proof: ZC::ZeroCheckProof, pub prod_x_comm: PCS::Commitment, pub frac_comm: PCS::Commitment, } -impl ProductCheck for PolyIOP +impl ProductCheck for PolyIOP where - E: PairingEngine, - PCS: PolynomialCommitmentScheme>>, + E: Pairing, + PCS: PolynomialCommitmentScheme>>, { - type ProductCheckSubClaim = ProductCheckSubClaim; + type ProductCheckSubClaim = ProductCheckSubClaim; type ProductCheckProof = ProductCheckProof; fn init_transcript() -> Self::Transcript { - IOPTranscript::::new(b"Initializing ProductCheck transcript") + IOPTranscript::::new(b"Initializing ProductCheck transcript") } fn prove( pcs_param: &PCS::ProverParam, fxs: &[Self::MultilinearExtension], gxs: &[Self::MultilinearExtension], - transcript: &mut IOPTranscript, + transcript: &mut IOPTranscript, ) -> Result< ( Self::ProductCheckProof, @@ -220,7 +220,7 @@ where fn verify( proof: &Self::ProductCheckProof, - aux_info: &VPAuxInfo, + aux_info: &VPAuxInfo, transcript: &mut Self::Transcript, ) -> Result { let start = start_timer!(|| "prod_check verify"); @@ -232,14 +232,17 @@ where // invoke the zero check on the iop_proof // the virtual poly info for Q(x) - let zero_check_sub_claim = - >::verify(&proof.zero_check_proof, aux_info, transcript)?; + let zero_check_sub_claim = >::verify( + &proof.zero_check_proof, + aux_info, + transcript, + )?; // the final query is on prod_x - let mut final_query = vec![E::Fr::one(); aux_info.num_variables]; + let mut final_query = vec![E::ScalarField::one(); aux_info.num_variables]; // the point has to be reversed because Arkworks uses big-endian. - final_query[0] = E::Fr::zero(); - let final_eval = E::Fr::one(); + final_query[0] = E::ScalarField::zero(); + let final_eval = E::ScalarField::one(); end_timer!(start); @@ -260,53 +263,60 @@ mod test { }; use arithmetic::VPAuxInfo; use ark_bls12_381::{Bls12_381, Fr}; - use ark_ec::PairingEngine; + use ark_ec::pairing::Pairing; use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; use ark_std::test_rng; use std::{marker::PhantomData, sync::Arc}; fn check_frac_poly( - frac_poly: &Arc>, - fs: &[Arc>], - gs: &[Arc>], + frac_poly: &Arc>, + fs: &[Arc>], + gs: &[Arc>], ) where - E: PairingEngine, + E: Pairing, { let mut flag = true; let num_vars = frac_poly.num_vars; for i in 0..1 << num_vars { let nom = fs .iter() - .fold(E::Fr::from(1u8), |acc, f| acc * f.evaluations[i]); + .fold(E::ScalarField::from(1u8), |acc, f| acc * f.evaluations[i]); let denom = gs .iter() - .fold(E::Fr::from(1u8), |acc, g| acc * g.evaluations[i]); + .fold(E::ScalarField::from(1u8), |acc, g| acc * g.evaluations[i]); if denom * frac_poly.evaluations[i] != nom { flag = false; break; } } - assert_eq!(flag, true); + assert!(flag); } // fs and gs are guaranteed to have the same product // fs and hs doesn't have the same product fn test_product_check_helper( - fs: &[Arc>], - gs: &[Arc>], - hs: &[Arc>], + fs: &[Arc>], + gs: &[Arc>], + hs: &[Arc>], pcs_param: &PCS::ProverParam, ) -> Result<(), PolyIOPErrors> where - E: PairingEngine, - PCS: PolynomialCommitmentScheme>>, + E: Pairing, + PCS: PolynomialCommitmentScheme< + E, + Polynomial = Arc>, + >, { - let mut transcript = as ProductCheck>::init_transcript(); + 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)?; + let (proof, prod_x, frac_poly) = as ProductCheck>::prove( + pcs_param, + fs, + gs, + &mut transcript, + )?; - let mut transcript = as ProductCheck>::init_transcript(); + let mut transcript = as ProductCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; // what's aux_info for? @@ -315,8 +325,11 @@ mod test { num_variables: fs[0].num_vars, phantom: PhantomData::default(), }; - let prod_subclaim = - as ProductCheck>::verify(&proof, &aux_info, &mut transcript)?; + let prod_subclaim = as ProductCheck>::verify( + &proof, + &aux_info, + &mut transcript, + )?; assert_eq!( prod_x.evaluate(&prod_subclaim.final_query.0).unwrap(), prod_subclaim.final_query.1, @@ -325,15 +338,19 @@ mod test { check_frac_poly::(&frac_poly, fs, gs); // bad path - let mut transcript = as ProductCheck>::init_transcript(); + let mut transcript = as ProductCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; - let (bad_proof, prod_x_bad, frac_poly) = - as ProductCheck>::prove(pcs_param, fs, hs, &mut transcript)?; + let (bad_proof, prod_x_bad, frac_poly) = as ProductCheck< + E, + PCS, + >>::prove( + pcs_param, fs, hs, &mut transcript + )?; - let mut transcript = as ProductCheck>::init_transcript(); + let mut transcript = as ProductCheck>::init_transcript(); transcript.append_message(b"testing", b"initializing transcript for testing")?; - let bad_subclaim = as ProductCheck>::verify( + let bad_subclaim = as ProductCheck>::verify( &bad_proof, &aux_info, &mut transcript, diff --git a/subroutines/src/poly_iop/structs.rs b/subroutines/src/poly_iop/structs.rs index b8e0848..b87aa2a 100644 --- a/subroutines/src/poly_iop/structs.rs +++ b/subroutines/src/poly_iop/structs.rs @@ -8,7 +8,7 @@ use arithmetic::VirtualPolynomial; use ark_ff::PrimeField; -use ark_serialize::{CanonicalSerialize, SerializationError, Write}; +use ark_serialize::CanonicalSerialize; /// An IOP proof is a collections of /// - messages from prover to verifier at each round through the interactive diff --git a/subroutines/src/poly_iop/sum_check/verifier.rs b/subroutines/src/poly_iop/sum_check/verifier.rs index 043cb3c..d600212 100644 --- a/subroutines/src/poly_iop/sum_check/verifier.rs +++ b/subroutines/src/poly_iop/sum_check/verifier.rs @@ -321,7 +321,7 @@ mod test { use super::interpolate_uni_poly; use crate::poly_iop::errors::PolyIOPErrors; use ark_bls12_381::Fr; - use ark_poly::{univariate::DensePolynomial, Polynomial, UVPolynomial}; + use ark_poly::{univariate::DensePolynomial, DenseUVPolynomial, Polynomial}; use ark_std::{vec::Vec, UniformRand}; #[test] diff --git a/subroutines/src/poly_iop/utils.rs b/subroutines/src/poly_iop/utils.rs index ea3aa9c..e1761eb 100644 --- a/subroutines/src/poly_iop/utils.rs +++ b/subroutines/src/poly_iop/utils.rs @@ -13,7 +13,7 @@ macro_rules! to_bytes { ($x:expr) => {{ let mut buf = ark_std::vec![]; - ark_serialize::CanonicalSerialize::serialize($x, &mut buf).map(|_| buf) + ark_serialize::CanonicalSerialize::serialize_compressed($x, &mut buf).map(|_| buf) }}; } @@ -28,7 +28,7 @@ mod test { let f1 = Fr::one(); let mut bytes = ark_std::vec![]; - f1.serialize(&mut bytes).unwrap(); + f1.serialize_compressed(&mut bytes).unwrap(); assert_eq!(bytes, to_bytes!(&f1).unwrap()); } } diff --git a/transcript/Cargo.toml b/transcript/Cargo.toml index c12ee3d..eac798d 100644 --- a/transcript/Cargo.toml +++ b/transcript/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" [dependencies] -ark-ff = { version = "^0.3.0", default-features = false } -ark-serialize = { version = "^0.3.0", default-features = false } -ark-std = { version = "^0.3.0", default-features = false } +ark-ff = { version = "^0.4.0", default-features = false } +ark-serialize = { version = "^0.4.0", default-features = false } +ark-std = { version = "^0.4.0", default-features = false } displaydoc = { version = "0.2.3", default-features = false } merlin = { version = "3.0.0", default-features = false } diff --git a/transcript/src/lib.rs b/transcript/src/lib.rs index c103ab9..3129cae 100644 --- a/transcript/src/lib.rs +++ b/transcript/src/lib.rs @@ -126,6 +126,6 @@ impl IOPTranscript { macro_rules! to_bytes { ($x:expr) => {{ let mut buf = ark_std::vec![]; - ark_serialize::CanonicalSerialize::serialize($x, &mut buf).map(|_| buf) + ark_serialize::CanonicalSerialize::serialize_compressed($x, &mut buf).map(|_| buf) }}; }