Browse Source

refactor multilinear PCS opening

main
chancharles92 1 year ago
committed by GitHub
parent
commit
f16db389e3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 29 deletions
  1. +17
    -26
      subroutines/src/pcs/multilinear_kzg/mod.rs
  2. +12
    -3
      subroutines/src/pcs/multilinear_kzg/srs.rs

+ 17
- 26
subroutines/src/pcs/multilinear_kzg/mod.rs

@ -209,11 +209,10 @@ impl PolynomialCommitmentScheme for MultilinearKzgPCS {
/// same. This function does not need to take the evaluation value as an /// same. This function does not need to take the evaluation value as an
/// input. /// input.
/// ///
/// This function takes 2^{num_var +1} number of scalar multiplications over
/// This function takes 2^{num_var} number of scalar multiplications over
/// G1: /// G1:
/// - it proceeds with `num_var` number of rounds, /// - it proceeds with `num_var` number of rounds,
/// - at round i, we compute an MSM for `2^{num_var - i + 1}` number of G2
/// elements.
/// - at round i, we compute an MSM for `2^{num_var - i}` number of G1 elements.
fn open_internal<E: PairingEngine>( fn open_internal<E: PairingEngine>(
prover_param: &MultilinearProverParam<E>, prover_param: &MultilinearProverParam<E>,
polynomial: &DenseMultilinearExtension<E::Fr>, polynomial: &DenseMultilinearExtension<E::Fr>,
@ -237,41 +236,34 @@ fn open_internal(
} }
let nv = polynomial.num_vars(); let nv = polynomial.num_vars();
let ignored = prover_param.num_vars - nv;
let mut r: Vec<Vec<E::Fr>> = (0..nv + 1).map(|_| Vec::new()).collect();
let mut q: Vec<Vec<E::Fr>> = (0..nv + 1).map(|_| Vec::new()).collect();
r[nv] = polynomial.to_evaluations();
let mut f = polynomial.to_evaluations();
let mut proofs = Vec::new(); let mut proofs = Vec::new();
for (i, (&point_at_k, gi)) in point for (i, (&point_at_k, gi)) in point
.iter() .iter()
.zip(prover_param.powers_of_g[ignored..].iter())
.take(nv)
.zip(prover_param.powers_of_g[1..nv + 1].iter())
.enumerate() .enumerate()
{ {
let ith_round = start_timer!(|| format!("{}-th round", i)); let ith_round = start_timer!(|| format!("{}-th round", i));
let k = nv - i;
let cur_dim = 1 << (k - 1);
let mut cur_q = vec![E::Fr::zero(); cur_dim];
let mut cur_r = vec![E::Fr::zero(); cur_dim];
let one_minus_point_at_k = E::Fr::one() - point_at_k;
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 ith_round_eval = start_timer!(|| format!("{}-th round eval", i)); let ith_round_eval = start_timer!(|| format!("{}-th round eval", i));
for b in 0..(1 << (k - 1)) {
// q_b = pre_r [2^b + 1] - pre_r [2^b]
cur_q[b] = r[k][(b << 1) + 1] - r[k][b << 1];
for b in 0..(1 << k) {
// q[b] = f[1, b] - f[0, b]
q[b] = f[(b << 1) + 1] - f[b << 1];
// r_b = pre_r [2^b]*(1-p) + pre_r [2^b + 1] * p
cur_r[b] = r[k][b << 1] * one_minus_point_at_k + (r[k][(b << 1) + 1] * point_at_k);
// r[b] = f[0, b] + q[b] * p
r[b] = f[b << 1] + (q[b] * point_at_k);
} }
f = r;
end_timer!(ith_round_eval); end_timer!(ith_round_eval);
let scalars: Vec<_> = (0..(1 << k)).map(|x| cur_q[x >> 1].into_repr()).collect();
q[k] = cur_q;
r[k - 1] = cur_r;
let scalars: Vec<_> = q.iter().map(|x| x.into_repr()).collect();
// this is a MSM over G1 and is likely to be the bottleneck // 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)); let msm_timer = start_timer!(|| format!("msm of size {} at round {}", gi.evals.len(), i));
@ -309,7 +301,6 @@ fn verify_internal(
))); )));
} }
let ignored = verifier_param.num_vars - num_var;
let prepare_inputs_timer = start_timer!(|| "prepare pairing inputs"); let prepare_inputs_timer = start_timer!(|| "prepare pairing inputs");
let scalar_size = E::Fr::size_in_bits(); let scalar_size = E::Fr::size_in_bits();
@ -324,7 +315,7 @@ fn verify_internal(
FixedBaseMSM::multi_scalar_mul(scalar_size, window_size, &h_table, point); FixedBaseMSM::multi_scalar_mul(scalar_size, window_size, &h_table, point);
let h_vec: Vec<_> = (0..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[i].into_projective() - h_mul[i])
.collect(); .collect();
let h_vec: Vec<E::G2Affine> = E::G2Projective::batch_normalization_into_affine(&h_vec); let h_vec: Vec<E::G2Affine> = E::G2Projective::batch_normalization_into_affine(&h_vec);
end_timer!(prepare_inputs_timer); end_timer!(prepare_inputs_timer);
@ -370,7 +361,7 @@ mod tests {
) -> Result<(), PCSError> { ) -> Result<(), PCSError> {
let nv = poly.num_vars(); let nv = poly.num_vars();
assert_ne!(nv, 0); assert_ne!(nv, 0);
let (ck, vk) = MultilinearKzgPCS::trim(params, None, Some(nv + 1))?;
let (ck, vk) = MultilinearKzgPCS::trim(params, None, Some(nv))?;
let point: Vec<_> = (0..nv).map(|_| Fr::rand(rng)).collect(); let point: Vec<_> = (0..nv).map(|_| Fr::rand(rng)).collect();
let com = MultilinearKzgPCS::commit(&ck, poly)?; let com = MultilinearKzgPCS::commit(&ck, poly)?;
let (proof, value) = MultilinearKzgPCS::open(&ck, poly, &point)?; let (proof, value) = MultilinearKzgPCS::open(&ck, poly, &point)?;

+ 12
- 3
subroutines/src/pcs/multilinear_kzg/srs.rs

@ -44,8 +44,9 @@ pub struct MultilinearUniversalParams {
pub struct MultilinearProverParam<E: PairingEngine> { pub struct MultilinearProverParam<E: PairingEngine> {
/// number of variables /// number of variables
pub num_vars: usize, pub num_vars: usize,
/// `pp_{num_vars}`, `pp_{num_vars - 1}`, `pp_{num_vars - 2}`, ..., defined
/// by XZZPD19
/// `pp_{0}`, `pp_{1}`, ...,pp_{nu_vars} defined
/// by XZZPD19 where pp_{nv-0}=g and
/// pp_{nv-i}=g^{eq((t_1,..t_i),(X_1,..X_i))}
pub powers_of_g: Vec<Evaluations<E::G1Affine>>, pub powers_of_g: Vec<Evaluations<E::G1Affine>>,
/// generator for G1 /// generator for G1
pub g: E::G1Affine, pub g: E::G1Affine,
@ -190,6 +191,10 @@ impl StructuredReferenceString for MultilinearUniversalPara
powers_of_g.push(pp_k_g); powers_of_g.push(pp_k_g);
start += size; start += size;
} }
let gg = Evaluations {
evals: [g.into_affine()].to_vec(),
};
powers_of_g.push(gg);
let pp = Self::ProverParam { let pp = Self::ProverParam {
num_vars, num_vars,
@ -245,7 +250,11 @@ mod tests {
fn test_srs_gen() -> Result<(), PCSError> { fn test_srs_gen() -> Result<(), PCSError> {
let mut rng = test_rng(); let mut rng = test_rng();
for nv in 4..10 { for nv in 4..10 {
let _ = MultilinearUniversalParams::<E>::gen_srs_for_testing(&mut rng, nv)?;
let params = MultilinearUniversalParams::<E>::gen_srs_for_testing(&mut rng, nv)?;
assert_eq!(
params.prover_param.g,
params.prover_param.powers_of_g[0].evals[0]
);
} }
Ok(()) Ok(())

Loading…
Cancel
Save