Skip to content

Commit

Permalink
perf: naive parallel implementation for multi_open_rou_proofs (#428)
Browse files Browse the repository at this point in the history
* parallel impl for multi_open_rou_proofs()

* feature-gate timer logs for open()

* fix build warning/break when 'parallel' feature is off

* new feature gate no-fk23

* fix build break for feature combo --no-default-features and test-srs,print-trace

* rename feature no-fk23 -> naive-kzg-multi-open as per #428 (comment)
  • Loading branch information
ggutoski authored Nov 28, 2023
1 parent 265eaaa commit 1c5f59a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 11 deletions.
3 changes: 3 additions & 0 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ print-trace = ["ark-std/print-trace"]
kzg-print-trace = [
"print-trace",
] # leave disabled to reduce pollution in downstream users of KZG (such as VID)
naive-kzg-multi-open = [
"parallel",
] # enable to use an alternate (parallel) impl of multi_open_rou_proofs()
parallel = [
"ark-ff/parallel",
"ark-ec/parallel",
Expand Down
59 changes: 49 additions & 10 deletions primitives/src/pcs/univariate_kzg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,18 @@ impl<E: Pairing> PolynomialCommitmentScheme for UnivariateKzgPCS<E> {
polynomial: &Self::Polynomial,
point: &Self::Point,
) -> Result<(Self::Proof, Self::Evaluation), PCSError> {
#[cfg(feature = "kzg-print-trace")]
let open_time =
start_timer!(|| format!("Opening polynomial of degree {}", polynomial.degree()));

let divisor = Self::Polynomial::from_coefficients_vec(vec![-*point, E::ScalarField::one()]);

#[cfg(feature = "kzg-print-trace")]
let witness_time = start_timer!(|| "Computing witness polynomial");

let witness_polynomial = polynomial / &divisor;

#[cfg(feature = "kzg-print-trace")]
end_timer!(witness_time);

let (num_leading_zeros, witness_coeffs) =
Expand All @@ -164,9 +170,13 @@ impl<E: Pairing> PolynomialCommitmentScheme for UnivariateKzgPCS<E> {
)
.into_affine();

// TODO offer an `open()` that doesn't also evaluate
// https://github.com/EspressoSystems/jellyfish/issues/426
let eval = polynomial.evaluate(point);

#[cfg(feature = "kzg-print-trace")]
end_timer!(open_time);

Ok((Self::Proof { proof }, eval))
}

Expand Down Expand Up @@ -322,16 +332,45 @@ impl<E: Pairing> UnivariatePCS for UnivariateKzgPCS<E> {
num_points: usize,
domain: &Radix2EvaluationDomain<Self::Evaluation>,
) -> Result<Vec<Self::Proof>, PCSError> {
let mut h_poly = Self::compute_h_poly_in_fk23(prover_param, &polynomial.coeffs)?;
let proofs: Vec<_> = h_poly
.batch_evaluate_rou(domain)?
.into_iter()
.take(num_points)
.map(|g| UnivariateKzgProof {
proof: g.into_affine(),
})
.collect();
Ok(proofs)
#[cfg(feature = "naive-kzg-multi-open")]
{
use ark_poly::EvaluationDomain;
let prover_param = prover_param.borrow(); // needed for Send + Sync

// We prefer use `.par_bridge()` instead of
// `.collect::<Vec<_>>().par_iter()`.
// (It avoids an unnecessary `collect()`.)
// However, `par_iter` is guaranteed to preserve order,
// whereas `par_bridge` is not!
// https://github.com/rayon-rs/rayon/issues/551#issuecomment-882069261
// https://docs.rs/rayon/latest/rayon/iter/trait.ParallelBridge.html
//
// We prefer to compute only the proof---not the evaluation.
// However, `Self::open()` returns both,
// so we throw away the eval via `.map(|r| r.0)`.
// https://github.com/EspressoSystems/jellyfish/issues/426
domain
.elements()
.take(num_points)
.collect::<Vec<_>>()
.par_iter()
.map(|point| Self::open(prover_param, polynomial, point).map(|r| r.0))
.collect()
}

#[cfg(not(feature = "naive-kzg-multi-open"))]
{
let mut h_poly = Self::compute_h_poly_in_fk23(prover_param, &polynomial.coeffs)?;
let proofs: Vec<_> = h_poly
.batch_evaluate_rou(domain)?
.into_iter()
.take(num_points)
.map(|g| UnivariateKzgProof {
proof: g.into_affine(),
})
.collect();
Ok(proofs)
}
}

/// Compute the evaluations in [`Self::multi_open_rou()`].
Expand Down
3 changes: 2 additions & 1 deletion primitives/src/pcs/univariate_kzg/srs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ mod tests {
rng: &mut R,
max_degree: usize,
) -> Result<UnivariateUniversalParams<E>, PCSError> {
let setup_time = start_timer!(|| format!("KZG10::Setup with degree {}", max_degree));
let setup_time =
start_timer!(|| ark_std::format!("KZG10::Setup with degree {}", max_degree));
let beta = E::ScalarField::rand(rng);
let g = E::G1::rand(rng);
let h = E::G2::rand(rng);
Expand Down

0 comments on commit 1c5f59a

Please sign in to comment.