Skip to content

Commit

Permalink
move openings to g1 (#38) and remove switch_group feature
Browse files Browse the repository at this point in the history
  • Loading branch information
zhenfeizhang authored Jun 29, 2022
1 parent 3b58050 commit a8c7378
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 132 deletions.
10 changes: 3 additions & 7 deletions pcs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ path = "benches/bench.rs"
harness = false

[features]
# by default we switch the groups
# default = [ "parallel", "print-trace", "group-switched" ]
default = [ "parallel", "group-switched" ]
# default = [ "parallel", "print-trace" ]
default = [ "parallel" ]
parallel = [
"ark-std/parallel",
"ark-ff/parallel",
Expand All @@ -35,7 +34,4 @@ 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 = []
]
3 changes: 1 addition & 2 deletions pcs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ 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.
- `print-trace`: print out user friendly information about the running time for each micro component.
64 changes: 17 additions & 47 deletions pcs/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,13 @@ 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>,
}

Expand Down Expand Up @@ -106,9 +100,9 @@ impl<E: PairingEngine> MultilinearCommitmentScheme<E> for KZGMultilinearPC<E> {

let mut proofs = Vec::new();

for (i, (&point_at_k, hi)) in point
for (i, (&point_at_k, gi)) in point
.iter()
.zip(prover_param.powers_of_h.iter())
.zip(prover_param.powers_of_g.iter())
.take(nv)
.enumerate()
{
Expand All @@ -133,8 +127,8 @@ impl<E: PairingEngine> MultilinearCommitmentScheme<E> for KZGMultilinearPC<E> {
q[k] = cur_q;
r[k - 1] = cur_r;

// this is a MSM over G2 and is likely to be the bottleneck
proofs.push(VariableBaseMSM::multi_scalar_mul(&hi.evals, &scalars).into_affine());
// this is a MSM over G1 and is likely to be the bottleneck
proofs.push(VariableBaseMSM::multi_scalar_mul(&gi.evals, &scalars).into_affine());
end_timer!(ith_round);
}

Expand All @@ -161,66 +155,42 @@ impl<E: PairingEngine> MultilinearCommitmentScheme<E> for KZGMultilinearPC<E> {
let scalar_size = E::Fr::size_in_bits();
let window_size = FixedBaseMSM::get_mul_window_size(verifier_param.num_vars);

let g_table = FixedBaseMSM::get_window_table(
let h_table = FixedBaseMSM::get_window_table(
scalar_size,
window_size,
verifier_param.g.into_projective(),
verifier_param.h.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)
.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());
let h_mul: Vec<E::G2Projective> =
FixedBaseMSM::multi_scalar_mul(scalar_size, window_size, &h_table, point);

#[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];
let h_vec: Vec<_> = (0..verifier_param.num_vars)
.map(|i| verifier_param.h_mask[i].into_projective() - h_mul[i])
.collect();
let h_vec: Vec<E::G2Affine> = E::G2Projective::batch_normalization_into_affine(&h_vec);
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)
.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
h_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::G1Prepared::from(
(verifier_param.g.mul(value) - commitment.g_product.into_projective())
.into_affine(),
),
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();

end_timer!(pairing_product_timer);
Expand Down
94 changes: 18 additions & 76 deletions pcs/src/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ pub struct Evaluations<C: AffineCurve> {
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>,
/// h^randomness: h^t1, h^t2, ..., **h^{t_nv}**
pub h_mask: Vec<E::G2Affine>,
}

/// Prover Parameters
Expand All @@ -32,26 +29,11 @@ pub struct ProverParam<E: PairingEngine> {
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
Expand All @@ -61,22 +43,13 @@ pub struct VerifierParam<E: PairingEngine> {
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>,

/// h^randomness: h^t1, h^t2, ..., **h^{t_nv}**
pub h_mask: Vec<E::G2Affine>,
}

impl<E: PairingEngine> UniversalParams<E> {
Expand All @@ -91,7 +64,7 @@ impl<E: PairingEngine> UniversalParams<E> {
num_vars: self.prover_param.num_vars,
g: self.prover_param.g,
h: self.prover_param.h,
g_mask: self.g_mask.clone(),
h_mask: self.h_mask.clone(),
}
}

Expand All @@ -112,7 +85,6 @@ impl<E: PairingEngine> UniversalParams<E> {

let to_reduce = self.prover_param.num_vars - supported_num_vars;
let ck = ProverParam {
powers_of_h: self.prover_param.powers_of_h[to_reduce..].to_vec(),
powers_of_g: self.prover_param.powers_of_g[to_reduce..].to_vec(),
g: self.prover_param.g,
h: self.prover_param.h,
Expand All @@ -122,7 +94,7 @@ impl<E: PairingEngine> UniversalParams<E> {
num_vars: supported_num_vars,
g: self.prover_param.g,
h: self.prover_param.h,
g_mask: self.g_mask[to_reduce..].to_vec(),
h_mask: self.h_mask[to_reduce..].to_vec(),
};
Ok((ck, vk))
}
Expand All @@ -144,18 +116,11 @@ impl<E: PairingEngine> UniversalParams<E> {

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();

let t: Vec<_> = (0..num_vars).map(|_| E::Fr::rand(rng)).collect();
let scalar_bits = E::Fr::size_in_bits();

Expand Down Expand Up @@ -186,35 +151,18 @@ impl<E: PairingEngine> UniversalParams<E> {
}
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;
for i in 0..num_vars {
let size = 1 << (num_vars - i);
let pp_k_g = Evaluations {
evals: pp_g[start..(start + size)].to_vec(),
};
let pp_k_h = Evaluations {
evals: pp_h[start..(start + size)].to_vec(),
};
powers_of_g.push(pp_k_g);
powers_of_h.push(pp_k_h);
start += size;
}

Expand All @@ -223,32 +171,26 @@ impl<E: PairingEngine> UniversalParams<E> {
g: g.into_affine(),
h: h.into_affine(),
powers_of_g,
powers_of_h,
};

end_timer!(pp_generation_timer);

let vp_generation_timer = start_timer!(|| "VP generation");
let g_mask = {
let h_mask = {
let window_size = FixedBaseMSM::get_mul_window_size(num_vars);
let g_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, g);

#[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
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,
))
};
end_timer!(vp_generation_timer);
end_timer!(total_timer);
Ok(Self {
prover_param: pp,
g_mask,
h_mask,
})
}
}
Expand Down

0 comments on commit a8c7378

Please sign in to comment.