Skip to content

Commit 6c90b7a

Browse files
authored
Merge pull request #2207 from AleoHQ/remove_dead_code_linear_combinations
Perf: Remove clone and dead code linear combinations of commitments
2 parents 499ea09 + b16767e commit 6c90b7a

File tree

2 files changed

+42
-135
lines changed

2 files changed

+42
-135
lines changed

algorithms/src/polycommit/sonic_pc/mod.rs

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -209,43 +209,34 @@ impl<E: PairingEngine, S: AlgebraicSponge<E::Fq, 2>> SonicKZG10<E, S> {
209209
hiding_bound,
210210
));
211211

212-
let (comm, rand) = p
213-
.sum()?
214-
.map(move |p| {
215-
let rng_ref = rng.as_mut().map(|s| s as _);
216-
match p {
217-
PolynomialWithBasis::Lagrange { evaluations } => {
218-
let domain = crate::fft::EvaluationDomain::new(evaluations.evaluations.len()).unwrap();
219-
let lagrange_basis = ck
220-
.lagrange_basis(domain)
221-
.ok_or(PCError::UnsupportedLagrangeBasisSize(domain.size()))?;
222-
assert!(domain.size().is_power_of_two());
223-
assert!(lagrange_basis.size().is_power_of_two());
224-
kzg10::KZG10::commit_lagrange(
225-
&lagrange_basis,
226-
&evaluations.evaluations,
227-
hiding_bound,
228-
rng_ref,
229-
)
230-
}
231-
PolynomialWithBasis::Monomial { polynomial, degree_bound } => {
232-
let powers = if let Some(degree_bound) = degree_bound {
233-
ck.shifted_powers_of_beta_g(degree_bound).unwrap()
234-
} else {
235-
ck.powers()
236-
};
237-
238-
kzg10::KZG10::commit(&powers, &polynomial, hiding_bound, rng_ref)
239-
}
212+
let (comm, rand) = {
213+
let rng_ref = rng.as_mut().map(|s| s as _);
214+
match p.polynomial {
215+
PolynomialWithBasis::Lagrange { evaluations } => {
216+
let domain = crate::fft::EvaluationDomain::new(evaluations.evaluations.len()).unwrap();
217+
let lagrange_basis = ck
218+
.lagrange_basis(domain)
219+
.ok_or(PCError::UnsupportedLagrangeBasisSize(domain.size()))?;
220+
assert!(domain.size().is_power_of_two());
221+
assert!(lagrange_basis.size().is_power_of_two());
222+
kzg10::KZG10::commit_lagrange(
223+
&lagrange_basis,
224+
&evaluations.evaluations,
225+
hiding_bound,
226+
rng_ref,
227+
)?
240228
}
241-
})
242-
.try_fold((E::G1Projective::zero(), Randomness::empty()), |mut a, b| {
243-
let b = b?;
244-
a.0.add_assign_mixed(&b.0.0);
245-
a.1 += (E::Fr::one(), &b.1);
246-
Ok::<_, PCError>(a)
247-
})?;
248-
let comm = kzg10::KZGCommitment(comm.to_affine());
229+
PolynomialWithBasis::Monomial { polynomial, degree_bound } => {
230+
let powers = if let Some(degree_bound) = degree_bound {
231+
ck.shifted_powers_of_beta_g(degree_bound).unwrap()
232+
} else {
233+
ck.powers()
234+
};
235+
236+
kzg10::KZG10::commit(&powers, &polynomial, hiding_bound, rng_ref)?
237+
}
238+
}
239+
};
249240

250241
Ok((LabeledCommitment::new(label.to_string(), comm, degree_bound), rand))
251242
});

algorithms/src/polycommit/sonic_pc/polynomial.rs

Lines changed: 15 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ use crate::fft::{DensePolynomial, EvaluationDomain, Evaluations as EvaluationsOn
1717
use snarkvm_fields::{Field, PrimeField};
1818
use snarkvm_utilities::{cfg_iter, cfg_iter_mut, CanonicalDeserialize, CanonicalSerialize};
1919

20-
use anyhow::{ensure, Result};
21-
use hashbrown::HashMap;
20+
use anyhow::Result;
2221
use std::borrow::Cow;
2322

2423
#[cfg(feature = "serial")]
@@ -142,7 +141,7 @@ impl<F: Field> LabeledPolynomial<F> {
142141
#[derive(Debug, Clone)]
143142
pub struct LabeledPolynomialWithBasis<'a, F: PrimeField> {
144143
pub info: PolynomialInfo,
145-
pub polynomial: Vec<(F, PolynomialWithBasis<'a, F>)>,
144+
pub polynomial: PolynomialWithBasis<'a, F>,
146145
}
147146

148147
impl<'a, F: PrimeField> LabeledPolynomialWithBasis<'a, F> {
@@ -155,16 +154,6 @@ impl<'a, F: PrimeField> LabeledPolynomialWithBasis<'a, F> {
155154
) -> Self {
156155
let polynomial = PolynomialWithBasis::new_monomial_basis_ref(polynomial, degree_bound);
157156
let info = PolynomialInfo::new(label, degree_bound, hiding_bound);
158-
Self { info, polynomial: vec![(F::one(), polynomial)] }
159-
}
160-
161-
/// Construct a new labeled polynomial by consuming `polynomial`.
162-
pub fn new_linear_combination(
163-
label: PolynomialLabel,
164-
polynomial: Vec<(F, PolynomialWithBasis<'a, F>)>,
165-
hiding_bound: Option<usize>,
166-
) -> Self {
167-
let info = PolynomialInfo::new(label, None, hiding_bound);
168157
Self { info, polynomial }
169158
}
170159

@@ -175,7 +164,7 @@ impl<'a, F: PrimeField> LabeledPolynomialWithBasis<'a, F> {
175164
) -> Self {
176165
let polynomial = PolynomialWithBasis::new_lagrange_basis(polynomial);
177166
let info = PolynomialInfo::new(label, None, hiding_bound);
178-
Self { info, polynomial: vec![(F::one(), polynomial)] }
167+
Self { info, polynomial }
179168
}
180169

181170
pub fn new_lagrange_basis_ref(
@@ -185,7 +174,7 @@ impl<'a, F: PrimeField> LabeledPolynomialWithBasis<'a, F> {
185174
) -> Self {
186175
let polynomial = PolynomialWithBasis::new_lagrange_basis_ref(polynomial);
187176
let info = PolynomialInfo::new(label, None, hiding_bound);
188-
Self { info, polynomial: vec![(F::one(), polynomial)] }
177+
Self { info, polynomial }
189178
}
190179

191180
/// Return the label for `self`.
@@ -199,96 +188,23 @@ impl<'a, F: PrimeField> LabeledPolynomialWithBasis<'a, F> {
199188
}
200189

201190
pub fn degree(&self) -> usize {
202-
self.polynomial
203-
.iter()
204-
.map(|(_, p)| match p {
205-
PolynomialWithBasis::Lagrange { evaluations } => evaluations.domain().size() - 1,
206-
PolynomialWithBasis::Monomial { polynomial, .. } => polynomial.degree(),
207-
})
208-
.max()
209-
.unwrap_or(0)
191+
match &self.polynomial {
192+
PolynomialWithBasis::Lagrange { evaluations } => evaluations.domain().size() - 1,
193+
PolynomialWithBasis::Monomial { polynomial, .. } => polynomial.degree(),
194+
}
210195
}
211196

212197
/// Evaluate the polynomial in `self`.
213198
pub fn evaluate(&self, point: F) -> F {
214-
self.polynomial.iter().map(|(coeff, p)| p.evaluate(point) * coeff).sum()
215-
}
216-
217-
/// Compute a linear combination of the terms in `self.polynomial`, producing an iterator
218-
/// over polynomials of the same time.
219-
pub fn sum(&self) -> Result<impl Iterator<Item = PolynomialWithBasis<'a, F>>> {
220-
if self.polynomial.len() == 1 && self.polynomial[0].0.is_one() {
221-
Ok(vec![self.polynomial[0].1.clone()].into_iter())
222-
} else {
223-
use PolynomialWithBasis::*;
224-
let mut lagrange_polys = HashMap::<usize, Vec<_>>::new();
225-
let mut dense_polys = HashMap::<_, DensePolynomial<F>>::new();
226-
let mut sparse_poly = SparsePolynomial::zero();
227-
// We have sets of polynomials divided along three criteria:
228-
// 1. All `Lagrange` polynomials are in the set corresponding to their domain.
229-
// 2. All `Dense` polynomials are in the set corresponding to their degree bound.
230-
// 3. All `Sparse` polynomials are in the set corresponding to their degree bound.
231-
for (c, poly) in self.polynomial.iter() {
232-
match poly {
233-
Monomial { polynomial, degree_bound } => {
234-
use Polynomial::*;
235-
match polynomial.as_ref() {
236-
Dense(p) => {
237-
if let Some(e) = dense_polys.get_mut(degree_bound) {
238-
// Zip safety: `p` could be of smaller degree than `e`,
239-
// so it's okay to just use `zip` here.
240-
ensure!(e.len() >= p.coeffs.len());
241-
cfg_iter_mut!(e).zip(&p.coeffs).for_each(|(e, f)| *e += *c * f)
242-
} else {
243-
let mut e: DensePolynomial<F> = p.clone().into_owned();
244-
cfg_iter_mut!(e).for_each(|e| *e *= c);
245-
dense_polys.insert(degree_bound, e);
246-
}
247-
}
248-
Sparse(p) => sparse_poly += (*c, p.as_ref()),
249-
}
250-
}
251-
Lagrange { evaluations } => {
252-
let domain = evaluations.domain().size();
253-
if let Some(e) = lagrange_polys.get_mut(&domain) {
254-
ensure!(e.len() == evaluations.evaluations.len());
255-
cfg_iter_mut!(e).zip_eq(&evaluations.evaluations).for_each(|(e, f)| *e += *c * f)
256-
} else {
257-
let mut e = evaluations.clone().into_owned().evaluations;
258-
cfg_iter_mut!(e).for_each(|e| *e *= c);
259-
lagrange_polys.insert(domain, e);
260-
}
261-
}
262-
}
263-
}
264-
let sparse_poly = Polynomial::from(sparse_poly);
265-
let sparse_poly = Monomial { polynomial: Cow::Owned(sparse_poly), degree_bound: None };
266-
Ok(lagrange_polys
267-
.into_iter()
268-
.map(|(k, v)| {
269-
let domain = EvaluationDomain::new(k).unwrap();
270-
Lagrange { evaluations: Cow::Owned(EvaluationsOnDomain::from_vec_and_domain(v, domain)) }
271-
})
272-
.chain({
273-
dense_polys
274-
.into_iter()
275-
.map(|(degree_bound, p)| PolynomialWithBasis::new_dense_monomial_basis(p, *degree_bound))
276-
})
277-
.chain([sparse_poly])
278-
.collect::<Vec<_>>()
279-
.into_iter())
280-
}
199+
self.polynomial.evaluate(point)
281200
}
282201

283202
/// Retrieve the degree bound in `self`.
284203
pub fn degree_bound(&self) -> Option<usize> {
285-
self.polynomial
286-
.iter()
287-
.filter_map(|(_, p)| match p {
288-
PolynomialWithBasis::Monomial { degree_bound, .. } => *degree_bound,
289-
_ => None,
290-
})
291-
.max()
204+
match self.polynomial {
205+
PolynomialWithBasis::Monomial { degree_bound, .. } => degree_bound,
206+
_ => None,
207+
}
292208
}
293209

294210
/// Retrieve whether the polynomial in `self` should be hidden.
@@ -308,7 +224,7 @@ impl<'a, F: PrimeField> From<&'a LabeledPolynomial<F>> for LabeledPolynomialWith
308224
polynomial: Cow::Borrowed(other.polynomial()),
309225
degree_bound: other.degree_bound(),
310226
};
311-
Self { info: other.info.clone(), polynomial: vec![(F::one(), polynomial)] }
227+
Self { info: other.info.clone(), polynomial }
312228
}
313229
}
314230

@@ -318,7 +234,7 @@ impl<'a, F: PrimeField> From<LabeledPolynomial<F>> for LabeledPolynomialWithBasi
318234
polynomial: Cow::Owned(other.polynomial),
319235
degree_bound: other.info.degree_bound,
320236
};
321-
Self { info: other.info.clone(), polynomial: vec![(F::one(), polynomial)] }
237+
Self { info: other.info.clone(), polynomial }
322238
}
323239
}
324240

0 commit comments

Comments
 (0)