1use crate::{vector::NapiVector, wrappers::lookups::NapiLookupInfo};
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, 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},
17};
18use mina_poseidon::pasta::FULL_ROUNDS;
19use napi::{bindgen_prelude::*, Error, Status};
20use napi_derive::napi;
21use paste::paste;
22use poly_commitment::{commitment::PolyComm, ipa::SRS, SRS as _};
23use serde::{Deserialize, Serialize};
24use std::{path::Path, sync::Arc};
25
26macro_rules! impl_verification_key {
27 (
28 $NapiG: ty,
29 $G: ty,
30 $NapiF: ty,
31 $F: ty,
32 $NapiPolyComm: ty,
33 $NapiSrs: ty,
34 $GOther: ty,
35 $FrSpongeParams: path,
36 $FqSpongeParams: path,
37 $NapiIndex: ty,
38 $field_name: ident
39 ) => {
40 paste! {
41 #[napi(object, js_name = [<Wasm $field_name:camel Domain>])]
42 #[derive(Clone, Debug, Serialize, Deserialize, Default)]
43 pub struct [<Napi $field_name:camel Domain>] {
44 #[napi(js_name = "log_size_of_group")]
45 pub log_size_of_group: i32,
46 #[napi(js_name = "group_gen")]
47 pub group_gen: $NapiF,
48 }
49 type NapiDomain = [<Napi $field_name:camel Domain>];
50
51 impl From<NapiDomain> for Domain<[<$F>]> {
52 fn from(domain: NapiDomain) -> Self {
53 let size = 1 << domain.log_size_of_group;
54 Domain::<[<$F>]>::new(size).expect("Failed to create evaluation domain")
55 }
56 }
57
58 impl From<&Domain<$F>> for NapiDomain {
59 fn from(domain: &Domain<$F>) -> Self {
60 Self {
61 log_size_of_group: domain.log_size_of_group as i32,
62 group_gen: domain.group_gen.into(),
63 }
64 }
65 }
66
67 #[napi(object, js_name = [<Wasm $field_name:camel PlonkVerificationEvals>])]
68 #[derive(Clone, Debug, Serialize, Deserialize, Default)]
69 pub struct [<Napi $field_name:camel PlonkVerificationEvals>] {
70 #[napi(js_name = "sigma_comm")]
71 pub sigma_comm: NapiVector<$NapiPolyComm>,
72 #[napi(js_name = "coefficients_comm")]
73 pub coefficients_comm: NapiVector<$NapiPolyComm>,
74 #[napi(js_name = "generic_comm")]
75 pub generic_comm: $NapiPolyComm,
76 #[napi(js_name = "psm_comm")]
77 pub psm_comm: $NapiPolyComm,
78 #[napi(js_name = "complete_add_comm")]
79 pub complete_add_comm: $NapiPolyComm,
80 #[napi(js_name = "mul_comm")]
81 pub mul_comm: $NapiPolyComm,
82 #[napi(js_name = "emul_comm")]
83 pub emul_comm: $NapiPolyComm,
84 #[napi(js_name = "endomul_scalar_comm")]
85 pub endomul_scalar_comm: $NapiPolyComm,
86 #[napi(js_name = "xor_comm")]
87 pub xor_comm: Option<$NapiPolyComm>,
88 #[napi(js_name = "range_check0_comm")]
89 pub range_check0_comm: Option<$NapiPolyComm>,
90 #[napi(js_name = "range_check1_comm")]
91 pub range_check1_comm: Option<$NapiPolyComm>,
92 #[napi(js_name = "foreign_field_add_comm")]
93 pub foreign_field_add_comm: Option<$NapiPolyComm>,
94 #[napi(js_name = "foreign_field_mul_comm")]
95 pub foreign_field_mul_comm: Option<$NapiPolyComm>,
96 #[napi(js_name = "rot_comm")]
97 pub rot_comm: Option<$NapiPolyComm>,
98 }
99 type NapiPlonkVerificationEvals = [<Napi $field_name:camel PlonkVerificationEvals>];
100
101 impl From<&VerifierIndex<FULL_ROUNDS, $G, SRS<$G>>> for NapiPlonkVerificationEvals {
102 fn from(index: &VerifierIndex<FULL_ROUNDS, $G, SRS<$G>>) -> Self {
103 Self {
104 sigma_comm: index.sigma_comm.iter().map(Into::into).collect(),
105 coefficients_comm: index.coefficients_comm.iter().map(Into::into).collect(),
106 generic_comm: index.generic_comm.clone().into(),
107 psm_comm: index.psm_comm.clone().into(),
108 complete_add_comm: index.complete_add_comm.clone().into(),
109 mul_comm: index.mul_comm.clone().into(),
110 emul_comm: index.emul_comm.clone().into(),
111 endomul_scalar_comm: index.endomul_scalar_comm.clone().into(),
112 xor_comm: index.xor_comm.clone().map(Into::into),
113 range_check0_comm: index.range_check0_comm.clone().map(Into::into),
114 range_check1_comm: index.range_check1_comm.clone().map(Into::into),
115 foreign_field_add_comm: index.foreign_field_add_comm.clone().map(Into::into),
116 foreign_field_mul_comm: index.foreign_field_mul_comm.clone().map(Into::into),
117 rot_comm: index.rot_comm.clone().map(Into::into),
118 }
119 }
120 }
121
122 #[derive(Clone, Debug, Serialize, Deserialize, Default)]
123 #[napi(object, js_name = [<Wasm $field_name:camel Shifts>])]
124 pub struct [<Napi $field_name:camel Shifts>] {
125 pub s0: $NapiF,
126 pub s1: $NapiF,
127 pub s2: $NapiF,
128 pub s3: $NapiF,
129 pub s4: $NapiF,
130 pub s5: $NapiF,
131 pub s6: $NapiF,
132 }
133 type NapiShifts = [<Napi $field_name:camel Shifts>];
134
135 impl From<&[$F; 7]> for NapiShifts {
136 fn from(shifts: &[$F; 7]) -> Self {
137 Self {
138 s0: shifts[0].into(),
139 s1: shifts[1].into(),
140 s2: shifts[2].into(),
141 s3: shifts[3].into(),
142 s4: shifts[4].into(),
143 s5: shifts[5].into(),
144 s6: shifts[6].into(),
145 }
146 }
147 }
148
149 #[derive(Clone, Debug, Serialize, Deserialize, Default)]
150 #[napi(object, js_name = [<Wasm $field_name:camel LookupSelectors>])]
151 pub struct [<Napi $field_name:camel LookupSelectors>] {
152 #[napi(js_name = "xor")]
153 pub xor: Option<$NapiPolyComm>,
154 #[napi(js_name = "lookup")]
155 pub lookup: Option<$NapiPolyComm>,
156 #[napi(js_name = "range_check")]
157 pub range_check: Option<$NapiPolyComm>,
158 #[napi(js_name = "ffmul")]
159 pub ffmul: Option<$NapiPolyComm>,
160 }
161 type NapiLookupSelectors = [<Napi $field_name:camel LookupSelectors>];
162
163 impl From<NapiLookupSelectors> for LookupSelectors<PolyComm<$G>> {
164 fn from(x: NapiLookupSelectors) -> Self {
165 Self {
166 xor: x.xor.map(Into::into),
167 lookup: x.lookup.map(Into::into),
168 range_check: x.range_check.map(Into::into),
169 ffmul: x.ffmul.map(Into::into),
170 }
171 }
172 }
173
174 impl From<&NapiLookupSelectors> for LookupSelectors<PolyComm<$G>> {
175 fn from(x: &NapiLookupSelectors) -> Self {
176 Self {
177 xor: x.xor.clone().map(Into::into),
178 lookup: x.lookup.clone().map(Into::into),
179 range_check: x.range_check.clone().map(Into::into),
180 ffmul: x.ffmul.clone().map(Into::into),
181 }
182 }
183 }
184
185 impl From<&LookupSelectors<PolyComm<$G>>> for NapiLookupSelectors {
186 fn from(x: &LookupSelectors<PolyComm<$G>>) -> Self {
187 Self {
188 xor: x.xor.clone().map(Into::into),
189 lookup: x.lookup.clone().map(Into::into),
190 range_check: x.range_check.clone().map(Into::into),
191 ffmul: x.ffmul.clone().map(Into::into),
192 }
193 }
194 }
195
196 impl From<LookupSelectors<PolyComm<$G>>> for NapiLookupSelectors {
197 fn from(x: LookupSelectors<PolyComm<$G>>) -> Self {
198 Self {
199 xor: x.xor.clone().map(Into::into),
200 lookup: x.lookup.clone().map(Into::into),
201 range_check: x.range_check.clone().map(Into::into),
202 ffmul: x.ffmul.clone().map(Into::into),
203 }
204 }
205 }
206
207 #[napi(object, js_name = [<Wasm $field_name:camel LookupVerifierIndex>])]
208 #[derive(Clone, Debug, Serialize, Deserialize, Default)]
209 pub struct [<Napi $field_name:camel LookupVerifierIndex>] {
210 #[napi(js_name = "joint_lookup_used")]
211 pub joint_lookup_used: bool,
212
213 #[napi(js_name = "lookup_table")]
214 pub lookup_table: NapiVector<$NapiPolyComm>,
215
216 #[napi(js_name = "lookup_selectors")]
217 pub lookup_selectors: NapiLookupSelectors,
218
219 #[napi(js_name = "table_ids")]
220 pub table_ids: Option<$NapiPolyComm>,
221
222 #[napi(js_name = "lookup_info")]
223 pub lookup_info: NapiLookupInfo,
224
225 #[napi(js_name = "runtime_tables_selector")]
226 pub runtime_tables_selector: Option<$NapiPolyComm>,
227 }
228 type NapiLookupVerifierIndex = [<Napi $field_name:camel LookupVerifierIndex>];
229
230 impl From<&LookupVerifierIndex<$G>> for NapiLookupVerifierIndex {
231 fn from(x: &LookupVerifierIndex<$G>) -> Self {
232 Self {
233 joint_lookup_used: x.joint_lookup_used.into(),
234 lookup_table: x.lookup_table.clone().iter().map(Into::into).collect(),
235 lookup_selectors: x.lookup_selectors.clone().into(),
236 table_ids: x.table_ids.clone().map(Into::into),
237 lookup_info: x.lookup_info.into(),
238 runtime_tables_selector: x.runtime_tables_selector.clone().map(Into::into)
239 }
240 }
241 }
242
243 impl From<LookupVerifierIndex<$G>> for NapiLookupVerifierIndex {
244 fn from(x: LookupVerifierIndex<$G>) -> Self {
245 Self {
246 joint_lookup_used: x.joint_lookup_used.into(),
247 lookup_table: x.lookup_table.iter().map(Into::into).collect(),
248 lookup_selectors: x.lookup_selectors.into(),
249 table_ids: x.table_ids.map(Into::into),
250 lookup_info: x.lookup_info.into(),
251 runtime_tables_selector: x.runtime_tables_selector.map(Into::into)
252 }
253 }
254 }
255
256 impl From<&NapiLookupVerifierIndex> for LookupVerifierIndex<$G> {
257 fn from(x: &NapiLookupVerifierIndex) -> Self {
258 Self {
259 joint_lookup_used: x.joint_lookup_used.into(),
260 lookup_table: x.lookup_table.clone().iter().map(Into::into).collect(),
261 lookup_selectors: x.lookup_selectors.clone().into(),
262 table_ids: x.table_ids.clone().map(Into::into),
263 lookup_info: x.lookup_info.clone().into(),
264 runtime_tables_selector: x.runtime_tables_selector.clone().map(Into::into)
265 }
266 }
267 }
268
269 impl From<NapiLookupVerifierIndex> for LookupVerifierIndex<$G> {
270 fn from(x: NapiLookupVerifierIndex) -> Self {
271 Self {
272 joint_lookup_used: x.joint_lookup_used.into(),
273 lookup_table: x.lookup_table.iter().map(Into::into).collect(),
274 lookup_selectors: x.lookup_selectors.into(),
275 table_ids: x.table_ids.map(Into::into),
276 lookup_info: x.lookup_info.into(),
277 runtime_tables_selector: x.runtime_tables_selector.map(Into::into)
278 }
279 }
280 }
281
282 #[napi(object, js_name = [<Wasm $field_name:camel PlonkVerifierIndex>])]
283 #[derive(Clone, Debug, Default)]
284 pub struct [<Napi $field_name:camel PlonkVerifierIndex>] {
285 pub domain: NapiDomain,
286 #[napi(js_name = "max_poly_size")]
287 pub max_poly_size: i32,
288 #[napi(js_name = "public_")]
289 pub public_: i32,
290 #[napi(js_name = "prev_challenges")]
291 pub prev_challenges: i32,
292 pub srs: $NapiSrs,
293 pub evals: NapiPlonkVerificationEvals,
294 pub shifts: NapiShifts,
295 #[napi(js_name = "lookup_index")]
296 pub lookup_index: Option<NapiLookupVerifierIndex>,
297 #[napi(js_name = "zk_rows")]
298 pub zk_rows: i32,
299 }
300 type NapiPlonkVerifierIndex = [<Napi $field_name:camel PlonkVerifierIndex>];
301
302 fn compute_feature_flags(index: &NapiPlonkVerifierIndex) -> FeatureFlags {
303 let xor = index.evals.xor_comm.is_some();
304 let range_check0 = index.evals.range_check0_comm.is_some();
305 let range_check1 = index.evals.range_check1_comm.is_some();
306 let foreign_field_add = index.evals.foreign_field_add_comm.is_some();
307 let foreign_field_mul = index.evals.foreign_field_mul_comm.is_some();
308 let rot = index.evals.rot_comm.is_some();
309
310 let lookup = index
311 .lookup_index.as_ref()
312 .map_or(false, |li| li.lookup_info.features.patterns.lookup);
313
314 let runtime_tables = index
315 .lookup_index.as_ref()
316 .map_or(false, |li| li.runtime_tables_selector.is_some());
317
318 let patterns = LookupPatterns {
319 xor,
320 lookup,
321 range_check: range_check0 || range_check1 || rot,
322 foreign_field_mul,
323 };
324
325 FeatureFlags {
326 range_check0,
327 range_check1,
328 foreign_field_add,
329 foreign_field_mul,
330 xor,
331 rot,
332 lookup_features: LookupFeatures {
333 patterns,
334 joint_lookup_used: patterns.joint_lookups_used(),
335 uses_runtime_tables: runtime_tables,
336 },
337 }
338 }
339
340 impl From<NapiPlonkVerifierIndex> for VerifierIndex<FULL_ROUNDS, $G, SRS<$G>> {
341 fn from(index: NapiPlonkVerifierIndex) -> Self {
342 let max_poly_size = index.max_poly_size;
343 let public_ = index.public_;
344 let prev_challenges = index.prev_challenges;
345 let log_size_of_group = index.domain.log_size_of_group;
346 let srs = &index.srs;
347 let evals = &index.evals;
348 let shifts = &index.shifts;
349
350 let (endo_q, _endo_r) = poly_commitment::ipa::endos::<GAffineOther>();
351 let domain = Domain::<$F>::new(1 << log_size_of_group).unwrap();
352
353 let feature_flags = compute_feature_flags(&index);
354 let (linearization, powers_of_alpha) = expr_linearization(Some(&feature_flags), true);
355
356 let index = {
357 let zk_rows = index.zk_rows as u64;
358
359 VerifierIndex {
360 domain,
361
362 sigma_comm: core::array::from_fn(|i| (&evals.sigma_comm[i]).into()),
363 generic_comm: (&evals.generic_comm).into(),
364 coefficients_comm: core::array::from_fn(|i| (&evals.coefficients_comm[i]).into()),
365
366 psm_comm: (&evals.psm_comm).into(),
367
368 complete_add_comm: (&evals.complete_add_comm).into(),
369 mul_comm: (&evals.mul_comm).into(),
370 emul_comm: (&evals.emul_comm).into(),
371
372 endomul_scalar_comm: (&evals.endomul_scalar_comm).into(),
373 xor_comm: (&evals.xor_comm).as_ref().map(Into::into),
374 range_check0_comm: (&evals.range_check0_comm).as_ref().map(Into::into),
375 range_check1_comm: (&evals.range_check1_comm).as_ref().map(Into::into),
376 foreign_field_add_comm: (&evals.foreign_field_add_comm).as_ref().map(Into::into),
377 foreign_field_mul_comm: (&evals.foreign_field_mul_comm).as_ref().map(Into::into),
378 rot_comm: (&evals.rot_comm).as_ref().map(Into::into),
379
380 w: {
381 let res = std::sync::OnceLock::new();
382 res.set(zk_w(domain, zk_rows)).unwrap();
383 res
384 },
385 endo: endo_q,
386 max_poly_size: max_poly_size as usize,
387 public: public_ as usize,
388 prev_challenges: prev_challenges as usize,
389 permutation_vanishing_polynomial_m: {
390 let res = std::sync::OnceLock::new();
391 res.set(permutation_vanishing_polynomial(domain, zk_rows))
392 .unwrap();
393 res
394 },
395 shift: [
396 shifts.s0.into(),
397 shifts.s1.into(),
398 shifts.s2.into(),
399 shifts.s3.into(),
400 shifts.s4.into(),
401 shifts.s5.into(),
402 shifts.s6.into(),
403 ],
404 srs: { Arc::clone(&srs.0) },
405
406 zk_rows,
407
408 linearization,
409 powers_of_alpha,
410 lookup_index: index.lookup_index.map(Into::into),
411 }
412 };
413 (index, srs.0.clone()).0
414 }
415 }
416
417 impl From<(&VerifierIndex<FULL_ROUNDS, $G, SRS<$G>>, &$NapiSrs)> for NapiPlonkVerifierIndex {
418 fn from((index, srs): (&VerifierIndex<FULL_ROUNDS, $G, SRS<$G>>, &$NapiSrs)) -> Self {
421 Self {
422 domain: (&index.domain).into(),
423 max_poly_size: index.max_poly_size as i32,
424 public_: index.public as i32,
425 prev_challenges: index.prev_challenges as i32,
426 srs: srs.clone(),
427 evals: index.into(),
428 shifts: (&index.shift).into(),
429 lookup_index: index.lookup_index.as_ref().map(Into::into),
430 zk_rows: index.zk_rows as i32,
431 }
432 }
433 }
434
435 pub fn read_raw(
436 offset: Option<i32>,
437 srs: &$NapiSrs,
438 path: String,
439 ) -> napi::Result<VerifierIndex<FULL_ROUNDS, $G, SRS<$G>>> {
440 let path = Path::new(&path);
441 let (endo_q, _endo_r) = poly_commitment::ipa::endos::<$GOther>();
442 VerifierIndex::<FULL_ROUNDS, $G, SRS<$G>>::from_file(
443 srs.0.clone(),
444 path,
445 offset.map(|x| x as u64),
446 endo_q,
447 ).map_err(|e| Error::new(Status::GenericFailure, format!("read_raw: {}", e)))
448 }
449
450 #[napi(js_name = [<caml_pasta_ $field_name:snake _plonk_verifier_index_read>])]
451 pub fn [<caml_pasta_ $field_name:snake _plonk_verifier_index_read>](
452 offset: Option<i32>,
453 srs: &$NapiSrs,
454 path: String,
455 ) -> napi::Result<NapiPlonkVerifierIndex> {
456 let vi = read_raw(offset, srs, path)?;
457 Ok(NapiPlonkVerifierIndex::from((&vi, srs)))
458 }
459
460 #[napi(js_name = [<caml_pasta_ $field_name:snake _plonk_verifier_index_write>])]
461 pub fn [<caml_pasta_ $field_name:snake _plonk_verifier_index_write>](
462 append: Option<bool>,
463 index: NapiPlonkVerifierIndex,
464 path: String,
465 ) -> napi::Result<()> {
466 let index: VerifierIndex<FULL_ROUNDS, $G, SRS<$G>> = index.into();
467 let path = Path::new(&path);
468 index
469 .to_file(path, append)
470 .map_err(|e| Error::new(Status::GenericFailure, format!("plonk_verifier_index_write: {}", e)))
471 }
472
473 #[napi(js_name = [<caml_pasta_ $field_name:snake _plonk_verifier_index_serialize>])]
474 pub fn [<caml_pasta_ $field_name:snake _plonk_verifier_index_serialize>](
475 index: NapiPlonkVerifierIndex,
476 ) -> String {
477 let index: VerifierIndex<FULL_ROUNDS, $G, SRS<$G>> = index.into();
478 serde_json::to_string(&index).unwrap()
479 }
480
481 #[napi(js_name = [<caml_pasta_ $field_name:snake _plonk_verifier_index_deserialize>])]
482 pub fn [<caml_pasta_ $field_name:snake _plonk_verifier_index_deserialize>](
483 srs: &$NapiSrs,
484 index: String,
485 ) -> napi::Result<NapiPlonkVerifierIndex> {
486 match serde_json::from_str::<VerifierIndex<FULL_ROUNDS, $G, SRS<$G>>>(&index) {
487 Ok(vi) => Ok(NapiPlonkVerifierIndex::from((&vi, srs))),
488 Err(e) => Err(Error::new(Status::GenericFailure, e.to_string())),
489 }
490 }
491
492 #[napi(js_name = [<caml_pasta_ $field_name:snake _plonk_verifier_index_create>])]
493 pub fn [<caml_pasta_ $field_name:snake _plonk_verifier_index_create>](
494 index: &External<$NapiIndex>,
495 ) -> NapiPlonkVerifierIndex {
496 index.0.srs.get_lagrange_basis(index.0.as_ref().cs.domain.d1);
497 let verifier_index = index.0.as_ref().verifier_index();
498 let srs: $NapiSrs = (&index.0.srs).into();
499 NapiPlonkVerifierIndex::from((&verifier_index, &srs))
500 }
501
502 #[napi(js_name = [<caml_pasta_ $field_name:snake _plonk_verifier_index_shifts>])]
503 pub fn [<caml_pasta_ $field_name:snake _plonk_verifier_index_shifts>](log2_size: i32) -> napi::bindgen_prelude::Result<NapiShifts> {
504 let size = 1usize << (log2_size as u32);
505 let domain = Domain::<$F>::new(size)
506 .ok_or_else(|| Error::new(Status::InvalidArg, "failed to create evaluation domain"))?;
507
508 let shifts = Shifts::new(&domain);
509 let s = shifts.shifts();
510
511 Ok(NapiShifts {
512 s0: s[0].clone().into(),
513 s1: s[1].clone().into(),
514 s2: s[2].clone().into(),
515 s3: s[3].clone().into(),
516 s4: s[4].clone().into(),
517 s5: s[5].clone().into(),
518 s6: s[6].clone().into(),
519 })
520 }
521
522 #[napi(js_name = [<caml_pasta_ $field_name:snake _plonk_verifier_index_dummy>])]
523 pub fn [<caml_pasta_ $field_name:snake _plonk_verifier_index_dummy>]() -> NapiPlonkVerifierIndex {
524 fn comm() -> $NapiPolyComm {
525 let g: $NapiG = $G::generator().into();
526 $NapiPolyComm {
527 shifted: None,
528 unshifted: vec![g].into(),
529 }
530 }
531 fn vec_comm(num: usize) -> NapiVector<$NapiPolyComm> {
532 (0..num).map(|_| comm()).collect()
533 }
534
535 NapiPlonkVerifierIndex {
536 domain: NapiDomain {
537 log_size_of_group: 1,
538 group_gen: $F::one().into(),
539 },
540 max_poly_size: 0,
541 public_: 0,
542 prev_challenges: 0,
543 srs: $NapiSrs(Arc::new(SRS::create(0))),
544 evals: NapiPlonkVerificationEvals {
545 sigma_comm: vec_comm(PERMUTS),
546 coefficients_comm: vec_comm(COLUMNS),
547 generic_comm: comm(),
548 psm_comm: comm(),
549 complete_add_comm: comm(),
550 mul_comm: comm(),
551 emul_comm: comm(),
552 endomul_scalar_comm: comm(),
553 xor_comm: None,
554 range_check0_comm: None,
555 range_check1_comm: None,
556 foreign_field_add_comm: None,
557 foreign_field_mul_comm: None,
558 rot_comm: None,
559 },
560 shifts:
561 NapiShifts {
562 s0: $F::one().into(),
563 s1: $F::one().into(),
564 s2: $F::one().into(),
565 s3: $F::one().into(),
566 s4: $F::one().into(),
567 s5: $F::one().into(),
568 s6: $F::one().into(),
569 },
570 lookup_index: None,
571 zk_rows: 3,
572 }
573 }
574
575 #[napi(js_name = [<caml_pasta_ $field_name:snake _plonk_verifier_index_deep_copy>])]
576 pub fn [<caml_pasta_ $field_name:snake _plonk_verifier_index_deep_copy>](
577 x: NapiPlonkVerifierIndex,
578 ) -> NapiPlonkVerifierIndex {
579 x.clone()
580 }
581
582 }
583 }
584}
585
586pub mod fp {
587 use super::*;
588 use crate::{
589 pasta_fp_plonk_index::WasmPastaFpPlonkIndex as NapiPastaFpPlonkIndex,
590 poly_comm::vesta::NapiFpPolyComm as NapiPolyComm,
591 srs::fp::NapiFpSrs,
592 wrappers::{field::NapiPastaFp, group::NapiGVesta},
593 };
594 use mina_curves::pasta::{Fp, Pallas as GAffineOther, Vesta as GAffine};
595
596 impl_verification_key!(
597 NapiGVesta,
598 GAffine,
599 NapiPastaFp,
600 Fp,
601 NapiPolyComm,
602 NapiFpSrs,
603 GAffineOther,
604 mina_poseidon::pasta::fp_kimchi,
605 mina_poseidon::pasta::fq_kimchi,
606 NapiPastaFpPlonkIndex,
607 fp
608 );
609}
610
611pub mod fq {
612 use super::*;
613 use crate::{
614 pasta_fq_plonk_index::WasmPastaFqPlonkIndex as NapiPastaFqPlonkIndex,
615 poly_comm::pallas::NapiFqPolyComm as NapiPolyComm,
616 srs::fq::NapiFqSrs,
617 wrappers::{field::NapiPastaFq, group::NapiGPallas},
618 };
619 use mina_curves::pasta::{Fq, Pallas as GAffine, Vesta as GAffineOther};
620
621 impl_verification_key!(
622 NapiGPallas,
623 GAffine,
624 NapiPastaFq,
625 Fq,
626 NapiPolyComm,
627 NapiFqSrs,
628 GAffineOther,
629 mina_poseidon::pasta::fq_kimchi,
630 mina_poseidon::pasta::fp_kimchi,
631 NapiPastaFqPlonkIndex,
632 fq
633 );
634}