kimchi_stubs/
projective.rs1use ark_ec::{AffineRepr, CurveGroup, Group};
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 y: ark_ff::BigInteger256 = y.0.into();
57 x.as_ref().mul_bigint(&y).into()
58 }
59
60 #[ocaml_gen::func]
61 #[ocaml::func]
62 pub fn [<caml_ $name:snake _random>]() -> $GroupProjective {
63 let rng = &mut rand::rngs::OsRng;
64 let proj: $Projective = UniformRand::rand(rng);
65 proj.into()
66 }
67
68 #[ocaml_gen::func]
69 #[ocaml::func]
70 pub fn [<caml_ $name:snake _rng>](i: ocaml::Int) -> $GroupProjective {
71 let i: u64 = (i as u32).into();
74 let mut rng: StdRng = rand::SeedableRng::seed_from_u64(i);
75 let proj: $Projective = UniformRand::rand(&mut rng);
76 proj.into()
77 }
78
79 #[ocaml_gen::func]
80 #[ocaml::func]
81 pub extern "C" fn [<caml_ $name:snake _endo_base>]() -> $CamlBaseField {
82 let (endo_q, _endo_r) = poly_commitment::ipa::endos::<GAffine>();
83 endo_q.into()
84 }
85
86 #[ocaml_gen::func]
87 #[ocaml::func]
88 pub extern "C" fn [<caml_ $name:snake _endo_scalar>]() -> $CamlScalarField {
89 let (_endo_q, endo_r) = poly_commitment::ipa::endos::<GAffine>();
90 endo_r.into()
91 }
92
93 #[ocaml_gen::func]
94 #[ocaml::func]
95 pub fn [<caml_ $name:snake _to_affine>](x: ocaml::Pointer<$GroupProjective>) -> $CamlG {
96 x.as_ref().into_affine().into()
97 }
98
99 #[ocaml_gen::func]
100 #[ocaml::func]
101 pub fn [<caml_ $name:snake _of_affine>](x: $CamlG) -> $GroupProjective {
102 Into::<GAffine>::into(x).into_group().into()
103 }
104
105 #[ocaml_gen::func]
106 #[ocaml::func]
107 pub fn [<caml_ $name:snake _of_affine_coordinates>](x: $CamlBaseField, y: $CamlBaseField) -> $GroupProjective {
108 let res = $Projective::new_unchecked(x.into(), y.into(), <$BaseField as ark_ff::One>::one());
109 res.into()
110 }
111
112 #[ocaml_gen::func]
113 #[ocaml::func]
114 pub fn [<caml_ $name:snake _affine_deep_copy>](x: $CamlG) -> $CamlG {
115 x
116 }
117 }
118 }
119}
120
121pub mod pallas {
122 use super::*;
123 use crate::arkworks::{CamlFp, CamlFq, CamlGPallas, CamlGroupProjectivePallas};
124 use mina_curves::pasta::{curves::pallas::ProjectivePallas, Fp, Pallas as GAffine};
125
126 impl_projective!(
127 pallas,
128 CamlGroupProjectivePallas,
129 CamlGPallas,
130 CamlFq,
131 Fp,
132 CamlFp,
133 ProjectivePallas
134 );
135}
136
137pub mod vesta {
138 use super::*;
139 use crate::arkworks::{CamlFp, CamlFq, CamlGVesta, CamlGroupProjectiveVesta};
140 use mina_curves::pasta::{curves::vesta::ProjectiveVesta, Fq, Vesta as GAffine};
141
142 impl_projective!(
143 vesta,
144 CamlGroupProjectiveVesta,
145 CamlGVesta,
146 CamlFp,
147 Fq,
148 CamlFq,
149 ProjectiveVesta
150 );
151}