plonk_wasm/
oracles.rs

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