plonk_wasm/
plonk_verifier_index.rs

1use crate::wasm_vector::WasmVector;
2use ark_ec::AffineRepr;
3use ark_ff::One;
4use ark_poly::{EvaluationDomain, Radix2EvaluationDomain as Domain};
5use kimchi::{
6    circuits::{
7        constraints::FeatureFlags,
8        lookup::{
9            index::LookupSelectors,
10            lookups::{LookupFeatures, LookupInfo, LookupPatterns},
11        },
12        polynomials::permutation::{permutation_vanishing_polynomial, zk_w, Shifts},
13        wires::{COLUMNS, PERMUTS},
14    },
15    linearization::expr_linearization,
16    verifier_index::{LookupVerifierIndex, VerifierIndex as DlogVerifierIndex},
17};
18use paste::paste;
19use poly_commitment::{
20    commitment::PolyComm,
21    ipa::{OpeningProof, SRS},
22    SRS as _,
23};
24use std::{path::Path, sync::Arc};
25use wasm_bindgen::prelude::*;
26
27macro_rules! impl_verification_key {
28    (
29     $name: ident,
30     $WasmG: ty,
31     $G: ty,
32     $WasmF: ty,
33     $F: ty,
34     $WasmPolyComm: ty,
35     $WasmSrs: ty,
36     $GOther: ty,
37     $FrSpongeParams: path,
38     $FqSpongeParams: path,
39     $WasmIndex: ty,
40     $field_name: ident
41     ) => {
42        paste! {
43            #[wasm_bindgen]
44            #[derive(Clone, Copy)]
45            pub struct [<Wasm $field_name:camel Domain>] {
46                pub log_size_of_group: i32,
47                pub group_gen: $WasmF,
48            }
49            type WasmDomain = [<Wasm $field_name:camel Domain>];
50
51            #[wasm_bindgen]
52            impl [<Wasm $field_name:camel Domain>]{
53                #[wasm_bindgen(constructor)]
54                pub fn new(log_size_of_group: i32, group_gen: $WasmF) -> Self {
55                    WasmDomain {log_size_of_group, group_gen}
56                }
57            }
58
59            #[wasm_bindgen]
60            #[derive(Clone)]
61            pub struct [<Wasm $field_name:camel PlonkVerificationEvals>] {
62                #[wasm_bindgen(skip)]
63                pub sigma_comm: WasmVector<$WasmPolyComm>,
64                #[wasm_bindgen(skip)]
65                pub coefficients_comm: WasmVector<$WasmPolyComm>,
66                #[wasm_bindgen(skip)]
67                pub generic_comm: $WasmPolyComm,
68                #[wasm_bindgen(skip)]
69                pub psm_comm: $WasmPolyComm,
70                #[wasm_bindgen(skip)]
71                pub complete_add_comm: $WasmPolyComm,
72                #[wasm_bindgen(skip)]
73                pub mul_comm: $WasmPolyComm,
74                #[wasm_bindgen(skip)]
75                pub emul_comm: $WasmPolyComm,
76                #[wasm_bindgen(skip)]
77                pub endomul_scalar_comm: $WasmPolyComm,
78                #[wasm_bindgen(skip)]
79                pub xor_comm: Option<$WasmPolyComm>,
80                #[wasm_bindgen(skip)]
81                pub range_check0_comm: Option<$WasmPolyComm>,
82                #[wasm_bindgen(skip)]
83                pub range_check1_comm: Option<$WasmPolyComm>,
84                #[wasm_bindgen(skip)]
85                pub foreign_field_add_comm: Option<$WasmPolyComm>,
86                #[wasm_bindgen(skip)]
87                pub foreign_field_mul_comm: Option<$WasmPolyComm>,
88                #[wasm_bindgen(skip)]
89                pub rot_comm: Option<$WasmPolyComm>
90            }
91
92            type WasmPlonkVerificationEvals = [<Wasm $field_name:camel PlonkVerificationEvals>];
93
94
95            #[wasm_bindgen]
96            impl [<Wasm $field_name:camel PlonkVerificationEvals>] {
97                #[allow(clippy::too_many_arguments)]
98                #[wasm_bindgen(constructor)]
99                pub fn new(
100                    sigma_comm: WasmVector<$WasmPolyComm>,
101                    coefficients_comm: WasmVector<$WasmPolyComm>,
102                    generic_comm: &$WasmPolyComm,
103                    psm_comm: &$WasmPolyComm,
104                    complete_add_comm: &$WasmPolyComm,
105                    mul_comm: &$WasmPolyComm,
106                    emul_comm: &$WasmPolyComm,
107                    endomul_scalar_comm: &$WasmPolyComm,
108                    xor_comm: Option<$WasmPolyComm>,
109                    range_check0_comm: Option<$WasmPolyComm>,
110                    range_check1_comm: Option<$WasmPolyComm>,
111                    foreign_field_add_comm: Option<$WasmPolyComm>,
112                    foreign_field_mul_comm: Option<$WasmPolyComm>,
113                    rot_comm: Option<$WasmPolyComm>,
114                    ) -> Self {
115                    WasmPlonkVerificationEvals {
116                        sigma_comm: sigma_comm.clone(),
117                        coefficients_comm: coefficients_comm.clone(),
118                        generic_comm: generic_comm.clone(),
119                        psm_comm: psm_comm.clone(),
120                        complete_add_comm: complete_add_comm.clone(),
121                        mul_comm: mul_comm.clone(),
122                        emul_comm: emul_comm.clone(),
123                        endomul_scalar_comm: endomul_scalar_comm.clone(),
124                        xor_comm: xor_comm.clone(),
125                        range_check0_comm: range_check0_comm.clone(),
126                        range_check1_comm: range_check1_comm.clone(),
127                        foreign_field_mul_comm: foreign_field_mul_comm.clone(),
128                        foreign_field_add_comm: foreign_field_add_comm.clone(),
129                        rot_comm: rot_comm.clone(),
130                    }
131                }
132
133                #[wasm_bindgen(getter)]
134                pub fn sigma_comm(&self) -> WasmVector<$WasmPolyComm> {
135                    self.sigma_comm.clone()
136                }
137
138                #[wasm_bindgen(setter)]
139                pub fn set_sigma_comm(&mut self, x: WasmVector<$WasmPolyComm>) {
140                    self.sigma_comm = x;
141                }
142
143                #[wasm_bindgen(getter)]
144                pub fn coefficients_comm(&self) -> WasmVector<$WasmPolyComm> {
145                    self.coefficients_comm.clone()
146                }
147
148                #[wasm_bindgen(setter)]
149                pub fn set_coefficients_comm(&mut self, x: WasmVector<$WasmPolyComm>) {
150                    self.coefficients_comm = x;
151                }
152
153                #[wasm_bindgen(getter)]
154                pub fn generic_comm(&self) -> $WasmPolyComm {
155                    self.generic_comm.clone()
156                }
157
158                #[wasm_bindgen(setter)]
159                pub fn set_generic_comm(&mut self, x: $WasmPolyComm) {
160                    self.generic_comm = x;
161                }
162
163                #[wasm_bindgen(getter)]
164                pub fn psm_comm(&self) -> $WasmPolyComm {
165                    self.psm_comm.clone()
166                }
167
168                #[wasm_bindgen(setter)]
169                pub fn set_psm_comm(&mut self, x: $WasmPolyComm) {
170                    self.psm_comm = x;
171                }
172
173                #[wasm_bindgen(getter)]
174                pub fn complete_add_comm(&self) -> $WasmPolyComm {
175                    self.complete_add_comm.clone()
176                }
177
178                #[wasm_bindgen(setter)]
179                pub fn set_complete_add_comm(&mut self, x: $WasmPolyComm) {
180                    self.complete_add_comm = x;
181                }
182
183                #[wasm_bindgen(getter)]
184                pub fn mul_comm(&self) -> $WasmPolyComm {
185                    self.mul_comm.clone()
186                }
187
188                #[wasm_bindgen(setter)]
189                pub fn set_mul_comm(&mut self, x: $WasmPolyComm) {
190                    self.mul_comm = x;
191                }
192
193                #[wasm_bindgen(getter)]
194                pub fn emul_comm(&self) -> $WasmPolyComm {
195                    self.emul_comm.clone()
196                }
197
198                #[wasm_bindgen(setter)]
199                pub fn set_emul_comm(&mut self, x: $WasmPolyComm) {
200                    self.emul_comm = x;
201                }
202
203                #[wasm_bindgen(getter)]
204                pub fn endomul_scalar_comm(&self) -> $WasmPolyComm {
205                    self.endomul_scalar_comm.clone()
206                }
207
208                #[wasm_bindgen(setter)]
209                pub fn set_endomul_scalar_comm(&mut self, x: $WasmPolyComm) {
210                    self.endomul_scalar_comm = x;
211                }
212
213                #[wasm_bindgen(getter)]
214                pub fn xor_comm(&self) -> Option<$WasmPolyComm> {
215                    self.xor_comm.clone()
216                }
217
218                #[wasm_bindgen(setter)]
219                pub fn set_xor_comm(&mut self, x: Option<$WasmPolyComm>) {
220                    self.xor_comm = x;
221                }
222
223                #[wasm_bindgen(getter)]
224                pub fn rot_comm(&self) -> Option<$WasmPolyComm> {
225                    self.rot_comm.clone()
226                }
227
228                #[wasm_bindgen(setter)]
229                pub fn set_rot_comm(&mut self, x: Option<$WasmPolyComm>) {
230                    self.rot_comm = x;
231                }
232
233                #[wasm_bindgen(getter)]
234                pub fn range_check0_comm(&self) -> Option<$WasmPolyComm> {
235                    self.range_check0_comm.clone()
236                }
237
238                #[wasm_bindgen(setter)]
239                pub fn set_range_check0_comm(&mut self, x: Option<$WasmPolyComm>) {
240                    self.range_check0_comm = x;
241                }
242
243                #[wasm_bindgen(getter)]
244                pub fn range_check1_comm(&self) -> Option<$WasmPolyComm> {
245                    self.range_check1_comm.clone()
246                }
247
248                #[wasm_bindgen(setter)]
249                pub fn set_range_check1_comm(&mut self, x: Option<$WasmPolyComm>) {
250                    self.range_check1_comm = x;
251                }
252
253                #[wasm_bindgen(getter)]
254                pub fn foreign_field_add_comm(&self) -> Option<$WasmPolyComm> {
255                    self.foreign_field_add_comm.clone()
256                }
257
258                #[wasm_bindgen(setter)]
259                pub fn set_foreign_field_add_comm(&mut self, x: Option<$WasmPolyComm>) {
260                    self.foreign_field_add_comm = x;
261                }
262
263                #[wasm_bindgen(getter)]
264                pub fn foreign_field_mul_comm(&self) -> Option<$WasmPolyComm> {
265                    self.foreign_field_mul_comm.clone()
266                }
267
268                #[wasm_bindgen(setter)]
269                pub fn set_foreign_field_mul_comm(&mut self, x: Option<$WasmPolyComm>) {
270                    self.foreign_field_mul_comm = x;
271                }
272
273            }
274
275            #[derive(Clone, Copy)]
276            #[wasm_bindgen]
277            pub struct [<Wasm $field_name:camel Shifts>] {
278                pub s0: $WasmF,
279                pub s1: $WasmF,
280                pub s2: $WasmF,
281                pub s3: $WasmF,
282                pub s4: $WasmF,
283                pub s5: $WasmF,
284                pub s6: $WasmF,
285            }
286            type WasmShifts = [<Wasm $field_name:camel Shifts>];
287
288            #[wasm_bindgen]
289            impl [<Wasm $field_name:camel Shifts>] {
290                #[wasm_bindgen(constructor)]
291                pub fn new(
292                    s0: $WasmF,
293                    s1: $WasmF,
294                    s2: $WasmF,
295                    s3: $WasmF,
296                    s4: $WasmF,
297                    s5: $WasmF,
298                    s6: $WasmF
299                ) -> Self {
300                    Self { s0, s1, s2, s3, s4, s5, s6}
301                }
302            }
303
304            #[wasm_bindgen]
305            #[derive(Clone)]
306            pub struct [<Wasm $field_name:camel LookupSelectors>] {
307                #[wasm_bindgen(skip)]
308                pub xor: Option<$WasmPolyComm>,
309                #[wasm_bindgen(skip)]
310                pub lookup : Option<$WasmPolyComm>,
311                #[wasm_bindgen(skip)]
312                pub range_check: Option<$WasmPolyComm>,
313                #[wasm_bindgen(skip)]
314                pub ffmul: Option<$WasmPolyComm>,
315            }
316
317            type WasmLookupSelectors = [<Wasm $field_name:camel LookupSelectors>];
318
319            impl From<WasmLookupSelectors> for LookupSelectors<PolyComm<$G>> {
320                fn from(x: WasmLookupSelectors) -> Self {
321                    Self {
322                        xor: x.xor.map(Into::into),
323                        lookup: x.lookup.map(Into::into),
324                        range_check: x.range_check.map(Into::into),
325                        ffmul: x.ffmul.map(Into::into),
326                    }
327                }
328            }
329
330            impl From<&WasmLookupSelectors> for LookupSelectors<PolyComm<$G>> {
331                fn from(x: &WasmLookupSelectors) -> Self {
332                    Self {
333                        xor: x.xor.clone().map(Into::into),
334                        lookup: x.lookup.clone().map(Into::into),
335                        range_check: x.range_check.clone().map(Into::into),
336                        ffmul: x.ffmul.clone().map(Into::into),
337                    }
338                }
339            }
340
341            impl From<&LookupSelectors<PolyComm<$G>>> for WasmLookupSelectors {
342                fn from(x: &LookupSelectors<PolyComm<$G>>) -> Self {
343                    Self {
344                        xor: x.xor.clone().map(Into::into),
345                        lookup: x.lookup.clone().map(Into::into),
346                        range_check: x.range_check.clone().map(Into::into),
347                        ffmul: x.ffmul.clone().map(Into::into),
348                    }
349                }
350            }
351
352            impl From<LookupSelectors<PolyComm<$G>>> for WasmLookupSelectors {
353                fn from(x: LookupSelectors<PolyComm<$G>>) -> Self {
354                    Self {
355                        xor: x.xor.clone().map(Into::into),
356                        lookup: x.lookup.clone().map(Into::into),
357                        range_check: x.range_check.clone().map(Into::into),
358                        ffmul: x.ffmul.clone().map(Into::into),
359                    }
360                }
361            }
362
363            #[wasm_bindgen]
364            impl [<Wasm $field_name:camel LookupSelectors>] {
365                #[wasm_bindgen(constructor)]
366                pub fn new(
367                    xor: Option<$WasmPolyComm>,
368                    lookup: Option<$WasmPolyComm>,
369                    range_check: Option<$WasmPolyComm>,
370                    ffmul: Option<$WasmPolyComm>
371                ) -> Self {
372                    Self {
373                        xor,
374                        lookup,
375                        range_check,
376                        ffmul
377                    }
378                }
379
380                #[wasm_bindgen(getter)]
381                pub fn xor(&self) -> Option<$WasmPolyComm> {
382                    self.xor.clone()
383                }
384
385                #[wasm_bindgen(setter)]
386                pub fn set_xor(&mut self, x: Option<$WasmPolyComm>) {
387                    self.xor = x
388                }
389
390                #[wasm_bindgen(getter)]
391                pub fn lookup(&self) -> Option<$WasmPolyComm> {
392                    self.lookup.clone()
393                }
394
395                #[wasm_bindgen(setter)]
396                pub fn set_lookup(&mut self, x: Option<$WasmPolyComm>) {
397                    self.lookup = x
398                }
399
400                #[wasm_bindgen(getter)]
401                pub fn ffmul(&self) -> Option<$WasmPolyComm> {
402                    self.ffmul.clone()
403                }
404
405                #[wasm_bindgen(setter)]
406                pub fn set_ffmul(&mut self, x: Option<$WasmPolyComm>) {
407                    self.ffmul = x
408                }
409
410                #[wasm_bindgen(getter)]
411                pub fn range_check(&self) -> Option<$WasmPolyComm> {
412                    self.range_check.clone()
413                }
414
415                #[wasm_bindgen(setter)]
416                pub fn set_range_check(&mut self, x: Option<$WasmPolyComm>) {
417                    self.range_check = x
418                }
419            }
420
421            #[wasm_bindgen]
422            #[derive(Clone)]
423            pub struct [<Wasm $field_name:camel LookupVerifierIndex>] {
424                pub joint_lookup_used: bool,
425
426                #[wasm_bindgen(skip)]
427                pub lookup_table: WasmVector<$WasmPolyComm>,
428
429                #[wasm_bindgen(skip)]
430                pub lookup_selectors: WasmLookupSelectors,
431
432                #[wasm_bindgen(skip)]
433                pub table_ids: Option<$WasmPolyComm>,
434
435                #[wasm_bindgen(skip)]
436                pub lookup_info: LookupInfo,
437
438                #[wasm_bindgen(skip)]
439                pub runtime_tables_selector: Option<$WasmPolyComm>,
440            }
441
442            type WasmLookupVerifierIndex = [<Wasm $field_name:camel LookupVerifierIndex>];
443
444            impl From<&LookupVerifierIndex<$G>> for WasmLookupVerifierIndex {
445                fn from(x: &LookupVerifierIndex<$G>) -> Self {
446                    Self {
447                        joint_lookup_used: x.joint_lookup_used.into(),
448                        lookup_table: x.lookup_table.clone().iter().map(Into::into).collect(),
449                        lookup_selectors: x.lookup_selectors.clone().into(),
450                        table_ids: x.table_ids.clone().map(Into::into),
451                        lookup_info: x.lookup_info.clone(),
452                        runtime_tables_selector: x.runtime_tables_selector.clone().map(Into::into)
453                    }
454                }
455            }
456
457            impl From<LookupVerifierIndex<$G>> for WasmLookupVerifierIndex {
458                fn from(x: LookupVerifierIndex<$G>) -> Self {
459                    Self {
460                        joint_lookup_used: x.joint_lookup_used.into(),
461                        lookup_table: x.lookup_table.iter().map(Into::into).collect(),
462                        lookup_selectors: x.lookup_selectors.into(),
463                        table_ids: x.table_ids.map(Into::into),
464                        lookup_info: x.lookup_info,
465                        runtime_tables_selector: x.runtime_tables_selector.map(Into::into)
466                    }
467                }
468            }
469
470
471            impl From<&WasmLookupVerifierIndex> for LookupVerifierIndex<$G> {
472                fn from(x: &WasmLookupVerifierIndex) -> Self {
473                    Self {
474                        joint_lookup_used: x.joint_lookup_used.into(),
475                        lookup_table: x.lookup_table.clone().iter().map(Into::into).collect(),
476                        lookup_selectors: x.lookup_selectors.clone().into(),
477                        table_ids: x.table_ids.clone().map(Into::into),
478                        lookup_info: x.lookup_info,
479                        runtime_tables_selector: x.runtime_tables_selector.clone().map(Into::into)
480                    }
481                }
482            }
483
484            impl From<WasmLookupVerifierIndex> for LookupVerifierIndex<$G> {
485                fn from(x: WasmLookupVerifierIndex) -> Self {
486                    Self {
487                        joint_lookup_used: x.joint_lookup_used.into(),
488                        lookup_table: x.lookup_table.iter().map(Into::into).collect(),
489                        lookup_selectors: x.lookup_selectors.into(),
490                        table_ids: x.table_ids.map(Into::into),
491                        lookup_info: x.lookup_info,
492                        runtime_tables_selector: x.runtime_tables_selector.map(Into::into)
493                    }
494                }
495            }
496
497            #[wasm_bindgen]
498            impl [<Wasm $field_name:camel LookupVerifierIndex>] {
499                #[wasm_bindgen(constructor)]
500                pub fn new(
501                    joint_lookup_used: bool,
502                    lookup_table: WasmVector<$WasmPolyComm>,
503                    lookup_selectors: WasmLookupSelectors,
504                    table_ids: Option<$WasmPolyComm>,
505                    lookup_info: &LookupInfo,
506                    runtime_tables_selector: Option<$WasmPolyComm>
507                ) -> WasmLookupVerifierIndex {
508                    WasmLookupVerifierIndex {
509                        joint_lookup_used,
510                        lookup_table,
511                        lookup_selectors,
512                        table_ids,
513                        lookup_info: lookup_info.clone(),
514                        runtime_tables_selector
515                    }
516                }
517
518                #[wasm_bindgen(getter)]
519                pub fn lookup_table(&self) -> WasmVector<$WasmPolyComm> {
520                    self.lookup_table.clone()
521                }
522
523                #[wasm_bindgen(setter)]
524                pub fn set_lookup_table(&mut self, x: WasmVector<$WasmPolyComm>) {
525                    self.lookup_table = x
526                }
527
528                #[wasm_bindgen(getter)]
529                pub fn lookup_selectors(&self) -> WasmLookupSelectors {
530                    self.lookup_selectors.clone()
531                }
532
533                #[wasm_bindgen(setter)]
534                pub fn set_lookup_selectors(&mut self, x: WasmLookupSelectors) {
535                    self.lookup_selectors = x
536                }
537
538                #[wasm_bindgen(getter)]
539                pub fn table_ids(&self) -> Option<$WasmPolyComm>{
540                    self.table_ids.clone()
541                }
542
543                #[wasm_bindgen(setter)]
544                pub fn set_table_ids(&mut self, x: Option<$WasmPolyComm>) {
545                    self.table_ids = x
546                }
547
548                #[wasm_bindgen(getter)]
549                pub fn lookup_info(&self) -> LookupInfo {
550                    self.lookup_info.clone()
551                }
552
553                #[wasm_bindgen(setter)]
554                pub fn set_lookup_info(&mut self, x: LookupInfo) {
555                    self.lookup_info = x
556                }
557
558                #[wasm_bindgen(getter)]
559                pub fn runtime_tables_selector(&self) -> Option<$WasmPolyComm> {
560                    self.runtime_tables_selector.clone()
561                }
562
563                #[wasm_bindgen(setter)]
564                pub fn set_runtime_tables_selector(&mut self, x: Option<$WasmPolyComm>) {
565                    self.runtime_tables_selector = x
566                }
567            }
568
569            #[wasm_bindgen]
570            #[derive(Clone)]
571            pub struct [<Wasm $field_name:camel PlonkVerifierIndex>] {
572                pub domain: WasmDomain,
573                pub max_poly_size: i32,
574                pub public_: i32,
575                pub prev_challenges: i32,
576                #[wasm_bindgen(skip)]
577                pub srs: $WasmSrs,
578                #[wasm_bindgen(skip)]
579                pub evals: WasmPlonkVerificationEvals,
580                pub shifts: WasmShifts,
581                #[wasm_bindgen(skip)]
582                pub lookup_index: Option<WasmLookupVerifierIndex>,
583                pub zk_rows: isize,
584            }
585            type WasmPlonkVerifierIndex = [<Wasm $field_name:camel PlonkVerifierIndex>];
586
587            #[wasm_bindgen]
588            impl [<Wasm $field_name:camel PlonkVerifierIndex>] {
589                #[wasm_bindgen(constructor)]
590                #[allow(clippy::too_many_arguments)]
591                pub fn new(
592                    domain: &WasmDomain,
593                    max_poly_size: i32,
594                    public_: i32,
595                    prev_challenges: i32,
596                    srs: &$WasmSrs,
597                    evals: &WasmPlonkVerificationEvals,
598                    shifts: &WasmShifts,
599                    lookup_index: Option<WasmLookupVerifierIndex>,
600                    zk_rows: isize,
601                ) -> Self {
602                    WasmPlonkVerifierIndex {
603                        domain: domain.clone(),
604                        max_poly_size,
605                        public_,
606                        prev_challenges,
607                        srs: srs.clone(),
608                        evals: evals.clone(),
609                        shifts: shifts.clone(),
610                        lookup_index: lookup_index.clone(),
611                        zk_rows,
612                    }
613                }
614
615                #[wasm_bindgen(getter)]
616                pub fn srs(&self) -> $WasmSrs {
617                    self.srs.clone()
618                }
619
620                #[wasm_bindgen(setter)]
621                pub fn set_srs(&mut self, x: $WasmSrs) {
622                    self.srs = x
623                }
624
625                #[wasm_bindgen(getter)]
626                pub fn evals(&self) -> WasmPlonkVerificationEvals {
627                    self.evals.clone()
628                }
629
630                #[wasm_bindgen(setter)]
631                pub fn set_evals(&mut self, x: WasmPlonkVerificationEvals) {
632                    self.evals = x
633                }
634
635                #[wasm_bindgen(getter)]
636                pub fn lookup_index(&self) -> Option<WasmLookupVerifierIndex> {
637                    self.lookup_index.clone()
638                }
639
640                #[wasm_bindgen(setter)]
641                pub fn set_lookup_index(&mut self, li: Option<WasmLookupVerifierIndex>) {
642                    self.lookup_index = li
643                }
644            }
645
646            pub fn to_wasm(
647                srs: &Arc<SRS<$G>>,
648                vi: DlogVerifierIndex<$G, OpeningProof<$G>>,
649            ) -> WasmPlonkVerifierIndex {
650                WasmPlonkVerifierIndex {
651                    domain: WasmDomain {
652                        log_size_of_group: vi.domain.log_size_of_group as i32,
653                        group_gen: vi.domain.group_gen.into(),
654                    },
655                    max_poly_size: vi.max_poly_size as i32,
656                    public_: vi.public as i32,
657                    prev_challenges: vi.prev_challenges as i32,
658                    srs: srs.into(),
659                    evals: WasmPlonkVerificationEvals {
660                        sigma_comm: IntoIterator::into_iter(vi.sigma_comm).map(From::from).collect(),
661                        coefficients_comm: IntoIterator::into_iter(vi.coefficients_comm).map(From::from).collect(),
662                        generic_comm: vi.generic_comm.into(),
663                        psm_comm: vi.psm_comm.into(),
664                        complete_add_comm: vi.complete_add_comm.into(),
665                        mul_comm: vi.mul_comm.into(),
666                        emul_comm: vi.emul_comm.into(),
667                        endomul_scalar_comm: vi.endomul_scalar_comm.into(),
668                        xor_comm: vi.xor_comm.map(|v| v.into()),
669                        range_check0_comm: vi.range_check0_comm.map(|v| v.into()),
670                        range_check1_comm: vi.range_check1_comm.map(|v| v.into()),
671                        foreign_field_add_comm: vi.foreign_field_add_comm.map(|v| v.into()),
672                        foreign_field_mul_comm: vi.foreign_field_mul_comm.map(|v| v.into()),
673                        rot_comm: vi.rot_comm.map(|v| v.into())
674                    },
675                    shifts:
676                        WasmShifts {
677                            s0: vi.shift[0].into(),
678                            s1: vi.shift[1].into(),
679                            s2: vi.shift[2].into(),
680                            s3: vi.shift[3].into(),
681                            s4: vi.shift[4].into(),
682                            s5: vi.shift[5].into(),
683                            s6: vi.shift[6].into(),
684                        },
685                    lookup_index: vi.lookup_index.map(Into::into),
686                    zk_rows: vi.zk_rows as isize,
687                }
688            }
689
690            fn compute_feature_flags(index: &WasmPlonkVerifierIndex) -> FeatureFlags {
691                let xor = index.evals.xor_comm.is_some();
692                let range_check0 = index.evals.range_check0_comm.is_some();
693                let range_check1 = index.evals.range_check1_comm.is_some();
694                let foreign_field_add = index.evals.foreign_field_add_comm.is_some();
695                let foreign_field_mul = index.evals.foreign_field_mul_comm.is_some();
696                let rot = index.evals.rot_comm.is_some();
697
698                let lookup = index
699                    .lookup_index.as_ref()
700                    .map_or(false, |li| li.lookup_info.features.patterns.lookup);
701
702                let runtime_tables = index
703                    .lookup_index.as_ref()
704                    .map_or(false, |li| li.runtime_tables_selector.is_some());
705
706                let patterns = LookupPatterns {
707                    xor,
708                    lookup,
709                    range_check: range_check0 || range_check1 || rot,
710                    foreign_field_mul,
711                };
712
713                FeatureFlags {
714                    range_check0,
715                    range_check1,
716                    foreign_field_add,
717                    foreign_field_mul,
718                    xor,
719                    rot,
720                    lookup_features: LookupFeatures {
721                        patterns,
722                        joint_lookup_used: patterns.joint_lookups_used(),
723                        uses_runtime_tables: runtime_tables,
724                    },
725                }
726            }
727
728            pub fn of_wasm(
729                index: WasmPlonkVerifierIndex,
730            ) -> (DlogVerifierIndex<GAffine, OpeningProof<GAffine>>, Arc<SRS<GAffine>>) {
731                let max_poly_size = index.max_poly_size;
732                let public_ = index.public_;
733                let prev_challenges = index.prev_challenges;
734                let log_size_of_group = index.domain.log_size_of_group;
735                let srs = &index.srs;
736                let evals = &index.evals;
737                let shifts = &index.shifts;
738
739                let (endo_q, _endo_r) = poly_commitment::ipa::endos::<$GOther>();
740                let domain = Domain::<$F>::new(1 << log_size_of_group).unwrap();
741
742                let feature_flags = compute_feature_flags(&index);
743                let (linearization, powers_of_alpha) = expr_linearization(Some(&feature_flags), true);
744
745                let index = {
746                    let zk_rows = index.zk_rows as u64;
747
748                    DlogVerifierIndex {
749                        domain,
750
751                        sigma_comm: core::array::from_fn(|i| (&evals.sigma_comm[i]).into()),
752                        generic_comm: (&evals.generic_comm).into(),
753                        coefficients_comm: core::array::from_fn(|i| (&evals.coefficients_comm[i]).into()),
754
755                        psm_comm: (&evals.psm_comm).into(),
756
757                        complete_add_comm: (&evals.complete_add_comm).into(),
758                        mul_comm: (&evals.mul_comm).into(),
759                        emul_comm: (&evals.emul_comm).into(),
760
761                        endomul_scalar_comm: (&evals.endomul_scalar_comm).into(),
762                        xor_comm: (&evals.xor_comm).as_ref().map(Into::into),
763                        range_check0_comm: (&evals.range_check0_comm).as_ref().map(Into::into),
764                        range_check1_comm: (&evals.range_check1_comm).as_ref().map(Into::into),
765                        foreign_field_add_comm: (&evals.foreign_field_add_comm).as_ref().map(Into::into),
766                        foreign_field_mul_comm: (&evals.foreign_field_mul_comm).as_ref().map(Into::into),
767                        rot_comm: (&evals.rot_comm).as_ref().map(Into::into),
768
769                        w: {
770                            let res = once_cell::sync::OnceCell::new();
771                            res.set(zk_w(domain, zk_rows)).unwrap();
772                            res
773                        },
774                        endo: endo_q,
775                        max_poly_size: max_poly_size as usize,
776                        public: public_ as usize,
777                        prev_challenges: prev_challenges as usize,
778                        permutation_vanishing_polynomial_m: {
779                            let res = once_cell::sync::OnceCell::new();
780                            res.set(permutation_vanishing_polynomial(domain, zk_rows)).unwrap();
781                            res
782                        },
783                        shift: [
784                            shifts.s0.into(),
785                            shifts.s1.into(),
786                            shifts.s2.into(),
787                            shifts.s3.into(),
788                            shifts.s4.into(),
789                            shifts.s5.into(),
790                            shifts.s6.into()
791                        ],
792                        srs: {
793                          Arc::clone(&srs.0)
794                        },
795
796                        zk_rows,
797
798                        linearization,
799                        powers_of_alpha,
800                        lookup_index: index.lookup_index.map(Into::into),
801                    }
802                };
803                (index, srs.0.clone())
804            }
805
806            impl From<WasmPlonkVerifierIndex> for DlogVerifierIndex<$G, OpeningProof<$G>> {
807                fn from(index: WasmPlonkVerifierIndex) -> Self {
808                    of_wasm(index).0
809                }
810            }
811
812            pub fn read_raw(
813                offset: Option<i32>,
814                srs: &$WasmSrs,
815                path: String,
816            ) -> Result<DlogVerifierIndex<$G, OpeningProof<$G>>, JsValue> {
817                let path = Path::new(&path);
818                let (endo_q, _endo_r) = poly_commitment::ipa::endos::<GAffineOther>();
819                DlogVerifierIndex::<$G, OpeningProof<$G>>::from_file(
820                    srs.0.clone(),
821                    path,
822                    offset.map(|x| x as u64),
823                    endo_q,
824                ).map_err(|e| JsValue::from_str(format!("read_raw: {}", e).as_str()))
825            }
826
827            #[wasm_bindgen]
828            pub fn [<$name:snake _read>](
829                offset: Option<i32>,
830                srs: &$WasmSrs,
831                path: String,
832            ) -> Result<WasmPlonkVerifierIndex, JsValue> {
833                let vi = read_raw(offset, srs, path)?;
834                Ok(to_wasm(srs, vi.into()))
835            }
836
837            #[wasm_bindgen]
838            pub fn [<$name:snake _write>](
839                append: Option<bool>,
840                index: WasmPlonkVerifierIndex,
841                path: String,
842            ) -> Result<(), JsValue> {
843                let index: DlogVerifierIndex<$G, OpeningProof<$G>> = index.into();
844                let path = Path::new(&path);
845                index.to_file(path, append).map_err(|e| {
846                    println!("{}", e);
847                    JsValue::from_str("caml_pasta_fp_plonk_verifier_index_raw_read")
848                })
849            }
850
851            #[wasm_bindgen]
852            pub fn [<$name:snake _serialize>](
853                index: WasmPlonkVerifierIndex,
854            ) -> String {
855                let index: DlogVerifierIndex<$G, OpeningProof<$G>> = index.into();
856                serde_json::to_string(&index).unwrap()
857            }
858
859            #[wasm_bindgen]
860            pub fn [<$name:snake _deserialize>](
861                srs: &$WasmSrs,
862                index: String,
863            ) -> Result<WasmPlonkVerifierIndex, JsError> {
864                let vi: Result<DlogVerifierIndex<$G, OpeningProof<$G>>, serde_json::Error> = serde_json::from_str(&index);
865                match vi {
866                    Ok(vi) => Ok(to_wasm(srs, vi)),
867                    Err(e) => Err(JsError::new(&(e.to_string()))),
868                }
869            }
870
871            #[wasm_bindgen]
872            pub fn [<$name:snake _create>](
873                index: &$WasmIndex,
874            ) -> WasmPlonkVerifierIndex {
875                index.0.srs.get_lagrange_basis(index.0.as_ref().cs.domain.d1);
876                let verifier_index = index.0.as_ref().verifier_index();
877                to_wasm(&index.0.as_ref().srs, verifier_index)
878            }
879
880            #[wasm_bindgen]
881            pub fn [<$name:snake _shifts>](log2_size: i32) -> WasmShifts {
882                let domain = Domain::<$F>::new(1 << log2_size).unwrap();
883                let shifts = Shifts::new(&domain);
884                let s = shifts.shifts();
885                WasmShifts {
886                    s0: s[0].clone().into(),
887                    s1: s[1].clone().into(),
888                    s2: s[2].clone().into(),
889                    s3: s[3].clone().into(),
890                    s4: s[4].clone().into(),
891                    s5: s[5].clone().into(),
892                    s6: s[6].clone().into(),
893                }
894            }
895
896            #[wasm_bindgen]
897            pub fn [<$name:snake _dummy>]() -> WasmPlonkVerifierIndex {
898                fn comm() -> $WasmPolyComm {
899                    let g: $WasmG = $G::generator().into();
900                    $WasmPolyComm {
901                        shifted: None,
902                        unshifted: vec![g].into(),
903                    }
904                }
905                fn vec_comm(num: usize) -> WasmVector<$WasmPolyComm> {
906                    (0..num).map(|_| comm()).collect()
907                }
908
909                WasmPlonkVerifierIndex {
910                    domain: WasmDomain {
911                        log_size_of_group: 1,
912                        group_gen: $F::one().into(),
913                    },
914                    max_poly_size: 0,
915                    public_: 0,
916                    prev_challenges: 0,
917                    srs: $WasmSrs(Arc::new(SRS::create(0))),
918                    evals: WasmPlonkVerificationEvals {
919                        sigma_comm: vec_comm(PERMUTS),
920                        coefficients_comm: vec_comm(COLUMNS),
921                        generic_comm: comm(),
922                        psm_comm: comm(),
923                        complete_add_comm: comm(),
924                        mul_comm: comm(),
925                        emul_comm: comm(),
926                        endomul_scalar_comm: comm(),
927                        xor_comm: None,
928                        range_check0_comm: None,
929                        range_check1_comm: None,
930                        foreign_field_add_comm: None,
931                        foreign_field_mul_comm: None,
932                        rot_comm: None,
933                    },
934                    shifts:
935                        WasmShifts {
936                            s0: $F::one().into(),
937                            s1: $F::one().into(),
938                            s2: $F::one().into(),
939                            s3: $F::one().into(),
940                            s4: $F::one().into(),
941                            s5: $F::one().into(),
942                            s6: $F::one().into(),
943                        },
944                    lookup_index: None,
945                    zk_rows: 3,
946                }
947            }
948
949            #[wasm_bindgen]
950            pub fn [<$name:snake _deep_copy>](
951                x: &WasmPlonkVerifierIndex,
952            ) -> WasmPlonkVerifierIndex {
953                x.clone()
954            }
955
956        }
957    }
958}
959
960pub mod fp {
961    use super::*;
962    use crate::{
963        arkworks::{WasmGVesta, WasmPastaFp},
964        pasta_fp_plonk_index::WasmPastaFpPlonkIndex,
965        poly_comm::vesta::WasmFpPolyComm as WasmPolyComm,
966        srs::fp::WasmFpSrs,
967    };
968    use mina_curves::pasta::{Fp, Pallas as GAffineOther, Vesta as GAffine};
969
970    impl_verification_key!(
971        caml_pasta_fp_plonk_verifier_index,
972        WasmGVesta,
973        GAffine,
974        WasmPastaFp,
975        Fp,
976        WasmPolyComm,
977        WasmFpSrs,
978        GAffineOther,
979        mina_poseidon::pasta::fp_kimchi,
980        mina_poseidon::pasta::fq_kimchi,
981        WasmPastaFpPlonkIndex,
982        Fp
983    );
984}
985
986pub mod fq {
987    use super::*;
988    use crate::{
989        arkworks::{WasmGPallas, WasmPastaFq},
990        pasta_fq_plonk_index::WasmPastaFqPlonkIndex,
991        poly_comm::pallas::WasmFqPolyComm as WasmPolyComm,
992        srs::fq::WasmFqSrs,
993    };
994    use mina_curves::pasta::{Fq, Pallas as GAffine, Vesta as GAffineOther};
995
996    impl_verification_key!(
997        caml_pasta_fq_plonk_verifier_index,
998        WasmGPallas,
999        GAffine,
1000        WasmPastaFq,
1001        Fq,
1002        WasmPolyComm,
1003        WasmFqSrs,
1004        GAffineOther,
1005        mina_poseidon::pasta::fq_kimchi,
1006        mina_poseidon::pasta::fp_kimchi,
1007        WasmPastaFqPlonkIndex,
1008        Fq
1009    );
1010}