plonk_wasm/
oracles.rs

1use kimchi::{
2    circuits::scalars::RandomOracles, proof::ProverProof,
3    verifier_index::VerifierIndex as DlogVerifierIndex,
4};
5use mina_poseidon::{
6    self,
7    constants::PlonkSpongeConstantsKimchi,
8    sponge::{DefaultFqSponge, DefaultFrSponge},
9    FqSponge,
10};
11use paste::paste;
12use poly_commitment::{
13    commitment::{shift_scalar, PolyComm},
14    ipa::OpeningProof,
15    SRS,
16};
17use wasm_bindgen::prelude::*;
18// use wasm_bindgen::convert::{IntoWasmAbi, FromWasmAbi};
19use crate::wasm_vector::WasmVector;
20// use crate::wasm_flat_vector::WasmFlatVector;
21use ark_ff::{One, Zero};
22
23//
24// CamlOracles
25//
26
27//
28// Implementation
29//
30
31macro_rules! impl_oracles {
32    ($WasmF: ty,
33     $F: ty,
34     $WasmG: ty,
35     $G: ty,
36     $WasmPolyComm: ty,
37     $WasmProverProof: ty,
38     $index: ty,
39     $curve_params: ty,
40     $field_name: ident) => {
41
42        paste! {
43            use crate::wasm_flat_vector::WasmFlatVector;
44            use mina_poseidon::sponge::ScalarChallenge;
45
46            #[wasm_bindgen]
47            #[derive(Clone, Copy)]
48            pub struct [<Wasm $field_name:camel RandomOracles>] {
49                pub joint_combiner_chal: Option<$WasmF>,
50                pub joint_combiner: Option<$WasmF>,
51                pub beta: $WasmF,
52                pub gamma: $WasmF,
53                pub alpha_chal: $WasmF,
54                pub alpha: $WasmF,
55                pub zeta: $WasmF,
56                pub v: $WasmF,
57                pub u: $WasmF,
58                pub zeta_chal: $WasmF,
59                pub v_chal: $WasmF,
60                pub u_chal: $WasmF,
61            }
62            type WasmRandomOracles = [<Wasm $field_name:camel RandomOracles>];
63
64            #[wasm_bindgen]
65            impl [<Wasm $field_name:camel RandomOracles>] {
66                #[allow(clippy::too_many_arguments)]
67                #[wasm_bindgen(constructor)]
68                pub fn new(
69                    joint_combiner_chal: Option<$WasmF>,
70                    joint_combiner: Option<$WasmF>,
71                    beta: $WasmF,
72                    gamma: $WasmF,
73                    alpha_chal: $WasmF,
74                    alpha: $WasmF,
75                    zeta: $WasmF,
76                    v: $WasmF,
77                    u: $WasmF,
78                    zeta_chal: $WasmF,
79                    v_chal: $WasmF,
80                    u_chal: $WasmF) -> Self  {
81                    Self {
82                        joint_combiner_chal,
83                        joint_combiner,
84                        beta,
85                        gamma,
86                        alpha_chal,
87                        alpha,
88                        zeta,
89                        v,
90                        u,
91                        zeta_chal,
92                        v_chal,
93                        u_chal,
94                    }
95                }
96            }
97
98            impl From<RandomOracles<$F>> for WasmRandomOracles
99            {
100                fn from(ro: RandomOracles<$F>) -> Self {
101                    Self {
102                        joint_combiner_chal: ro.joint_combiner.as_ref().map(|x| x.0.0.into()),
103                        joint_combiner: ro.joint_combiner.as_ref().map(|x| x.1.into()),
104                        beta: ro.beta.into(),
105                        gamma: ro.gamma.into(),
106                        alpha_chal: ro.alpha_chal.0.into(),
107                        alpha: ro.alpha.into(),
108                        zeta: ro.zeta.into(),
109                        v: ro.v.into(),
110                        u: ro.u.into(),
111                        zeta_chal: ro.zeta_chal.0.into(),
112                        v_chal: ro.v_chal.0.into(),
113                        u_chal: ro.u_chal.0.into(),
114                    }
115                }
116            }
117
118            impl From<WasmRandomOracles> for RandomOracles<$F>
119            {
120                fn from(ro: WasmRandomOracles) -> Self {
121                    Self {
122                        joint_combiner: ro.joint_combiner_chal.and_then(|x| {
123                            ro.joint_combiner.map(|y| (ScalarChallenge(x.into()), y.into()))
124                        }),
125                        beta: ro.beta.into(),
126                        gamma: ro.gamma.into(),
127                        alpha_chal: ScalarChallenge(ro.alpha_chal.into()),
128                        alpha: ro.alpha.into(),
129                        zeta: ro.zeta.into(),
130                        v: ro.v.into(),
131                        u: ro.u.into(),
132                        zeta_chal: ScalarChallenge(ro.zeta_chal.into()),
133                        v_chal: ScalarChallenge(ro.v_chal.into()),
134                        u_chal: ScalarChallenge(ro.u_chal.into()),
135                    }
136                }
137            }
138
139            #[wasm_bindgen]
140            #[derive(Clone)]
141            pub struct [<Wasm $field_name:camel Oracles>] {
142                pub o: [<Wasm $field_name:camel RandomOracles>],
143                pub p_eval0: $WasmF,
144                pub p_eval1: $WasmF,
145                #[wasm_bindgen(skip)]
146                pub opening_prechallenges: WasmFlatVector<$WasmF>,
147                pub digest_before_evaluations: $WasmF,
148            }
149
150            #[wasm_bindgen]
151            impl [<Wasm $field_name:camel Oracles>] {
152                #[wasm_bindgen(constructor)]
153                pub fn new(
154                    o: WasmRandomOracles,
155                    p_eval0: $WasmF,
156                    p_eval1: $WasmF,
157                    opening_prechallenges: WasmFlatVector<$WasmF>,
158                    digest_before_evaluations: $WasmF) -> Self {
159                    Self {o, p_eval0, p_eval1, opening_prechallenges, digest_before_evaluations}
160                }
161
162                #[wasm_bindgen(getter)]
163                pub fn opening_prechallenges(&self) -> WasmFlatVector<$WasmF> {
164                    self.opening_prechallenges.clone()
165                }
166
167                #[wasm_bindgen(setter)]
168                pub fn set_opening_prechallenges(&mut self, x: WasmFlatVector<$WasmF>) {
169                    self.opening_prechallenges = x;
170                }
171            }
172
173            #[wasm_bindgen]
174            pub fn [<$F:snake _oracles_create>](
175                lgr_comm: WasmVector<$WasmPolyComm>, // the bases to commit polynomials
176                index: $index,    // parameters
177                proof: $WasmProverProof, // the final proof (contains public elements at the beginning)
178            ) -> Result<[<Wasm $field_name:camel Oracles>], JsError> {
179                // conversions
180                let result = crate::rayon::run_in_pool(|| {
181                    let index: DlogVerifierIndex<$G, OpeningProof<$G>> = index.into();
182
183                    let lgr_comm: Vec<PolyComm<$G>> = lgr_comm
184                        .into_iter()
185                        .take(proof.public.len())
186                        .map(Into::into)
187                        .collect();
188                    let lgr_comm_refs: Vec<_> = lgr_comm.iter().collect();
189
190                    let p_comm = PolyComm::<$G>::multi_scalar_mul(
191                        &lgr_comm_refs,
192                        &proof
193                            .public
194                            .iter()
195                            .map(|a| a.clone().into())
196                            .map(|s: $F| -s)
197                            .collect::<Vec<_>>(),
198                    );
199                    let p_comm = {
200                        index
201                            .srs()
202                            .mask_custom(
203                                p_comm.clone(),
204                                &p_comm.map(|_| $F::one()),
205                            )
206                            .unwrap()
207                            .commitment
208                    };
209
210                    let (proof, public_input): (ProverProof<$G, OpeningProof<$G>>, Vec<$F>) = proof.into();
211
212                    let oracles_result =
213                        proof.oracles::<
214                            DefaultFqSponge<$curve_params, PlonkSpongeConstantsKimchi>,
215                            DefaultFrSponge<$F, PlonkSpongeConstantsKimchi>
216                        >(&index, &p_comm, Some(&public_input));
217                    let oracles_result = match oracles_result {
218                        Err(e) => {
219                            return Err(format!("oracles_create: {}", e));
220                        }
221                        Ok(cs) => cs,
222                    };
223
224                    let (mut sponge, combined_inner_product, p_eval, digest, oracles) = (
225                        oracles_result.fq_sponge,
226                        oracles_result.combined_inner_product,
227                        oracles_result.public_evals,
228                        oracles_result.digest,
229                        oracles_result.oracles,
230                    );
231
232                    sponge.absorb_fr(&[shift_scalar::<$G>(combined_inner_product)]);
233
234                    let opening_prechallenges = proof
235                        .proof
236                        .prechallenges(&mut sponge)
237                        .into_iter()
238                        .map(|x| x.0.into())
239                        .collect();
240
241                    Ok((oracles, p_eval, opening_prechallenges, digest))
242                });
243
244                match result {
245                    Ok((oracles, p_eval, opening_prechallenges, digest)) => Ok([<Wasm $field_name:camel Oracles>] {
246                        o: oracles.into(),
247                        p_eval0: p_eval[0][0].into(),
248                        p_eval1: p_eval[1][0].into(),
249                        opening_prechallenges,
250                        digest_before_evaluations: digest.into()
251                    }),
252                    Err(err) => Err(JsError::new(&err))
253                }
254            }
255
256            #[wasm_bindgen]
257            pub fn [<$F:snake _oracles_dummy>]() -> [<Wasm $field_name:camel Oracles>] {
258                [<Wasm $field_name:camel Oracles>] {
259                    o: RandomOracles::<$F>::default().into(),
260                    p_eval0: $F::zero().into(),
261                    p_eval1: $F::zero().into(),
262                    opening_prechallenges: vec![].into(),
263                    digest_before_evaluations: $F::zero().into(),
264                }
265            }
266
267            #[wasm_bindgen]
268            pub fn [<$F:snake _oracles_deep_copy>](
269                x: $WasmProverProof,
270            ) -> $WasmProverProof {
271                x
272            }
273        }
274    }
275}
276
277//
278//
279//
280
281pub mod fp {
282    use super::*;
283    use crate::{
284        arkworks::WasmPastaFp, plonk_proof::fp::WasmFpProverProof as WasmProverProof,
285        plonk_verifier_index::fp::WasmFpPlonkVerifierIndex as WasmPlonkVerifierIndex,
286        poly_comm::vesta::WasmFpPolyComm as WasmPolyComm,
287    };
288    use mina_curves::pasta::{Fp, Vesta as GAffine, VestaParameters};
289
290    impl_oracles!(
291        WasmPastaFp,
292        Fp,
293        WasmGVesta,
294        GAffine,
295        WasmPolyComm,
296        WasmProverProof,
297        WasmPlonkVerifierIndex,
298        VestaParameters,
299        Fp
300    );
301}
302
303pub mod fq {
304    use super::*;
305    use crate::{
306        arkworks::WasmPastaFq, plonk_proof::fq::WasmFqProverProof as WasmProverProof,
307        plonk_verifier_index::fq::WasmFqPlonkVerifierIndex as WasmPlonkVerifierIndex,
308        poly_comm::pallas::WasmFqPolyComm as WasmPolyComm,
309    };
310    use mina_curves::pasta::{Fq, Pallas as GAffine, PallasParameters};
311
312    impl_oracles!(
313        WasmPastaFq,
314        Fq,
315        WasmGPallas,
316        GAffine,
317        WasmPolyComm,
318        WasmProverProof,
319        WasmPlonkVerifierIndex,
320        PallasParameters,
321        Fq
322    );
323}