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