1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(
3 unused,
4 future_incompatible,
5 nonstandard_style,
6 rust_2018_idioms,
7 rust_2021_compatibility,
8 clippy::missing_const_for_fn
9)]
10#![forbid(unsafe_code)]
11#![allow(clippy::op_ref, clippy::suspicious_op_assign_impl)]
12#![doc = include_str!("../README.md")]
13
14use ark_ff::{
15 fields::{Field, PrimeField},
16 UniformRand,
17};
18use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
19use ark_std::{
20 fmt::{Debug, Display},
21 hash::Hash,
22 ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
23 vec::*,
24};
25pub use scalar_mul::{variable_base::VariableBaseMSM, ScalarMul};
26use zeroize::Zeroize;
27
28pub use ark_ff::AdditiveGroup;
29
30pub mod models;
31pub use self::models::*;
32
33pub mod scalar_mul;
34
35pub mod hashing;
38
39pub mod pairing;
40
41pub trait PrimeGroup: AdditiveGroup<Scalar = Self::ScalarField> {
43 type ScalarField: PrimeField;
45
46 #[must_use]
48 fn generator() -> Self;
49
50 fn mul_bigint(&self, other: impl AsRef<[u64]>) -> Self;
52
53 fn mul_bits_be(&self, other: impl Iterator<Item = bool>) -> Self {
56 let mut res = Self::zero();
57 for b in other.skip_while(|b| !b) {
58 res.double_in_place();
60 if b {
61 res += self;
62 }
63 }
64 res
65 }
66}
67
68pub trait CurveGroup:
73 PrimeGroup
74 + Add<Self::Affine, Output = Self>
75 + AddAssign<Self::Affine>
76 + Sub<Self::Affine, Output = Self>
77 + SubAssign<Self::Affine>
78 + VariableBaseMSM
79 + ScalarMul<MulBase = Self::Affine>
80 + From<Self::Affine>
81 + Into<Self::Affine>
82 + core::iter::Sum<Self::Affine>
83 + for<'a> core::iter::Sum<&'a Self::Affine>
84{
85 type Config: CurveConfig<ScalarField = Self::ScalarField, BaseField = Self::BaseField>;
86 type BaseField: Field;
88 type Affine: AffineRepr<
90 Config = Self::Config,
91 Group = Self,
92 ScalarField = Self::ScalarField,
93 BaseField = Self::BaseField,
94 > + From<Self>
95 + Into<Self>;
96
97 type FullGroup;
100
101 #[must_use]
103 fn normalize_batch(v: &[Self]) -> Vec<Self::Affine>;
104
105 fn into_affine(self) -> Self::Affine {
107 self.into()
108 }
109}
110
111pub trait AffineRepr:
117 Eq
118 + 'static
119 + Sized
120 + CanonicalSerialize
121 + CanonicalDeserialize
122 + Copy
123 + Clone
124 + Default
125 + UniformRand
126 + Send
127 + Sync
128 + Hash
129 + Debug
130 + Display
131 + Zeroize
132 + Neg<Output = Self>
133 + From<<Self as AffineRepr>::Group>
134 + Into<<Self as AffineRepr>::Group>
135 + Add<Self, Output = Self::Group>
136 + for<'a> Add<&'a Self, Output = Self::Group>
137 + Add<Self::Group, Output = Self::Group>
138 + for<'a> Add<&'a Self::Group, Output = Self::Group>
139 + Sub<Self, Output = Self::Group>
140 + for<'a> Sub<&'a Self, Output = Self::Group>
141 + Sub<Self::Group, Output = Self::Group>
142 + for<'a> Sub<&'a Self::Group, Output = Self::Group>
143 + Mul<Self::ScalarField, Output = Self::Group>
144 + for<'a> Mul<&'a Self::ScalarField, Output = Self::Group>
145{
146 type Config: CurveConfig<ScalarField = Self::ScalarField, BaseField = Self::BaseField>;
147 type ScalarField: PrimeField + Into<<Self::ScalarField as PrimeField>::BigInt>;
148 type BaseField: Field;
150
151 type Group: CurveGroup<
153 Config = Self::Config,
154 Affine = Self,
155 ScalarField = Self::ScalarField,
156 BaseField = Self::BaseField,
157 > + From<Self>
158 + Into<Self>
159 + MulAssign<Self::ScalarField>; const GENERATOR: Self;
162 const ZERO: Self;
163
164 fn xy(&self) -> Option<(Self::BaseField, Self::BaseField)>;
166
167 fn x(&self) -> Option<Self::BaseField> {
169 self.xy().map(|(x, _)| x)
170 }
171
172 fn y(&self) -> Option<Self::BaseField> {
174 self.xy().map(|(_, y)| y)
175 }
176
177 fn zero() -> Self;
179
180 fn is_zero(&self) -> bool;
182
183 #[must_use]
185 fn generator() -> Self;
186
187 fn into_group(self) -> Self::Group {
189 self.into()
190 }
191
192 fn from_random_bytes(bytes: &[u8]) -> Option<Self>;
196
197 #[must_use]
199 fn mul_bigint(&self, by: impl AsRef<[u64]>) -> Self::Group;
200
201 #[must_use]
205 fn clear_cofactor(&self) -> Self;
206
207 #[must_use]
210 fn mul_by_cofactor_to_group(&self) -> Self::Group;
211
212 #[must_use]
214 fn mul_by_cofactor(&self) -> Self {
215 self.mul_by_cofactor_to_group().into()
216 }
217
218 #[must_use]
221 fn mul_by_cofactor_inv(&self) -> Self {
222 self.mul_bigint(Self::Config::COFACTOR_INV.into_bigint())
223 .into()
224 }
225}
226
227pub trait CurveCycle
231where
232 Self::E1: MulAssign<<Self::E2 as CurveGroup>::BaseField>,
233 Self::E2: MulAssign<<Self::E1 as CurveGroup>::BaseField>,
234{
235 type E1: CurveGroup<
236 BaseField = <Self::E2 as PrimeGroup>::ScalarField,
237 ScalarField = <Self::E2 as CurveGroup>::BaseField,
238 >;
239 type E2: CurveGroup;
240}
241
242pub trait PairingFriendlyCycle: CurveCycle {
244 type Engine1: pairing::Pairing<
245 G1 = Self::E1,
246 G1Affine = <Self::E1 as CurveGroup>::Affine,
247 ScalarField = <Self::E1 as PrimeGroup>::ScalarField,
248 >;
249
250 type Engine2: pairing::Pairing<
251 G1 = Self::E2,
252 G1Affine = <Self::E2 as CurveGroup>::Affine,
253 ScalarField = <Self::E2 as PrimeGroup>::ScalarField,
254 >;
255}