Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for hiding degree bound #41

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/ipa_pc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{LabeledCommitment, LabeledPolynomial, LinearCombination};
use crate::{PCCommitterKey, PCRandomness, PCUniversalParams, Polynomial, PolynomialCommitment};

use algebra_core::{
to_bytes, AffineCurve, Field, One, PrimeField, ProjectiveCurve, ToBytes, UniformRand,
to_bytes, AffineCurve, Field, One, PrimeField, ProjectiveCurve, UniformRand,
VariableBaseMSM, Zero,
};
use core::{convert::TryInto, marker::PhantomData};
Expand Down Expand Up @@ -340,6 +340,7 @@ impl<G: AffineCurve, D: Digest> PolynomialCommitment<G::ScalarField> for InnerPr
fn trim(
pp: &Self::UniversalParams,
supported_degree: usize,
_supported_hiding_bound: usize,
_enforced_degree_bounds: Option<&[usize]>,
) -> Result<(Self::CommitterKey, Self::VerifierKey), Self::Error> {
// Ensure that supported_degree + 1 is a power of two
Expand Down
5 changes: 3 additions & 2 deletions src/kzg10/data_structures.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::*;
use algebra_core::{AffineCurve, PairingEngine, PrimeField, ProjectiveCurve, ToBytes, Zero};
use core::ops::{Add, AddAssign};
use std::collections::BTreeMap;

/// `UniversalParams` are the universal parameters for the KZG10 scheme.
#[derive(Derivative)]
Expand All @@ -9,13 +10,13 @@ pub struct UniversalParams<E: PairingEngine> {
/// Group elements of the form `{ \beta^i G }`, where `i` ranges from 0 to `degree`.
pub powers_of_g: Vec<E::G1Affine>,
/// Group elements of the form `{ \beta^i \gamma G }`, where `i` ranges from 0 to `degree`.
pub powers_of_gamma_g: Vec<E::G1Affine>,
pub powers_of_gamma_g: BTreeMap<usize, E::G1Affine>,
/// The generator of G2.
pub h: E::G2Affine,
/// \beta times the above generator of G2.
pub beta_h: E::G2Affine,
/// Group elements of the form `{ \beta^i G2 }`, where `i` ranges from `0` to `-degree`.
pub prepared_neg_powers_of_h: Option<Vec<E::G2Prepared>>,
pub prepared_neg_powers_of_h: BTreeMap<usize, E::G2Prepared>,
/// The generator of G2, prepared for use in pairings.
#[derivative(Debug = "ignore")]
pub prepared_h: E::G2Prepared,
Expand Down
24 changes: 19 additions & 5 deletions src/kzg10/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use core::marker::PhantomData;

mod data_structures;
pub use data_structures::*;
use std::collections::BTreeMap;

/// `KZG10` is an implementation of the polynomial commitment scheme of
/// [Kate, Zaverucha and Goldbgerg][kzg10]
Expand Down Expand Up @@ -79,7 +80,10 @@ impl<E: PairingEngine> KZG10<E> {

let powers_of_g = E::G1Projective::batch_normalization_into_affine(&powers_of_g);
let powers_of_gamma_g =
E::G1Projective::batch_normalization_into_affine(&powers_of_gamma_g);
E::G1Projective::batch_normalization_into_affine(&powers_of_gamma_g)
.into_iter()
.enumerate()
.collect();

let prepared_neg_powers_of_h_time =
start_timer!(|| "Generating negative powers of h in G2");
Expand All @@ -100,9 +104,17 @@ impl<E: PairingEngine> KZG10<E> {
);

let affines = E::G2Projective::batch_normalization_into_affine(&neg_powers_of_h);
Some(affines.into_iter().map(|a| a.into()).collect())
let mut affines_map = BTreeMap::new();
affines
.into_iter()
.enumerate()
.map(|(i, a)| (i, a.into()))
.for_each(|(i, a)| {
affines_map.insert(i, a);
});
affines_map
} else {
None
BTreeMap::new()
};

end_timer!(prepared_neg_powers_of_h_time);
Expand Down Expand Up @@ -477,15 +489,17 @@ mod tests {
supported_degree += 1;
}
let powers_of_g = pp.powers_of_g[..=supported_degree].to_vec();
let powers_of_gamma_g = pp.powers_of_gamma_g[..=supported_degree].to_vec();
let powers_of_gamma_g = (0..=supported_degree)
.map(|i| pp.powers_of_gamma_g[&i])
.collect();

let powers = Powers {
powers_of_g: Cow::Owned(powers_of_g),
powers_of_gamma_g: Cow::Owned(powers_of_gamma_g),
};
let vk = VerifierKey {
g: pp.powers_of_g[0],
gamma_g: pp.powers_of_gamma_g[0],
gamma_g: pp.powers_of_gamma_g[&0],
h: pp.h,
beta_h: pp.beta_h,
prepared_h: pp.prepared_h.clone(),
Expand Down
28 changes: 27 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ pub trait PolynomialCommitment<F: Field>: Sized {
fn trim(
pp: &Self::UniversalParams,
supported_degree: usize,
supported_hiding_bound: usize,
enforced_degree_bounds: Option<&[usize]>,
) -> Result<(Self::CommitterKey, Self::VerifierKey), Self::Error>;

Expand Down Expand Up @@ -519,8 +520,22 @@ pub mod tests {
))
}

let supported_hiding_bound = polynomials
.iter()
.map(|p| match p.hiding_bound() {
Some(b) => b,
None => 0,
})
.max()
.unwrap_or(0);
println!("supported degree: {:?}", supported_degree);
let (ck, vk) = PC::trim(&pp, supported_degree, Some(degree_bounds.as_slice()))?;
println!("supported hiding bound: {:?}", supported_hiding_bound);
let (ck, vk) = PC::trim(
&pp,
supported_degree,
supported_hiding_bound,
Some(degree_bounds.as_slice()),
)?;
println!("Trimmed");

let (comms, rands) = PC::commit(&ck, &polynomials, Some(rng))?;
Expand Down Expand Up @@ -628,11 +643,21 @@ pub mod tests {
hiding_bound,
))
}
let supported_hiding_bound = polynomials
.iter()
.map(|p| match p.hiding_bound() {
Some(b) => b,
None => 0,
})
.max()
.unwrap_or(0);
println!("supported degree: {:?}", supported_degree);
println!("supported hiding bound: {:?}", supported_hiding_bound);
println!("num_points_in_query_set: {:?}", num_points_in_query_set);
let (ck, vk) = PC::trim(
&pp,
supported_degree,
supported_hiding_bound,
degree_bounds.as_ref().map(|s| s.as_slice()),
)?;
println!("Trimmed");
Expand Down Expand Up @@ -769,6 +794,7 @@ pub mod tests {
let (ck, vk) = PC::trim(
&pp,
supported_degree,
supported_degree,
degree_bounds.as_ref().map(|s| s.as_slice()),
)?;
println!("Trimmed");
Expand Down
12 changes: 6 additions & 6 deletions src/marlin_pc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,10 @@ impl<E: PairingEngine> PolynomialCommitment<E::Fr> for MarlinKZG10<E> {
kzg10::KZG10::setup(max_degree, false, rng).map_err(Into::into)
}

// TODO: should trim also take in the hiding_bounds? That way we don't
// have to store many powers of gamma_g.
// TODO: add an optional hiding_bound.
fn trim(
pp: &Self::UniversalParams,
supported_degree: usize,
supported_hiding_bound: usize,
enforced_degree_bounds: Option<&[usize]>,
) -> Result<(Self::CommitterKey, Self::VerifierKey), Self::Error> {
let max_degree = pp.max_degree();
Expand All @@ -187,15 +185,17 @@ impl<E: PairingEngine> PolynomialCommitment<E::Fr> for MarlinKZG10<E> {
supported_degree
));
let powers = pp.powers_of_g[..=supported_degree].to_vec();
// We want to support making up to supported_degree queries to committed
// We want to support making up to `supported_hiding_bound` queries to committed
// polynomials.
let powers_of_gamma_g = pp.powers_of_gamma_g[..=(supported_degree + 1)].to_vec();
let powers_of_gamma_g = (0..=supported_hiding_bound + 1)
.map(|i| pp.powers_of_gamma_g[&i])
.collect::<Vec<_>>();
end_timer!(ck_time);

// Construct the core KZG10 verifier key.
let vk = kzg10::VerifierKey {
g: pp.powers_of_g[0],
gamma_g: pp.powers_of_gamma_g[0],
gamma_g: pp.powers_of_gamma_g[&0],
h: pp.h,
beta_h: pp.beta_h,
prepared_h: pp.prepared_h.clone(),
Expand Down
23 changes: 12 additions & 11 deletions src/sonic_pc/data_structures.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::kzg10;
use crate::{PCCommitterKey, PCVerifierKey, Vec};
use algebra_core::PairingEngine;
use std::collections::BTreeMap;

/// `UniversalParams` are the universal parameters for the KZG10 scheme.
pub type UniversalParams<E> = kzg10::UniversalParams<E>;
Expand Down Expand Up @@ -33,7 +34,7 @@ pub struct CommitterKey<E: PairingEngine> {

/// The powers used to commit to shifted hiding polynomials.
/// This is `None` if `self` does not support enforcing any degree bounds.
pub shifted_powers_of_gamma_g: Option<Vec<E::G1Affine>>,
pub shifted_powers_of_gamma_g: Option<BTreeMap<usize, Vec<E::G1Affine>>>,

/// The degree bounds that are supported by `self`.
/// Sorted in ascending order from smallest bound to largest bound.
Expand All @@ -60,26 +61,26 @@ impl<E: PairingEngine> CommitterKey<E> {
) -> Option<kzg10::Powers<E>> {
match (&self.shifted_powers_of_g, &self.shifted_powers_of_gamma_g) {
(Some(shifted_powers_of_g), Some(shifted_powers_of_gamma_g)) => {
let powers_range = if let Some(degree_bound) = degree_bound.into() {
let max_bound = self
.enforced_degree_bounds
.as_ref()
.unwrap()
.last()
.unwrap();
let (bound, powers_range) = if let Some(degree_bound) = degree_bound.into() {
assert!(self
.enforced_degree_bounds
.as_ref()
.unwrap()
.contains(&degree_bound));
let max_bound = self
.enforced_degree_bounds
.as_ref()
.unwrap()
.last()
.unwrap();
(max_bound - degree_bound)..
(degree_bound, (max_bound - degree_bound)..)
} else {
0..
(*max_bound, 0..)
};

let ck = kzg10::Powers {
powers_of_g: shifted_powers_of_g[powers_range.clone()].into(),
powers_of_gamma_g: shifted_powers_of_gamma_g[powers_range].into(),
powers_of_gamma_g: shifted_powers_of_gamma_g[&bound].clone().into(),
};

Some(ck)
Expand Down
26 changes: 20 additions & 6 deletions src/sonic_pc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,11 @@ impl<E: PairingEngine> PolynomialCommitment<E::Fr> for SonicKZG10<E> {
fn trim(
pp: &Self::UniversalParams,
supported_degree: usize,
supported_hiding_bound: usize,
enforced_degree_bounds: Option<&[usize]>,
) -> Result<(Self::CommitterKey, Self::VerifierKey), Self::Error> {
let trim_time = start_timer!(|| "Trimming public parameters");
let prepared_neg_powers_of_h = pp.prepared_neg_powers_of_h.as_ref().unwrap();
let prepared_neg_powers_of_h = &pp.prepared_neg_powers_of_h;
let max_degree = pp.max_degree();
if supported_degree > max_degree {
return Err(Error::TrimmingDegreeTooLarge);
Expand Down Expand Up @@ -180,8 +181,19 @@ impl<E: PairingEngine> PolynomialCommitment<E::Fr> for SonicKZG10<E> {
));

let shifted_powers_of_g = pp.powers_of_g[lowest_shift_degree..].to_vec();
let shifted_powers_of_gamma_g =
pp.powers_of_gamma_g[lowest_shift_degree..].to_vec();
let mut shifted_powers_of_gamma_g = BTreeMap::new();
// Also add degree 0.
for degree_bound in enforced_degree_bounds {
let shift_degree = max_degree - degree_bound;
let mut powers_for_degree_bound = vec![];
for i in 0..=supported_hiding_bound + 1 {
// We have an additional degree in `powers_of_gamma_g` beyond `powers_of_g`.
if shift_degree + i < max_degree + 2 {
powers_for_degree_bound.push(pp.powers_of_gamma_g[&(shift_degree + i)]);
}
}
shifted_powers_of_gamma_g.insert(*degree_bound, powers_for_degree_bound);
}

end_timer!(shifted_ck_time);

Expand All @@ -195,7 +207,7 @@ impl<E: PairingEngine> PolynomialCommitment<E::Fr> for SonicKZG10<E> {
.map(|bound| {
(
*bound,
prepared_neg_powers_of_h[max_degree - *bound].clone(),
prepared_neg_powers_of_h[&(max_degree - *bound)].clone(),
)
})
.collect();
Expand All @@ -213,7 +225,9 @@ impl<E: PairingEngine> PolynomialCommitment<E::Fr> for SonicKZG10<E> {
};

let powers_of_g = pp.powers_of_g[..=supported_degree].to_vec();
let powers_of_gamma_g = pp.powers_of_gamma_g[..=(supported_degree + 1)].to_vec();
let powers_of_gamma_g = (0..=supported_hiding_bound + 1)
.map(|i| pp.powers_of_gamma_g[&i])
.collect();

let ck = CommitterKey {
powers_of_g,
Expand All @@ -227,7 +241,7 @@ impl<E: PairingEngine> PolynomialCommitment<E::Fr> for SonicKZG10<E> {
let g = pp.powers_of_g[0];
let h = pp.h;
let beta_h = pp.beta_h;
let gamma_g = pp.powers_of_gamma_g[0];
let gamma_g = pp.powers_of_gamma_g[&0];
let prepared_h = (&pp.prepared_h).clone();
let prepared_beta_h = (&pp.prepared_beta_h).clone();

Expand Down