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}