1use crate::bls12381::big;
21use crate::bls12381::big::BIG;
22use crate::bls12381::ecp;
23use crate::bls12381::fp2::FP2;
24use crate::bls12381::rom;
25use crate::bls12381::fp;
26use crate::bls12381::fp::FP;
27use crate::bls12381::dbig::DBIG;
28
29#[derive(Clone)]
30pub struct ECP2 {
31 x: FP2,
32 y: FP2,
33 z: FP2,
34}
35
36#[cfg(feature = "std")]
37impl std::fmt::Debug for ECP2 {
38 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
39 write!(formatter, "{}", self.tostring())
40 }
41}
42
43#[cfg(feature = "std")]
44impl std::fmt::Display for ECP2 {
45 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
46 write!(formatter, "{}", self.tostring())
47 }
48}
49
50#[allow(non_snake_case)]
51impl ECP2 {
52 pub fn new() -> ECP2 {
53 ECP2 {
54 x: FP2::new(),
55 y: FP2::new_int(1),
56 z: FP2::new(),
57 }
58 }
59 #[allow(non_snake_case)]
60 pub fn new_fp2s(ix: &FP2, iy: &FP2) -> ECP2 {
62 let mut E = ECP2::new();
63 E.x.copy(&ix);
64 E.y.copy(&iy);
65 E.z.one();
66 E.x.norm();
67
68 let rhs = ECP2::rhs(&E.x);
69 let mut y2 = FP2::new_copy(&E.y);
70 y2.sqr();
71 if !y2.equals(&rhs) {
72 E.inf();
73 }
74 E
75 }
76
77 pub fn new_fp2(ix: &FP2, s:isize) -> ECP2 {
79 let mut E = ECP2::new();
80 let mut h = FP::new();
81 E.x.copy(&ix);
82 E.y.one();
83 E.z.one();
84 E.x.norm();
85 let mut rhs = ECP2::rhs(&E.x);
86 if rhs.qr(Some(&mut h)) == 1 {
87 rhs.sqrt(Some(&h));
88 if rhs.sign() != s {
89 rhs.neg();
90 }
91 rhs.reduce();
92 E.y.copy(&rhs);
93 } else {
94 E.inf();
95 }
96 E
97 }
98
99 pub fn is_infinity(&self) -> bool {
101 self.x.iszilch() && self.z.iszilch()
102 }
103
104 pub fn copy(&mut self, P: &ECP2) {
106 self.x.copy(&P.x);
107 self.y.copy(&P.y);
108 self.z.copy(&P.z);
109 }
110
111 pub fn inf(&mut self) {
113 self.x.zero();
114 self.y.one();
115 self.z.zero();
116 }
117
118 pub fn neg(&mut self) {
120 self.y.norm();
121 self.y.neg();
122 self.y.norm();
123 }
124
125 pub fn cmove(&mut self, Q: &ECP2, d: isize) {
127 self.x.cmove(&Q.x, d);
128 self.y.cmove(&Q.y, d);
129 self.z.cmove(&Q.z, d);
130 }
131
132 fn teq(b: i32, c: i32) -> isize {
134 let mut x = b ^ c;
135 x -= 1; ((x >> 31) & 1) as isize
137 }
138
139 pub fn selector(&mut self, W: &[ECP2], b: i32) {
141 let mut MP = ECP2::new();
142 let m = b >> 31;
143 let mut babs = (b ^ m) - m;
144
145 babs = (babs - 1) / 2;
146
147 self.cmove(&W[0], ECP2::teq(babs, 0)); self.cmove(&W[1], ECP2::teq(babs, 1));
149 self.cmove(&W[2], ECP2::teq(babs, 2));
150 self.cmove(&W[3], ECP2::teq(babs, 3));
151 self.cmove(&W[4], ECP2::teq(babs, 4));
152 self.cmove(&W[5], ECP2::teq(babs, 5));
153 self.cmove(&W[6], ECP2::teq(babs, 6));
154 self.cmove(&W[7], ECP2::teq(babs, 7));
155
156 MP.copy(self);
157 MP.neg();
158 self.cmove(&MP, (m & 1) as isize);
159 }
160
161 pub fn equals(&self, Q: &ECP2) -> bool {
163 let mut a = FP2::new_copy(&self.x);
164 let mut b = FP2::new_copy(&Q.x);
165
166 a.mul(&Q.z);
167 b.mul(&self.z);
168 if !a.equals(&b) {
169 return false;
170 }
171 a.copy(&self.y);
172 a.mul(&Q.z);
173 b.copy(&Q.y);
174 b.mul(&self.z);
175 if !a.equals(&b) {
176 return false;
177 }
178
179 true
180 }
181
182 pub fn affine(&mut self) {
184 if self.is_infinity() {
185 return;
186 }
187 let one = FP2::new_int(1);
188 if self.z.equals(&one) {
189 return;
190 }
191 self.z.inverse(None);
192
193 self.x.mul(&self.z);
194 self.x.reduce();
195 self.y.mul(&self.z);
196 self.y.reduce();
197 self.z.copy(&one);
198 }
199
200 pub fn getx(&self) -> FP2 {
202 let mut W = ECP2::new();
203 W.copy(self);
204 W.affine();
205 FP2::new_copy(&W.x)
206 }
207
208 pub fn gety(&self) -> FP2 {
210 let mut W = ECP2::new();
211 W.copy(self);
212 W.affine();
213 FP2::new_copy(&W.y)
214 }
215
216 pub fn getpx(&self) -> FP2 {
218 FP2::new_copy(&self.x)
219 }
220 pub fn getpy(&self) -> FP2 {
222 FP2::new_copy(&self.y)
223 }
224 pub fn getpz(&self) -> FP2 {
226 FP2::new_copy(&self.z)
227 }
228
229 pub fn tobytes(&self, b: &mut [u8], compress: bool) {
231 const MB:usize = 2*(big::MODBYTES as usize);
232 let mut t: [u8; MB] = [0; MB];
233 let mut alt=false;
234 let mut W = ECP2::new();
235 W.copy(self);
236 W.affine();
237 W.x.tobytes(&mut t);
238
239 if (fp::MODBITS-1)%8 <= 4 && ecp::ALLOW_ALT_COMPRESS {
240 alt=true;
241 }
242 if alt {
243 for i in 0..MB {
244 b[i]=t[i]
245 }
246 if !compress {
247 W.y.tobytes(&mut t);
248 for i in 0..MB {
249 b[i+MB]=t[i];
250 }
251 } else {
252 b[0]|=0x80;
253 if W.y.islarger()==1 {
254 b[0]|=0x20;
255 }
256 }
257
258 } else {
259 for i in 0..MB {
260 b[i+1]=t[i];
261 }
262 if !compress {
263 b[0]=0x04;
264 W.y.tobytes(&mut t);
265 for i in 0..MB {
266 b[i+MB+1]=t[i];
267 }
268 } else {
269 b[0]=0x02;
270 if W.y.sign() == 1 {
271 b[0]=0x03;
272 }
273 }
274 }
275 }
276
277 pub fn frombytes(b: &[u8]) -> ECP2 {
279 const MB:usize = 2*(big::MODBYTES as usize);
280 let mut t: [u8; MB] = [0; MB];
281 let typ=b[0] as isize;
282 let mut alt=false;
283
284 if (fp::MODBITS-1)%8 <= 4 && ecp::ALLOW_ALT_COMPRESS {
285 alt=true;
286 }
287
288 if alt {
289 for i in 0..MB {
290 t[i]=b[i];
291 }
292 t[0]&=0x1f;
293 let rx=FP2::frombytes(&t);
294 if (b[0]&0x80)==0 {
295 for i in 0..MB {
296 t[i]=b[i+MB];
297 }
298 let ry=FP2::frombytes(&t);
299 ECP2::new_fp2s(&rx,&ry)
300 } else {
301 let sgn=(b[0]&0x20)>>5;
302 let mut P=ECP2::new_fp2(&rx,0);
303 let cmp=P.y.islarger();
304 if (sgn == 1 && cmp != 1) || (sgn == 0 && cmp == 1) {
305 P.neg();
306 }
307 P
308 }
309 } else {
310 for i in 0..MB {
311 t[i]=b[i+1];
312 }
313 let rx=FP2::frombytes(&t);
314 if typ == 0x04 {
315 for i in 0..MB {
316 t[i]=b[i+MB+1];
317 }
318 let ry=FP2::frombytes(&t);
319 ECP2::new_fp2s(&rx,&ry)
320 } else {
321 ECP2::new_fp2(&rx,typ&1)
322 }
323 }
324 }
325
326 #[cfg(feature = "std")]
328 pub fn tostring(&self) -> String {
329 let mut W = ECP2::new();
330 W.copy(self);
331 W.affine();
332 if W.is_infinity() {
333 String::from("infinity")
334 } else {
335 format!("({},{})", W.x.tostring(), W.y.tostring())
336 }
337 }
338
339 pub fn rhs(x: &FP2) -> FP2 {
341 let mut r = FP2::new_copy(x);
342 r.sqr();
343 let mut b = FP2::new_big(&BIG::new_ints(&rom::CURVE_B));
344 if ecp::SEXTIC_TWIST == ecp::D_TYPE {
345 b.div_ip();
346 }
347 if ecp::SEXTIC_TWIST == ecp::M_TYPE {
348 b.norm();
349 b.mul_ip();
350 b.norm();
351 }
352
353 r.mul(x);
354 r.add(&b);
355
356 r.reduce();
357 r
358 }
359
360 pub fn dbl(&mut self) -> isize {
362 let mut iy = FP2::new_copy(&self.y);
363 if ecp::SEXTIC_TWIST == ecp::D_TYPE {
364 iy.mul_ip();
365 iy.norm();
366 }
367
368 let mut t0 = FP2::new_copy(&self.y); t0.sqr();
370 if ecp::SEXTIC_TWIST == ecp::D_TYPE {
371 t0.mul_ip();
372 }
373 let mut t1 = FP2::new_copy(&iy);
374 t1.mul(&self.z);
375 let mut t2 = FP2::new_copy(&self.z);
376 t2.sqr();
377
378 self.z.copy(&t0);
379 self.z.add(&t0);
380 self.z.norm();
381 self.z.dbl();
382 self.z.dbl();
383 self.z.norm();
384
385 t2.imul(3 * rom::CURVE_B_I);
386 if ecp::SEXTIC_TWIST == ecp::M_TYPE {
387 t2.mul_ip();
388 t2.norm();
389 }
390 let mut x3 = FP2::new_copy(&t2);
391 x3.mul(&self.z);
392
393 let mut y3 = FP2::new_copy(&t0);
394
395 y3.add(&t2);
396 y3.norm();
397 self.z.mul(&t1);
398 t1.copy(&t2);
399 t1.add(&t2);
400 t2.add(&t1);
401 t2.norm();
402 t0.sub(&t2);
403 t0.norm(); y3.mul(&t0);
405 y3.add(&x3); t1.copy(&self.x);
407 t1.mul(&iy); self.x.copy(&t0);
409 self.x.norm();
410 self.x.mul(&t1);
411 self.x.dbl(); self.x.norm();
414 self.y.copy(&y3);
415 self.y.norm();
416
417 1
418 }
419
420 pub fn add(&mut self, Q: &ECP2) -> isize {
422 let b = 3 * rom::CURVE_B_I;
423 let mut t0 = FP2::new_copy(&self.x);
424 t0.mul(&Q.x); let mut t1 = FP2::new_copy(&self.y);
426 t1.mul(&Q.y); let mut t2 = FP2::new_copy(&self.z);
429 t2.mul(&Q.z);
430 let mut t3 = FP2::new_copy(&self.x);
431 t3.add(&self.y);
432 t3.norm(); let mut t4 = FP2::new_copy(&Q.x);
434 t4.add(&Q.y);
435 t4.norm(); t3.mul(&t4); t4.copy(&t0);
438 t4.add(&t1); t3.sub(&t4);
441 t3.norm();
442 if ecp::SEXTIC_TWIST == ecp::D_TYPE {
443 t3.mul_ip();
444 t3.norm(); }
446 t4.copy(&self.y);
447 t4.add(&self.z);
448 t4.norm(); let mut x3 = FP2::new_copy(&Q.y);
450 x3.add(&Q.z);
451 x3.norm(); t4.mul(&x3); x3.copy(&t1); x3.add(&t2); t4.sub(&x3);
458 t4.norm();
459 if ecp::SEXTIC_TWIST == ecp::D_TYPE {
460 t4.mul_ip();
461 t4.norm(); }
463 x3.copy(&self.x);
464 x3.add(&self.z);
465 x3.norm(); let mut y3 = FP2::new_copy(&Q.x);
467 y3.add(&Q.z);
468 y3.norm(); x3.mul(&y3); y3.copy(&t0);
471 y3.add(&t2); y3.rsub(&x3);
473 y3.norm(); if ecp::SEXTIC_TWIST == ecp::D_TYPE {
476 t0.mul_ip();
477 t0.norm(); t1.mul_ip();
479 t1.norm(); }
481 x3.copy(&t0);
482 x3.add(&t0);
483 t0.add(&x3);
484 t0.norm();
485 t2.imul(b);
486 if ecp::SEXTIC_TWIST == ecp::M_TYPE {
487 t2.mul_ip();
488 t2.norm();
489 }
490 let mut z3 = FP2::new_copy(&t1);
491 z3.add(&t2);
492 z3.norm();
493 t1.sub(&t2);
494 t1.norm();
495 y3.imul(b);
496 if ecp::SEXTIC_TWIST == ecp::M_TYPE {
497 y3.mul_ip();
498 y3.norm();
499 }
500 x3.copy(&y3);
501 x3.mul(&t4);
502 t2.copy(&t3);
503 t2.mul(&t1);
504 x3.rsub(&t2);
505 y3.mul(&t0);
506 t1.mul(&z3);
507 y3.add(&t1);
508 t0.mul(&t3);
509 z3.mul(&t4);
510 z3.add(&t0);
511
512 self.x.copy(&x3);
513 self.x.norm();
514 self.y.copy(&y3);
515 self.y.norm();
516 self.z.copy(&z3);
517 self.z.norm();
518
519 0
520 }
521
522 pub fn sub(&mut self, Q: &ECP2) -> isize {
524 let mut NQ = ECP2::new();
525 NQ.copy(Q);
526 NQ.neg();
527 self.add(&NQ)
528 }
529
530 pub fn frob(&mut self, x: &FP2) {
532 let mut x2 = FP2::new_copy(x);
533 x2.sqr();
534 self.x.conj();
535 self.y.conj();
536 self.z.conj();
537 self.z.reduce();
538 self.x.mul(&x2);
539 self.y.mul(&x2);
540 self.y.mul(x);
541 }
542
543 pub fn mul(&self, e: &BIG) -> ECP2 {
545 let mut mt = BIG::new();
547 let mut t = BIG::new();
548 let mut P = ECP2::new();
549 let mut Q = ECP2::new();
550 let mut C = ECP2::new();
551
552 if self.is_infinity() {
553 return P;
554 }
555
556 let mut W: [ECP2; 8] = [
557 ECP2::new(),
558 ECP2::new(),
559 ECP2::new(),
560 ECP2::new(),
561 ECP2::new(),
562 ECP2::new(),
563 ECP2::new(),
564 ECP2::new(),
565 ];
566
567 const CT: usize = 1 + (big::NLEN * (big::BASEBITS as usize) + 3) / 4;
568 let mut w: [i8; CT] = [0; CT];
569
570 Q.copy(&self);
572 Q.dbl();
573
574 W[0].copy(&self);
575
576 for i in 1..8 {
577 C.copy(&W[i - 1]);
578 W[i].copy(&C);
579 W[i].add(&Q);
580 }
581
582 t.copy(&e);
584 let s = t.parity();
585 t.inc(1);
586 t.norm();
587 let ns = t.parity();
588 mt.copy(&t);
589 mt.inc(1);
590 mt.norm();
591 t.cmove(&mt, s);
592 Q.cmove(&self, ns);
593 C.copy(&Q);
594
595 let nb = 1 + (t.nbits() + 3) / 4;
596
597 for i in 0..nb {
599 w[i] = (t.lastbits(5) - 16) as i8;
600 t.dec(w[i] as isize);
601 t.norm();
602 t.fshr(4);
603 }
604 w[nb] = (t.lastbits(5)) as i8;
605
606 P.selector(&W, w[nb] as i32);
609 for i in (0..nb).rev() {
610 Q.selector(&W, w[i] as i32);
611 P.dbl();
612 P.dbl();
613 P.dbl();
614 P.dbl();
615 P.add(&Q);
616 }
617 P.sub(&C);
618 P
619 }
620
621 #[allow(non_snake_case)]
622 pub fn cfp(&mut self) {
623 let mut X = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
624 if ecp::SEXTIC_TWIST == ecp::M_TYPE {
625 X.inverse(None);
626 X.norm();
627 }
628 let x = BIG::new_ints(&rom::CURVE_BNX);
629 if ecp::CURVE_PAIRING_TYPE == ecp::BN {
632 let mut T = self.mul(&x);
633 if ecp::SIGN_OF_X == ecp::NEGATIVEX {
634 T.neg();
635 }
636 let mut K = ECP2::new();
637 K.copy(&T);
638 K.dbl();
639 K.add(&T);
640
641 K.frob(&X);
642 self.frob(&X);
643 self.frob(&X);
644 self.frob(&X);
645 self.add(&T);
646 self.add(&K);
647 T.frob(&X);
648 T.frob(&X);
649 self.add(&T);
650 }
651 if ecp::CURVE_PAIRING_TYPE > ecp::BN {
654 let mut xQ = self.mul(&x);
655 let mut x2Q = xQ.mul(&x);
656
657 if ecp::SIGN_OF_X == ecp::NEGATIVEX {
658 xQ.neg();
659 }
660 x2Q.sub(&xQ);
661 x2Q.sub(&self);
662
663 xQ.sub(&self);
664 xQ.frob(&X);
665
666 self.dbl();
667 self.frob(&X);
668 self.frob(&X);
669
670 self.add(&x2Q);
671 self.add(&xQ);
672 }
673 }
674
675
676 pub fn mul4(Q: &[ECP2], u: &[BIG]) -> ECP2 {
682 let mut W = ECP2::new();
683 let mut P = ECP2::new();
684
685 let mut T: [ECP2; 8] = [
686 ECP2::new(),
687 ECP2::new(),
688 ECP2::new(),
689 ECP2::new(),
690 ECP2::new(),
691 ECP2::new(),
692 ECP2::new(),
693 ECP2::new(),
694 ];
695
696 let mut mt = BIG::new();
697
698 let mut t: [BIG; 4] = [
699 BIG::new_copy(&u[0]),
700 BIG::new_copy(&u[1]),
701 BIG::new_copy(&u[2]),
702 BIG::new_copy(&u[3]),
703 ];
704
705 const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
706 let mut w: [i8; CT] = [0; CT];
707 let mut s: [i8; CT] = [0; CT];
708
709 for i in 0..4 {
710 t[i].norm();
711 }
712
713 T[0].copy(&Q[0]);
714 W.copy(&T[0]);
715 T[1].copy(&W);
716 T[1].add(&Q[1]); T[2].copy(&W);
718 T[2].add(&Q[2]);
719 W.copy(&T[1]); T[3].copy(&W);
721 T[3].add(&Q[2]);
722 W.copy(&T[0]); T[4].copy(&W);
724 T[4].add(&Q[3]);
725 W.copy(&T[1]); T[5].copy(&W);
727 T[5].add(&Q[3]);
728 W.copy(&T[2]); T[6].copy(&W);
730 T[6].add(&Q[3]);
731 W.copy(&T[3]); T[7].copy(&W);
733 T[7].add(&Q[3]); let pb = 1 - t[0].parity();
737 t[0].inc(pb);
738 t[0].norm();
739
740 mt.zero();
742 for i in 0..4 {
743 mt.or(&t[i]);
744 }
745
746 let nb = 1 + mt.nbits();
747
748 s[nb - 1] = 1;
751 for i in 0..nb - 1 {
752 t[0].fshr(1);
753 s[i] = (2 * t[0].parity() - 1) as i8;
754 }
755
756 for i in 0..nb {
758 w[i] = 0;
759 let mut k = 1;
760 for j in 1..4 {
761 let bt = s[i] * (t[j].parity() as i8);
762 t[j].fshr(1);
763 t[j].dec((bt >> 1) as isize);
764 t[j].norm();
765 w[i] += bt * (k as i8);
766 k *= 2;
767 }
768 }
769
770 P.selector(&T, (2 * w[nb - 1] + 1) as i32);
772 for i in (0..nb - 1).rev() {
773 P.dbl();
774 W.selector(&T, (2 * w[i] + s[i]) as i32);
775 P.add(&W);
776 }
777
778 W.copy(&P);
780 W.sub(&Q[0]);
781 P.cmove(&W, pb);
782
783 P
784 }
785
786#[allow(non_snake_case)]
788 pub fn hap2point(h: &BIG) -> ECP2 {
789 let mut Q: ECP2;
790 let one = BIG::new_int(1);
791 let mut x =BIG::new_copy(&h);
792 loop {
793 let X = FP2::new_bigs(&one, &x);
794 Q = ECP2::new_fp2(&X,0);
795 if !Q.is_infinity() {
796 break;
797 }
798 x.inc(1);
799 x.norm();
800 }
801 Q
802 }
803
804#[allow(unreachable_code)]
806 #[allow(non_snake_case)]
807 pub fn map2point(H: &FP2) -> ECP2 {
808 let mut T=FP2::new_copy(H); let sgn=T.sign(); if ecp::HTC_ISO_G2 == 0 {
811 } else {
868let NY=FP2::new_int(1);
870 let Ad=FP2::new_bigs(&BIG::new_ints(&rom::CURVE_ADR),&BIG::new_ints(&rom::CURVE_ADI));
871 let Bd=FP2::new_bigs(&BIG::new_ints(&rom::CURVE_BDR),&BIG::new_ints(&rom::CURVE_BDI));
872 let ZZ=FP2::new_ints(fp::RIADZG2A,fp::RIADZG2B);
873 let mut hint=FP::new();
874
875 T.sqr();
876 T.mul(&ZZ);
877 let mut W=FP2::new_copy(&T);
878 W.add(&NY); W.norm();
879
880 W.mul(&T);
881 let mut D=FP2::new_copy(&Ad);
882 D.mul(&W);
883
884 W.add(&NY); W.norm();
885 W.mul(&Bd);
886 W.neg(); W.norm();
887
888 let mut X2=FP2::new_copy(&W);
889 let mut X3=FP2::new_copy(&T);
890 X3.mul(&X2);
891
892 let mut GX1=FP2::new_copy(&X2); GX1.sqr();
893 let mut D2=FP2::new_copy(&D); D2.sqr();
894
895 W.copy(&Ad); W.mul(&D2); GX1.add(&W); GX1.norm(); GX1.mul(&X2); D2.mul(&D); W.copy(&Bd); W.mul(&D2); GX1.add(&W); GX1.norm(); W.copy(&GX1); W.mul(&D);
898 let qr=W.qr(Some(&mut hint));
899 D.copy(&W); D.inverse(Some(&hint));
900 D.mul(&GX1);
901 X2.mul(&D);
902 X3.mul(&D);
903 T.mul(&H);
904 D2.copy(&D); D2.sqr();
905
906 D.copy(&D2); D.mul(&T);
907 T.copy(&W); T.mul(&ZZ);
908
909 let mut s=FP::new_big(&BIG::new_ints(&rom::CURVE_HTPC2));
910 s.mul(&hint);
911
912 X2.cmove(&X3,1-qr);
913 W.cmove(&T,1-qr);
914 D2.cmove(&D,1-qr);
915 hint.cmove(&s,1-qr);
916
917 let mut Y=FP2::new_copy(&W); Y.sqrt(Some(&hint));
918 Y.mul(&D2);
919
920 let ne=Y.sign()^sgn;
921 W.copy(&Y); W.neg(); W.norm();
922 Y.cmove(&W,ne);
923
924 let mut k=0;
925 let isox=ecp::HTC_ISO_G2;
926 let isoy=3*(isox-1)/2;
927
928 let mut xnum=FP2::new_bigs(&BIG::new_ints(&rom::PCR[k]),&BIG::new_ints(&rom::PCI[k])); k+=1;
930 for _ in 0..isox {
931 xnum.mul(&X2);
932 xnum.add(&FP2::new_bigs(&BIG::new_ints(&rom::PCR[k]),&BIG::new_ints(&rom::PCI[k]))); k+=1;
933 xnum.norm();
934 }
935 let mut xden=FP2::new_copy(&X2);
937 xden.add(&FP2::new_bigs(&BIG::new_ints(&rom::PCR[k]),&BIG::new_ints(&rom::PCI[k]))); k+=1;
938 xden.norm();
939 for _ in 0..isox-2 {
940 xden.mul(&X2);
941 xden.add(&FP2::new_bigs(&BIG::new_ints(&rom::PCR[k]),&BIG::new_ints(&rom::PCI[k]))); k+=1;
942 xden.norm();
943 }
944 let mut ynum=FP2::new_bigs(&BIG::new_ints(&rom::PCR[k]),&BIG::new_ints(&rom::PCI[k])); k+=1;
946 for _ in 0..isoy {
947 ynum.mul(&X2);
948 ynum.add(&FP2::new_bigs(&BIG::new_ints(&rom::PCR[k]),&BIG::new_ints(&rom::PCI[k]))); k+=1;
949 ynum.norm();
950 }
951 let mut yden=FP2::new_copy(&X2);
953 yden.add(&FP2::new_bigs(&BIG::new_ints(&rom::PCR[k]),&BIG::new_ints(&rom::PCI[k]))); k+=1;
954 yden.norm();
955 for _ in 0..isoy-1 {
956 yden.mul(&X2);
957 yden.add(&FP2::new_bigs(&BIG::new_ints(&rom::PCR[k]),&BIG::new_ints(&rom::PCI[k]))); k+=1;
958 yden.norm();
959 }
960 ynum.mul(&Y);
961
962 let mut Q=ECP2::new();
963 T.copy(&xnum); T.mul(&yden);
964 Q.x.copy(&T);
965 T.copy(&ynum); T.mul(&xden);
966 Q.y.copy(&T);
967 T.copy(&xden); T.mul(&yden);
968 Q.z.copy(&T);
969 return Q;
970}
973 ECP2::new()
974 }
975
976#[allow(non_snake_case)]
978 pub fn mapit(h: &[u8]) -> ECP2 {
979 let q = BIG::new_ints(&rom::MODULUS);
980 let mut dx = DBIG::frombytes(h);
981 let x=dx.dmod(&q);
982 let mut P=ECP2::hap2point(&x);
983 P.cfp();
984 P
985 }
986
987 pub fn generator() -> ECP2 {
988 ECP2::new_fp2s(
989 &FP2::new_bigs(
990 &BIG::new_ints(&rom::CURVE_PXA),
991 &BIG::new_ints(&rom::CURVE_PXB),
992 ),
993 &FP2::new_bigs(
994 &BIG::new_ints(&rom::CURVE_PYA),
995 &BIG::new_ints(&rom::CURVE_PYB),
996 ),
997 )
998 }
999}