Skip to content
Open
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
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@

### Breaking changes

### Features

- Add `commit_sparse` method for KZG10.

### Improvements

### Bug fixes

## v0.4.0

### Breaking changes

- [\#112](https://github.com/arkworks-rs/poly-commit/pull/112) Upgrade all dependencies to `0.4`.
- [\#82](https://github.com/arkworks-rs/poly-commit/pull/82) Argument `opening_challenge: F` for `open`,
`check`, has been changed from `F` to `opening_challenges: &mut ChallengeGenerator`.
Expand Down
110 changes: 98 additions & 12 deletions poly-commit/src/kzg10/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use crate::{BTreeMap, Error, LabeledPolynomial, PCCommitmentState};
use ark_ec::{pairing::Pairing, scalar_mul::ScalarMul, AffineRepr, CurveGroup, VariableBaseMSM};
use ark_ff::{One, PrimeField, UniformRand, Zero};
use ark_poly::DenseUVPolynomial;
use ark_poly::{univariate::SparsePolynomial, DenseUVPolynomial};
use ark_std::{format, marker::PhantomData, ops::Div, ops::Mul, rand::RngCore};
#[cfg(not(feature = "std"))]
use ark_std::{string::ToString, vec::Vec};
Expand Down Expand Up @@ -179,6 +179,7 @@
end_timer!(msm_time);

let mut randomness = Randomness::<E::ScalarField, P>::empty();

if let Some(hiding_degree) = hiding_bound {
let mut rng = rng.ok_or(Error::MissingRng)?;
let sample_random_poly_time = start_timer!(|| format!(
Expand All @@ -192,23 +193,82 @@
powers.powers_of_gamma_g.len(),
)?;
end_timer!(sample_random_poly_time);
}

let random_ints = convert_to_bigints(&randomness.blinding_polynomial.coeffs());
let msm_time = start_timer!(|| "MSM to compute commitment to random poly");
let random_commitment = <E::G1 as VariableBaseMSM>::msm_bigint(
&powers.powers_of_gamma_g,
random_ints.as_slice(),
)
.into_affine();
end_timer!(msm_time);
let random_ints = convert_to_bigints(&randomness.blinding_polynomial.coeffs());
let msm_time = start_timer!(|| "MSM to compute commitment to random poly");
let random_commitment = <E::G1 as VariableBaseMSM>::msm_bigint(
&powers.powers_of_gamma_g,
random_ints.as_slice(),
)
.into_affine();
end_timer!(msm_time);

commitment += &random_commitment;
commitment += &random_commitment;
}

end_timer!(commit_time);
Ok((Commitment(commitment.into()), randomness))
}

/// Outputs a commitment to `sparse_polynomial`. Calling `commit_sparse(&powers, sparse_poly, Some(hiding), Some(rng))`
/// is equivalent to calling `commit(&powers, sparse_poly.into(), Some(hiding), Some(rng))`.
/// `commit_sparse` is significantly faster than `commit` when both the polynomial is sparse
/// and the hiding bound is low, and significantly slower otherwise.
/// Foreseen use is when the verifier needs to compute a commitment to X-omega, X^k or X^n - 1 (thus with no hiding).
pub fn commit_sparse(
powers: &Powers<E>,
sparse_polynomial: &SparsePolynomial<E::ScalarField>,
hiding_bound: Option<usize>,
rng: Option<&mut dyn RngCore>,
) -> Result<(Commitment<E>, Randomness<E::ScalarField, P>), Error> {
// Naively compute the MSM. Much faster than the generic implementation in the case of sparse polynomials
let commit_unblinded = sparse_polynomial
.coeffs

Check failure on line 225 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Check no_std

field `coeffs` of struct `ark_poly::univariate::SparsePolynomial` is private

Check failure on line 225 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable)

field `coeffs` of struct `ark_poly::univariate::SparsePolynomial` is private
.clone()
.into_iter()
.map(|(i, coeff)| (powers.powers_of_g[i] * coeff))

Check warning on line 228 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Check no_std

unnecessary parentheses around closure body

Check failure on line 228 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable)

unnecessary parentheses around closure body
.sum::<E::G1>();

let mut randomness = Randomness::<E::ScalarField, P>::empty();
let mut gamma_g_commit = E::G1::zero();

if let Some(hiding_degree) = hiding_bound {
let mut rng = rng.ok_or(Error::MissingRng)?;
let sample_random_poly_time = start_timer!(|| format!(
"Sampling a random polynomial of degree {}",
hiding_degree
));

randomness = Randomness::rand(hiding_degree, false, None, &mut rng);
Self::check_hiding_bound(
randomness.blinding_polynomial.degree(),
powers.powers_of_gamma_g.len(),
)?;
end_timer!(sample_random_poly_time);

// Create a sparse polynomial from the blinding polynomial of type DenseUVPolynomial
let sparse_randomness = SparsePolynomial::from_coefficients_vec(
randomness
.blinding_polynomial
.coeffs()
.iter()
.cloned()
.enumerate()
.collect(),
);

// MSM compute the commitment to sparse_random on the powers of gamma_g
gamma_g_commit = sparse_randomness
.coeffs

Check failure on line 261 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Check no_std

field `coeffs` of struct `ark_poly::univariate::SparsePolynomial` is private

Check failure on line 261 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable)

field `coeffs` of struct `ark_poly::univariate::SparsePolynomial` is private
.into_iter()
.map(|(i, coeff)| (powers.powers_of_gamma_g[i] * coeff))

Check warning on line 263 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Check no_std

unnecessary parentheses around closure body

Check failure on line 263 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable)

unnecessary parentheses around closure body
.sum::<E::G1>();
}

let commit = (commit_unblinded + gamma_g_commit).into();

Check failure on line 267 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Check no_std

mismatched types

Check failure on line 267 in poly-commit/src/kzg10/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable)

mismatched types

Ok((Commitment(commit), randomness))
}

/// Compute witness polynomial.
///
/// The witness polynomial $w(x)$ the quotient of the division (p(x) - p(z)) / (x - z)
Expand Down Expand Up @@ -543,6 +603,32 @@
assert_eq!(f_comm, f_comm_2);
}

#[test]
fn equivalence_sparse_dense_commit() {
let rng = &mut test_rng();
let degree = 10; // only test on small poly commitments
let pp = KZG_Bls12_381::setup(degree, false, rng).unwrap();
let (powers, _) = KZG_Bls12_381::trim(&pp, degree).unwrap();

for _ in 0..5 {
let p = UniPoly_381::rand(degree, rng);
// Use a fresh rng each time for reproducibility between sparse and dense commit
let (comm_dense, _) =
KZG_Bls12_381::commit(&powers, &p, Some(degree - 1), Some(&mut test_rng()))
.unwrap();

let (comm_sparse, _) = KZG_Bls12_381::commit_sparse(
&powers,
&p.into(),
Some(degree - 1),
Some(&mut test_rng()),
)
.unwrap();

assert_eq!(comm_dense, comm_sparse);
}
}

fn end_to_end_test_template<E, P>() -> Result<(), Error>
where
E: Pairing,
Expand Down
Loading