1#![allow(clippy::too_many_arguments, clippy::needless_borrows_for_generic_args)]
2#![deny(missing_debug_implementations)]
4#![cfg_attr(feature = "asm", feature(asm_const))]
6
7extern crate byteorder;
8extern crate rand as rand_crate;
9
10#[cfg(test)]
11pub mod tests;
12
13pub extern crate ff;
14
15pub use ff::*;
16
17pub mod bls12_381;
18pub mod bn256;
19pub mod compact_bn256;
20
21mod wnaf;
22pub use self::wnaf::Wnaf;
23
24mod base;
25pub use self::base::*;
26
27use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, ScalarEngine, SqrtField};
28use std::error::Error;
29use std::fmt;
30
31pub mod rand {
32 pub use crate::ff::rand::Rng;
33 pub use crate::ff::Rand;
34 pub use crate::rand_crate::{distributions, random, rngs, seq, thread_rng, RngCore, SeedableRng};
35
36 #[derive(Clone, Debug)]
37 pub struct XorShiftRng(pub rand_xorshift::XorShiftRng);
38
39 impl XorShiftRng {
40 pub fn from_seed(seed: [u32; 4]) -> Self {
41 let mut seed_bytes = [0u8; 16];
42 for (chunk, word) in seed_bytes.chunks_exact_mut(4).zip(seed.iter()) {
43 chunk.copy_from_slice(&word.to_le_bytes());
44 }
45
46 <Self as SeedableRng>::from_seed(seed_bytes)
47 }
48 }
49
50 impl RngCore for XorShiftRng {
51 fn next_u32(&mut self) -> u32 {
52 self.0.next_u32()
53 }
54
55 fn next_u64(&mut self) -> u64 {
56 self.0.next_u64()
57 }
58
59 fn fill_bytes(&mut self, dest: &mut [u8]) {
60 self.0.fill_bytes(dest)
61 }
62
63 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), crate::rand_crate::Error> {
64 self.0.try_fill_bytes(dest)
65 }
66 }
67
68 impl SeedableRng for XorShiftRng {
69 type Seed = <rand_xorshift::XorShiftRng as SeedableRng>::Seed;
70
71 fn from_seed(seed: Self::Seed) -> Self {
72 Self(rand_xorshift::XorShiftRng::from_seed(seed))
73 }
74 }
75}
76
77pub trait Engine: ScalarEngine {
81 type G1: CurveProjective<Engine = Self, Base = Self::Fq, Scalar = Self::Fr, Affine = Self::G1Affine> + From<Self::G1Affine>;
83
84 type G1Affine: CurveAffine<Engine = Self, Base = Self::Fq, Scalar = Self::Fr, Projective = Self::G1, Pair = Self::G2Affine, PairingResult = Self::Fqk> + From<Self::G1> + RawEncodable;
86
87 type G2: CurveProjective<Engine = Self, Base = Self::Fqe, Scalar = Self::Fr, Affine = Self::G2Affine> + From<Self::G2Affine>;
89
90 type G2Affine: CurveAffine<Engine = Self, Base = Self::Fqe, Scalar = Self::Fr, Projective = Self::G2, Pair = Self::G1Affine, PairingResult = Self::Fqk> + From<Self::G2>;
92
93 type Fq: PrimeField + SqrtField;
95
96 type Fqe: SqrtField;
98
99 type Fqk: Field;
101
102 fn miller_loop<'a, I>(i: I) -> Self::Fqk
104 where
105 I: IntoIterator<Item = &'a (&'a <Self::G1Affine as CurveAffine>::Prepared, &'a <Self::G2Affine as CurveAffine>::Prepared)>;
106
107 fn final_exponentiation(r: &Self::Fqk) -> Option<Self::Fqk>;
109
110 fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
112 where
113 G1: Into<Self::G1Affine>,
114 G2: Into<Self::G2Affine>,
115 {
116 Self::final_exponentiation(&Self::miller_loop([(&(p.into().prepare()), &(q.into().prepare()))].iter())).unwrap()
117 }
118}
119
120pub trait CurveProjective: PartialEq + Eq + Sized + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + ff::Rand + 'static {
123 type Engine: Engine<Fr = Self::Scalar>;
124 type Scalar: PrimeField + SqrtField;
125 type Base: SqrtField;
126 type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar, Base = Self::Base>;
127
128 fn zero() -> Self;
130
131 fn one() -> Self;
133
134 fn is_zero(&self) -> bool;
136
137 fn batch_normalization(v: &mut [Self]);
140
141 fn is_normalized(&self) -> bool;
144
145 fn double(&mut self);
147
148 fn add_assign(&mut self, other: &Self);
150
151 fn sub_assign(&mut self, other: &Self) {
153 let mut tmp = *other;
154 tmp.negate();
155 self.add_assign(&tmp);
156 }
157
158 fn add_assign_mixed(&mut self, other: &Self::Affine);
160
161 fn negate(&mut self);
163
164 fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S);
166
167 fn into_affine(&self) -> Self::Affine;
169
170 fn recommended_wnaf_for_scalar(scalar: <Self::Scalar as PrimeField>::Repr) -> usize;
173
174 fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
177
178 fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) {
181 unimplemented!("default implementation does not exist for this function")
182 }
183
184 fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) {
187 unimplemented!("default implementation does not exist for this function")
188 }
189
190 fn from_xyz_unchecked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Self {
193 unimplemented!("default implementation does not exist for this function")
194 }
195
196 fn from_xyz_checked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Result<Self, GroupDecodingError> {
199 unimplemented!("default implementation does not exist for this function")
200 }
201}
202
203pub trait CurveAffine: Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static + serde::Serialize + serde::de::DeserializeOwned {
206 type Engine: Engine<Fr = Self::Scalar>;
207 type Scalar: PrimeField + SqrtField;
208 type Base: SqrtField;
209 type Projective: CurveProjective<Affine = Self, Scalar = Self::Scalar, Base = Self::Base>;
210 type Prepared: Clone + Send + Sync + 'static;
211 type Uncompressed: EncodedPoint<Affine = Self>;
212 type Compressed: EncodedPoint<Affine = Self>;
213 type Pair: CurveAffine<Pair = Self>;
214 type PairingResult: Field;
215
216 fn zero() -> Self;
218
219 fn one() -> Self;
221
222 fn is_zero(&self) -> bool;
225
226 fn negate(&mut self);
228
229 fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective;
231
232 fn prepare(&self) -> Self::Prepared;
234
235 fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
237
238 fn into_projective(&self) -> Self::Projective;
240
241 fn into_compressed(&self) -> Self::Compressed {
244 <Self::Compressed as EncodedPoint>::from_affine(*self)
245 }
246
247 fn into_uncompressed(&self) -> Self::Uncompressed {
250 <Self::Uncompressed as EncodedPoint>::from_affine(*self)
251 }
252
253 fn as_xy(&self) -> (&Self::Base, &Self::Base);
256
257 fn into_xy_unchecked(self) -> (Self::Base, Self::Base);
260
261 fn from_xy_unchecked(x: Self::Base, y: Self::Base) -> Self;
264
265 fn from_xy_checked(x: Self::Base, y: Self::Base) -> Result<Self, GroupDecodingError>;
268
269 fn a_coeff() -> Self::Base;
271
272 fn b_coeff() -> Self::Base;
274}
275
276pub trait RawEncodable: CurveAffine {
277 fn into_raw_uncompressed_le(&self) -> Self::Uncompressed;
280
281 fn from_raw_uncompressed_le_unchecked(encoded: &Self::Uncompressed, infinity: bool) -> Result<Self, GroupDecodingError>;
283
284 fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, infinity: bool) -> Result<Self, GroupDecodingError>;
286}
287
288pub trait EncodedPoint: Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static {
290 type Affine: CurveAffine;
291
292 fn empty() -> Self;
294
295 fn size() -> usize;
297
298 fn into_affine(&self) -> Result<Self::Affine, GroupDecodingError>;
301
302 fn into_affine_unchecked(&self) -> Result<Self::Affine, GroupDecodingError>;
310
311 fn from_affine(affine: Self::Affine) -> Self;
314}
315
316#[derive(Debug)]
318pub enum GroupDecodingError {
319 NotOnCurve,
321 NotInSubgroup,
323 CoordinateDecodingError(&'static str, PrimeFieldDecodingError),
325 UnexpectedCompressionMode,
327 UnexpectedInformation,
329}
330
331impl GroupDecodingError {
332 fn self_description(&self) -> &str {
333 match *self {
334 GroupDecodingError::NotOnCurve => "coordinate(s) do not lie on the curve",
335 GroupDecodingError::NotInSubgroup => "the element is not part of an r-order subgroup",
336 GroupDecodingError::CoordinateDecodingError(..) => "coordinate(s) could not be decoded",
337 GroupDecodingError::UnexpectedCompressionMode => "encoding has unexpected compression mode",
338 GroupDecodingError::UnexpectedInformation => "encoding has unexpected information",
339 }
340 }
341}
342
343impl Error for GroupDecodingError {
344 fn description(&self) -> &str {
345 self.self_description()
346 }
347}
348
349impl fmt::Display for GroupDecodingError {
350 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
351 match *self {
352 GroupDecodingError::CoordinateDecodingError(description, ref err) => {
353 write!(f, "{} decoding error: {}", description, err)
354 }
355 _ => write!(f, "{}", self.self_description()),
356 }
357 }
358}