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::*;
18use crate::wasm_vector::WasmVector;
20use ark_ff::{One, Zero};
22
23macro_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>, index: $index, proof: $WasmProverProof, ) -> Result<[<Wasm $field_name:camel Oracles>], JsError> {
179 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
277pub 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}