saffron/
commitment.rs

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/// Takes commitments C_i, computes α = hash(C_0 || C_1 || ... || C_n),
38/// returns ∑ α^i C_i.
39#[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}