mirror of
https://github.com/arnaucube/hyperplonk.git
synced 2026-01-11 16:41:28 +01:00
move openings to g1 (#38) and remove switch_group feature
This commit is contained in:
@@ -24,9 +24,8 @@ path = "benches/bench.rs"
|
|||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# by default we switch the groups
|
# default = [ "parallel", "print-trace" ]
|
||||||
# default = [ "parallel", "print-trace", "group-switched" ]
|
default = [ "parallel" ]
|
||||||
default = [ "parallel", "group-switched" ]
|
|
||||||
parallel = [
|
parallel = [
|
||||||
"ark-std/parallel",
|
"ark-std/parallel",
|
||||||
"ark-ff/parallel",
|
"ark-ff/parallel",
|
||||||
@@ -36,6 +35,3 @@ parallel = [
|
|||||||
print-trace = [
|
print-trace = [
|
||||||
"ark-std/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 = []
|
|
||||||
@@ -4,4 +4,3 @@ KZG based multilinear polynomial commitment
|
|||||||
# Compiling features:
|
# Compiling features:
|
||||||
- `parallel`: use multi-threading when possible.
|
- `parallel`: use multi-threading when possible.
|
||||||
- `print-trace`: print out user friendly information about the running time for each micro component.
|
- `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,19 +18,13 @@ pub struct Commitment<E: PairingEngine> {
|
|||||||
/// number of variables
|
/// number of variables
|
||||||
pub nv: usize,
|
pub nv: usize,
|
||||||
/// product of g as described by the vRAM paper
|
/// product of g as described by the vRAM paper
|
||||||
#[cfg(not(feature = "group-switched"))]
|
|
||||||
pub g_product: E::G1Affine,
|
pub g_product: E::G1Affine,
|
||||||
#[cfg(feature = "group-switched")]
|
|
||||||
pub g_product: E::G2Affine,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)]
|
#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)]
|
||||||
/// proof of opening
|
/// proof of opening
|
||||||
pub struct Proof<E: PairingEngine> {
|
pub struct Proof<E: PairingEngine> {
|
||||||
/// Evaluation of quotients
|
/// Evaluation of quotients
|
||||||
#[cfg(not(feature = "group-switched"))]
|
|
||||||
pub proofs: Vec<E::G2Affine>,
|
|
||||||
#[cfg(feature = "group-switched")]
|
|
||||||
pub proofs: Vec<E::G1Affine>,
|
pub proofs: Vec<E::G1Affine>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,9 +100,9 @@ impl<E: PairingEngine> MultilinearCommitmentScheme<E> for KZGMultilinearPC<E> {
|
|||||||
|
|
||||||
let mut proofs = Vec::new();
|
let mut proofs = Vec::new();
|
||||||
|
|
||||||
for (i, (&point_at_k, hi)) in point
|
for (i, (&point_at_k, gi)) in point
|
||||||
.iter()
|
.iter()
|
||||||
.zip(prover_param.powers_of_h.iter())
|
.zip(prover_param.powers_of_g.iter())
|
||||||
.take(nv)
|
.take(nv)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
@@ -133,8 +127,8 @@ impl<E: PairingEngine> MultilinearCommitmentScheme<E> for KZGMultilinearPC<E> {
|
|||||||
q[k] = cur_q;
|
q[k] = cur_q;
|
||||||
r[k - 1] = cur_r;
|
r[k - 1] = cur_r;
|
||||||
|
|
||||||
// this is a MSM over G2 and is likely to be the bottleneck
|
// this is a MSM over G1 and is likely to be the bottleneck
|
||||||
proofs.push(VariableBaseMSM::multi_scalar_mul(&hi.evals, &scalars).into_affine());
|
proofs.push(VariableBaseMSM::multi_scalar_mul(&gi.evals, &scalars).into_affine());
|
||||||
end_timer!(ith_round);
|
end_timer!(ith_round);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,66 +155,42 @@ impl<E: PairingEngine> MultilinearCommitmentScheme<E> for KZGMultilinearPC<E> {
|
|||||||
let scalar_size = E::Fr::size_in_bits();
|
let scalar_size = E::Fr::size_in_bits();
|
||||||
let window_size = FixedBaseMSM::get_mul_window_size(verifier_param.num_vars);
|
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,
|
scalar_size,
|
||||||
window_size,
|
window_size,
|
||||||
verifier_param.g.into_projective(),
|
verifier_param.h.into_projective(),
|
||||||
);
|
);
|
||||||
#[cfg(not(feature = "group-switched"))]
|
let h_mul: Vec<E::G2Projective> =
|
||||||
let g_mul: Vec<E::G1Projective> =
|
FixedBaseMSM::multi_scalar_mul(scalar_size, window_size, &h_table, point);
|
||||||
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)
|
let h_vec: Vec<_> = (0..verifier_param.num_vars)
|
||||||
.map(|i| verifier_param.g_mask[i].into_projective() - g_mul[i])
|
.map(|i| verifier_param.h_mask[i].into_projective() - h_mul[i])
|
||||||
.collect();
|
.collect();
|
||||||
g1_vec.push(verifier_param.g.mul(value) - commitment.g_product.into_projective());
|
let h_vec: Vec<E::G2Affine> = E::G2Projective::batch_normalization_into_affine(&h_vec);
|
||||||
|
|
||||||
#[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);
|
end_timer!(prepare_inputs_timer);
|
||||||
|
|
||||||
let pairing_product_timer = start_timer!(|| "pairing product");
|
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
|
let mut pairings: Vec<_> = proof
|
||||||
.proofs
|
.proofs
|
||||||
.iter()
|
.iter()
|
||||||
.take(verifier_param.num_vars)
|
|
||||||
.map(|&x| E::G1Prepared::from(x))
|
.map(|&x| E::G1Prepared::from(x))
|
||||||
.zip(
|
.zip(
|
||||||
g1_vec
|
h_vec
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.take(verifier_param.num_vars)
|
.take(verifier_param.num_vars)
|
||||||
.map(E::G2Prepared::from),
|
.map(E::G2Prepared::from),
|
||||||
)
|
)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
#[cfg(not(feature = "group-switched"))]
|
|
||||||
pairings.push((
|
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),
|
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();
|
let res = E::product_of_pairings(pairings.iter()) == E::Fqk::one();
|
||||||
|
|
||||||
end_timer!(pairing_product_timer);
|
end_timer!(pairing_product_timer);
|
||||||
|
|||||||
@@ -18,11 +18,8 @@ pub struct Evaluations<C: AffineCurve> {
|
|||||||
pub struct UniversalParams<E: PairingEngine> {
|
pub struct UniversalParams<E: PairingEngine> {
|
||||||
/// prover parameters
|
/// prover parameters
|
||||||
pub prover_param: ProverParam<E>,
|
pub prover_param: ProverParam<E>,
|
||||||
/// g^randomness: g^t1, g^t2, ...
|
/// h^randomness: h^t1, h^t2, ..., **h^{t_nv}**
|
||||||
#[cfg(not(feature = "group-switched"))]
|
pub h_mask: Vec<E::G2Affine>,
|
||||||
pub g_mask: Vec<E::G1Affine>,
|
|
||||||
#[cfg(feature = "group-switched")]
|
|
||||||
pub g_mask: Vec<E::G2Affine>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prover Parameters
|
/// Prover Parameters
|
||||||
@@ -32,26 +29,11 @@ pub struct ProverParam<E: PairingEngine> {
|
|||||||
pub num_vars: usize,
|
pub num_vars: usize,
|
||||||
/// `pp_{num_vars}`, `pp_{num_vars - 1}`, `pp_{num_vars - 2}`, ..., defined
|
/// `pp_{num_vars}`, `pp_{num_vars - 1}`, `pp_{num_vars - 2}`, ..., defined
|
||||||
/// by XZZPD19
|
/// by XZZPD19
|
||||||
#[cfg(not(feature = "group-switched"))]
|
|
||||||
pub powers_of_g: Vec<Evaluations<E::G1Affine>>,
|
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
|
/// generator for G1
|
||||||
#[cfg(not(feature = "group-switched"))]
|
|
||||||
pub g: E::G1Affine,
|
pub g: E::G1Affine,
|
||||||
#[cfg(feature = "group-switched")]
|
|
||||||
pub g: E::G2Affine,
|
|
||||||
/// generator for G2
|
/// generator for G2
|
||||||
#[cfg(not(feature = "group-switched"))]
|
|
||||||
pub h: E::G2Affine,
|
pub h: E::G2Affine,
|
||||||
#[cfg(feature = "group-switched")]
|
|
||||||
pub h: E::G1Affine,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verifier Parameters
|
/// Verifier Parameters
|
||||||
@@ -61,22 +43,13 @@ pub struct VerifierParam<E: PairingEngine> {
|
|||||||
pub num_vars: usize,
|
pub num_vars: usize,
|
||||||
|
|
||||||
/// generator of G1
|
/// generator of G1
|
||||||
#[cfg(not(feature = "group-switched"))]
|
|
||||||
pub g: E::G1Affine,
|
pub g: E::G1Affine,
|
||||||
#[cfg(feature = "group-switched")]
|
|
||||||
pub g: E::G2Affine,
|
|
||||||
|
|
||||||
/// generator of G2
|
/// generator of G2
|
||||||
#[cfg(not(feature = "group-switched"))]
|
|
||||||
pub h: E::G2Affine,
|
pub h: E::G2Affine,
|
||||||
#[cfg(feature = "group-switched")]
|
|
||||||
pub h: E::G1Affine,
|
|
||||||
|
|
||||||
/// g^t1, g^t2, ...
|
/// h^randomness: h^t1, h^t2, ..., **h^{t_nv}**
|
||||||
#[cfg(not(feature = "group-switched"))]
|
pub h_mask: Vec<E::G2Affine>,
|
||||||
pub g_mask: Vec<E::G1Affine>,
|
|
||||||
#[cfg(feature = "group-switched")]
|
|
||||||
pub g_mask: Vec<E::G2Affine>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: PairingEngine> UniversalParams<E> {
|
impl<E: PairingEngine> UniversalParams<E> {
|
||||||
@@ -91,7 +64,7 @@ impl<E: PairingEngine> UniversalParams<E> {
|
|||||||
num_vars: self.prover_param.num_vars,
|
num_vars: self.prover_param.num_vars,
|
||||||
g: self.prover_param.g,
|
g: self.prover_param.g,
|
||||||
h: self.prover_param.h,
|
h: self.prover_param.h,
|
||||||
g_mask: self.g_mask.clone(),
|
h_mask: self.h_mask.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +85,6 @@ impl<E: PairingEngine> UniversalParams<E> {
|
|||||||
|
|
||||||
let to_reduce = self.prover_param.num_vars - supported_num_vars;
|
let to_reduce = self.prover_param.num_vars - supported_num_vars;
|
||||||
let ck = ProverParam {
|
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(),
|
powers_of_g: self.prover_param.powers_of_g[to_reduce..].to_vec(),
|
||||||
g: self.prover_param.g,
|
g: self.prover_param.g,
|
||||||
h: self.prover_param.h,
|
h: self.prover_param.h,
|
||||||
@@ -122,7 +94,7 @@ impl<E: PairingEngine> UniversalParams<E> {
|
|||||||
num_vars: supported_num_vars,
|
num_vars: supported_num_vars,
|
||||||
g: self.prover_param.g,
|
g: self.prover_param.g,
|
||||||
h: self.prover_param.h,
|
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))
|
Ok((ck, vk))
|
||||||
}
|
}
|
||||||
@@ -144,18 +116,11 @@ impl<E: PairingEngine> UniversalParams<E> {
|
|||||||
|
|
||||||
let pp_generation_timer = start_timer!(|| "Prover Param generation");
|
let pp_generation_timer = start_timer!(|| "Prover Param generation");
|
||||||
|
|
||||||
#[cfg(not(feature = "group-switched"))]
|
|
||||||
let g = E::G1Projective::rand(rng);
|
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);
|
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_g = Vec::new();
|
||||||
let mut powers_of_h = Vec::new();
|
|
||||||
let t: Vec<_> = (0..num_vars).map(|_| E::Fr::rand(rng)).collect();
|
let t: Vec<_> = (0..num_vars).map(|_| E::Fr::rand(rng)).collect();
|
||||||
let scalar_bits = E::Fr::size_in_bits();
|
let scalar_bits = E::Fr::size_in_bits();
|
||||||
|
|
||||||
@@ -186,35 +151,18 @@ impl<E: PairingEngine> UniversalParams<E> {
|
|||||||
}
|
}
|
||||||
let window_size = FixedBaseMSM::get_mul_window_size(total_scalars);
|
let window_size = FixedBaseMSM::get_mul_window_size(total_scalars);
|
||||||
let g_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, g);
|
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(
|
let pp_g = E::G1Projective::batch_normalization_into_affine(
|
||||||
&FixedBaseMSM::multi_scalar_mul(scalar_bits, window_size, &g_table, &pp_powers),
|
&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;
|
let mut start = 0;
|
||||||
for i in 0..num_vars {
|
for i in 0..num_vars {
|
||||||
let size = 1 << (num_vars - i);
|
let size = 1 << (num_vars - i);
|
||||||
let pp_k_g = Evaluations {
|
let pp_k_g = Evaluations {
|
||||||
evals: pp_g[start..(start + size)].to_vec(),
|
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_g.push(pp_k_g);
|
||||||
powers_of_h.push(pp_k_h);
|
|
||||||
start += size;
|
start += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,32 +171,26 @@ impl<E: PairingEngine> UniversalParams<E> {
|
|||||||
g: g.into_affine(),
|
g: g.into_affine(),
|
||||||
h: h.into_affine(),
|
h: h.into_affine(),
|
||||||
powers_of_g,
|
powers_of_g,
|
||||||
powers_of_h,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
end_timer!(pp_generation_timer);
|
end_timer!(pp_generation_timer);
|
||||||
|
|
||||||
let vp_generation_timer = start_timer!(|| "VP generation");
|
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 window_size = FixedBaseMSM::get_mul_window_size(num_vars);
|
||||||
let g_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, g);
|
let h_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, h);
|
||||||
|
E::G2Projective::batch_normalization_into_affine(&FixedBaseMSM::multi_scalar_mul(
|
||||||
#[cfg(not(feature = "group-switched"))]
|
scalar_bits,
|
||||||
let res = E::G1Projective::batch_normalization_into_affine(
|
window_size,
|
||||||
&FixedBaseMSM::multi_scalar_mul(scalar_bits, window_size, &g_table, &t),
|
&h_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!(vp_generation_timer);
|
||||||
end_timer!(total_timer);
|
end_timer!(total_timer);
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
prover_param: pp,
|
prover_param: pp,
|
||||||
g_mask,
|
h_mask,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user