arnaucube
arnaucube/hyperplonkPublic Self-hosted repository
feat: allow group switching, and switch group by default (#33)

zhenfei zhenfei.zhang@hotmail.com
Wed, 15 Jun 2022 17:39:54 -0400
commit

3b58050b2714ce25230b3baed53470f3676947a3

parent

1d12a3e582e2aed7e801c3861cb9d6582e37de37

5 files changed, 103 insertions(+), 9 deletions(-)

jump to
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