1use ark_ec::pairing::Pairing;
2use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM};
3use ark_ff::PrimeField;
4use ark_poly::EvaluationDomain;
5use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
6use ark_std::fmt;
7use ark_std::iter;
8use ark_std::ops::Range;
9use ark_std::vec::Vec;
10use w3f_pcs::pcs::kzg::urs::URS;
11use w3f_pcs::pcs::PcsParams;
12
13use crate::piop::params::ZK_ROWS;
14
15use crate::PiopParams;
16
17const IDLE_ROWS: usize = ZK_ROWS + 1;
18
19#[derive(Clone, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)]
35pub struct Ring<F: PrimeField, KzgCurve: Pairing<ScalarField = F>, G: AffineRepr<BaseField = F>> {
36 pub cx: KzgCurve::G1Affine,
38 pub cy: KzgCurve::G1Affine,
40 pub selector: KzgCurve::G1Affine,
42 pub max_keys: usize,
44 pub curr_keys: usize,
46 pub padding: G,
48}
49
50impl<F: PrimeField, KzgCurve: Pairing<ScalarField = F>, G: AffineRepr<BaseField = F>> fmt::Debug
51 for Ring<F, KzgCurve, G>
52{
53 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54 write!(
55 f,
56 "Ring(curr_keys={}, max_keys{})",
57 self.curr_keys, self.max_keys
58 )
59 }
60}
61
62impl<F: PrimeField, KzgCurve: Pairing<ScalarField = F>, G: AffineRepr<BaseField = F>>
63 Ring<F, KzgCurve, G>
64{
65 pub fn empty(
77 piop_params: &PiopParams<G>,
78 srs: impl Fn(Range<usize>) -> Result<Vec<KzgCurve::G1Affine>, ()>,
79 g: KzgCurve::G1,
80 ) -> Self {
81 let (padding_x, padding_y) = piop_params.padding.xy().unwrap(); let c1x = g * padding_x;
83 let c1y = g * padding_y;
84
85 let powers_of_h = piop_params.power_of_2_multiples_of_h();
86 let (mut xs, mut ys): (Vec<F>, Vec<F>) = powers_of_h
87 .iter()
88 .map(|p| p.xy().unwrap())
89 .map(|(x, y)| (x - padding_x, y - padding_y))
90 .unzip();
91 xs.resize(xs.len() + IDLE_ROWS, -padding_x);
92 ys.resize(ys.len() + IDLE_ROWS, -padding_y);
93 let domain_size = piop_params.domain.domain().size();
94 let srs_segment = &srs(piop_params.keyset_part_size..domain_size).unwrap();
95 let c2x = KzgCurve::G1::msm(srs_segment, &xs).unwrap();
96 let c2y = KzgCurve::G1::msm(srs_segment, &ys).unwrap();
97
98 let selector_inv = srs_segment.iter().sum::<KzgCurve::G1>();
99 let selector = g - selector_inv;
100
101 let (cx, cy, selector) = {
102 let affine = KzgCurve::G1::normalize_batch(&[c1x + c2x, c1y + c2y, selector]);
103 (affine[0], affine[1], affine[2])
104 };
105
106 Self {
107 cx,
108 cy,
109 selector,
110 max_keys: piop_params.keyset_part_size,
111 curr_keys: 0,
112 padding: piop_params.padding,
113 }
114 }
115
116 pub fn append(
121 &mut self,
122 keys: &[G],
123 srs: impl Fn(Range<usize>) -> Result<Vec<KzgCurve::G1Affine>, ()>,
124 ) {
125 let new_size = self.curr_keys + keys.len();
126 assert!(new_size <= self.max_keys);
127 let (padding_x, padding_y) = self.padding.xy().unwrap();
128 let (xs, ys): (Vec<F>, Vec<F>) = keys
129 .iter()
130 .map(|p| p.xy().unwrap())
131 .map(|(x, y)| (x - padding_x, y - padding_y))
132 .unzip();
133 let srs_segment = &srs(self.curr_keys..self.curr_keys + keys.len()).unwrap();
134 let cx_delta = KzgCurve::G1::msm(srs_segment, &xs).unwrap();
135 let cy_delta = KzgCurve::G1::msm(srs_segment, &ys).unwrap();
136
137 let (new_cx, new_cy) = {
138 let affine = KzgCurve::G1::normalize_batch(&[self.cx + cx_delta, self.cy + cy_delta]);
139 (affine[0], affine[1])
140 };
141
142 self.cx = new_cx;
143 self.cy = new_cy;
144 self.curr_keys = new_size;
145 }
146
147 pub fn with_keys(
154 piop_params: &PiopParams<G>,
155 keys: &[G],
156 srs: &RingBuilderKey<F, KzgCurve>,
157 ) -> Self {
158 let (padding_x, padding_y) = piop_params.padding.xy().unwrap(); let powers_of_h = piop_params.power_of_2_multiples_of_h();
160
161 let (xs, ys): (Vec<F>, Vec<F>) = keys
167 .iter()
168 .chain(&powers_of_h)
169 .map(|p| p.xy().unwrap())
170 .map(|(x, y)| (x - padding_x, y - padding_y))
171 .chain(iter::repeat((-padding_x, -padding_y)).take(4))
172 .chain(iter::once((padding_x, padding_y)))
173 .unzip();
174
175 let bases = [
177 &srs.lis_in_g1[..keys.len()],
178 &srs.lis_in_g1[piop_params.keyset_part_size..],
179 &[srs.g1.into()],
180 ]
181 .concat();
182
183 let cx = KzgCurve::G1::msm(&bases, &xs).unwrap();
184 let cy = KzgCurve::G1::msm(&bases, &ys).unwrap();
185 let selector_inv = srs.lis_in_g1[piop_params.keyset_part_size..]
186 .iter()
187 .sum::<KzgCurve::G1>();
188 let selector = srs.g1 - selector_inv;
189
190 let (cx, cy, selector) = {
191 let affine = KzgCurve::G1::normalize_batch(&[cx, cy, selector]);
192 (affine[0], affine[1], affine[2])
193 };
194
195 Self {
196 cx,
197 cy,
198 selector,
199 max_keys: piop_params.keyset_part_size,
200 curr_keys: keys.len(),
201 padding: piop_params.padding,
202 }
203 }
204
205 pub fn slots_left(&self) -> usize {
206 self.max_keys - self.curr_keys
207 }
208
209 pub const fn empty_unchecked(
210 domain_size: usize,
211 cx: KzgCurve::G1Affine,
212 cy: KzgCurve::G1Affine,
213 selector: KzgCurve::G1Affine,
214 padding: G,
215 ) -> Self {
216 let max_keys = domain_size - (G::ScalarField::MODULUS_BIT_SIZE as usize + IDLE_ROWS);
217 Self {
218 cx,
219 cy,
220 selector,
221 max_keys,
222 curr_keys: 0,
223 padding,
224 }
225 }
226}
227
228#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)]
229pub struct RingBuilderKey<F: PrimeField, KzgCurve: Pairing<ScalarField = F>> {
230 pub lis_in_g1: Vec<KzgCurve::G1Affine>,
232 pub g1: KzgCurve::G1,
234}
235
236impl<F: PrimeField, KzgCurve: Pairing<ScalarField = F>> RingBuilderKey<F, KzgCurve> {
237 pub fn from_srs(srs: &URS<KzgCurve>, domain_size: usize) -> Self {
238 let g1 = srs.powers_in_g1[0].into_group();
239 let ck = srs.ck_with_lagrangian(domain_size);
240 let lis_in_g1 = ck.lagrangian.unwrap().lis_in_g;
241 Self { lis_in_g1, g1 }
242 }
243}
244
245#[cfg(test)]
246mod tests {
247 use ark_bls12_381::{Bls12_381, Fr, G1Affine};
248 use ark_ed_on_bls12_381_bandersnatch::EdwardsAffine;
249 use ark_std::test_rng;
250 use w3f_pcs::pcs::kzg::urs::URS;
251 use w3f_pcs::pcs::kzg::KZG;
252 use w3f_pcs::pcs::PCS;
253
254 use w3f_plonk_common::test_helpers::random_vec;
255
256 use crate::ring::Ring;
257 use crate::PiopParams;
258
259 use super::*;
260
261 type TestRing = Ring<Fr, Bls12_381, EdwardsAffine>;
262
263 #[test]
264 fn test_ring_mgmt() {
265 let rng = &mut test_rng();
266
267 let domain_size = 1 << 9;
268
269 let pcs_params = KZG::<Bls12_381>::setup(domain_size - 1, rng);
270 let ring_builder_key = RingBuilderKey::from_srs(&pcs_params, domain_size);
271 let srs = |range: Range<usize>| Ok(ring_builder_key.lis_in_g1[range].to_vec());
272 let piop_params = PiopParams::rand(domain_size, rng);
273
274 let mut ring = TestRing::empty(&piop_params, srs, ring_builder_key.g1);
275 let (monimial_cx, monimial_cy) = get_monomial_commitment(&pcs_params, &piop_params, &[]);
276 assert_eq!(ring.cx, monimial_cx);
277 assert_eq!(ring.cy, monimial_cy);
278
279 let keys = random_vec::<EdwardsAffine, _>(ring.max_keys, rng);
280 ring.append(&keys, srs);
281 let (monimial_cx, monimial_cy) = get_monomial_commitment(&pcs_params, &piop_params, &keys);
282 assert_eq!(ring.cx, monimial_cx);
283 assert_eq!(ring.cy, monimial_cy);
284
285 let same_ring = TestRing::with_keys(&piop_params, &keys, &ring_builder_key);
286 assert_eq!(ring, same_ring);
287 }
288
289 #[test]
290 fn test_empty_rings() {
291 let rng = &mut test_rng();
292
293 let domain_size = 1 << 9;
294
295 let pcs_params = KZG::<Bls12_381>::setup(domain_size - 1, rng);
296 let ring_builder_key = RingBuilderKey::from_srs(&pcs_params, domain_size);
297 let srs = |range: Range<usize>| Ok(ring_builder_key.lis_in_g1[range].to_vec());
298 let piop_params = PiopParams::rand(domain_size, rng);
299
300 let ring = TestRing::empty(&piop_params, srs, ring_builder_key.g1);
301 let same_ring = TestRing::with_keys(&piop_params, &[], &ring_builder_key);
302 assert_eq!(ring, same_ring);
303 }
304
305 fn get_monomial_commitment(
306 pcs_params: &URS<Bls12_381>,
307 piop_params: &PiopParams<EdwardsAffine>,
308 keys: &[EdwardsAffine],
309 ) -> (G1Affine, G1Affine) {
310 let (_, verifier_key) =
311 crate::piop::index::<_, KZG<Bls12_381>, _>(pcs_params, piop_params, keys);
312 let [monimial_cx, monimial_cy] = verifier_key.fixed_columns_committed.points;
313 (monimial_cx.0, monimial_cy.0)
314 }
315}