From 366a2674bca4d8106cd18df608c408218ff868e0 Mon Sep 17 00:00:00 2001 From: chancharles92 Date: Tue, 6 Dec 2022 09:43:01 -0500 Subject: [PATCH] remove identity polynomial commitments and PCS evaluations (#104) * remove sid pcs evals * minor optimization + more timers --- hyperplonk/src/snark.rs | 44 +++++++------------ hyperplonk/src/structs.rs | 28 +++++++++--- .../src/pcs/multilinear_kzg/batching.rs | 13 ++++-- 3 files changed, 45 insertions(+), 40 deletions(-) diff --git a/hyperplonk/src/snark.rs b/hyperplonk/src/snark.rs index e1615ac..ce685f3 100644 --- a/hyperplonk/src/snark.rs +++ b/hyperplonk/src/snark.rs @@ -5,7 +5,7 @@ use crate::{ witness::WitnessColumn, HyperPlonkSNARK, }; -use arithmetic::{evaluate_opt, identity_permutation_mles, VPAuxInfo}; +use arithmetic::{evaluate_opt, gen_eval_point, VPAuxInfo}; use ark_ec::PairingEngine; use ark_poly::DenseMultilinearExtension; use ark_std::{end_timer, log2, start_timer, One, Zero}; @@ -51,13 +51,6 @@ where let (pcs_prover_param, pcs_verifier_param) = PCS::trim(pcs_srs, None, Some(supported_ml_degree))?; - // build identity oracles - let id_oracles = identity_permutation_mles(num_vars, index.num_witness_columns()); - let mut id_comms = vec![]; - for id_oracle in id_oracles.iter() { - id_comms.push(PCS::commit(&pcs_prover_param, id_oracle)?); - } - // build permutation oracles let mut permutation_oracles = vec![]; let mut perm_comms = vec![]; @@ -87,12 +80,10 @@ where Ok(( Self::ProvingKey { params: index.params.clone(), - id_oracles, permutation_oracles, selector_oracles, selector_commitments: selector_commitments.clone(), permutation_commitments: perm_comms.clone(), - id_commitments: id_comms.clone(), pcs_param: pcs_prover_param, }, Self::VerifyingKey { @@ -100,7 +91,6 @@ where pcs_param: pcs_verifier_param, selector_commitments, perm_commitments: perm_comms, - id_commitments: id_comms, }, )) } @@ -290,11 +280,6 @@ where &perm_check_point_1, ); - // s_id(x)'s points - for (s_id, s_com) in pk.id_oracles.iter().zip(pk.id_commitments.iter()) { - pcs_acc.insert_poly_and_points(s_id, s_com, perm_check_point); - } - // perms(x)'s points for (perm, pcom) in pk .permutation_oracles @@ -414,15 +399,13 @@ where // Extract evaluations from openings let prod_evals = &proof.batch_openings.f_i_eval_at_point_i[0..4]; let frac_evals = &proof.batch_openings.f_i_eval_at_point_i[4..7]; - let id_evals = &proof.batch_openings.f_i_eval_at_point_i[7..7 + num_witnesses]; - let perm_evals = - &proof.batch_openings.f_i_eval_at_point_i[7 + num_witnesses..7 + 2 * num_witnesses]; + let perm_evals = &proof.batch_openings.f_i_eval_at_point_i[7..7 + num_witnesses]; let witness_perm_evals = - &proof.batch_openings.f_i_eval_at_point_i[7 + 2 * num_witnesses..7 + 3 * num_witnesses]; + &proof.batch_openings.f_i_eval_at_point_i[7 + num_witnesses..7 + 2 * num_witnesses]; let witness_gate_evals = - &proof.batch_openings.f_i_eval_at_point_i[7 + 3 * num_witnesses..7 + 4 * num_witnesses]; + &proof.batch_openings.f_i_eval_at_point_i[7 + 2 * num_witnesses..7 + 3 * num_witnesses]; let selector_evals = &proof.batch_openings.f_i_eval_at_point_i - [7 + 4 * num_witnesses..7 + 4 * num_witnesses + num_selectors]; + [7 + 3 * num_witnesses..7 + 3 * num_witnesses + num_selectors]; let pi_eval = proof.batch_openings.f_i_eval_at_point_i.last().unwrap(); // ======================================================================= @@ -491,12 +474,18 @@ where let alpha = perm_check_sub_claim.product_check_sub_claim.alpha; let (beta, gamma) = perm_check_sub_claim.challenges; + let mut id_evals = vec![]; + for i in 0..num_witnesses { + let ith_point = gen_eval_point(i, log2(num_witnesses) as usize, &perm_check_point[..]); + id_evals.push(vk.params.eval_id_oracle(&ith_point[..])?); + } + // check evaluation subclaim let perm_gate_eval = eval_perm_gate( prod_evals, frac_evals, witness_perm_evals, - id_evals, + &id_evals[..], perm_evals, alpha, beta, @@ -546,12 +535,6 @@ where points.push(perm_check_point_0); points.push(perm_check_point_1); - // s_id's points - for &id_com in vk.id_commitments.iter() { - comms.push(id_com); - points.push(perm_check_point.clone()); - } - // perms' points for &pcom in vk.perm_commitments.iter() { comms.push(pcom); @@ -559,6 +542,7 @@ where } // witnesses' points + // TODO: merge points for &wcom in proof.witness_commits.iter() { comms.push(wcom); points.push(perm_check_point.clone()); @@ -579,6 +563,7 @@ where let r_pi = transcript.get_and_append_challenge_vectors(b"r_pi", ell)?; // check public evaluation + let pi_step = start_timer!(|| "check public evaluation"); let pi_poly = DenseMultilinearExtension::from_evaluations_slice(ell as usize, pub_input); let expect_pi_eval = evaluate_opt(&pi_poly, &r_pi[..]); if expect_pi_eval != *pi_eval { @@ -592,6 +577,7 @@ where comms.push(proof.witness_commits[0]); points.push(r_pi_padded); assert_eq!(comms.len(), proof.batch_openings.f_i_eval_at_point_i.len()); + end_timer!(pi_step); end_timer!(step); let step = start_timer!(|| "PCS batch verify"); diff --git a/hyperplonk/src/structs.rs b/hyperplonk/src/structs.rs index c381a16..df961e1 100644 --- a/hyperplonk/src/structs.rs +++ b/hyperplonk/src/structs.rs @@ -1,6 +1,6 @@ //! Main module for the HyperPlonk PolyIOP. -use crate::{custom_gate::CustomizedGates, selectors::SelectorColumn}; +use crate::{custom_gate::CustomizedGates, prelude::HyperPlonkErrors, selectors::SelectorColumn}; use ark_ec::PairingEngine; use ark_ff::PrimeField; use ark_poly::DenseMultilinearExtension; @@ -66,6 +66,26 @@ impl HyperPlonkParams { pub fn num_witness_columns(&self) -> usize { self.gate_func.num_witness_columns() } + + /// evaluate the identical polynomial + pub fn eval_id_oracle(&self, point: &[F]) -> Result { + let len = self.num_variables() + (log2(self.num_witness_columns()) as usize); + if point.len() != len { + return Err(HyperPlonkErrors::InvalidParameters(format!( + "ID oracle point length = {}, expected {}", + point.len(), + len, + ))); + } + + let mut res = F::zero(); + let mut base = F::one(); + for &v in point.iter() { + res += base * v; + base += base; + } + Ok(res) + } } /// The HyperPlonk index, consists of the following: @@ -107,16 +127,12 @@ pub struct HyperPlonkProvingKey>>, - /// The preprocessed identity polynomials - pub id_oracles: Vec>>, /// The preprocessed selector polynomials pub selector_oracles: Vec>>, /// Commitments to the preprocessed selector polynomials pub selector_commitments: Vec, /// Commitments to the preprocessed permutation polynomials pub permutation_commitments: Vec, - /// Commitments to the preprocessed identity polynomials - pub id_commitments: Vec, /// The parameters for PCS commitment pub pcs_param: PCS::ProverParam, } @@ -135,6 +151,4 @@ pub struct HyperPlonkVerifyingKey, /// Permutation oracles' commitments pub perm_commitments: Vec, - /// Commitments to the preprocessed identity polynomials - pub id_commitments: Vec, } diff --git a/subroutines/src/pcs/multilinear_kzg/batching.rs b/subroutines/src/pcs/multilinear_kzg/batching.rs index c235c2b..9b4e3f5 100644 --- a/subroutines/src/pcs/multilinear_kzg/batching.rs +++ b/subroutines/src/pcs/multilinear_kzg/batching.rs @@ -14,7 +14,8 @@ use crate::{ IOPProof, }; use arithmetic::{build_eq_x_r_vec, DenseMultilinearExtension, VPAuxInfo, VirtualPolynomial}; -use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; +use ark_ec::{msm::VariableBaseMSM, PairingEngine, ProjectiveCurve}; +use ark_ff::PrimeField; use ark_std::{end_timer, log2, start_timer, One, Zero}; use std::{marker::PhantomData, rc::Rc}; use transcript::IOPTranscript; @@ -189,15 +190,19 @@ where let a2 = &proof.sum_check_proof.point[..num_var]; // build g' commitment + let step = start_timer!(|| "build homomorphic commitment"); let eq_t_list = build_eq_x_r_vec(t.as_ref())?; - let mut g_prime_commit = E::G1Affine::zero().into_projective(); + let mut scalars = vec![]; + let mut bases = vec![]; for (i, point) in points.iter().enumerate() { let eq_i_a2 = eq_eval(a2, point)?; - let tmp = eq_i_a2 * eq_t_list[i]; - g_prime_commit += &f_i_commitments[i].0.mul(tmp); + scalars.push((eq_i_a2 * eq_t_list[i]).into_repr()); + bases.push(f_i_commitments[i].0); } + let g_prime_commit = VariableBaseMSM::multi_scalar_mul(&bases, &scalars); + end_timer!(step); // ensure \sum_i eq(t, ) * f_i_evals matches the sum via SumCheck let mut sum = E::Fr::zero();