Verify opening proofs for all polynomials involved in a number of linear combinations (LC) simultaneously.
(
vk: &Self::VerifierKey,
linear_combinations: impl IntoIterator<Item = &'a LinearCombination<F>>,
commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>
| 487 | /// Verify opening proofs for all polynomials involved in a number of |
| 488 | /// linear combinations (LC) simultaneously. |
| 489 | fn check_combinations<'a, R: RngCore>( |
| 490 | vk: &Self::VerifierKey, |
| 491 | linear_combinations: impl IntoIterator<Item = &'a LinearCombination<F>>, |
| 492 | commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>, |
| 493 | eqn_query_set: &QuerySet<P::Point>, |
| 494 | eqn_evaluations: &Evaluations<P::Point, F>, |
| 495 | proof: &BatchLCProof<F, Self::BatchProof>, |
| 496 | sponge: &mut impl CryptographicSponge, |
| 497 | rng: &mut R, |
| 498 | ) -> Result<bool, Self::Error> |
| 499 | where |
| 500 | Self::Commitment: 'a, |
| 501 | { |
| 502 | // The default implementation does this by batch-checking each |
| 503 | // batch-opening proof of polynomials appearing in those LC that were |
| 504 | // queried at the same point, then computing the evaluations of each LC |
| 505 | // using the proved polynomial evaluations. |
| 506 | let BatchLCProof { proof, evals } = proof; |
| 507 | let lc_s = BTreeMap::from_iter(linear_combinations.into_iter().map(|lc| (lc.label(), lc))); |
| 508 | |
| 509 | // Rearrange the information about queries on linear combinations into |
| 510 | // information about queries on individual polynomials. |
| 511 | let poly_query_set = lc_query_set_to_poly_query_set(lc_s.values().copied(), eqn_query_set); |
| 512 | let sorted_by_poly_and_query_label: BTreeSet<_> = poly_query_set |
| 513 | .clone() |
| 514 | .into_iter() |
| 515 | .map(|(poly_label, v)| ((poly_label.clone(), v.1), v.0)) |
| 516 | .collect(); |
| 517 | |
| 518 | let poly_evals = Evaluations::from_iter( |
| 519 | sorted_by_poly_and_query_label |
| 520 | .into_iter() |
| 521 | .zip(evals.clone().unwrap()) |
| 522 | .map(|(((poly_label, point), _query_label), eval)| ((poly_label, point), eval)), |
| 523 | ); |
| 524 | |
| 525 | for &(ref lc_label, (_, ref point)) in eqn_query_set { |
| 526 | if let Some(lc) = lc_s.get(lc_label) { |
| 527 | let claimed_rhs = *eqn_evaluations |
| 528 | .get(&(lc_label.clone(), point.clone())) |
| 529 | .ok_or(Error::MissingEvaluation { |
| 530 | label: lc_label.to_string(), |
| 531 | })?; |
| 532 | |
| 533 | let mut actual_rhs = F::zero(); |
| 534 | |
| 535 | // Compute the value of the linear combination by adding the |
| 536 | // claimed value for each polynomial in it (to be proved later) |
| 537 | // scaled by the corresponding coefficient. |
| 538 | for (coeff, label) in lc.iter() { |
| 539 | let eval = match label { |
| 540 | LCTerm::One => F::one(), |
| 541 | LCTerm::PolyLabel(l) => *poly_evals |
| 542 | .get(&(l.clone().into(), point.clone())) |
| 543 | .ok_or(Error::MissingEvaluation { |
| 544 | label: format!("{}-{:?}", l.clone(), point.clone()), |
| 545 | })?, |
| 546 | }; |
nothing calls this directly
no test coverage detected