On input a list of polynomials, linear combinations of those polynomials, and a query set, `open_combination` outputs a proof of evaluation of the combinations at the points in the query set.
(
ck: &PC::CommitterKey,
lc_s: impl IntoIterator<Item = &'a LinearCombination<E::ScalarField>>,
polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<E::ScalarField, P>>,
| 222 | /// and a query set, `open_combination` outputs a proof of evaluation of |
| 223 | /// the combinations at the points in the query set. |
| 224 | fn open_combinations<'a, D>( |
| 225 | ck: &PC::CommitterKey, |
| 226 | lc_s: impl IntoIterator<Item = &'a LinearCombination<E::ScalarField>>, |
| 227 | polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<E::ScalarField, P>>, |
| 228 | commitments: impl IntoIterator<Item = &'a LabeledCommitment<PC::Commitment>>, |
| 229 | query_set: &QuerySet<D>, |
| 230 | sponge: &mut impl CryptographicSponge, |
| 231 | states: impl IntoIterator<Item = &'a PC::CommitmentState>, |
| 232 | rng: Option<&mut dyn RngCore>, |
| 233 | ) -> Result<BatchLCProof<E::ScalarField, PC::BatchProof>, Error> |
| 234 | where |
| 235 | P: 'a + Polynomial<E::ScalarField, Point = D>, |
| 236 | D: Debug + Clone + Hash + Ord + Sync, |
| 237 | PC: PolynomialCommitment< |
| 238 | E::ScalarField, |
| 239 | P, |
| 240 | Commitment = marlin_pc::Commitment<E>, |
| 241 | Error = Error, |
| 242 | >, |
| 243 | PC::CommitmentState: 'a + AddAssign<(E::ScalarField, &'a PC::CommitmentState)>, |
| 244 | PC::Commitment: 'a, |
| 245 | { |
| 246 | let label_map = polynomials |
| 247 | .into_iter() |
| 248 | .zip(states) |
| 249 | .zip(commitments) |
| 250 | .map(|((p, r), c)| (p.label(), (p, r, c))) |
| 251 | .collect::<BTreeMap<_, _>>(); |
| 252 | |
| 253 | let mut lc_polynomials = Vec::new(); |
| 254 | let mut lc_states: Vec<PC::CommitmentState> = Vec::new(); |
| 255 | let mut lc_commitments = Vec::new(); |
| 256 | let mut lc_info = Vec::new(); |
| 257 | |
| 258 | for lc in lc_s { |
| 259 | let lc_label = lc.label().clone(); |
| 260 | let mut poly = P::zero(); |
| 261 | let mut degree_bound = None; |
| 262 | let mut hiding_bound = None; |
| 263 | |
| 264 | let mut randomness = PC::CommitmentState::empty(); |
| 265 | let mut coeffs_and_comms = Vec::new(); |
| 266 | |
| 267 | let num_polys = lc.len(); |
| 268 | for (coeff, label) in lc.iter().filter(|(_, l)| !l.is_one()) { |
| 269 | let label: &String = label.try_into().expect("cannot be one!"); |
| 270 | let &(cur_poly, cur_state, cur_comm) = |
| 271 | label_map.get(label).ok_or(Error::MissingPolynomial { |
| 272 | label: label.to_string(), |
| 273 | })?; |
| 274 | if num_polys == 1 && cur_poly.degree_bound().is_some() { |
| 275 | assert!( |
| 276 | coeff.is_one(), |
| 277 | "Coefficient must be one for degree-bounded equations" |
| 278 | ); |
| 279 | degree_bound = cur_poly.degree_bound(); |
| 280 | } else if cur_poly.degree_bound().is_some() { |
| 281 | return Err(Error::EquationHasDegreeBounds(lc_label)); |
nothing calls this directly
no test coverage detected