fawkes_crypto_pairing_ce/
lib.rs1#![cfg_attr(feature = "cargo-clippy", deny(warnings))]
5#![deny(missing_debug_implementations)]
13
14extern crate byteorder;
15extern crate rand;
16
17#[cfg(test)]
18pub mod tests;
19
20pub extern crate ff;
21
22pub use ff::*;
23
24pub mod bls12_381;
25pub mod bn256;
26
27mod wnaf;
28pub use self::wnaf::Wnaf;
29
30use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, ScalarEngine, SqrtField};
31use std::error::Error;
32use std::fmt;
33
34pub trait Engine: ScalarEngine {
38 type G1: CurveProjective<
40 Engine = Self,
41 Base = Self::Fq,
42 Scalar = Self::Fr,
43 Affine = Self::G1Affine,
44 >
45 + From<Self::G1Affine>;
46
47 type G1Affine: CurveAffine<
49 Engine = Self,
50 Base = Self::Fq,
51 Scalar = Self::Fr,
52 Projective = Self::G1,
53 Pair = Self::G2Affine,
54 PairingResult = Self::Fqk,
55 >
56 + From<Self::G1> + RawEncodable;
57
58 type G2: CurveProjective<
60 Engine = Self,
61 Base = Self::Fqe,
62 Scalar = Self::Fr,
63 Affine = Self::G2Affine,
64 >
65 + From<Self::G2Affine>;
66
67 type G2Affine: CurveAffine<
69 Engine = Self,
70 Base = Self::Fqe,
71 Scalar = Self::Fr,
72 Projective = Self::G2,
73 Pair = Self::G1Affine,
74 PairingResult = Self::Fqk,
75 >
76 + From<Self::G2> + RawEncodable;
77
78 type Fq: PrimeField + SqrtField;
80
81 type Fqe: SqrtField;
83
84 type Fqk: Field;
86
87 fn miller_loop<'a, I>(i: I) -> Self::Fqk
89 where
90 I: IntoIterator<
91 Item = &'a (
92 &'a <Self::G1Affine as CurveAffine>::Prepared,
93 &'a <Self::G2Affine as CurveAffine>::Prepared,
94 ),
95 >;
96
97 fn final_exponentiation(r: &Self::Fqk) -> Option<Self::Fqk>;
99
100 fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
102 where
103 G1: Into<Self::G1Affine>,
104 G2: Into<Self::G2Affine>,
105 {
106 Self::final_exponentiation(&Self::miller_loop(
107 [(&(p.into().prepare()), &(q.into().prepare()))].iter(),
108 )).unwrap()
109 }
110}
111
112pub trait CurveProjective:
115 PartialEq
116 + Eq
117 + Sized
118 + Copy
119 + Clone
120 + Send
121 + Sync
122 + fmt::Debug
123 + fmt::Display
124 + rand::Rand
125 + 'static
126{
127 type Engine: Engine<Fr = Self::Scalar>;
128 type Scalar: PrimeField + SqrtField;
129 type Base: SqrtField;
130 type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>;
131
132 fn zero() -> Self;
134
135 fn one() -> Self;
137
138 fn is_zero(&self) -> bool;
140
141 fn batch_normalization(v: &mut [Self]);
144
145 fn is_normalized(&self) -> bool;
148
149 fn double(&mut self);
151
152 fn add_assign(&mut self, other: &Self);
154
155 fn sub_assign(&mut self, other: &Self) {
157 let mut tmp = *other;
158 tmp.negate();
159 self.add_assign(&tmp);
160 }
161
162 fn add_assign_mixed(&mut self, other: &Self::Affine);
164
165 fn negate(&mut self);
167
168 fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S);
170
171 fn into_affine(&self) -> Self::Affine;
173
174 fn recommended_wnaf_for_scalar(scalar: <Self::Scalar as PrimeField>::Repr) -> usize;
177
178 fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
181}
182
183pub trait CurveAffine:
186 Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static
187{
188 type Engine: Engine<Fr = Self::Scalar>;
189 type Scalar: PrimeField + SqrtField;
190 type Base: SqrtField;
191 type Projective: CurveProjective<Affine = Self, Scalar = Self::Scalar>;
192 type Prepared: Clone + Send + Sync + 'static;
193 type Uncompressed: EncodedPoint<Affine = Self>;
194 type Compressed: EncodedPoint<Affine = Self>;
195 type Pair: CurveAffine<Pair = Self>;
196 type PairingResult: Field;
197
198 fn zero() -> Self;
200
201 fn one() -> Self;
203
204 fn is_zero(&self) -> bool;
207
208 fn negate(&mut self);
210
211 fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective;
213
214 fn prepare(&self) -> Self::Prepared;
216
217 fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
219
220 fn into_projective(&self) -> Self::Projective;
222
223 fn into_compressed(&self) -> Self::Compressed {
226 <Self::Compressed as EncodedPoint>::from_affine(*self)
227 }
228
229 fn into_uncompressed(&self) -> Self::Uncompressed {
232 <Self::Uncompressed as EncodedPoint>::from_affine(*self)
233 }
234}
235
236pub trait RawEncodable: CurveAffine {
237 fn into_raw_uncompressed_le(&self) -> Self::Uncompressed;
240
241 fn from_raw_uncompressed_le_unchecked(encoded: &Self::Uncompressed, infinity: bool) -> Result<Self, GroupDecodingError>;
243
244 fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, infinity: bool) -> Result<Self, GroupDecodingError>;
246}
247
248pub trait EncodedPoint:
250 Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static
251{
252 type Affine: CurveAffine;
253
254 fn empty() -> Self;
256
257 fn size() -> usize;
259
260 fn into_affine(&self) -> Result<Self::Affine, GroupDecodingError>;
263
264 fn into_affine_unchecked(&self) -> Result<Self::Affine, GroupDecodingError>;
272
273 fn from_affine(affine: Self::Affine) -> Self;
276}
277
278#[derive(Debug)]
280pub enum GroupDecodingError {
281 NotOnCurve,
283 NotInSubgroup,
285 CoordinateDecodingError(&'static str, PrimeFieldDecodingError),
287 UnexpectedCompressionMode,
289 UnexpectedInformation,
291}
292
293impl Error for GroupDecodingError {
294 fn description(&self) -> &str {
295 match *self {
296 GroupDecodingError::NotOnCurve => "coordinate(s) do not lie on the curve",
297 GroupDecodingError::NotInSubgroup => "the element is not part of an r-order subgroup",
298 GroupDecodingError::CoordinateDecodingError(..) => "coordinate(s) could not be decoded",
299 GroupDecodingError::UnexpectedCompressionMode => {
300 "encoding has unexpected compression mode"
301 }
302 GroupDecodingError::UnexpectedInformation => "encoding has unexpected information",
303 }
304 }
305}
306
307impl fmt::Display for GroupDecodingError {
308 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
309 match *self {
310 GroupDecodingError::CoordinateDecodingError(description, ref err) => {
311 write!(f, "{} decoding error: {}", description, err)
312 }
313 _ => write!(f, "{}", self.to_string()),
314 }
315 }
316}