pairing_ce/bls12_381/
mod.rs1mod ec;
2pub mod fq;
3pub mod fq12;
4pub mod fq2;
5pub mod fq6;
6pub mod fr;
7
8#[cfg(test)]
9mod tests;
10
11pub use self::ec::{
12 G1, G1Affine, G1Compressed, G1Prepared, G1Uncompressed, G2, G2Affine, G2Compressed, G2Prepared,
13 G2Uncompressed,
14};
15pub use self::fq::{Fq, FqRepr};
16pub use self::fq12::Fq12;
17pub use self::fq2::Fq2;
18pub use self::fq6::Fq6;
19pub use self::fr::{Fr, FrRepr};
20
21use super::{CurveAffine, Engine};
22
23use ff::{BitIterator, Field, ScalarEngine};
24
25const BLS_X: u64 = 0xd201000000010000;
27const BLS_X_IS_NEGATIVE: bool = true;
28
29#[derive(Clone, Copy, Debug)]
30pub struct Bls12;
31
32impl ScalarEngine for Bls12 {
33 type Fr = Fr;
34}
35
36impl Engine for Bls12 {
37 type G1 = G1;
38 type G1Affine = G1Affine;
39 type G2 = G2;
40 type G2Affine = G2Affine;
41 type Fq = Fq;
42 type Fqe = Fq2;
43 type Fqk = Fq12;
44
45 fn miller_loop<'a, I>(i: I) -> Self::Fqk
46 where
47 I: IntoIterator<
48 Item = &'a (
49 &'a <Self::G1Affine as CurveAffine>::Prepared,
50 &'a <Self::G2Affine as CurveAffine>::Prepared,
51 ),
52 >,
53 {
54 let mut pairs = vec![];
55 for &(p, q) in i {
56 if !p.is_zero() && !q.is_zero() {
57 pairs.push((p, q.coeffs.iter()));
58 }
59 }
60
61 fn ell(f: &mut Fq12, coeffs: &(Fq2, Fq2, Fq2), p: &G1Affine) {
63 let mut c0 = coeffs.0;
64 let mut c1 = coeffs.1;
65
66 c0.c0.mul_assign(&p.y);
67 c0.c1.mul_assign(&p.y);
68
69 c1.c0.mul_assign(&p.x);
70 c1.c1.mul_assign(&p.x);
71
72 f.mul_by_014(&coeffs.2, &c1, &c0);
74 }
75
76 let mut f = Fq12::one();
77
78 let mut found_one = false;
79 for i in BitIterator::new(&[BLS_X >> 1]) {
80 if !found_one {
81 found_one = i;
82 continue;
83 }
84
85 for &mut (p, ref mut coeffs) in &mut pairs {
86 ell(&mut f, coeffs.next().unwrap(), &p.0);
87 }
88
89 if i {
90 for &mut (p, ref mut coeffs) in &mut pairs {
91 ell(&mut f, coeffs.next().unwrap(), &p.0);
92 }
93 }
94
95 f.square();
96 }
97
98 for &mut (p, ref mut coeffs) in &mut pairs {
99 ell(&mut f, coeffs.next().unwrap(), &p.0);
100 }
101
102 if BLS_X_IS_NEGATIVE {
103 f.conjugate();
104 }
105
106 f
107 }
108
109 fn final_exponentiation(r: &Fq12) -> Option<Fq12> {
110 let mut f1 = *r;
111 f1.conjugate();
112
113 match r.inverse() {
114 Some(mut f2) => {
115 let mut r = f1;
116 r.mul_assign(&f2);
117 f2 = r;
118 r.frobenius_map(2);
119 r.mul_assign(&f2);
120
121 fn exp_by_x(f: &mut Fq12, x: u64) {
122 *f = f.pow(&[x]);
123 if BLS_X_IS_NEGATIVE {
124 f.conjugate();
125 }
126 }
127
128 let mut x = BLS_X;
129 let mut y0 = r;
130 y0.square();
131 let mut y1 = y0;
132 exp_by_x(&mut y1, x);
133 x >>= 1;
134 let mut y2 = y1;
135 exp_by_x(&mut y2, x);
136 x <<= 1;
137 let mut y3 = r;
138 y3.conjugate();
139 y1.mul_assign(&y3);
140 y1.conjugate();
141 y1.mul_assign(&y2);
142 y2 = y1;
143 exp_by_x(&mut y2, x);
144 y3 = y2;
145 exp_by_x(&mut y3, x);
146 y1.conjugate();
147 y3.mul_assign(&y1);
148 y1.conjugate();
149 y1.frobenius_map(3);
150 y2.frobenius_map(2);
151 y1.mul_assign(&y2);
152 y2 = y3;
153 exp_by_x(&mut y2, x);
154 y2.mul_assign(&y0);
155 y2.mul_assign(&r);
156 y1.mul_assign(&y2);
157 y2 = y3;
158 y2.frobenius_map(1);
159 y1.mul_assign(&y2);
160
161 Some(y1)
162 }
163 None => None,
164 }
165 }
166}
167
168impl G2Prepared {
169 pub fn is_zero(&self) -> bool {
170 self.infinity
171 }
172
173 pub fn from_affine(q: G2Affine) -> Self {
174 if q.is_zero() {
175 return G2Prepared {
176 coeffs: vec![],
177 infinity: true,
178 };
179 }
180
181 fn doubling_step(r: &mut G2) -> (Fq2, Fq2, Fq2) {
182 let mut tmp0 = r.x;
184 tmp0.square();
185
186 let mut tmp1 = r.y;
187 tmp1.square();
188
189 let mut tmp2 = tmp1;
190 tmp2.square();
191
192 let mut tmp3 = tmp1;
193 tmp3.add_assign(&r.x);
194 tmp3.square();
195 tmp3.sub_assign(&tmp0);
196 tmp3.sub_assign(&tmp2);
197 tmp3.double();
198
199 let mut tmp4 = tmp0;
200 tmp4.double();
201 tmp4.add_assign(&tmp0);
202
203 let mut tmp6 = r.x;
204 tmp6.add_assign(&tmp4);
205
206 let mut tmp5 = tmp4;
207 tmp5.square();
208
209 let mut zsquared = r.z;
210 zsquared.square();
211
212 r.x = tmp5;
213 r.x.sub_assign(&tmp3);
214 r.x.sub_assign(&tmp3);
215
216 r.z.add_assign(&r.y);
217 r.z.square();
218 r.z.sub_assign(&tmp1);
219 r.z.sub_assign(&zsquared);
220
221 r.y = tmp3;
222 r.y.sub_assign(&r.x);
223 r.y.mul_assign(&tmp4);
224
225 tmp2.double();
226 tmp2.double();
227 tmp2.double();
228
229 r.y.sub_assign(&tmp2);
230
231 tmp3 = tmp4;
232 tmp3.mul_assign(&zsquared);
233 tmp3.double();
234 tmp3.negate();
235
236 tmp6.square();
237 tmp6.sub_assign(&tmp0);
238 tmp6.sub_assign(&tmp5);
239
240 tmp1.double();
241 tmp1.double();
242
243 tmp6.sub_assign(&tmp1);
244
245 tmp0 = r.z;
246 tmp0.mul_assign(&zsquared);
247 tmp0.double();
248
249 (tmp0, tmp3, tmp6)
250 }
251
252 fn addition_step(r: &mut G2, q: &G2Affine) -> (Fq2, Fq2, Fq2) {
253 let mut zsquared = r.z;
255 zsquared.square();
256
257 let mut ysquared = q.y;
258 ysquared.square();
259
260 let mut t0 = zsquared;
261 t0.mul_assign(&q.x);
262
263 let mut t1 = q.y;
264 t1.add_assign(&r.z);
265 t1.square();
266 t1.sub_assign(&ysquared);
267 t1.sub_assign(&zsquared);
268 t1.mul_assign(&zsquared);
269
270 let mut t2 = t0;
271 t2.sub_assign(&r.x);
272
273 let mut t3 = t2;
274 t3.square();
275
276 let mut t4 = t3;
277 t4.double();
278 t4.double();
279
280 let mut t5 = t4;
281 t5.mul_assign(&t2);
282
283 let mut t6 = t1;
284 t6.sub_assign(&r.y);
285 t6.sub_assign(&r.y);
286
287 let mut t9 = t6;
288 t9.mul_assign(&q.x);
289
290 let mut t7 = t4;
291 t7.mul_assign(&r.x);
292
293 r.x = t6;
294 r.x.square();
295 r.x.sub_assign(&t5);
296 r.x.sub_assign(&t7);
297 r.x.sub_assign(&t7);
298
299 r.z.add_assign(&t2);
300 r.z.square();
301 r.z.sub_assign(&zsquared);
302 r.z.sub_assign(&t3);
303
304 let mut t10 = q.y;
305 t10.add_assign(&r.z);
306
307 let mut t8 = t7;
308 t8.sub_assign(&r.x);
309 t8.mul_assign(&t6);
310
311 t0 = r.y;
312 t0.mul_assign(&t5);
313 t0.double();
314
315 r.y = t8;
316 r.y.sub_assign(&t0);
317
318 t10.square();
319 t10.sub_assign(&ysquared);
320
321 let mut ztsquared = r.z;
322 ztsquared.square();
323
324 t10.sub_assign(&ztsquared);
325
326 t9.double();
327 t9.sub_assign(&t10);
328
329 t10 = r.z;
330 t10.double();
331
332 t6.negate();
333
334 t1 = t6;
335 t1.double();
336
337 (t10, t1, t9)
338 }
339
340 let mut coeffs = vec![];
341 let mut r: G2 = q.into();
342
343 let mut found_one = false;
344 for i in BitIterator::new([BLS_X >> 1]) {
345 if !found_one {
346 found_one = i;
347 continue;
348 }
349
350 coeffs.push(doubling_step(&mut r));
351
352 if i {
353 coeffs.push(addition_step(&mut r, &q));
354 }
355 }
356
357 coeffs.push(doubling_step(&mut r));
358
359 G2Prepared {
360 coeffs,
361 infinity: false,
362 }
363 }
364}
365
366#[test]
367fn bls12_engine_tests() {
368 crate::tests::engine::engine_tests::<Bls12>();
369}
370
371#[test]
372fn bbb() {
373 let shifting = BLS_X >>1;
374 println!("{}", shifting);
375}