mina_tree/proofs/
urs_utils.rs

1/// Copy-pasted from https://github.com/MinaProtocol/mina/blob/cf2a732ae39f4e784707e1fc32832da805bb7d09/src/lib/crypto/kimchi_bindings/stubs/src/urs_utils.rs
2use ark_ec::{msm::VariableBaseMSM, ProjectiveCurve};
3use ark_ff::{batch_inversion, One, PrimeField, UniformRand, Zero};
4use poly_commitment::{
5    commitment::{b_poly_coefficients, CommitmentCurve},
6    srs::SRS,
7};
8use rayon::prelude::*;
9
10// TODO: Not compatible with variable rounds
11pub fn batch_dlog_accumulator_check<G: CommitmentCurve>(
12    urs: &SRS<G>,
13    comms: &[G],
14    chals: &[G::ScalarField],
15) -> bool {
16    let k = comms.len();
17
18    if k == 0 {
19        assert_eq!(chals.len(), 0);
20        return true;
21    }
22
23    let rounds = chals.len() / k;
24    assert_eq!(chals.len() % rounds, 0);
25
26    let rs = {
27        let r = G::ScalarField::rand(&mut rand::rngs::OsRng);
28        let mut rs = vec![G::ScalarField::one(); k];
29        for i in 1..k {
30            rs[i] = r * rs[i - 1];
31        }
32        rs
33    };
34
35    let mut points = urs.g.clone();
36    let n = points.len();
37    points.extend(comms);
38
39    let mut scalars = vec![G::ScalarField::zero(); n];
40    scalars.extend(&rs[..]);
41
42    let chal_invs = {
43        let mut cs = chals.to_vec();
44        batch_inversion(&mut cs);
45        cs
46    };
47
48    let termss: Vec<_> = chals
49        .par_iter()
50        .zip(chal_invs)
51        .chunks(rounds)
52        .zip(rs)
53        .map(|(chunk, r)| {
54            let chals: Vec<_> = chunk.iter().map(|(c, _)| **c).collect();
55            let mut s = b_poly_coefficients(&chals);
56            s.iter_mut().for_each(|c| *c *= &r);
57            s
58        })
59        .collect();
60
61    for terms in termss {
62        assert_eq!(terms.len(), n);
63        for i in 0..n {
64            scalars[i] -= &terms[i];
65        }
66    }
67
68    let scalars: Vec<_> = scalars.iter().map(|x| x.into_repr()).collect();
69    VariableBaseMSM::multi_scalar_mul(&points, &scalars) == G::Projective::zero()
70}
71
72#[allow(unused)]
73pub fn batch_dlog_accumulator_generate<G: CommitmentCurve>(
74    urs: &SRS<G>,
75    num_comms: usize,
76    chals: &Vec<G::ScalarField>,
77) -> Vec<G> {
78    let k = num_comms;
79
80    if k == 0 {
81        assert_eq!(chals.len(), 0);
82        return vec![];
83    }
84
85    let rounds = chals.len() / k;
86    assert_eq!(chals.len() % rounds, 0);
87
88    let comms: Vec<_> = chals
89        .into_par_iter()
90        .chunks(rounds)
91        .map(|chals| {
92            let chals: Vec<G::ScalarField> = chals.into_iter().copied().collect();
93            let scalars: Vec<_> = b_poly_coefficients(&chals)
94                .into_iter()
95                .map(|x| x.into_repr())
96                .collect();
97            let points: Vec<_> = urs.g.clone();
98            VariableBaseMSM::multi_scalar_mul(&points, &scalars).into_affine()
99        })
100        .collect();
101
102    comms
103}