1use ark_ec::{
2 pairing::{Pairing, PairingOutput},
3 AffineRepr, CurveGroup, VariableBaseMSM,
4};
5use ark_ff::PrimeField;
6use ark_std::{
7 cfg_into_iter, cfg_iter, cfg_iter_mut,
8 ops::{AddAssign, Mul, MulAssign},
9 string::ToString,
10 vec::Vec,
11};
12use dock_crypto_utils::{
13 ff::{powers, sum_of_powers},
14 randomized_pairing_check::RandomizedPairingChecker,
15};
16
17use crate::aggregation::{
18 commitment::PairCommitment,
19 key::{Key, PreparedVKey},
20};
21
22use crate::aggregation::{
23 error::AggregationError,
24 kzg::{prove_commitment_v, prove_commitment_w, verify_kzg_v, verify_kzg_w, KZGOpening},
25 srs::VerifierSRSProjective,
26};
27
28#[cfg(feature = "parallel")]
29use rayon::prelude::*;
30
31pub(crate) fn compress<C: AffineRepr>(vec: &mut Vec<C>, split: usize, scalar: &C::ScalarField) {
35 let s_repr = scalar.into_bigint();
36 let (left, right) = vec.split_at_mut(split);
37 cfg_iter_mut!(left)
38 .zip(cfg_iter!(right))
39 .for_each(|(a_l, a_r)| {
40 let x = a_r.mul_bigint(s_repr);
41 *a_l = (x + *a_l).into_affine();
42 });
43 let len = left.len();
44 vec.resize(len, C::zero());
45}
46
47pub(crate) fn inner_product_and_single_commitments<E: Pairing>(
48 c_left: &[E::G1Affine],
49 c_right: &[E::G1Affine],
50 r_left_bi: &[<E::ScalarField as PrimeField>::BigInt],
51 r_right_bi: &[<E::ScalarField as PrimeField>::BigInt],
52 vk_left_prep: PreparedVKey<E>,
53 vk_right_prep: PreparedVKey<E>,
54) -> (
55 E::G1Affine,
56 E::G1Affine,
57 PairCommitment<E>,
58 PairCommitment<E>,
59) {
60 let zc_l = E::G1::msm_bigint(c_right, r_left_bi).into_affine();
62 let zc_r = E::G1::msm_bigint(c_left, r_right_bi).into_affine();
64
65 let tuc_l = PairCommitment::<E>::single(vk_left_prep, c_right).unwrap();
67 let tuc_r = PairCommitment::<E>::single(vk_right_prep, c_left).unwrap();
69
70 (zc_l, zc_r, tuc_l, tuc_r)
71}
72
73pub(crate) fn inner_product_and_double_commitments<E: Pairing>(
74 a_left: &[E::G1Affine],
75 a_right: &[E::G1Affine],
76 b_left: Vec<E::G2Prepared>,
77 b_right: Vec<E::G2Prepared>,
78 wk_left: &Key<E::G1Affine>,
79 wk_right: &Key<E::G1Affine>,
80 vk_left_prep: PreparedVKey<E>,
81 vk_right_prep: PreparedVKey<E>,
82) -> (
83 PairingOutput<E>,
84 PairingOutput<E>,
85 PairCommitment<E>,
86 PairCommitment<E>,
87) {
88 let tab_l =
89 PairCommitment::<E>::double(vk_left_prep, wk_right, &a_right, b_left.clone()).unwrap();
90
91 let tab_r =
92 PairCommitment::<E>::double(vk_right_prep, wk_left, &a_left, b_right.clone()).unwrap();
93
94 let zab_l = E::multi_pairing(a_right, b_left);
96 let zab_r = E::multi_pairing(a_left, b_right);
97 (zab_l, zab_r, tab_l, tab_r)
98}
99
100pub(crate) fn aggregate_public_inputs<G: AffineRepr>(
101 public_inputs: &[Vec<G::ScalarField>],
102 r_powers: &[G::ScalarField],
103 r_sum: G::ScalarField,
104 gamma_abc_g1: &[G],
105) -> G {
106 let l = public_inputs[0].len();
117
118 let mut summed = cfg_into_iter!(0..l)
120 .map(|i| {
121 let mut c = public_inputs[0][i];
123 for j in 1..public_inputs.len() {
124 let mut ai = public_inputs[j][i];
125 ai.mul_assign(&r_powers[j]);
126 c.add_assign(&ai);
127 }
128 c.into_bigint()
129 })
130 .collect::<Vec<_>>();
131
132 summed.insert(0, r_sum.into_bigint());
133
134 G::Group::msm_bigint(&gamma_abc_g1, &summed).into_affine()
135}
136
137pub(crate) fn prove_commitments<E: Pairing>(
138 h_alpha_powers_table: &[E::G2Affine],
139 h_beta_powers_table: &[E::G2Affine],
140 g_alpha_powers_table: &[E::G1Affine],
141 g_beta_powers_table: &[E::G1Affine],
142 challenges: &[E::ScalarField],
143 challenges_inv: &[E::ScalarField],
144 shift: &E::ScalarField,
145 kzg_challenge: &E::ScalarField,
146) -> Result<(KZGOpening<E::G2Affine>, KZGOpening<E::G1Affine>), AggregationError> {
147 let vkey_opening = prove_commitment_v(
148 h_alpha_powers_table,
149 h_beta_powers_table,
150 challenges_inv,
151 kzg_challenge,
152 )?;
153 let wkey_opening = prove_commitment_w(
154 g_alpha_powers_table,
155 g_beta_powers_table,
156 challenges,
157 shift,
158 kzg_challenge,
159 )?;
160 Ok((vkey_opening, wkey_opening))
161}
162
163pub(crate) fn verify_kzg<E: Pairing>(
164 v_srs: &VerifierSRSProjective<E>,
165 final_vkey: &(E::G2Affine, E::G2Affine),
166 vkey_opening: &KZGOpening<E::G2Affine>,
167 final_wkey: &(E::G1Affine, E::G1Affine),
168 wkey_opening: &KZGOpening<E::G1Affine>,
169 challenges: &[E::ScalarField],
170 challenges_inv: &[E::ScalarField],
171 shift: &E::ScalarField,
172 kzg_challenge: &E::ScalarField,
173 pairing_checker: &mut RandomizedPairingChecker<E>,
174) {
175 verify_kzg_v(
178 v_srs,
179 final_vkey,
180 vkey_opening,
181 &challenges_inv,
182 kzg_challenge,
183 pairing_checker,
184 );
185
186 verify_kzg_w(
188 v_srs,
189 final_wkey,
190 wkey_opening,
191 &challenges,
192 shift,
193 kzg_challenge,
194 pairing_checker,
195 );
196}
197
198pub(crate) fn final_verification_check<E: Pairing>(
199 mut source1: Vec<E::G1Affine>,
200 mut source2: Vec<E::G2Affine>,
201 z_c: E::G1Affine,
202 z_ab: &PairingOutput<E>,
203 r: &E::ScalarField,
204 public_inputs: &[Vec<E::ScalarField>],
205 alpha_g1: &E::G1Affine,
206 beta_g2: E::G2Affine,
207 gamma_g2: E::G2Affine,
208 delta_g2: E::G2Affine,
209 gamma_abc_g1: &[E::G1Affine],
210 checker: &mut RandomizedPairingChecker<E>,
211) -> Result<(), AggregationError> {
212 let public_inputs_len = public_inputs
213 .len()
214 .try_into()
215 .map_err(|_| AggregationError::PublicInputsTooLarge(public_inputs.len()))?;
216 let r_powers = powers(r, public_inputs_len);
217 let r_sum = sum_of_powers::<E::ScalarField>(r, public_inputs_len);
218
219 let alpha_g1_r_sum = alpha_g1.mul(r_sum);
222 source1.push(alpha_g1_r_sum.into_affine());
223 source2.push(beta_g2);
224
225 source1.push(aggregate_public_inputs(
226 public_inputs,
227 &r_powers,
228 r_sum,
229 gamma_abc_g1,
230 ));
231 source2.push(gamma_g2);
232
233 source1.push(z_c);
234 source2.push(delta_g2);
235
236 checker.add_multiple_sources_and_target(&source1, source2, &z_ab);
237
238 match checker.verify() {
239 true => Ok(()),
240 false => Err(AggregationError::InvalidProof(
241 "Proof Verification Failed due to pairing checks".to_string(),
242 )),
243 }
244}