1use crate::{
2 wasm_flat_vector::WasmFlatVector,
3 wasm_vector::{fp::WasmVecVecFp, fq::WasmVecVecFq, WasmVector},
4};
5use ark_ec::AffineRepr;
6use ark_ff::One;
7use core::{array, convert::TryInto};
8use groupmap::GroupMap;
9use kimchi::{
10 circuits::{lookup::runtime_tables::RuntimeTable, wires::COLUMNS},
11 proof::{
12 LookupCommitments, PointEvaluations, ProofEvaluations, ProverCommitments, ProverProof,
13 RecursionChallenge,
14 },
15 prover_index::ProverIndex,
16 verifier::{batch_verify, Context},
17};
18use mina_poseidon::{
19 constants::PlonkSpongeConstantsKimchi,
20 sponge::{DefaultFqSponge, DefaultFrSponge},
21};
22use paste::paste;
23use poly_commitment::{
24 commitment::{CommitmentCurve, PolyComm},
25 ipa::OpeningProof,
26 SRS as _,
27};
28use serde::{Deserialize, Serialize};
29use wasm_bindgen::prelude::*;
30
31#[wasm_bindgen]
32extern "C" {
33 #[wasm_bindgen(js_namespace = console)]
34 fn log(s: &str);
35}
36
37macro_rules! impl_proof {
38 (
39 $name: ident,
40 $WasmG: ty,
41 $G: ty,
42 $WasmF: ty,
43 $F: ty,
44 $WasmPolyComm: ty,
45 $WasmSrs: ty,
46 $GOther: ty,
47 $FrSpongeParams: path,
48 $FqSpongeParams: path,
49 $WasmIndex: ty,
50 $WasmVerifierIndex: ty,
51 $field_name: ident
52 ) => {
53 paste! {
54 type WasmVecVecF = [<WasmVecVec $field_name:camel>];
55
56 #[derive(Clone)]
57 pub struct [<Wasm $field_name:camel ProofEvaluations>](
58 ProofEvaluations<PointEvaluations<Vec<$F>>>
59 );
60 type WasmProofEvaluations = [<Wasm $field_name:camel ProofEvaluations>];
61
62 impl wasm_bindgen::describe::WasmDescribe for WasmProofEvaluations {
63 fn describe() {
64 <JsValue as wasm_bindgen::describe::WasmDescribe>::describe()
65 }
66 }
67
68 impl wasm_bindgen::convert::FromWasmAbi for WasmProofEvaluations {
69 type Abi = <JsValue as wasm_bindgen::convert::FromWasmAbi>::Abi;
70 unsafe fn from_abi(js: Self::Abi) -> Self {
71 let js: JsValue = wasm_bindgen::convert::FromWasmAbi::from_abi(js);
72 Self(
73 ProofEvaluations::deserialize(
74 crate::wasm_ocaml_serde::de::Deserializer::from(js),
75 )
76 .unwrap(),
77 )
78 }
79 }
80
81 impl wasm_bindgen::convert::IntoWasmAbi for WasmProofEvaluations {
82 type Abi = <JsValue as wasm_bindgen::convert::IntoWasmAbi>::Abi;
83 fn into_abi(self) -> Self::Abi {
84 let js = self
85 .0
86 .serialize(&crate::wasm_ocaml_serde::ser::Serializer::new())
87 .unwrap();
88 wasm_bindgen::convert::IntoWasmAbi::into_abi(js)
89 }
90 }
91
92 impl From<&WasmProofEvaluations> for ProofEvaluations<PointEvaluations<Vec<$F>>> {
93 fn from(x: &WasmProofEvaluations) -> Self {
94 x.0.clone()
95 }
96 }
97
98 impl From<WasmProofEvaluations> for ProofEvaluations<PointEvaluations<Vec<$F>>> {
99 fn from(x: WasmProofEvaluations) -> Self {
100 x.0
101 }
102 }
103
104 impl From<&ProofEvaluations<PointEvaluations<Vec<$F>>>> for WasmProofEvaluations {
105 fn from(x: &ProofEvaluations<PointEvaluations<Vec<$F>>>) -> Self {
106 Self(x.clone())
107 }
108 }
109
110 impl From<ProofEvaluations<PointEvaluations<Vec<$F>>>> for WasmProofEvaluations {
111 fn from(x: ProofEvaluations<PointEvaluations<Vec<$F>>>) -> Self {
112 Self(x)
113 }
114 }
115
116 #[wasm_bindgen]
117 #[derive(Clone)]
118 pub struct [<Wasm $field_name:camel LookupCommitments>]
119 {
120 #[wasm_bindgen(skip)]
121 pub sorted: WasmVector<$WasmPolyComm>,
122 #[wasm_bindgen(skip)]
123 pub aggreg: $WasmPolyComm,
124 #[wasm_bindgen(skip)]
125 pub runtime: Option<$WasmPolyComm>,
126 }
127
128 type WasmLookupCommitments = [<Wasm $field_name:camel LookupCommitments>];
129
130 #[wasm_bindgen]
131 impl [<Wasm $field_name:camel LookupCommitments>] {
132 #[wasm_bindgen(constructor)]
133 pub fn new(
134 sorted: WasmVector<$WasmPolyComm>,
135 aggreg: $WasmPolyComm,
136 runtime: Option<$WasmPolyComm>) -> Self {
137 WasmLookupCommitments { sorted, aggreg, runtime }
138 }
139
140 #[wasm_bindgen(getter)]
141 pub fn sorted(&self) -> WasmVector<$WasmPolyComm> {
142 self.sorted.clone()
143 }
144
145 #[wasm_bindgen(getter)]
146 pub fn aggreg(&self) -> $WasmPolyComm {
147 self.aggreg.clone()
148 }
149
150 #[wasm_bindgen(getter)]
151 pub fn runtime(&self) -> Option<$WasmPolyComm> {
152 self.runtime.clone()
153 }
154
155 #[wasm_bindgen(setter)]
156 pub fn set_sorted(&mut self, s: WasmVector<$WasmPolyComm>) {
157 self.sorted = s
158 }
159
160 #[wasm_bindgen(setter)]
161 pub fn set_aggreg(&mut self, a: $WasmPolyComm) {
162 self.aggreg = a
163 }
164
165 #[wasm_bindgen(setter)]
166 pub fn set_runtime(&mut self, r: Option<$WasmPolyComm>) {
167 self.runtime = r
168 }
169 }
170
171
172 impl From<&LookupCommitments<$G>> for WasmLookupCommitments {
173 fn from(x: &LookupCommitments<$G>) -> Self {
174 WasmLookupCommitments {
175 sorted: x.sorted.iter().map(Into::into).collect(),
176 aggreg: x.aggreg.clone().into(),
177 runtime: x.runtime.clone().map(Into::into)
178 }
179 }
180 }
181
182 impl From<LookupCommitments<$G>> for WasmLookupCommitments {
183 fn from(x: LookupCommitments<$G>) -> Self {
184 WasmLookupCommitments {
185 sorted: x.sorted.into_iter().map(Into::into).collect(),
186 aggreg: x.aggreg.into(),
187 runtime: x.runtime.map(Into::into)
188 }
189 }
190 }
191
192 impl From<&WasmLookupCommitments> for LookupCommitments<$G> {
193 fn from(x: &WasmLookupCommitments) -> Self {
194 LookupCommitments {
195 sorted: x.sorted.iter().map(Into::into).collect(),
196 aggreg: x.aggreg.clone().into(),
197 runtime: x.runtime.clone().map(Into::into)
198 }
199 }
200 }
201
202 impl From<WasmLookupCommitments> for LookupCommitments<$G> {
203 fn from(x: WasmLookupCommitments) -> Self {
204 LookupCommitments {
205 sorted: x.sorted.into_iter().map(Into::into).collect(),
206 aggreg: x.aggreg.into(),
207 runtime: x.runtime.map(Into::into)
208 }
209 }
210 }
211
212 #[wasm_bindgen]
213 #[derive(Clone)]
214 pub struct [<Wasm $field_name:camel ProverCommitments>]
215 {
216 #[wasm_bindgen(skip)]
217 pub w_comm: WasmVector<$WasmPolyComm>,
218 #[wasm_bindgen(skip)]
219 pub z_comm: $WasmPolyComm,
220 #[wasm_bindgen(skip)]
221 pub t_comm: $WasmPolyComm,
222 #[wasm_bindgen(skip)]
223 pub lookup: Option<WasmLookupCommitments>,
224 }
225 type WasmProverCommitments = [<Wasm $field_name:camel ProverCommitments>];
226
227 #[wasm_bindgen]
228 impl [<Wasm $field_name:camel ProverCommitments>] {
229 #[wasm_bindgen(constructor)]
230 pub fn new(
231 w_comm: WasmVector<$WasmPolyComm>,
232 z_comm: $WasmPolyComm,
233 t_comm: $WasmPolyComm,
234 lookup: Option<WasmLookupCommitments>
235 ) -> Self {
236 WasmProverCommitments { w_comm, z_comm, t_comm, lookup }
237 }
238
239 #[wasm_bindgen(getter)]
240 pub fn w_comm(&self) -> WasmVector<$WasmPolyComm> {
241 self.w_comm.clone()
242 }
243 #[wasm_bindgen(getter)]
244 pub fn z_comm(&self) -> $WasmPolyComm {
245 self.z_comm.clone()
246 }
247 #[wasm_bindgen(getter)]
248 pub fn t_comm(&self) -> $WasmPolyComm {
249 self.t_comm.clone()
250 }
251
252 #[wasm_bindgen(getter)]
253 pub fn lookup(&self) -> Option<WasmLookupCommitments> {
254 self.lookup.clone()
255 }
256
257 #[wasm_bindgen(setter)]
258 pub fn set_w_comm(&mut self, x: WasmVector<$WasmPolyComm>) {
259 self.w_comm = x
260 }
261 #[wasm_bindgen(setter)]
262 pub fn set_z_comm(&mut self, x: $WasmPolyComm) {
263 self.z_comm = x
264 }
265 #[wasm_bindgen(setter)]
266 pub fn set_t_comm(&mut self, x: $WasmPolyComm) {
267 self.t_comm = x
268 }
269
270 #[wasm_bindgen(setter)]
271 pub fn set_lookup(&mut self, l: Option<WasmLookupCommitments>) {
272 self.lookup = l
273 }
274 }
275
276 impl From<&ProverCommitments<$G>> for WasmProverCommitments {
277 fn from(x: &ProverCommitments<$G>) -> Self {
278 WasmProverCommitments {
279 w_comm: x.w_comm.iter().map(Into::into).collect(),
280 z_comm: x.z_comm.clone().into(),
281 t_comm: x.t_comm.clone().into(),
282 lookup: x.lookup.clone().map(Into::into)
283 }
284 }
285 }
286
287 impl From<ProverCommitments<$G>> for WasmProverCommitments {
288 fn from(x: ProverCommitments<$G>) -> Self {
289 WasmProverCommitments {
290 w_comm: x.w_comm.iter().map(Into::into).collect(),
291 z_comm: x.z_comm.into(),
292 t_comm: x.t_comm.into(),
293 lookup: x.lookup.map(Into::into),
294 }
295 }
296 }
297
298 impl From<&WasmProverCommitments> for ProverCommitments<$G> {
299 fn from(x: &WasmProverCommitments) -> Self {
300 ProverCommitments {
301 w_comm: core::array::from_fn(|i| x.w_comm[i].clone().into()),
302 z_comm: x.z_comm.clone().into(),
303 t_comm: x.t_comm.clone().into(),
304 lookup: x.lookup.clone().map(Into::into),
305 }
306 }
307 }
308
309 impl From<WasmProverCommitments> for ProverCommitments<$G> {
310 fn from(x: WasmProverCommitments) -> Self {
311 ProverCommitments {
312 w_comm: core::array::from_fn(|i| (&x.w_comm[i]).into()),
313 z_comm: x.z_comm.into(),
314 t_comm: x.t_comm.into(),
315 lookup: x.lookup.map(Into::into),
316 }
317 }
318 }
319
320 #[wasm_bindgen]
321 #[derive(Clone, Debug)]
322 pub struct [<Wasm $field_name:camel OpeningProof>] {
323 #[wasm_bindgen(skip)]
324 pub lr_0: WasmVector<$WasmG>, #[wasm_bindgen(skip)]
326 pub lr_1: WasmVector<$WasmG>, #[wasm_bindgen(skip)]
328 pub delta: $WasmG,
329 pub z1: $WasmF,
330 pub z2: $WasmF,
331 #[wasm_bindgen(skip)]
332 pub sg: $WasmG,
333 }
334 type WasmOpeningProof = [<Wasm $field_name:camel OpeningProof>];
335
336 #[wasm_bindgen]
337 impl [<Wasm $field_name:camel OpeningProof>] {
338 #[wasm_bindgen(constructor)]
339 pub fn new(
340 lr_0: WasmVector<$WasmG>,
341 lr_1: WasmVector<$WasmG>,
342 delta: $WasmG,
343 z1: $WasmF,
344 z2: $WasmF,
345 sg: $WasmG) -> Self {
346 WasmOpeningProof { lr_0, lr_1, delta, z1, z2, sg }
347 }
348
349 #[wasm_bindgen(getter)]
350 pub fn lr_0(&self) -> WasmVector<$WasmG> {
351 self.lr_0.clone()
352 }
353 #[wasm_bindgen(getter)]
354 pub fn lr_1(&self) -> WasmVector<$WasmG> {
355 self.lr_1.clone()
356 }
357 #[wasm_bindgen(getter)]
358 pub fn delta(&self) -> $WasmG {
359 self.delta.clone()
360 }
361 #[wasm_bindgen(getter)]
362 pub fn sg(&self) -> $WasmG {
363 self.sg.clone()
364 }
365
366 #[wasm_bindgen(setter)]
367 pub fn set_lr_0(&mut self, lr_0: WasmVector<$WasmG>) {
368 self.lr_0 = lr_0
369 }
370 #[wasm_bindgen(setter)]
371 pub fn set_lr_1(&mut self, lr_1: WasmVector<$WasmG>) {
372 self.lr_1 = lr_1
373 }
374 #[wasm_bindgen(setter)]
375 pub fn set_delta(&mut self, delta: $WasmG) {
376 self.delta = delta
377 }
378 #[wasm_bindgen(setter)]
379 pub fn set_sg(&mut self, sg: $WasmG) {
380 self.sg = sg
381 }
382 }
383
384 impl From<&WasmOpeningProof> for OpeningProof<$G> {
385 fn from(x: &WasmOpeningProof) -> Self {
386 OpeningProof {
387 lr: x.lr_0.clone().into_iter().zip(x.lr_1.clone().into_iter()).map(|(x, y)| (x.into(), y.into())).collect(),
388 delta: x.delta.clone().into(),
389 z1: x.z1.into(),
390 z2: x.z2.into(),
391 sg: x.sg.clone().into(),
392 }
393 }
394 }
395
396 impl From<WasmOpeningProof> for OpeningProof<$G> {
397 fn from(x: WasmOpeningProof) -> Self {
398 let WasmOpeningProof {lr_0, lr_1, delta, z1, z2, sg} = x;
399 OpeningProof {
400 lr: lr_0.into_iter().zip(lr_1.into_iter()).map(|(x, y)| (x.into(), y.into())).collect(),
401 delta: delta.into(),
402 z1: z1.into(),
403 z2: z2.into(),
404 sg: sg.into(),
405 }
406 }
407 }
408
409 impl From<&OpeningProof<$G>> for WasmOpeningProof {
410 fn from(x: &OpeningProof<$G>) -> Self {
411 let (lr_0, lr_1) = x.lr.clone().into_iter().map(|(x, y)| (x.into(), y.into())).unzip();
412 WasmOpeningProof {
413 lr_0,
414 lr_1,
415 delta: x.delta.clone().into(),
416 z1: x.z1.into(),
417 z2: x.z2.into(),
418 sg: x.sg.clone().into(),
419 }
420 }
421 }
422
423 impl From<OpeningProof<$G>> for WasmOpeningProof {
424 fn from(x: OpeningProof<$G>) -> Self {
425 let (lr_0, lr_1) = x.lr.clone().into_iter().map(|(x, y)| (x.into(), y.into())).unzip();
426 WasmOpeningProof {
427 lr_0,
428 lr_1,
429 delta: x.delta.clone().into(),
430 z1: x.z1.into(),
431 z2: x.z2.into(),
432 sg: x.sg.clone().into(),
433 }
434 }
435 }
436
437 #[wasm_bindgen]
438 pub struct [<Wasm $field_name:camel ProverProof>] {
439 #[wasm_bindgen(skip)]
440 pub commitments: WasmProverCommitments,
441 #[wasm_bindgen(skip)]
442 pub proof: WasmOpeningProof,
443 #[wasm_bindgen(skip)]
445 pub evals: WasmProofEvaluations,
446 pub ft_eval1: $WasmF,
447 #[wasm_bindgen(skip)]
448 pub public: WasmFlatVector<$WasmF>,
449 #[wasm_bindgen(skip)]
450 pub prev_challenges_scalars: Vec<Vec<$F>>,
451 #[wasm_bindgen(skip)]
452 pub prev_challenges_comms: WasmVector<$WasmPolyComm>,
453 }
454 type WasmProverProof = [<Wasm $field_name:camel ProverProof>];
455
456 impl From<(&ProverProof<$G, OpeningProof<$G>>, &Vec<$F>)> for WasmProverProof {
457 fn from((x, public): (&ProverProof<$G, OpeningProof<$G>>, &Vec<$F>)) -> Self {
458 let (scalars, comms) =
459 x.prev_challenges
460 .iter()
461 .map(|RecursionChallenge { chals, comm }| {
462 (chals.clone().into(), comm.into())
463 })
464 .unzip();
465 WasmProverProof {
466 commitments: x.commitments.clone().into(),
467 proof: x.proof.clone().into(),
468 evals: x.evals.clone().into(),
469 ft_eval1: x.ft_eval1.clone().into(),
470 public: public.clone().into_iter().map(Into::into).collect(),
471 prev_challenges_scalars: scalars,
472 prev_challenges_comms: comms,
473 }
474 }
475 }
476
477 impl From<(ProverProof<$G, OpeningProof<$G>>, Vec<$F>)> for WasmProverProof {
478 fn from((x, public): (ProverProof<$G, OpeningProof<$G>>, Vec<$F>)) -> Self {
479 let ProverProof {ft_eval1, commitments, proof, evals , prev_challenges} = x;
480 let (scalars, comms) =
481 prev_challenges
482 .into_iter()
483 .map(|RecursionChallenge { chals, comm }| (chals.into(), comm.into()))
484 .unzip();
485 WasmProverProof {
486 commitments: commitments.into(),
487 proof: proof.into(),
488 evals: evals.into(),
489 ft_eval1: ft_eval1.clone().into(),
490 public: public.into_iter().map(Into::into).collect(),
491 prev_challenges_scalars: scalars,
492 prev_challenges_comms: comms,
493 }
494 }
495 }
496
497 impl From<&WasmProverProof> for (ProverProof<$G, OpeningProof<$G>>, Vec<$F>) {
498 fn from(x: &WasmProverProof) -> Self {
499 let proof = ProverProof {
500 commitments: x.commitments.clone().into(),
501 proof: x.proof.clone().into(),
502 evals: x.evals.clone().into(),
503 prev_challenges:
504 (&x.prev_challenges_scalars)
505 .into_iter()
506 .zip((&x.prev_challenges_comms).into_iter())
507 .map(|(chals, comm)| {
508 RecursionChallenge {
509 chals: chals.clone(),
510 comm: comm.into(),
511 }
512 })
513 .collect(),
514 ft_eval1: x.ft_eval1.clone().into()
515 };
516 let public = x.public.clone().into_iter().map(Into::into).collect();
517 (proof, public)
518 }
519 }
520
521 impl From<WasmProverProof> for (ProverProof<$G, OpeningProof<$G>>, Vec<$F>) {
522 fn from(x: WasmProverProof) -> Self {
523 let proof =ProverProof {
524 commitments: x.commitments.into(),
525 proof: x.proof.into(),
526 evals: x.evals.into(),
527 prev_challenges:
528 (x.prev_challenges_scalars)
529 .into_iter()
530 .zip((x.prev_challenges_comms).into_iter())
531 .map(|(chals, comm)| {
532 RecursionChallenge {
533 chals: chals.into(),
534 comm: comm.into(),
535 }
536 })
537 .collect(),
538 ft_eval1: x.ft_eval1.into()
539 };
540 let public = x.public.into_iter().map(Into::into).collect();
541 (proof, public)
542 }
543 }
544
545 #[wasm_bindgen]
546 impl [<Wasm $field_name:camel ProverProof>] {
547 #[wasm_bindgen(constructor)]
548 pub fn new(
549 commitments: WasmProverCommitments,
550 proof: WasmOpeningProof,
551 evals: WasmProofEvaluations,
552 ft_eval1: $WasmF,
553 public_: WasmFlatVector<$WasmF>,
554 prev_challenges_scalars: WasmVecVecF,
555 prev_challenges_comms: WasmVector<$WasmPolyComm>) -> Self {
556 WasmProverProof {
557 commitments,
558 proof,
559 evals,
560 ft_eval1,
561 public: public_,
562 prev_challenges_scalars: prev_challenges_scalars.0,
563 prev_challenges_comms,
564 }
565 }
566
567 #[wasm_bindgen(getter)]
568 pub fn commitments(&self) -> WasmProverCommitments {
569 self.commitments.clone()
570 }
571 #[wasm_bindgen(getter)]
572 pub fn proof(&self) -> WasmOpeningProof {
573 self.proof.clone()
574 }
575 #[wasm_bindgen(getter)]
576 pub fn evals(&self) -> WasmProofEvaluations {
577 self.evals.clone()
578 }
579 #[wasm_bindgen(getter)]
580 pub fn public_(&self) -> WasmFlatVector<$WasmF> {
581 self.public.clone()
582 }
583 #[wasm_bindgen(getter)]
584 pub fn prev_challenges_scalars(&self) -> WasmVecVecF {
585 [<WasmVecVec $field_name:camel>](self.prev_challenges_scalars.clone())
586 }
587 #[wasm_bindgen(getter)]
588 pub fn prev_challenges_comms(&self) -> WasmVector<$WasmPolyComm> {
589 self.prev_challenges_comms.clone()
590 }
591
592 #[wasm_bindgen(setter)]
593 pub fn set_commitments(&mut self, commitments: WasmProverCommitments) {
594 self.commitments = commitments
595 }
596 #[wasm_bindgen(setter)]
597 pub fn set_proof(&mut self, proof: WasmOpeningProof) {
598 self.proof = proof
599 }
600 #[wasm_bindgen(setter)]
601 pub fn set_evals(&mut self, evals: WasmProofEvaluations) {
602 self.evals = evals
603 }
604 #[wasm_bindgen(setter)]
605 pub fn set_public_(&mut self, public_: WasmFlatVector<$WasmF>) {
606 self.public = public_
607 }
608 #[wasm_bindgen(setter)]
609 pub fn set_prev_challenges_scalars(&mut self, prev_challenges_scalars: WasmVecVecF) {
610 self.prev_challenges_scalars = prev_challenges_scalars.0
611 }
612 #[wasm_bindgen(setter)]
613 pub fn set_prev_challenges_comms(&mut self, prev_challenges_comms: WasmVector<$WasmPolyComm>) {
614 self.prev_challenges_comms = prev_challenges_comms
615 }
616
617 #[wasm_bindgen]
618 #[allow(deprecated)]
619 pub fn serialize(&self) -> String {
620 let (proof, _public_input) = self.into();
621 let serialized = rmp_serde::to_vec(&proof).unwrap();
622 base64::encode(serialized)
624 }
625 }
626
627 #[wasm_bindgen]
628 pub struct [<Wasm $field_name:camel RuntimeTable>] {
629 id: i32,
630 data: WasmFlatVector<$WasmF>
631 }
632 type WasmRuntimeTable = [<Wasm $field_name:camel RuntimeTable>];
633
634 #[wasm_bindgen]
635 impl [<Wasm $field_name:camel RuntimeTable>] {
636 #[wasm_bindgen(constructor)]
637 pub fn new(id: i32, data: WasmFlatVector<$WasmF>) -> WasmRuntimeTable {
638 WasmRuntimeTable {id, data}
639 }
640 }
641
642 impl From<[<Wasm $field_name:camel RuntimeTable>]> for RuntimeTable<$F> {
643 fn from(wasm_rt: WasmRuntimeTable) -> RuntimeTable<$F> {
644 RuntimeTable {
645 id: wasm_rt.id.into(),
646 data: wasm_rt.data.into_iter().map(Into::into).collect()
647 }
648 }
649 }
650
651 #[wasm_bindgen]
652 pub fn [<$name:snake _create>](
653 index: &$WasmIndex,
654 witness: WasmVecVecF,
655 wasm_runtime_tables: WasmVector<WasmRuntimeTable>,
656 prev_challenges: WasmFlatVector<$WasmF>,
657 prev_sgs: WasmVector<$WasmG>,
658 ) -> Result<WasmProverProof, JsError> {
659 console_error_panic_hook::set_once();
660 let (maybe_proof, public_input) = crate::rayon::run_in_pool(|| {
661 index.0.srs.get_lagrange_basis(index.0.as_ref().cs.domain.d1);
662 let prev: Vec<RecursionChallenge<$G>> = {
663 if prev_challenges.is_empty() {
664 Vec::new()
665 } else {
666 let challenges_per_sg = prev_challenges.len() / prev_sgs.len();
667 prev_sgs
668 .into_iter()
669 .map(Into::<$G>::into)
670 .enumerate()
671 .map(|(i, sg)| {
672 let chals =
673 prev_challenges[(i * challenges_per_sg)..(i + 1) * challenges_per_sg]
674 .iter()
675 .map(|a| a.clone().into())
676 .collect();
677 let comm = PolyComm::<$G> {
678 chunks: vec![sg],
679 };
680 RecursionChallenge { chals, comm }
681 })
682 .collect()
683 }
684 };
685
686 let rust_runtime_tables: Vec<RuntimeTable<$F>> = wasm_runtime_tables.into_iter().map(Into::into).collect();
687
688 let witness: [Vec<_>; COLUMNS] = witness.0
689 .try_into()
690 .expect("the witness should be a column of 15 vectors");
691
692 let index: &ProverIndex<$G, OpeningProof<$G>> = &index.0.as_ref();
693
694 let public_input = witness[0][0..index.cs.public].to_vec();
695
696 let group_map = GroupMap::<_>::setup();
698 let maybe_proof = ProverProof::create_recursive::<
699 DefaultFqSponge<_, PlonkSpongeConstantsKimchi>,
700 DefaultFrSponge<_, PlonkSpongeConstantsKimchi>,
701 _>(&group_map, witness, &rust_runtime_tables, index, prev, None,
702 &mut rand::rngs::OsRng
703 );
704 (maybe_proof, public_input)
705 });
706
707 return match maybe_proof {
708 Ok(proof) => Ok((proof, public_input).into()),
709 Err(err) => Err(JsError::from(err))
710 }
711 }
712
713 #[wasm_bindgen]
714 pub fn [<$name:snake _verify>](
715 index: $WasmVerifierIndex,
716 proof: WasmProverProof,
717 ) -> bool {
718 crate::rayon::run_in_pool(|| {
719 let group_map = <$G as CommitmentCurve>::Map::setup();
720 let verifier_index = &index.into();
721 let (proof, public_input) = &proof.into();
722 batch_verify::<
723 $G,
724 DefaultFqSponge<_, PlonkSpongeConstantsKimchi>,
725 DefaultFrSponge<_, PlonkSpongeConstantsKimchi>,
726 OpeningProof<$G>
727 >(
728 &group_map,
729 &[Context { verifier_index, proof, public_input }]
730 ).is_ok()
731 })
732 }
733
734 #[wasm_bindgen]
735 pub struct [<WasmVecVec $field_name:camel PolyComm>](Vec<Vec<PolyComm<$G>>>);
736
737 #[wasm_bindgen]
738 impl [<WasmVecVec $field_name:camel PolyComm>] {
739 #[wasm_bindgen(constructor)]
740 pub fn create(n: i32) -> Self {
741 [<WasmVecVec $field_name:camel PolyComm>](Vec::with_capacity(n as usize))
742 }
743
744 #[wasm_bindgen]
745 pub fn push(&mut self, x: WasmVector<$WasmPolyComm>) {
746 self.0.push(x.into_iter().map(Into::into).collect())
747 }
748 }
749
750 #[wasm_bindgen]
751 pub fn [<$name:snake _batch_verify>](
752 indexes: WasmVector<$WasmVerifierIndex>,
753 proofs: WasmVector<WasmProverProof>,
754 ) -> bool {
755 crate::rayon::run_in_pool(|| {
756 let ts: Vec<_> = indexes
757 .into_iter()
758 .zip(proofs.into_iter())
759 .map(|(index, proof)| (index.into(), proof.into()))
760 .collect();
761 let ts: Vec<_> = ts.iter().map(|(verifier_index, (proof, public_input))| Context { verifier_index, proof, public_input}).collect();
762 let group_map = GroupMap::<_>::setup();
763
764 batch_verify::<
765 $G,
766 DefaultFqSponge<_, PlonkSpongeConstantsKimchi>,
767 DefaultFrSponge<_, PlonkSpongeConstantsKimchi>,
768 OpeningProof<$G>
769 >(&group_map, &ts)
770 .is_ok()
771 })
772 }
773
774 #[wasm_bindgen]
775 pub fn [<$name:snake _dummy>]() -> WasmProverProof {
776 fn comm() -> PolyComm<$G> {
777 let g = $G::generator();
778 PolyComm {
779 chunks: vec![g, g, g],
780 }
781 }
782
783 let prev = RecursionChallenge {
784 chals: vec![$F::one(), $F::one()],
785 comm: comm(),
786 };
787 let prev_challenges = vec![prev.clone(), prev.clone(), prev.clone()];
788
789 let g = $G::generator();
790 let proof = OpeningProof {
791 lr: vec![(g, g), (g, g), (g, g)],
792 z1: $F::one(),
793 z2: $F::one(),
794 delta: g,
795 sg: g,
796 };
797 let eval = || PointEvaluations {
798 zeta: vec![$F::one()],
799 zeta_omega: vec![$F::one()],
800 };
801 let evals = ProofEvaluations {
802 w: core::array::from_fn(|_| eval()),
803 coefficients: core::array::from_fn(|_| eval()),
804 z: eval(),
805 s: core::array::from_fn(|_| eval()),
806 generic_selector: eval(),
807 poseidon_selector: eval(),
808 complete_add_selector: eval(),
809 mul_selector: eval(),
810 emul_selector: eval(),
811 endomul_scalar_selector: eval(),
812 range_check0_selector: None,
813 range_check1_selector: None,
814 foreign_field_add_selector: None,
815 foreign_field_mul_selector: None,
816 xor_selector: None,
817 rot_selector: None,
818 lookup_aggregation: None,
819 lookup_table: None,
820 lookup_sorted: array::from_fn(|_| None),
821 runtime_lookup_table: None,
822 runtime_lookup_table_selector: None,
823 xor_lookup_selector: None,
824 lookup_gate_lookup_selector: None,
825 range_check_lookup_selector: None,
826 foreign_field_mul_lookup_selector: None,
827 public: None,
828 };
829
830 let dlogproof = ProverProof {
831 commitments: ProverCommitments {
832 w_comm: core::array::from_fn(|_| comm()),
833 z_comm: comm(),
834 t_comm: comm(),
835 lookup: None,
836 },
837 proof,
838 evals,
839 ft_eval1: $F::one(),
840 prev_challenges,
841 };
842
843 let public = vec![$F::one(), $F::one()];
844 (dlogproof, public).into()
845 }
846
847 #[wasm_bindgen]
848 pub fn [<$name:snake _deep_copy>](
849 x: WasmProverProof
850 ) -> WasmProverProof {
851 x
852 }
853 }
854 }
855}
856
857pub mod fp {
858 use super::*;
859 use crate::{
860 arkworks::{WasmGVesta, WasmPastaFp},
861 pasta_fp_plonk_index::WasmPastaFpPlonkIndex,
862 plonk_verifier_index::fp::WasmFpPlonkVerifierIndex as WasmPlonkVerifierIndex,
863 poly_comm::vesta::WasmFpPolyComm as WasmPolyComm,
864 };
865 use mina_curves::pasta::{Fp, Vesta as GAffine};
866
867 impl_proof!(
868 caml_pasta_fp_plonk_proof,
869 WasmGVesta,
870 GAffine,
871 WasmPastaFp,
872 Fp,
873 WasmPolyComm,
874 WasmSrs,
875 GAffineOther,
876 mina_poseidon::pasta::fp_kimchi,
877 mina_poseidon::pasta::fq_kimchi,
878 WasmPastaFpPlonkIndex,
879 WasmPlonkVerifierIndex,
880 Fp
881 );
882}
883
884pub mod fq {
885 use super::*;
886 use crate::{
887 arkworks::{WasmGPallas, WasmPastaFq},
888 pasta_fq_plonk_index::WasmPastaFqPlonkIndex,
889 plonk_verifier_index::fq::WasmFqPlonkVerifierIndex as WasmPlonkVerifierIndex,
890 poly_comm::pallas::WasmFqPolyComm as WasmPolyComm,
891 };
892 use mina_curves::pasta::{Fq, Pallas as GAffine};
893
894 impl_proof!(
895 caml_pasta_fq_plonk_proof,
896 WasmGPallas,
897 GAffine,
898 WasmPastaFq,
899 Fq,
900 WasmPolyComm,
901 WasmSrs,
902 GAffineOther,
903 mina_poseidon::pasta::fq_kimchi,
904 mina_poseidon::pasta::fp_kimchi,
905 WasmPastaFqPlonkIndex,
906 WasmPlonkVerifierIndex,
907 Fq
908 );
909}