kimchi_stubs/
projective.rs1use ark_ec::{AdditiveGroup, AffineRepr, CurveGroup, PrimeGroup};
2use ark_ff::UniformRand;
3use paste::paste;
4use rand::rngs::StdRng;
5
6macro_rules! impl_projective {
7 ($name: ident, $GroupProjective: ty, $CamlG: ty, $CamlScalarField: ty, $BaseField: ty, $CamlBaseField: ty, $Projective: ty) => {
8
9 paste! {
10 #[ocaml_gen::func]
11 #[ocaml::func]
12 pub fn [<caml_ $name:snake _one>]() -> $GroupProjective {
13 $Projective::generator().into()
14 }
15
16 #[ocaml_gen::func]
17 #[ocaml::func]
18 pub fn [<caml_ $name:snake _add>](
19 x: ocaml::Pointer<$GroupProjective>,
20 y: ocaml::Pointer<$GroupProjective>,
21 ) -> $GroupProjective {
22 x.as_ref() + y.as_ref()
23 }
24
25 #[ocaml_gen::func]
26 #[ocaml::func]
27 pub fn [<caml_ $name:snake _sub>](
28 x: ocaml::Pointer<$GroupProjective>,
29 y: ocaml::Pointer<$GroupProjective>,
30 ) -> $GroupProjective {
31 x.as_ref() - y.as_ref()
32 }
33
34 #[ocaml_gen::func]
35 #[ocaml::func]
36 pub fn [<caml_ $name:snake _negate>](
37 x: ocaml::Pointer<$GroupProjective>,
38 ) -> $GroupProjective {
39 -(*x.as_ref())
40 }
41
42 #[ocaml_gen::func]
43 #[ocaml::func]
44 pub fn [<caml_ $name:snake _double>](
45 x: ocaml::Pointer<$GroupProjective>,
46 ) -> $GroupProjective {
47 x.as_ref().double().into()
48 }
49
50 #[ocaml_gen::func]
51 #[ocaml::func]
52 pub fn [<caml_ $name:snake _scale>](
53 x: ocaml::Pointer<$GroupProjective>,
54 y: $CamlScalarField,
55 ) -> $GroupProjective {
56 let ctx = ark_ec::scalar_mul::wnaf::WnafContext::new(4);
61 ctx.mul(x.as_ref().0, &y.0).into()
62 }
63
64 #[ocaml_gen::func]
65 #[ocaml::func]
66 pub fn [<caml_ $name:snake _random>]() -> $GroupProjective {
67 let rng = &mut rand::rngs::OsRng;
68 let proj: $Projective = UniformRand::rand(rng);
69 proj.into()
70 }
71
72 #[ocaml_gen::func]
73 #[ocaml::func]
74 pub fn [<caml_ $name:snake _rng>](i: ocaml::Int) -> $GroupProjective {
75 let i: u64 = (i as u32).into();
78 let mut rng: StdRng = rand::SeedableRng::seed_from_u64(i);
79 let proj: $Projective = UniformRand::rand(&mut rng);
80 proj.into()
81 }
82
83 #[ocaml_gen::func]
84 #[ocaml::func]
85 pub extern "C" fn [<caml_ $name:snake _endo_base>]() -> $CamlBaseField {
86 let (endo_q, _endo_r) = poly_commitment::ipa::endos::<GAffine>();
87 endo_q.into()
88 }
89
90 #[ocaml_gen::func]
91 #[ocaml::func]
92 pub extern "C" fn [<caml_ $name:snake _endo_scalar>]() -> $CamlScalarField {
93 let (_endo_q, endo_r) = poly_commitment::ipa::endos::<GAffine>();
94 endo_r.into()
95 }
96
97 #[ocaml_gen::func]
98 #[ocaml::func]
99 pub fn [<caml_ $name:snake _to_affine>](x: ocaml::Pointer<$GroupProjective>) -> $CamlG {
100 x.as_ref().into_affine().into()
101 }
102
103 #[ocaml_gen::func]
104 #[ocaml::func]
105 pub fn [<caml_ $name:snake _of_affine>](x: $CamlG) -> $GroupProjective {
106 Into::<GAffine>::into(x).into_group().into()
107 }
108
109 #[ocaml_gen::func]
110 #[ocaml::func]
111 pub fn [<caml_ $name:snake _of_affine_coordinates>](x: $CamlBaseField, y: $CamlBaseField) -> $GroupProjective {
112 let res = $Projective::new_unchecked(x.into(), y.into(), <$BaseField as ark_ff::One>::one());
113 res.into()
114 }
115
116 #[ocaml_gen::func]
117 #[ocaml::func]
118 pub fn [<caml_ $name:snake _affine_deep_copy>](x: $CamlG) -> $CamlG {
119 x
120 }
121 }
122 }
123}
124
125pub mod pallas {
126 use super::*;
127 use crate::arkworks::{CamlFp, CamlFq, CamlGPallas, CamlGroupProjectivePallas};
128 use mina_curves::pasta::{curves::pallas::ProjectivePallas, Fp, Pallas as GAffine};
129
130 impl_projective!(
131 pallas,
132 CamlGroupProjectivePallas,
133 CamlGPallas,
134 CamlFq,
135 Fp,
136 CamlFp,
137 ProjectivePallas
138 );
139}
140
141pub mod vesta {
142 use super::*;
143 use crate::arkworks::{CamlFp, CamlFq, CamlGVesta, CamlGroupProjectiveVesta};
144 use mina_curves::pasta::{curves::vesta::ProjectiveVesta, Fq, Vesta as GAffine};
145
146 impl_projective!(
147 vesta,
148 CamlGroupProjectiveVesta,
149 CamlGVesta,
150 CamlFp,
151 Fq,
152 CamlFq,
153 ProjectiveVesta
154 );
155}