plonk_wasm/
plonk_proof.rs

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>, // vector of rounds of L commitments
325                #[wasm_bindgen(skip)]
326                pub lr_1: WasmVector<$WasmG>, // vector of rounds of R commitments
327                #[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                // OCaml doesn't have sized arrays, so we have to convert to a tuple..
444                #[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                    // Deprecated used on purpose: updating this leads to a bug in o1js
623                    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                    // Release the runtime lock so that other threads can run using it while we generate the proof.
697                    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}