plonk_wasm/
projective.rs

1use ark_ec::{AffineRepr, CurveGroup, Group};
2use ark_ff::UniformRand;
3use paste::paste;
4use rand::rngs::StdRng;
5
6use wasm_bindgen::prelude::*;
7
8macro_rules! impl_projective {
9    ($name: ident,
10     $GroupProjective: ty,
11     $CamlG: ty,
12     $CamlScalarField: ty,
13     $BaseField: ty,
14     $CamlBaseField: ty,
15     $Projective: ty) => {
16
17        paste! {
18            #[wasm_bindgen]
19            pub fn [<caml_ $name:snake _one>]() -> $GroupProjective {
20                $Projective::generator().into()
21            }
22
23            #[wasm_bindgen]
24            pub fn [<caml_ $name:snake _add>](
25                x: &$GroupProjective,
26                y: &$GroupProjective,
27            ) -> $GroupProjective {
28                x.as_ref() + y.as_ref()
29            }
30
31            #[wasm_bindgen]
32            pub fn [<caml_ $name:snake _sub>](
33                x: &$GroupProjective,
34                y: &$GroupProjective,
35            ) -> $GroupProjective {
36                x.as_ref() - y.as_ref()
37            }
38
39            #[wasm_bindgen]
40            pub fn [<caml_ $name:snake _negate>](
41                x: &$GroupProjective,
42            ) -> $GroupProjective {
43                -(*x.as_ref())
44            }
45
46            #[wasm_bindgen]
47            pub fn [<caml_ $name:snake _double>](
48                x: &$GroupProjective,
49            ) -> $GroupProjective {
50                x.as_ref().double().into()
51            }
52
53            #[wasm_bindgen]
54            pub fn [<caml_ $name:snake _scale>](
55                x: &$GroupProjective,
56                y: $CamlScalarField,
57            ) -> $GroupProjective {
58                let y: ark_ff::BigInteger256 = y.0.into();
59                x.as_ref().mul_bigint(&y).into()
60            }
61
62            #[wasm_bindgen]
63            pub fn [<caml_ $name:snake _random>]() -> $GroupProjective {
64                let rng = &mut rand::rngs::OsRng;
65                let proj: $Projective = UniformRand::rand(rng);
66                proj.into()
67            }
68
69            #[wasm_bindgen]
70            pub fn [<caml_ $name:snake _rng>](i: u32) -> $GroupProjective {
71                // We only care about entropy here, so we force a conversion i32 -> u32.
72                let i: u64 = (i as u32).into();
73                let mut rng: StdRng = rand::SeedableRng::seed_from_u64(i);
74                let proj: $Projective = UniformRand::rand(&mut rng);
75                proj.into()
76            }
77
78            // improper_ctypes_definitions is allowed here because the CamlBase/ScalarField struct
79            // already has #[repr(C)] in its definition
80            #[allow(improper_ctypes_definitions)]
81            #[wasm_bindgen]
82            pub extern "C" fn [<caml_ $name:snake _endo_base>]() -> $CamlBaseField {
83                let (endo_q, _endo_r) = poly_commitment::ipa::endos::<GAffine>();
84                endo_q.into()
85            }
86
87            // improper_ctypes_definitions is allowed here because the CamlBase/ScalarField struct
88            // already has #[repr(C)] in its definition
89            #[allow(improper_ctypes_definitions)]
90            #[wasm_bindgen]
91            pub extern "C" fn [<caml_ $name:snake _endo_scalar>]() -> $CamlScalarField {
92                let (_endo_q, endo_r) = poly_commitment::ipa::endos::<GAffine>();
93                endo_r.into()
94            }
95
96            #[wasm_bindgen]
97            pub fn [<caml_ $name:snake _to_affine>](
98                x: &$GroupProjective
99                ) -> $CamlG {
100                x.as_ref().into_affine().into()
101            }
102
103            #[wasm_bindgen]
104            pub fn [<caml_ $name:snake _of_affine>](x: $CamlG) -> $GroupProjective {
105                Into::<GAffine>::into(x).into_group().into()
106            }
107
108            #[wasm_bindgen]
109            pub fn [<caml_ $name:snake _of_affine_coordinates>](x: $CamlBaseField, y: $CamlBaseField) -> $GroupProjective {
110                let res = $Projective::new_unchecked(x.into(), y.into(), <$BaseField as ark_ff::One>::one());
111                res.into()
112            }
113
114            #[wasm_bindgen]
115            pub fn [<caml_ $name:snake _affine_deep_copy>](x: $CamlG) -> $CamlG {
116                x
117            }
118        }
119    }
120}
121
122pub mod pallas {
123    use super::*;
124    use arkworks::{WasmGPallas, WasmPallasGProjective, WasmPastaFp, WasmPastaFq};
125    use mina_curves::pasta::{Fp, Pallas as GAffine, ProjectivePallas};
126
127    impl_projective!(
128        pallas,
129        WasmPallasGProjective,
130        WasmGPallas,
131        WasmPastaFq,
132        Fp,
133        WasmPastaFp,
134        ProjectivePallas
135    );
136}
137
138pub mod vesta {
139    use super::*;
140    use arkworks::{WasmGVesta, WasmPastaFp, WasmPastaFq, WasmVestaGProjective};
141    use mina_curves::pasta::{Fq, ProjectiveVesta, Vesta as GAffine};
142
143    impl_projective!(
144        vesta,
145        WasmVestaGProjective,
146        WasmGVesta,
147        WasmPastaFp,
148        Fq,
149        WasmPastaFq,
150        ProjectiveVesta
151    );
152}