1use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM};
2use kimchi::curve::KimchiCurve;
3use mina_poseidon::FqSponge;
4use poly_commitment::{ipa::SRS, SRS as _};
5use rayon::prelude::*;
6use tracing::instrument;
7
8use crate::utils;
9
10#[instrument(skip_all, level = "debug")]
11pub fn commit_to_field_elems<G: KimchiCurve>(srs: &SRS<G>, data: &[G::ScalarField]) -> Vec<G>
12where
13 <G as AffineRepr>::Group: VariableBaseMSM,
14{
15 let basis: Vec<G> = srs
16 .get_lagrange_basis_from_domain_size(crate::SRS_SIZE)
17 .iter()
18 .map(|x| x.chunks[0])
19 .collect();
20
21 let commitments_projective = (0..data.len() / crate::SRS_SIZE)
22 .into_par_iter()
23 .map(|idx| {
24 G::Group::msm(
25 &basis,
26 &data[crate::SRS_SIZE * idx..crate::SRS_SIZE * (idx + 1)],
27 )
28 .unwrap()
29 })
30 .collect::<Vec<_>>();
31
32 let commitments = G::Group::normalize_batch(commitments_projective.as_slice());
33
34 commitments
35}
36
37#[instrument(skip_all, level = "debug")]
40pub fn combine_commitments<G: AffineRepr, EFqSponge: FqSponge<G::BaseField, G, G::ScalarField>>(
41 sponge: &mut EFqSponge,
42 commitments: &[G],
43) -> (G, G::ScalarField) {
44 for commitment in commitments.iter() {
45 sponge.absorb_g(std::slice::from_ref(commitment))
46 }
47 let alpha = sponge.challenge();
48 let combined_data_commitment = utils::aggregate_commitments(alpha, commitments);
49 (combined_data_commitment, alpha)
50}