Opens a list of polynomial commitments at a desired point. This requires the list of original polynomials (`labeled_polynomials`) as well as the random values using by the Pedersen multi-commits during the commitment phase (`randomness`). Cf. sections "Square-root commitment scheme" and appendix A.2 from the reference article. # Panics Panics if - `rng` is None, since Hyrax requires randomness i
(
ck: &Self::CommitterKey,
labeled_polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<G::ScalarField, P>>,
commitments: impl IntoIterator<Item = &'a LabeledCommitment<
| 271 | /// - The number of variables of a polynomial doesn't match that of the |
| 272 | /// point. |
| 273 | fn open<'a>( |
| 274 | ck: &Self::CommitterKey, |
| 275 | labeled_polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<G::ScalarField, P>>, |
| 276 | commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>, |
| 277 | point: &'a P::Point, |
| 278 | sponge: &mut impl CryptographicSponge, |
| 279 | states: impl IntoIterator<Item = &'a Self::CommitmentState>, |
| 280 | rng: Option<&mut dyn RngCore>, |
| 281 | ) -> Result<Self::Proof, Self::Error> |
| 282 | where |
| 283 | Self::Commitment: 'a, |
| 284 | Self::CommitmentState: 'a, |
| 285 | P: 'a, |
| 286 | { |
| 287 | let n = point.len(); |
| 288 | |
| 289 | if n % 2 == 1 { |
| 290 | // Only polynomials with an even number of variables are |
| 291 | // supported in this implementation |
| 292 | return Err(Error::InvalidNumberOfVariables); |
| 293 | } |
| 294 | |
| 295 | let dim = 1 << n / 2; |
| 296 | |
| 297 | // Reversing the point is necessary because the MLE interface returns |
| 298 | // evaluations in little-endian order |
| 299 | let point_rev: Vec<G::ScalarField> = point.iter().rev().cloned().collect(); |
| 300 | |
| 301 | let point_lower = &point_rev[n / 2..]; |
| 302 | let point_upper = &point_rev[..n / 2]; |
| 303 | |
| 304 | // Deriving the tensors which result in the evaluation of the polynomial |
| 305 | // when they are multiplied by the coefficient matrix. |
| 306 | let l = tensor_prime(point_lower); |
| 307 | let r = tensor_prime(point_upper); |
| 308 | |
| 309 | let mut proofs = Vec::new(); |
| 310 | |
| 311 | let rng_inner = rng.expect("Opening polynomials requires randomness"); |
| 312 | |
| 313 | for (l_poly, (l_com, state)) in labeled_polynomials |
| 314 | .into_iter() |
| 315 | .zip(commitments.into_iter().zip(states.into_iter())) |
| 316 | { |
| 317 | let label = l_poly.label(); |
| 318 | if label != l_com.label() { |
| 319 | return Err(Error::MismatchedLabels { |
| 320 | commitment_label: l_com.label().to_string(), |
| 321 | polynomial_label: label.to_string(), |
| 322 | }); |
| 323 | } |
| 324 | |
| 325 | let poly = l_poly.polynomial(); |
| 326 | let com = l_com.commitment(); |
| 327 | |
| 328 | if poly.num_vars() != n { |
| 329 | return Err(Error::MismatchedNumVars { |
| 330 | poly_nv: poly.num_vars(), |
nothing calls this directly
no test coverage detected