1#![cfg_attr(feature = "cargo-clippy", deny(warnings))]
5#![cfg_attr(feature = "cargo-clippy", allow(clippy::inline_always))]
6#![cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))]
7#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))]
8#![cfg_attr(feature = "cargo-clippy", allow(clippy::many_single_char_names))]
9#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
10#![cfg_attr(feature = "cargo-clippy", allow(clippy::write_literal))]
11#![cfg_attr(feature = "cargo-clippy", allow(clippy::missing_safety_doc))]
12#![cfg_attr(feature = "cargo-clippy", allow(clippy::cognitive_complexity))]
13#![deny(missing_debug_implementations)]
15
16extern crate digest;
17extern crate ff_zeroize as ff;
18extern crate rand_core;
19extern crate rand_xorshift;
20#[cfg(test)]
21extern crate sha2;
22#[cfg(test)]
23extern crate sha3;
24#[macro_use]
25extern crate zeroize;
26
27#[cfg(test)]
28pub mod tests;
29
30pub mod bls12_381;
31pub mod hash_to_curve;
32pub mod hash_to_field;
33pub mod serdes;
34pub mod signum;
35
36mod wnaf;
37pub use self::wnaf::Wnaf;
38
39use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, ScalarEngine, SqrtField};
40use std::error::Error;
41use std::fmt;
42
43pub trait Engine: ScalarEngine {
47 type G1: CurveProjective<Engine = Self, Base = Self::Fq, Scalar = Self::Fr, Affine = Self::G1Affine>
49 + From<Self::G1Affine>;
50
51 type G1Affine: CurveAffine<
53 Engine = Self,
54 Base = Self::Fq,
55 Scalar = Self::Fr,
56 Projective = Self::G1,
57 Pair = Self::G2Affine,
58 PairingResult = Self::Fqk,
59 > + From<Self::G1>;
60
61 type G2: CurveProjective<Engine = Self, Base = Self::Fqe, Scalar = Self::Fr, Affine = Self::G2Affine>
63 + From<Self::G2Affine>;
64
65 type G2Affine: CurveAffine<
67 Engine = Self,
68 Base = Self::Fqe,
69 Scalar = Self::Fr,
70 Projective = Self::G2,
71 Pair = Self::G1Affine,
72 PairingResult = Self::Fqk,
73 > + From<Self::G2>;
74
75 type Fq: PrimeField + SqrtField;
77
78 type Fqe: SqrtField;
80
81 type Fqk: Field;
83
84 fn miller_loop<'a, I>(i: I) -> Self::Fqk
86 where
87 I: IntoIterator<
88 Item = &'a (
89 &'a <Self::G1Affine as CurveAffine>::Prepared,
90 &'a <Self::G2Affine as CurveAffine>::Prepared,
91 ),
92 >;
93
94 fn final_exponentiation(&Self::Fqk) -> Option<Self::Fqk>;
96
97 fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
99 where
100 G1: Into<Self::G1Affine>,
101 G2: Into<Self::G2Affine>,
102 {
103 Self::final_exponentiation(&Self::miller_loop(
104 [(&(p.into().prepare()), &(q.into().prepare()))].iter(),
105 ))
106 .unwrap()
107 }
108
109 fn pairing_product<G1, G2>(p1: G1, q1: G2, p2: G1, q2: G2) -> Self::Fqk
111 where
112 G1: Into<Self::G1Affine>,
113 G2: Into<Self::G2Affine>,
114 {
115 Self::final_exponentiation(&Self::miller_loop(
116 [
117 (&(p1.into().prepare()), &(q1.into().prepare())),
118 (&(p2.into().prepare()), &(q2.into().prepare())),
119 ]
120 .iter(),
121 ))
122 .unwrap()
123 }
124
125 fn pairing_multi_product(p: &[Self::G1Affine], q: &[Self::G2Affine]) -> Self::Fqk {
127 let prep_p: Vec<<Self::G1Affine as CurveAffine>::Prepared> =
128 p.iter().map(|v| v.prepare()).collect();
129 let prep_q: Vec<<Self::G2Affine as CurveAffine>::Prepared> =
130 q.iter().map(|v| v.prepare()).collect();
131 let mut pairs = Vec::with_capacity(p.len());
132 for i in 0..p.len() {
133 pairs.push((&prep_p[i], &prep_q[i]));
134 }
135 let t = Self::miller_loop(&pairs);
136 Self::final_exponentiation(&t).unwrap()
137 }
138}
139
140pub trait CurveProjective:
143 PartialEq
144 + Eq
145 + Sized
146 + Copy
147 + Clone
148 + Send
149 + Sync
150 + fmt::Debug
151 + fmt::Display
152+ 'static
154{
155 type Engine: Engine<Fr = Self::Scalar>;
156 type Scalar: PrimeField + SqrtField;
157 type Base: SqrtField;
158 type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>;
159
160 fn random<R: rand_core::RngCore>(rng: &mut R)-> Self;
162
163 fn zero() -> Self;
165
166 fn one() -> Self;
168
169 fn is_zero(&self) -> bool;
171
172 fn batch_normalization(v: &mut [Self]);
175
176 fn is_normalized(&self) -> bool;
179
180 fn double(&mut self);
182
183 fn add_assign(&mut self, other: &Self);
185
186 fn sub_assign(&mut self, other: &Self) {
188 let mut tmp = *other;
189 tmp.negate();
190 self.add_assign(&tmp);
191 }
192
193 fn add_assign_mixed(&mut self, other: &Self::Affine);
195
196 fn sub_assign_mixed(&mut self, other: &Self::Affine) {
198 let mut tmp = *other;
199 tmp.negate();
200 self.add_assign_mixed(&tmp);
201 }
202
203 fn negate(&mut self);
205
206 fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S);
208
209 fn into_affine(&self) -> Self::Affine;
211
212 fn recommended_wnaf_for_scalar(scalar: <Self::Scalar as PrimeField>::Repr) -> usize;
215
216 fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
219
220 fn as_tuple(&self) -> (&Self::Base, &Self::Base, &Self::Base);
222
223 unsafe fn as_tuple_mut(&mut self) -> (&mut Self::Base, &mut Self::Base, &mut Self::Base);
227
228 }
237
238pub trait CurveAffine:
241 Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static
242{
243 type Engine: Engine<Fr = Self::Scalar>;
244 type Scalar: PrimeField + SqrtField;
245 type Base: SqrtField;
246 type Projective: CurveProjective<Affine = Self, Scalar = Self::Scalar>;
247 type Prepared: Clone + Send + Sync + 'static;
248 type Uncompressed: EncodedPoint<Affine = Self>;
249 type Compressed: EncodedPoint<Affine = Self>;
250 type Pair: CurveAffine<Pair = Self>;
251 type PairingResult: Field;
252
253 fn zero() -> Self;
255
256 fn one() -> Self;
258
259 fn is_zero(&self) -> bool;
262
263 fn negate(&mut self);
265
266 fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective;
268
269 fn prepare(&self) -> Self::Prepared;
271
272 fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
274
275 fn into_projective(&self) -> Self::Projective;
277
278 fn into_compressed(&self) -> Self::Compressed {
281 <Self::Compressed as EncodedPoint>::from_affine(*self)
282 }
283
284 fn into_uncompressed(&self) -> Self::Uncompressed {
287 <Self::Uncompressed as EncodedPoint>::from_affine(*self)
288 }
289
290 fn as_tuple(&self) -> (&Self::Base, &Self::Base);
292
293 unsafe fn as_tuple_mut(&mut self) -> (&mut Self::Base, &mut Self::Base);
297
298 fn sum_of_products(bases: &[Self], scalars: &[&[u64; 4]]) -> Self::Projective;
304
305 fn find_pippinger_window(num_components: usize) -> usize;
307
308 fn find_pippinger_window_via_estimate(num_components: usize) -> usize;
310
311 fn sum_of_products_pippinger(
314 bases: &[Self],
315 scalars: &[&[u64; 4]],
316 window: usize,
317 ) -> Self::Projective;
318
319 fn sum_of_products_precomp_256(
323 bases: &[Self],
324 scalars: &[&[u64; 4]],
325 pre: &[Self],
326 ) -> Self::Projective;
327
328 fn precomp_3(&self, pre: &mut [Self]);
330
331 fn mul_precomp_3<S: Into<<Self::Scalar as PrimeField>::Repr>>(
334 &self,
335 other: S,
336 pre: &[Self],
337 ) -> Self::Projective;
338
339 fn precomp_256(&self, pre: &mut [Self]);
341
342 fn mul_precomp_256<S: Into<<Self::Scalar as PrimeField>::Repr>>(
345 &self,
346 other: S,
347 pre: &[Self],
348 ) -> Self::Projective;
349}
350
351pub trait EncodedPoint:
353 Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static
354{
355 type Affine: CurveAffine;
356
357 fn empty() -> Self;
359
360 fn size() -> usize;
362
363 fn into_affine(&self) -> Result<Self::Affine, GroupDecodingError>;
366
367 fn into_affine_unchecked(&self) -> Result<Self::Affine, GroupDecodingError>;
375
376 fn from_affine(affine: Self::Affine) -> Self;
379}
380
381pub trait SubgroupCheck {
382 fn in_subgroup(&self) -> bool;
385}
386
387#[derive(Debug)]
389pub enum GroupDecodingError {
390 NotOnCurve,
392 NotInSubgroup,
394 CoordinateDecodingError(&'static str, PrimeFieldDecodingError),
396 UnexpectedCompressionMode,
398 UnexpectedInformation,
400}
401
402impl Error for GroupDecodingError {
403 fn description(&self) -> &str {
404 match *self {
405 GroupDecodingError::NotOnCurve => "coordinate(s) do not lie on the curve",
406 GroupDecodingError::NotInSubgroup => "the element is not part of an r-order subgroup",
407 GroupDecodingError::CoordinateDecodingError(..) => "coordinate(s) could not be decoded",
408 GroupDecodingError::UnexpectedCompressionMode => {
409 "encoding has unexpected compression mode"
410 }
411 GroupDecodingError::UnexpectedInformation => "encoding has unexpected information",
412 }
413 }
414}
415
416impl fmt::Display for GroupDecodingError {
417 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
418 match *self {
419 GroupDecodingError::CoordinateDecodingError(description, ref err) => {
420 write!(f, "{} decoding error: {}", description, err)
421 }
422 _ => write!(f, "{}", self.to_string()),
423 }
424 }
425}