mirror of
https://github.com/arnaucube/hyperplonk.git
synced 2026-01-11 00:21:28 +01:00
feat: allow group switching, and switch group by default (#33)
This commit is contained in:
@@ -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",
|
||||
@@ -35,3 +36,6 @@ 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 = []
|
||||
@@ -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.
|
||||
@@ -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,20 +166,28 @@ impl<E: PairingEngine> MultilinearCommitmentScheme<E> for KZGMultilinearPC<E> {
|
||||
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)
|
||||
.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,11 +195,32 @@ impl<E: PairingEngine> MultilinearCommitmentScheme<E> for KZGMultilinearPC<E> {
|
||||
.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();
|
||||
|
||||
end_timer!(pairing_product_timer);
|
||||
|
||||
@@ -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 @@ 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
|
||||
@@ -44,12 +59,24 @@ pub struct ProverParam<E: PairingEngine> {
|
||||
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 @@ impl<E: PairingEngine> UniversalParams<E> {
|
||||
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,12 +188,22 @@ impl<E: PairingEngine> UniversalParams<E> {
|
||||
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);
|
||||
@@ -187,12 +232,17 @@ impl<E: PairingEngine> UniversalParams<E> {
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user