snarkvm_curves/traits/
group.rs1use crate::{PairingEngine, templates::short_weierstrass_jacobian};
17use snarkvm_fields::{Field, PrimeField, SquareRootField, Zero};
18use snarkvm_utilities::{FromBytes, ToBytes, rand::Uniform, serialize::*};
19
20use core::{
21 fmt::{Debug, Display},
22 hash::Hash,
23 iter,
24 ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
25};
26use serde::{Serialize, de::DeserializeOwned};
27
28pub trait ProjectiveCurve:
30 CanonicalSerialize
31 + CanonicalDeserialize
32 + Copy
33 + Clone
34 + Debug
35 + Display
36 + Default
37 + FromBytes
38 + Send
39 + Sync
40 + 'static
41 + Eq
42 + Hash
43 + Neg<Output = Self>
44 + Uniform
45 + Zero
46 + Add<Self, Output = Self>
47 + Sub<Self, Output = Self>
48 + Mul<Self::ScalarField, Output = Self>
49 + AddAssign<Self>
50 + SubAssign<Self>
51 + MulAssign<Self::ScalarField>
52 + for<'a> Add<&'a Self, Output = Self>
53 + for<'a> Sub<&'a Self, Output = Self>
54 + for<'a> AddAssign<&'a Self>
55 + for<'a> SubAssign<&'a Self>
56 + PartialEq<Self::Affine>
57 + Sized
58 + ToBytes
59 + iter::Sum
60 + From<<Self as ProjectiveCurve>::Affine>
61{
62 type Affine: AffineCurve<Projective = Self, ScalarField = Self::ScalarField> + From<Self> + Into<Self>;
63 type BaseField: Field;
64 type ScalarField: PrimeField + SquareRootField + Into<<Self::ScalarField as PrimeField>::BigInteger>;
65
66 #[must_use]
68 fn prime_subgroup_generator() -> Self;
69
70 fn batch_normalization(v: &mut [Self]);
73
74 fn batch_normalization_into_affine(mut v: Vec<Self>) -> Vec<Self::Affine> {
77 Self::batch_normalization(&mut v);
78 v.into_iter().map(|v| v.into()).collect()
79 }
80
81 #[must_use]
84 fn is_normalized(&self) -> bool;
85
86 fn add_assign_mixed(&mut self, other: &Self::Affine);
88
89 fn add_mixed(&self, other: &Self::Affine) -> Self {
91 let mut copy = *self;
92 copy.add_assign_mixed(other);
93 copy
94 }
95
96 fn sub_assign_mixed(&mut self, other: &Self::Affine) {
98 self.add_assign_mixed(&-*other);
99 }
100
101 #[must_use]
103 fn double(&self) -> Self;
104
105 fn double_in_place(&mut self);
107
108 #[must_use]
110 #[allow(clippy::wrong_self_convention)]
111 fn to_affine(&self) -> Self::Affine;
112}
113
114#[allow(clippy::wrong_self_convention)]
117pub trait AffineCurve:
118 CanonicalSerialize
119 + CanonicalDeserialize
120 + Copy
121 + Clone
122 + Debug
123 + Display
124 + Default
125 + FromBytes
126 + Send
127 + Sync
128 + 'static
129 + Eq
130 + Hash
131 + Neg<Output = Self>
132 + Uniform
133 + PartialEq<Self::Projective>
134 + Mul<Self::ScalarField, Output = Self::Projective>
135 + Sized
136 + Serialize
137 + DeserializeOwned
138 + ToBytes
139 + From<<Self as AffineCurve>::Projective>
140 + Zero
141{
142 type Projective: ProjectiveCurve<Affine = Self, ScalarField = Self::ScalarField> + From<Self> + Into<Self>;
143 type BaseField: Field + SquareRootField;
144 type ScalarField: PrimeField + SquareRootField + Into<<Self::ScalarField as PrimeField>::BigInteger>;
145 type Coordinates;
146
147 fn from_coordinates(coordinates: Self::Coordinates) -> Option<Self>;
149
150 fn from_coordinates_unchecked(coordinates: Self::Coordinates) -> Self;
153
154 fn cofactor() -> &'static [u64];
156
157 #[must_use]
159 fn prime_subgroup_generator() -> Self;
160
161 fn from_x_coordinate(x: Self::BaseField, greatest: bool) -> Option<Self>;
167
168 fn pair_from_x_coordinate(x: Self::BaseField) -> Option<(Self, Self)>;
176
177 fn from_y_coordinate(y: Self::BaseField, greatest: bool) -> Option<Self>;
183
184 #[must_use]
187 fn mul_by_cofactor_to_projective(&self) -> Self::Projective;
188
189 #[must_use]
191 fn to_projective(&self) -> Self::Projective;
192
193 fn from_random_bytes(bytes: &[u8]) -> Option<Self>;
197
198 fn mul_bits(&self, bits: impl Iterator<Item = bool>) -> Self::Projective;
201
202 #[must_use]
204 fn mul_by_cofactor(&self) -> Self {
205 self.mul_by_cofactor_to_projective().into()
206 }
207
208 #[must_use]
211 fn mul_by_cofactor_inv(&self) -> Self;
212
213 #[must_use]
215 fn is_in_correct_subgroup_assuming_on_curve(&self) -> bool;
216
217 #[must_use]
219 fn to_x_coordinate(&self) -> Self::BaseField;
220
221 #[must_use]
223 fn to_y_coordinate(&self) -> Self::BaseField;
224
225 fn is_on_curve(&self) -> bool;
227
228 fn batch_add_loop_1(
230 a: &mut Self,
231 b: &mut Self,
232 half: &Self::BaseField, inversion_tmp: &mut Self::BaseField,
234 );
235
236 fn batch_add_loop_2(a: &mut Self, b: Self, inversion_tmp: &mut Self::BaseField);
238}
239
240pub trait PairingCurve: AffineCurve {
241 type Engine: PairingEngine<Fr = Self::ScalarField>;
242 type Prepared: CanonicalSerialize
243 + CanonicalDeserialize
244 + ToBytes
245 + FromBytes
246 + PartialEq
247 + Eq
248 + Default
249 + Clone
250 + Send
251 + Sync
252 + Debug
253 + 'static;
254 type PairWith: PairingCurve<PairWith = Self>;
255 type PairingResult: Field;
256
257 #[must_use]
259 fn prepare(&self) -> Self::Prepared;
260
261 #[must_use]
263 fn pairing_with(&self, other: &Self::PairWith) -> Self::PairingResult;
264}
265
266pub trait ModelParameters: 'static + Copy + Clone + Debug + PartialEq + Eq + Hash + Send + Sync + Sized {
267 type BaseField: Field + SquareRootField;
268 type ScalarField: PrimeField + SquareRootField + Into<<Self::ScalarField as PrimeField>::BigInteger>;
269}
270
271pub trait ShortWeierstrassParameters: ModelParameters {
272 const WEIERSTRASS_A: Self::BaseField;
274 const WEIERSTRASS_B: Self::BaseField;
276 const COFACTOR: &'static [u64];
278 const COFACTOR_INV: Self::ScalarField;
280 const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField);
282
283 const PHI: Self::BaseField;
284
285 const Q1: [u64; 4] = [9183663392111466540, 12968021215939883360, 3, 0];
288 const Q2: [u64; 4] = [13, 0, 0, 0];
290 const B1: Self::ScalarField;
292 const B2: Self::ScalarField;
294 const R128: Self::ScalarField;
296 const HALF_R: [u64; 8] = [0, 0, 0, 0x8000000000000000, 0, 0, 0, 0];
298
299 #[inline(always)]
300 fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
301 let mut copy = *elem;
302 copy *= &Self::WEIERSTRASS_A;
303 copy
304 }
305
306 #[inline(always)]
307 fn add_b(elem: &Self::BaseField) -> Self::BaseField {
308 let mut copy = *elem;
309 copy += &Self::WEIERSTRASS_B;
310 copy
311 }
312
313 fn is_in_correct_subgroup_assuming_on_curve(p: &short_weierstrass_jacobian::Affine<Self>) -> bool;
314
315 fn glv_endomorphism(p: short_weierstrass_jacobian::Affine<Self>) -> short_weierstrass_jacobian::Affine<Self>;
316
317 fn mul_projective(
318 p: short_weierstrass_jacobian::Projective<Self>,
319 by: Self::ScalarField,
320 ) -> short_weierstrass_jacobian::Projective<Self>;
321}
322
323pub trait TwistedEdwardsParameters: ModelParameters {
324 const EDWARDS_A: Self::BaseField;
326 const EDWARDS_D: Self::BaseField;
328 const COFACTOR: &'static [u64];
330 const COFACTOR_INV: Self::ScalarField;
332 const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField);
334
335 type MontgomeryParameters: MontgomeryParameters<BaseField = Self::BaseField>;
336
337 #[inline(always)]
338 fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
339 let mut copy = *elem;
340 copy *= &Self::EDWARDS_A;
341 copy
342 }
343}
344
345pub trait MontgomeryParameters: ModelParameters {
346 const MONTGOMERY_A: Self::BaseField;
348 const MONTGOMERY_B: Self::BaseField;
350
351 type TwistedEdwardsParameters: TwistedEdwardsParameters<BaseField = Self::BaseField>;
352}