plonk_wasm/
plonk_proof.rs

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>, // vector of rounds of L commitments
323                #[wasm_bindgen(skip)]
324                pub lr_1: WasmVector<$WasmG>, // vector of rounds of R commitments
325                #[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                // OCaml doesn't have sized arrays, so we have to convert to a tuple..
442                #[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                    // Deprecated used on purpose: updating this leads to a bug in o1js
621                    base64::encode(serialized)
622                }
623            }
624
625            #[wasm_bindgen]
626            pub struct [<Wasm $field_name:camel RuntimeTable>] {
627                id: i32,
628                data: WasmFlatVector<$WasmF>
629            }
630            type WasmRuntimeTable = [<Wasm $field_name:camel RuntimeTable>];
631
632            #[wasm_bindgen]
633            impl [<Wasm $field_name:camel RuntimeTable>] {
634                #[wasm_bindgen(constructor)]
635                pub fn new(id: i32, data: WasmFlatVector<$WasmF>) -> WasmRuntimeTable {
636                    WasmRuntimeTable {id, data}
637                }
638            }
639
640            impl From<[<Wasm $field_name:camel RuntimeTable>]> for RuntimeTable<$F> {
641                fn from(wasm_rt: WasmRuntimeTable) -> RuntimeTable<$F> {
642                    RuntimeTable {
643                        id: wasm_rt.id.into(),
644                        data: wasm_rt.data.into_iter().map(Into::into).collect()
645                    }
646                }
647            }
648
649            #[wasm_bindgen]
650            pub fn [<$name:snake _create>](
651                index: &$WasmIndex,
652                witness: WasmVecVecF,
653                wasm_runtime_tables: WasmVector<WasmRuntimeTable>,
654                prev_challenges: WasmFlatVector<$WasmF>,
655                prev_sgs: WasmVector<$WasmG>,
656            ) -> Result<WasmProverProof, JsError> {
657                console_error_panic_hook::set_once();
658                let (maybe_proof, public_input) = crate::rayon::run_in_pool(|| {
659                    index.0.srs.get_lagrange_basis(index.0.as_ref().cs.domain.d1);
660                    let prev: Vec<RecursionChallenge<$G>> = {
661                        if prev_challenges.is_empty() {
662                            Vec::new()
663                        } else {
664                            let challenges_per_sg = prev_challenges.len() / prev_sgs.len();
665                            prev_sgs
666                                .into_iter()
667                                .map(Into::<$G>::into)
668                                .enumerate()
669                                .map(|(i, sg)| {
670                                    let chals =
671                                        prev_challenges[(i * challenges_per_sg)..(i + 1) * challenges_per_sg]
672                                            .iter()
673                                            .map(|a| a.clone().into())
674                                            .collect();
675                                    let comm = PolyComm::<$G> {
676                                        chunks: vec![sg],
677                                    };
678                                    RecursionChallenge { chals, comm }
679                                })
680                                .collect()
681                        }
682                    };
683
684                    let rust_runtime_tables: Vec<RuntimeTable<$F>> = wasm_runtime_tables.into_iter().map(Into::into).collect();
685
686                    let witness: [Vec<_>; COLUMNS] = witness.0
687                        .try_into()
688                        .expect("the witness should be a column of 15 vectors");
689
690                    let index: &ProverIndex<$G, OpeningProof<$G>> = &index.0.as_ref();
691
692                    let public_input = witness[0][0..index.cs.public].to_vec();
693
694                    // Release the runtime lock so that other threads can run using it while we generate the proof.
695                    let group_map = GroupMap::<_>::setup();
696                    let maybe_proof = ProverProof::create_recursive::<
697                        DefaultFqSponge<_, PlonkSpongeConstantsKimchi>,
698                        DefaultFrSponge<_, PlonkSpongeConstantsKimchi>,
699                        _>(&group_map, witness, &rust_runtime_tables, index, prev, None,
700                           &mut rand::rngs::OsRng
701                    );
702                    (maybe_proof, public_input)
703                });
704
705                return match maybe_proof {
706                    Ok(proof) => Ok((proof, public_input).into()),
707                    Err(err) => Err(JsError::from(err))
708                }
709            }
710
711            #[wasm_bindgen]
712            pub fn [<$name:snake _verify>](
713                index: $WasmVerifierIndex,
714                proof: WasmProverProof,
715            ) -> bool {
716                crate::rayon::run_in_pool(|| {
717                    let group_map = <$G as CommitmentCurve>::Map::setup();
718                    let verifier_index = &index.into();
719                    let (proof, public_input) = &proof.into();
720                    batch_verify::<
721                        $G,
722                        DefaultFqSponge<_, PlonkSpongeConstantsKimchi>,
723                        DefaultFrSponge<_, PlonkSpongeConstantsKimchi>,
724                        OpeningProof<$G>
725                    >(
726                        &group_map,
727                        &[Context { verifier_index, proof, public_input }]
728                    ).is_ok()
729                })
730            }
731
732            #[wasm_bindgen]
733            pub struct [<WasmVecVec $field_name:camel PolyComm>](Vec<Vec<PolyComm<$G>>>);
734
735            #[wasm_bindgen]
736            impl [<WasmVecVec $field_name:camel PolyComm>] {
737                #[wasm_bindgen(constructor)]
738                pub fn create(n: i32) -> Self {
739                    [<WasmVecVec $field_name:camel PolyComm>](Vec::with_capacity(n as usize))
740                }
741
742                #[wasm_bindgen]
743                pub fn push(&mut self, x: WasmVector<$WasmPolyComm>) {
744                    self.0.push(x.into_iter().map(Into::into).collect())
745                }
746            }
747
748            #[wasm_bindgen]
749            pub fn [<$name:snake _batch_verify>](
750                indexes: WasmVector<$WasmVerifierIndex>,
751                proofs: WasmVector<WasmProverProof>,
752            ) -> bool {
753                crate::rayon::run_in_pool(|| {
754                    let ts: Vec<_> = indexes
755                        .into_iter()
756                        .zip(proofs.into_iter())
757                        .map(|(index, proof)| (index.into(), proof.into()))
758                        .collect();
759                    let ts: Vec<_> = ts.iter().map(|(verifier_index, (proof, public_input))| Context { verifier_index, proof, public_input}).collect();
760                    let group_map = GroupMap::<_>::setup();
761
762                    batch_verify::<
763                        $G,
764                        DefaultFqSponge<_, PlonkSpongeConstantsKimchi>,
765                        DefaultFrSponge<_, PlonkSpongeConstantsKimchi>,
766                        OpeningProof<$G>
767                    >(&group_map, &ts)
768                    .is_ok()
769                })
770            }
771
772            #[wasm_bindgen]
773            pub fn [<$name:snake _dummy>]() -> WasmProverProof {
774                fn comm() -> PolyComm<$G> {
775                    let g = $G::generator();
776                    PolyComm {
777                        chunks: vec![g, g, g],
778                    }
779                }
780
781                let prev = RecursionChallenge {
782                    chals: vec![$F::one(), $F::one()],
783                    comm: comm(),
784                };
785                let prev_challenges = vec![prev.clone(), prev.clone(), prev.clone()];
786
787                let g = $G::generator();
788                let proof = OpeningProof {
789                    lr: vec![(g, g), (g, g), (g, g)],
790                    z1: $F::one(),
791                    z2: $F::one(),
792                    delta: g,
793                    sg: g,
794                };
795                let eval = || PointEvaluations {
796                    zeta: vec![$F::one()],
797                    zeta_omega: vec![$F::one()],
798                };
799                let evals = ProofEvaluations {
800                    w: core::array::from_fn(|_| eval()),
801                    coefficients: core::array::from_fn(|_| eval()),
802                    z: eval(),
803                    s: core::array::from_fn(|_| eval()),
804                    generic_selector: eval(),
805                    poseidon_selector: eval(),
806                    complete_add_selector: eval(),
807                    mul_selector: eval(),
808                    emul_selector: eval(),
809                    endomul_scalar_selector: eval(),
810                    range_check0_selector: None,
811                    range_check1_selector: None,
812                    foreign_field_add_selector: None,
813                    foreign_field_mul_selector: None,
814                    xor_selector: None,
815                    rot_selector: None,
816                    lookup_aggregation: None,
817                    lookup_table: None,
818                    lookup_sorted: array::from_fn(|_| None),
819                    runtime_lookup_table: None,
820                    runtime_lookup_table_selector: None,
821                    xor_lookup_selector: None,
822                    lookup_gate_lookup_selector: None,
823                    range_check_lookup_selector: None,
824                    foreign_field_mul_lookup_selector: None,
825                    public: None,
826                };
827
828                let dlogproof = ProverProof {
829                    commitments: ProverCommitments {
830                        w_comm: core::array::from_fn(|_| comm()),
831                        z_comm: comm(),
832                        t_comm: comm(),
833                        lookup: None,
834                    },
835                    proof,
836                    evals,
837                    ft_eval1: $F::one(),
838                    prev_challenges,
839                };
840
841                let public = vec![$F::one(), $F::one()];
842                (dlogproof, public).into()
843            }
844
845            #[wasm_bindgen]
846            pub fn [<$name:snake _deep_copy>](
847                x: WasmProverProof
848            ) -> WasmProverProof {
849                x
850            }
851        }
852    }
853}
854
855pub mod fp {
856    use super::*;
857    use crate::{
858        pasta_fp_plonk_index::WasmPastaFpPlonkIndex,
859        plonk_verifier_index::fp::WasmFpPlonkVerifierIndex as WasmPlonkVerifierIndex,
860        poly_comm::vesta::WasmFpPolyComm as WasmPolyComm,
861    };
862    use arkworks::{WasmGVesta, WasmPastaFp};
863    use mina_curves::pasta::{Fp, Vesta as GAffine};
864
865    impl_proof!(
866        caml_pasta_fp_plonk_proof,
867        WasmGVesta,
868        GAffine,
869        WasmPastaFp,
870        Fp,
871        WasmPolyComm,
872        WasmSrs,
873        GAffineOther,
874        mina_poseidon::pasta::fp_kimchi,
875        mina_poseidon::pasta::fq_kimchi,
876        WasmPastaFpPlonkIndex,
877        WasmPlonkVerifierIndex,
878        Fp
879    );
880}
881
882pub mod fq {
883    use super::*;
884    use crate::{
885        pasta_fq_plonk_index::WasmPastaFqPlonkIndex,
886        plonk_verifier_index::fq::WasmFqPlonkVerifierIndex as WasmPlonkVerifierIndex,
887        poly_comm::pallas::WasmFqPolyComm as WasmPolyComm,
888    };
889    use arkworks::{WasmGPallas, WasmPastaFq};
890    use mina_curves::pasta::{Fq, Pallas as GAffine};
891
892    impl_proof!(
893        caml_pasta_fq_plonk_proof,
894        WasmGPallas,
895        GAffine,
896        WasmPastaFq,
897        Fq,
898        WasmPolyComm,
899        WasmSrs,
900        GAffineOther,
901        mina_poseidon::pasta::fq_kimchi,
902        mina_poseidon::pasta::fp_kimchi,
903        WasmPastaFqPlonkIndex,
904        WasmPlonkVerifierIndex,
905        Fq
906    );
907}