feat: allow group switching, and switch group by default (#33)
zhenfei zhenfei.zhang@hotmail.com
Wed, 15 Jun 2022 17:39:54 -0400
5 files changed,
103 insertions(+),
9 deletions(-)
M
pcs/Cargo.toml
→
pcs/Cargo.toml
@@ -24,8 +24,9 @@ path = "benches/bench.rs"
harness = false [features] -default = [ "parallel", "print-trace" ] -# default = [ "parallel" ] +# by default we switch the groups +# default = [ "parallel", "print-trace", "group-switched" ] +default = [ "parallel", "group-switched" ] parallel = [ "ark-std/parallel", "ark-ff/parallel",@@ -34,4 +35,7 @@ "ark-ec/parallel",
] print-trace = [ "ark-std/print-trace" - ] + ] +# With the flag, we switch the groups of G1 and G2 as in a normal KZG. +# i.e., commitments are over G2 and openings are over G1 when this feature is turned on. +group-switched = []
M
pcs/readme.md
→
pcs/readme.md
@@ -1,3 +1,7 @@
KZG based multilinear polynomial commitment ----- +# Compiling features: +- `parallel`: use multi-threading when possible. +- `print-trace`: print out user friendly information about the running time for each micro component. +- `group-switched`: witch the groups of G1 and G2 as in a normal KZG. i.e., commitments are over G2 and openings are over G1 when this feature is turned on.
M
pcs/src/commit.rs
→
pcs/src/commit.rs
@@ -18,14 +18,20 @@ pub struct Commitment<E: PairingEngine> {
/// number of variables pub nv: usize, /// product of g as described by the vRAM paper + #[cfg(not(feature = "group-switched"))] pub g_product: E::G1Affine, + #[cfg(feature = "group-switched")] + pub g_product: E::G2Affine, } #[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)] /// proof of opening pub struct Proof<E: PairingEngine> { /// Evaluation of quotients + #[cfg(not(feature = "group-switched"))] pub proofs: Vec<E::G2Affine>, + #[cfg(feature = "group-switched")] + pub proofs: Vec<E::G1Affine>, } impl<E: PairingEngine> MultilinearCommitmentScheme<E> for KZGMultilinearPC<E> {@@ -160,7 +166,11 @@ scalar_size,
window_size, verifier_param.g.into_projective(), ); + #[cfg(not(feature = "group-switched"))] let g_mul: Vec<E::G1Projective> = + FixedBaseMSM::multi_scalar_mul(scalar_size, window_size, &g_table, point); + #[cfg(feature = "group-switched")] + let g_mul: Vec<E::G2Projective> = FixedBaseMSM::multi_scalar_mul(scalar_size, window_size, &g_table, point); let mut g1_vec: Vec<_> = (0..verifier_param.num_vars)@@ -168,12 +178,16 @@ .map(|i| verifier_param.g_mask[i].into_projective() - g_mul[i])
.collect(); g1_vec.push(verifier_param.g.mul(value) - commitment.g_product.into_projective()); + #[cfg(not(feature = "group-switched"))] let g1_vec: Vec<E::G1Affine> = E::G1Projective::batch_normalization_into_affine(&g1_vec); + #[cfg(feature = "group-switched")] + let g1_vec: Vec<E::G2Affine> = E::G2Projective::batch_normalization_into_affine(&g1_vec); let tmp = g1_vec[verifier_param.num_vars]; end_timer!(prepare_inputs_timer); let pairing_product_timer = start_timer!(|| "pairing product"); + #[cfg(not(feature = "group-switched"))] let mut pairings: Vec<_> = g1_vec .into_iter() .take(verifier_param.num_vars)@@ -181,9 +195,30 @@ .map(E::G1Prepared::from)
.zip(proof.proofs.iter().map(|&x| E::G2Prepared::from(x))) .collect(); + #[cfg(feature = "group-switched")] + let mut pairings: Vec<_> = proof + .proofs + .iter() + .take(verifier_param.num_vars) + .map(|&x| E::G1Prepared::from(x)) + .zip( + g1_vec + .into_iter() + .take(verifier_param.num_vars) + .map(E::G2Prepared::from), + ) + .collect(); + + #[cfg(not(feature = "group-switched"))] pairings.push(( E::G1Prepared::from(tmp), E::G2Prepared::from(verifier_param.h), + )); + + #[cfg(feature = "group-switched")] + pairings.push(( + E::G1Prepared::from(verifier_param.h), + E::G2Prepared::from(tmp), )); let res = E::product_of_pairings(pairings.iter()) == E::Fqk::one();
M
pcs/src/param.rs
→
pcs/src/param.rs
@@ -19,7 +19,10 @@ pub struct UniversalParams<E: PairingEngine> {
/// prover parameters pub prover_param: ProverParam<E>, /// g^randomness: g^t1, g^t2, ... + #[cfg(not(feature = "group-switched"))] pub g_mask: Vec<E::G1Affine>, + #[cfg(feature = "group-switched")] + pub g_mask: Vec<E::G2Affine>, } /// Prover Parameters@@ -29,14 +32,26 @@ /// number of variables
pub num_vars: usize, /// `pp_{num_vars}`, `pp_{num_vars - 1}`, `pp_{num_vars - 2}`, ..., defined /// by XZZPD19 + #[cfg(not(feature = "group-switched"))] pub powers_of_g: Vec<Evaluations<E::G1Affine>>, + #[cfg(feature = "group-switched")] + pub powers_of_g: Vec<Evaluations<E::G2Affine>>, /// `pp_{num_vars}`, `pp_{num_vars - 1}`, `pp_{num_vars - 2}`, ..., defined /// by XZZPD19 + #[cfg(not(feature = "group-switched"))] pub powers_of_h: Vec<Evaluations<E::G2Affine>>, + #[cfg(feature = "group-switched")] + pub powers_of_h: Vec<Evaluations<E::G1Affine>>, /// generator for G1 + #[cfg(not(feature = "group-switched"))] pub g: E::G1Affine, + #[cfg(feature = "group-switched")] + pub g: E::G2Affine, /// generator for G2 + #[cfg(not(feature = "group-switched"))] pub h: E::G2Affine, + #[cfg(feature = "group-switched")] + pub h: E::G1Affine, } /// Verifier Parameters@@ -44,12 +59,24 @@ #[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)]
pub struct VerifierParam<E: PairingEngine> { /// number of variables pub num_vars: usize, + /// generator of G1 + #[cfg(not(feature = "group-switched"))] pub g: E::G1Affine, + #[cfg(feature = "group-switched")] + pub g: E::G2Affine, + /// generator of G2 + #[cfg(not(feature = "group-switched"))] pub h: E::G2Affine, + #[cfg(feature = "group-switched")] + pub h: E::G1Affine, + /// g^t1, g^t2, ... + #[cfg(not(feature = "group-switched"))] pub g_mask: Vec<E::G1Affine>, + #[cfg(feature = "group-switched")] + pub g_mask: Vec<E::G2Affine>, } impl<E: PairingEngine> UniversalParams<E> {@@ -116,8 +143,16 @@
let total_timer = start_timer!(|| "SRS generation"); let pp_generation_timer = start_timer!(|| "Prover Param generation"); + + #[cfg(not(feature = "group-switched"))] let g = E::G1Projective::rand(rng); + #[cfg(feature = "group-switched")] + let g = E::G2Projective::rand(rng); + + #[cfg(not(feature = "group-switched"))] let h = E::G2Projective::rand(rng); + #[cfg(feature = "group-switched")] + let h = E::G1Projective::rand(rng); let mut powers_of_g = Vec::new(); let mut powers_of_h = Vec::new();@@ -153,10 +188,20 @@ let window_size = FixedBaseMSM::get_mul_window_size(total_scalars);
let g_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, g); let h_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, h); + #[cfg(not(feature = "group-switched"))] let pp_g = E::G1Projective::batch_normalization_into_affine( &FixedBaseMSM::multi_scalar_mul(scalar_bits, window_size, &g_table, &pp_powers), ); + #[cfg(feature = "group-switched")] + let pp_g = E::G2Projective::batch_normalization_into_affine( + &FixedBaseMSM::multi_scalar_mul(scalar_bits, window_size, &g_table, &pp_powers), + ); + #[cfg(not(feature = "group-switched"))] let pp_h = E::G2Projective::batch_normalization_into_affine( + &FixedBaseMSM::multi_scalar_mul(scalar_bits, window_size, &h_table, &pp_powers), + ); + #[cfg(feature = "group-switched")] + let pp_h = E::G1Projective::batch_normalization_into_affine( &FixedBaseMSM::multi_scalar_mul(scalar_bits, window_size, &h_table, &pp_powers), ); let mut start = 0;@@ -187,12 +232,17 @@ let vp_generation_timer = start_timer!(|| "VP generation");
let g_mask = { let window_size = FixedBaseMSM::get_mul_window_size(num_vars); let g_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, g); - E::G1Projective::batch_normalization_into_affine(&FixedBaseMSM::multi_scalar_mul( - scalar_bits, - window_size, - &g_table, - &t, - )) + + #[cfg(not(feature = "group-switched"))] + let res = E::G1Projective::batch_normalization_into_affine( + &FixedBaseMSM::multi_scalar_mul(scalar_bits, window_size, &g_table, &t), + ); + + #[cfg(feature = "group-switched")] + let res = E::G2Projective::batch_normalization_into_affine( + &FixedBaseMSM::multi_scalar_mul(scalar_bits, window_size, &g_table, &t), + ); + res }; end_timer!(vp_generation_timer); end_timer!(total_timer);
M
scripts/run_tests.sh
→
scripts/run_tests.sh
@@ -3,6 +3,7 @@
# We want the code to panic if there is an integer overflow export RUSTFLAGS="-C overflow-checks=on" +cargo test --release -p pcs --no-default-features --features=parallel -- -Zunstable-options --report-time cargo test --release -- -Zunstable-options --report-time cargo test --no-run --features=print-trace cargo test --no-run --no-default-features