/// 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.
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.
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 .
fn open_combinations<'a, D>(
        ck: &PC::CommitterKey,
        lc_s: impl IntoIterator<Item = &'a LinearCombination<E::Fr>>,
        polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<E::Fr, P>>,
        commitments: impl IntoIterator<Item = &'a LabeledCommitment<PC::Commitment>>,
        query_set: &QuerySet<D>,
        opening_challenges: &mut ChallengeGenerator<E::Fr, S>,
        rands: impl IntoIterator<Item = &'a PC::Randomness>,
        rng: Option<&mut dyn RngCore>,
    ) -> Result<BatchLCProof<E::Fr, PC::BatchProof>, Error>
    where
        P: 'a + Polynomial<E::Fr, Point = D>,
        D: Debug + Clone + Hash + Ord + Sync,
        PC: PolynomialCommitment<
            E::Fr,
            P,
            S,
            Commitment = marlin_pc::Commitment<E>,
            PreparedCommitment = marlin_pc::PreparedCommitment<E>,
            Error = Error,
        >,
        PC::Randomness: 'a + AddAssign<(E::Fr, &'a PC::Randomness)>,
        PC::Commitment: 'a,
    {
        let label_map = polynomials
            .into_iter()
            .zip(rands)
            .zip(commitments)
            .map(|((p, r), c)| (p.label(), (p, r, c)))
            .collect::<BTreeMap<_, _>>();
        let mut lc_polynomials = Vec::new();
        let mut lc_randomness = Vec::new();
        let mut lc_commitments = Vec::new();
        let mut lc_info = Vec::new();
        for lc in lc_s {
            let lc_label = lc.label().clone();
            let mut poly = P::zero();
            let mut degree_bound = None;
            let mut hiding_bound = None;
            let mut randomness = PC::Randomness::empty();
            let mut coeffs_and_comms = Vec::new();
            let num_polys = lc.len();
            for (coeff, label) in lc.iter().filter(|(_, l)| !l.is_one()) {
                let label: &String = label.try_into().expect("cannot be one!");
                let &(cur_poly, cur_rand, cur_comm) =
                    label_map.get(label).ok_or(Error::MissingPolynomial {
                        label: label.to_string(),
                    })?;
                if num_polys == 1 && cur_poly.degree_bound().is_some() {
                    assert!(
                        coeff.is_one(),
                        "Coefficient must be one for degree-bounded equations"
                    );
                    degree_bound = cur_poly.degree_bound();
                } else if cur_poly.degree_bound().is_some() {
                    return Err(Error::EquationHasDegreeBounds(lc_label));
                }
                // Some(_) > None, always.
                hiding_bound = core::cmp::max(hiding_bound, cur_poly.hiding_bound());
                poly += (*coeff, cur_poly.polynomial());
                randomness += (*coeff, cur_rand);
                coeffs_and_comms.push((*coeff, cur_comm.commitment()));
            }
            let lc_poly =
                LabeledPolynomial::new(lc_label.clone(), poly, degree_bound, hiding_bound);
            lc_polynomials.push(lc_poly);
            lc_randomness.push(randomness);
            lc_commitments.push(Self::combine_commitments(coeffs_and_comms));
            lc_info.push((lc_label, degree_bound));
        }
        let comms = Self::normalize_commitments(lc_commitments);
        let lc_commitments = lc_info
            .into_iter()
            .zip(comms)
            .map(|((label, d), c)| LabeledCommitment::new(label, c, d))
            .collect::<Vec<_>>();
        let proof = PC::batch_open(
            ck,
            lc_polynomials.iter(),
            lc_commitments.iter(),
            &query_set,
            opening_challenges,
            lc_randomness.iter(),
            rng,
        )?;
        Ok(BatchLCProof { proof, evals: None })
    }
fn open_combinations < ' a , D > ( ck : & PC :: CommitterKey , lc_s : impl IntoIterator < Item = & ' a LinearCombination < E :: Fr > > , polynomials : impl IntoIterator < Item = & ' a LabeledPolynomial < E :: Fr , P > > , commitments : impl IntoIterator < Item = & ' a LabeledCommitment < PC :: Commitment > > , query_set : & QuerySet < D > , opening_challenges : & mut ChallengeGenerator < E :: Fr , S > , rands : impl IntoIterator < Item = & ' a PC :: Randomness > , rng : Option < & mut dyn RngCore > , ) -> Result < BatchLCProof < E :: Fr , PC :: BatchProof > , Error > where P : ' a + Polynomial < E :: Fr , Point = D > , D : Debug + Clone + Hash + Ord + Sync , PC : PolynomialCommitment < E :: Fr , P , S , Commitment = marlin_pc :: Commitment < E > , PreparedCommitment = marlin_pc :: PreparedCommitment < E > , Error = Error , > , PC :: Randomness : ' a + AddAssign < ( E :: Fr , & ' a PC :: Randomness ) > , PC :: Commitment : ' a , { let label_map = polynomials . into_iter ( ) . zip ( rands ) . zip ( commitments ) . map ( | ( ( p , r ) , c ) | ( p . label ( ) , ( p , r , c ) ) ) . collect :: < BTreeMap < _ , _ > > ( ) ; let mut lc_polynomials = Vec :: new ( ) ; let mut lc_randomness = Vec :: new ( ) ; let mut lc_commitments = Vec :: new ( ) ; let mut lc_info = Vec :: new ( ) ; for lc in lc_s { let lc_label = lc . label ( ) . clone ( ) ; let mut poly = P :: zero ( ) ; let mut degree_bound = None ; let mut hiding_bound = None ; let mut randomness = PC :: Randomness :: empty ( ) ; let mut coeffs_and_comms = Vec :: new ( ) ; let num_polys = lc . len ( ) ; for ( coeff , label ) in lc . iter ( ) . filter ( | ( _ , l ) | ! l . is_one ( ) ) { let label : & String = label . try_into ( ) . expect ( " " ) ; let & ( cur_poly , cur_rand , cur_comm ) = label_map . get ( label ) . ok_or ( Error :: MissingPolynomial { label : label . to_string ( ) , } ) ? ; if num_polys == 1 && cur_poly . degree_bound ( ) . is_some ( ) { assert ! ( coeff is_one ( ) " " ) ; degree_bound = cur_poly . degree_bound ( ) ; } else if cur_poly . degree_bound ( ) . is_some ( ) { return Err ( Error :: EquationHasDegreeBounds ( lc_label ) ) ; } // Some(_) > None, always. hiding_bound = core :: cmp :: max ( hiding_bound , cur_poly . hiding_bound ( ) ) ; poly += ( * coeff , cur_poly . polynomial ( ) ) ; randomness += ( * coeff , cur_rand ) ; coeffs_and_comms . push ( ( * coeff , cur_comm . commitment ( ) ) ) ; } let lc_poly = LabeledPolynomial :: new ( lc_label . clone ( ) , poly , degree_bound , hiding_bound ) ; lc_polynomials . push ( lc_poly ) ; lc_randomness . push ( randomness ) ; lc_commitments . push ( Self :: combine_commitments ( coeffs_and_comms ) ) ; lc_info . push ( ( lc_label , degree_bound ) ) ; } let comms = Self :: normalize_commitments ( lc_commitments ) ; let lc_commitments = lc_info . into_iter ( ) . zip ( comms ) . map ( | ( ( label , d ) , c ) | LabeledCommitment :: new ( label , c , d ) ) . collect :: < Vec < _ > > ( ) ; let proof = PC :: batch_open ( ck , lc_polynomials . iter ( ) , lc_commitments . iter ( ) , & query_set , opening_challenges , lc_randomness . iter ( ) , rng , ) ? ; Ok ( BatchLCProof { proof , evals : None } ) }
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.
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::Fr>>
polynomials
impl IntoIterator<Item = &'a LabeledPolynomial<E::Fr, P>>
commitments
impl IntoIterator<Item = &'a LabeledCommitment<PC::Commitment>>
query_set
&QuerySet<D>
opening_challenges
&mut ChallengeGenerator<E::Fr, S>
rands
impl IntoIterator<Item = &'a PC::Randomness>
rng
Option<&mut dyn RngCore>