github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/FP256BN/PAIR.go (about) 1 /* 2 Licensed to the Apache Software Foundation (ASF) under one 3 or more contributor license agreements. See the NOTICE file 4 distributed with this work for additional information 5 regarding copyright ownership. The ASF licenses this file 6 to you under the Apache License, Version 2.0 (the 7 "License"); you may not use this file except in compliance 8 with the License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, 13 software distributed under the License is distributed on an 14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 KIND, either express or implied. See the License for the 16 specific language governing permissions and limitations 17 under the License. 18 */ 19 20 /* MiotCL BN Curve Pairing functions */ 21 22 package FP256BN 23 24 25 26 /* Line function */ 27 func line(A *ECP2,B *ECP2,Qx *FP,Qy *FP) *FP12 { 28 var a *FP4 29 var b *FP4 30 var c *FP4 31 32 if (A==B) { /* Doubling */ 33 XX:=NewFP2copy(A.getx()) //X 34 YY:=NewFP2copy(A.gety()) //Y 35 ZZ:=NewFP2copy(A.getz()) //Z 36 YZ:=NewFP2copy(YY) //Y 37 YZ.mul(ZZ) //YZ 38 XX.sqr() //X^2 39 YY.sqr() //Y^2 40 ZZ.sqr() //Z^2 41 42 YZ.imul(4) 43 YZ.neg(); YZ.norm() //-4YZ 44 YZ.pmul(Qy); //-4YZ.Ys 45 46 XX.imul(6) //6X^2 47 XX.pmul(Qx); //6X^2.Xs 48 49 sb:=3*CURVE_B_I 50 ZZ.imul(sb); // 3bZ^2 51 if SEXTIC_TWIST == D_TYPE { 52 ZZ.div_ip2(); 53 } 54 if SEXTIC_TWIST == M_TYPE { 55 ZZ.mul_ip(); 56 ZZ.add(ZZ); 57 YZ.mul_ip(); 58 YZ.norm(); 59 } 60 ZZ.norm() // 3b.Z^2 61 62 YY.add(YY) 63 ZZ.sub(YY); ZZ.norm() // 3b.Z^2-2Y^2 64 65 a=NewFP4fp2s(YZ,ZZ); // -4YZ.Ys | 3b.Z^2-2Y^2 | 6X^2.Xs 66 if SEXTIC_TWIST == D_TYPE { 67 68 b=NewFP4fp2(XX) // L(0,1) | L(0,0) | L(1,0) 69 c=NewFP4int(0) 70 } 71 if SEXTIC_TWIST == M_TYPE { 72 b=NewFP4int(0) 73 c=NewFP4fp2(XX); c.times_i() 74 } 75 A.dbl(); 76 77 } else { /* Addition */ 78 79 X1:=NewFP2copy(A.getx()) // X1 80 Y1:=NewFP2copy(A.gety()) // Y1 81 T1:=NewFP2copy(A.getz()) // Z1 82 T2:=NewFP2copy(A.getz()) // Z1 83 84 T1.mul(B.gety()) // T1=Z1.Y2 85 T2.mul(B.getx()) // T2=Z1.X2 86 87 X1.sub(T2); X1.norm() // X1=X1-Z1.X2 88 Y1.sub(T1); Y1.norm() // Y1=Y1-Z1.Y2 89 90 T1.copy(X1) // T1=X1-Z1.X2 91 X1.pmul(Qy) // X1=(X1-Z1.X2).Ys 92 93 if SEXTIC_TWIST == M_TYPE { 94 X1.mul_ip() 95 X1.norm() 96 } 97 98 T1.mul(B.gety()) // T1=(X1-Z1.X2).Y2 99 100 T2.copy(Y1) // T2=Y1-Z1.Y2 101 T2.mul(B.getx()) // T2=(Y1-Z1.Y2).X2 102 T2.sub(T1); T2.norm() // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2 103 Y1.pmul(Qx); Y1.neg(); Y1.norm() // Y1=-(Y1-Z1.Y2).Xs 104 105 a=NewFP4fp2s(X1,T2) // (X1-Z1.X2).Ys | (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2 | - (Y1-Z1.Y2).Xs 106 if SEXTIC_TWIST == D_TYPE { 107 b=NewFP4fp2(Y1) 108 c=NewFP4int(0) 109 } 110 if SEXTIC_TWIST == M_TYPE { 111 b=NewFP4int(0) 112 c=NewFP4fp2(Y1); c.times_i() 113 } 114 A.Add(B); 115 } 116 117 118 return NewFP12fp4s(a,b,c) 119 } 120 121 /* Optimal R-ate pairing */ 122 func Ate(P1 *ECP2,Q1 *ECP) *FP12 { 123 f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) 124 x:=NewBIGints(CURVE_Bnx) 125 n:=NewBIGcopy(x) 126 K:=NewECP2() 127 var lv *FP12 128 129 if CURVE_PAIRING_TYPE == BN { 130 if SEXTIC_TWIST==M_TYPE { 131 f.inverse(); 132 f.norm(); 133 } 134 n.pmul(6) 135 if SIGN_OF_X==POSITIVEX { 136 n.inc(2) 137 } else { 138 n.dec(2) 139 } 140 } else {n.copy(x)} 141 142 n.norm() 143 144 n3:=NewBIGcopy(n); 145 n3.pmul(3); 146 n3.norm(); 147 148 P:=NewECP2(); P.Copy(P1); P.Affine() 149 Q:=NewECP(); Q.Copy(Q1); Q.Affine() 150 151 152 Qx:=NewFPcopy(Q.getx()) 153 Qy:=NewFPcopy(Q.gety()) 154 155 A:=NewECP2() 156 r:=NewFP12int(1) 157 158 A.Copy(P) 159 160 NP:=NewECP2() 161 NP.Copy(P) 162 NP.neg() 163 164 nb:=n3.nbits() 165 166 for i:=nb-2;i>=1;i-- { 167 r.sqr() 168 lv=line(A,A,Qx,Qy) 169 r.smul(lv,SEXTIC_TWIST) 170 bt:=n3.bit(i)-n.bit(i); 171 if bt==1 { 172 lv=line(A,P,Qx,Qy) 173 r.smul(lv,SEXTIC_TWIST) 174 } 175 if bt==-1 { 176 //P.neg() 177 lv=line(A,NP,Qx,Qy) 178 r.smul(lv,SEXTIC_TWIST) 179 //P.neg() 180 } 181 } 182 183 if SIGN_OF_X==NEGATIVEX { 184 r.conj() 185 } 186 187 188 /* R-ate fixup required for BN curves */ 189 190 if CURVE_PAIRING_TYPE == BN { 191 if SIGN_OF_X==NEGATIVEX { 192 //r.conj() 193 A.neg() 194 } 195 196 K.Copy(P) 197 K.frob(f) 198 lv=line(A,K,Qx,Qy) 199 r.smul(lv,SEXTIC_TWIST) 200 K.frob(f) 201 K.neg() 202 lv=line(A,K,Qx,Qy) 203 r.smul(lv,SEXTIC_TWIST) 204 } 205 206 return r 207 } 208 209 /* Optimal R-ate double pairing e(P,Q).e(R,S) */ 210 func Ate2(P1 *ECP2,Q1 *ECP,R1 *ECP2,S1 *ECP) *FP12 { 211 f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) 212 x:=NewBIGints(CURVE_Bnx) 213 n:=NewBIGcopy(x) 214 K:=NewECP2() 215 var lv *FP12 216 217 if CURVE_PAIRING_TYPE == BN { 218 if SEXTIC_TWIST==M_TYPE { 219 f.inverse(); 220 f.norm(); 221 } 222 n.pmul(6); 223 if SIGN_OF_X==POSITIVEX { 224 n.inc(2) 225 } else { 226 n.dec(2) 227 } 228 } else {n.copy(x)} 229 230 n.norm() 231 232 n3:=NewBIGcopy(n); 233 n3.pmul(3); 234 n3.norm(); 235 236 P:=NewECP2(); P.Copy(P1); P.Affine() 237 Q:=NewECP(); Q.Copy(Q1); Q.Affine() 238 R:=NewECP2(); R.Copy(R1); R.Affine() 239 S:=NewECP(); S.Copy(S1); S.Affine() 240 241 242 Qx:=NewFPcopy(Q.getx()) 243 Qy:=NewFPcopy(Q.gety()) 244 Sx:=NewFPcopy(S.getx()) 245 Sy:=NewFPcopy(S.gety()) 246 247 A:=NewECP2() 248 B:=NewECP2() 249 r:=NewFP12int(1) 250 251 A.Copy(P) 252 B.Copy(R) 253 NP:=NewECP2() 254 NP.Copy(P) 255 NP.neg() 256 NR:=NewECP2() 257 NR.Copy(R) 258 NR.neg() 259 260 261 nb:=n3.nbits() 262 263 for i:=nb-2;i>=1;i-- { 264 r.sqr() 265 lv=line(A,A,Qx,Qy) 266 r.smul(lv,SEXTIC_TWIST) 267 lv=line(B,B,Sx,Sy) 268 r.smul(lv,SEXTIC_TWIST) 269 bt:=n3.bit(i)-n.bit(i); 270 if bt==1 { 271 lv=line(A,P,Qx,Qy) 272 r.smul(lv,SEXTIC_TWIST) 273 lv=line(B,R,Sx,Sy) 274 r.smul(lv,SEXTIC_TWIST) 275 } 276 if bt==-1 { 277 //P.neg(); 278 lv=line(A,NP,Qx,Qy) 279 r.smul(lv,SEXTIC_TWIST) 280 //P.neg(); 281 //R.neg() 282 lv=line(B,NR,Sx,Sy) 283 r.smul(lv,SEXTIC_TWIST) 284 //R.neg() 285 } 286 } 287 288 if SIGN_OF_X==NEGATIVEX { 289 r.conj() 290 } 291 292 /* R-ate fixup */ 293 if CURVE_PAIRING_TYPE == BN { 294 if SIGN_OF_X==NEGATIVEX { 295 // r.conj() 296 A.neg() 297 B.neg() 298 } 299 K.Copy(P) 300 K.frob(f) 301 302 lv=line(A,K,Qx,Qy) 303 r.smul(lv,SEXTIC_TWIST) 304 K.frob(f) 305 K.neg() 306 lv=line(A,K,Qx,Qy) 307 r.smul(lv,SEXTIC_TWIST) 308 309 K.Copy(R) 310 K.frob(f) 311 312 lv=line(B,K,Sx,Sy) 313 r.smul(lv,SEXTIC_TWIST) 314 K.frob(f) 315 K.neg() 316 lv=line(B,K,Sx,Sy) 317 r.smul(lv,SEXTIC_TWIST) 318 } 319 320 return r 321 } 322 323 /* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */ 324 func Fexp(m *FP12) *FP12 { 325 f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) 326 x:=NewBIGints(CURVE_Bnx) 327 r:=NewFP12copy(m) 328 329 /* Easy part of final exp */ 330 lv:=NewFP12copy(r) 331 lv.Inverse() 332 r.conj() 333 334 r.Mul(lv) 335 lv.Copy(r) 336 r.frob(f) 337 r.frob(f) 338 r.Mul(lv) 339 /* Hard part of final exp */ 340 if CURVE_PAIRING_TYPE == BN { 341 lv.Copy(r) 342 lv.frob(f) 343 x0:=NewFP12copy(lv) 344 x0.frob(f) 345 lv.Mul(r) 346 x0.Mul(lv) 347 x0.frob(f) 348 x1:=NewFP12copy(r) 349 x1.conj() 350 x4:=r.Pow(x) 351 if SIGN_OF_X==POSITIVEX { 352 x4.conj(); 353 } 354 355 x3:=NewFP12copy(x4) 356 x3.frob(f) 357 358 x2:=x4.Pow(x) 359 if SIGN_OF_X==POSITIVEX { 360 x2.conj(); 361 } 362 363 x5:=NewFP12copy(x2); x5.conj() 364 lv=x2.Pow(x) 365 if SIGN_OF_X==POSITIVEX { 366 lv.conj(); 367 } 368 369 x2.frob(f) 370 r.Copy(x2); r.conj() 371 372 x4.Mul(r) 373 x2.frob(f) 374 375 r.Copy(lv) 376 r.frob(f) 377 lv.Mul(r) 378 379 lv.usqr() 380 lv.Mul(x4) 381 lv.Mul(x5) 382 r.Copy(x3) 383 r.Mul(x5) 384 r.Mul(lv) 385 lv.Mul(x2) 386 r.usqr() 387 r.Mul(lv) 388 r.usqr() 389 lv.Copy(r) 390 lv.Mul(x1) 391 r.Mul(x0) 392 lv.usqr() 393 r.Mul(lv) 394 r.reduce() 395 } else { 396 397 // Ghamman & Fouotsa Method 398 y0:=NewFP12copy(r); y0.usqr() 399 y1:=y0.Pow(x) 400 if SIGN_OF_X==NEGATIVEX { 401 y1.conj(); 402 } 403 404 x.fshr(1); y2:=y1.Pow(x); 405 if SIGN_OF_X==NEGATIVEX { 406 y2.conj(); 407 } 408 409 x.fshl(1) 410 y3:=NewFP12copy(r); y3.conj() 411 y1.Mul(y3) 412 413 y1.conj() 414 y1.Mul(y2) 415 416 y2=y1.Pow(x) 417 if SIGN_OF_X==NEGATIVEX { 418 y2.conj(); 419 } 420 421 422 y3=y2.Pow(x) 423 if SIGN_OF_X==NEGATIVEX { 424 y3.conj(); 425 } 426 427 y1.conj() 428 y3.Mul(y1) 429 430 y1.conj(); 431 y1.frob(f); y1.frob(f); y1.frob(f) 432 y2.frob(f); y2.frob(f) 433 y1.Mul(y2) 434 435 y2=y3.Pow(x) 436 if SIGN_OF_X==NEGATIVEX { 437 y2.conj(); 438 } 439 440 y2.Mul(y0) 441 y2.Mul(r) 442 443 y1.Mul(y2) 444 y2.Copy(y3); y2.frob(f) 445 y1.Mul(y2) 446 r.Copy(y1) 447 r.reduce() 448 449 450 /* 451 x0:=NewFP12copy(r) 452 x1:=NewFP12copy(r) 453 lv.Copy(r); lv.frob(f) 454 x3:=NewFP12copy(lv); x3.conj(); x1.Mul(x3) 455 lv.frob(f); lv.frob(f) 456 x1.Mul(lv) 457 458 r.Copy(r.Pow(x)) //r=r.Pow(x); 459 x3.Copy(r); x3.conj(); x1.Mul(x3) 460 lv.Copy(r); lv.frob(f) 461 x0.Mul(lv) 462 lv.frob(f) 463 x1.Mul(lv) 464 lv.frob(f) 465 x3.Copy(lv); x3.conj(); x0.Mul(x3) 466 467 r.Copy(r.Pow(x)) 468 x0.Mul(r) 469 lv.Copy(r); lv.frob(f); lv.frob(f) 470 x3.Copy(lv); x3.conj(); x0.Mul(x3) 471 lv.frob(f) 472 x1.Mul(lv) 473 474 r.Copy(r.Pow(x)) 475 lv.Copy(r); lv.frob(f) 476 x3.Copy(lv); x3.conj(); x0.Mul(x3) 477 lv.frob(f) 478 x1.Mul(lv) 479 480 r.Copy(r.Pow(x)) 481 x3.Copy(r); x3.conj(); x0.Mul(x3) 482 lv.Copy(r); lv.frob(f) 483 x1.Mul(lv) 484 485 r.Copy(r.Pow(x)) 486 x1.Mul(r) 487 488 x0.usqr() 489 x0.Mul(x1) 490 r.Copy(x0) 491 r.reduce() */ 492 } 493 return r 494 } 495 496 /* GLV method */ 497 func glv(e *BIG) []*BIG { 498 var u []*BIG 499 if CURVE_PAIRING_TYPE == BN { 500 t:=NewBIGint(0) 501 q:=NewBIGints(CURVE_Order) 502 var v []*BIG 503 504 for i:=0;i<2;i++ { 505 t.copy(NewBIGints(CURVE_W[i])) // why not just t=new BIG(ROM.CURVE_W[i]); 506 d:=mul(t,e) 507 v=append(v,NewBIGcopy(d.div(q))) 508 u=append(u,NewBIGint(0)) 509 } 510 u[0].copy(e) 511 for i:=0;i<2;i++ { 512 for j:=0;j<2;j++ { 513 t.copy(NewBIGints(CURVE_SB[j][i])) 514 t.copy(Modmul(v[j],t,q)) 515 u[i].add(q) 516 u[i].sub(t) 517 u[i].Mod(q) 518 } 519 } 520 } else { 521 q:=NewBIGints(CURVE_Order) 522 x:=NewBIGints(CURVE_Bnx) 523 x2:=smul(x,x) 524 u=append(u,NewBIGcopy(e)) 525 u[0].Mod(x2) 526 u=append(u,NewBIGcopy(e)) 527 u[1].div(x2) 528 u[1].rsub(q) 529 } 530 return u 531 } 532 533 /* Galbraith & Scott Method */ 534 func gs(e *BIG) []*BIG { 535 var u []*BIG 536 if CURVE_PAIRING_TYPE == BN { 537 t:=NewBIGint(0) 538 q:=NewBIGints(CURVE_Order) 539 540 var v []*BIG 541 for i:=0;i<4;i++ { 542 t.copy(NewBIGints(CURVE_WB[i])) 543 d:=mul(t,e) 544 v=append(v,NewBIGcopy(d.div(q))) 545 u=append(u,NewBIGint(0)) 546 } 547 u[0].copy(e) 548 for i:=0;i<4;i++ { 549 for j:=0;j<4;j++ { 550 t.copy(NewBIGints(CURVE_BB[j][i])) 551 t.copy(Modmul(v[j],t,q)) 552 u[i].add(q) 553 u[i].sub(t) 554 u[i].Mod(q) 555 } 556 } 557 } else { 558 q:=NewBIGints(CURVE_Order) 559 x:=NewBIGints(CURVE_Bnx) 560 w:=NewBIGcopy(e) 561 for i:=0;i<3;i++ { 562 u=append(u,NewBIGcopy(w)) 563 u[i].Mod(x) 564 w.div(x) 565 } 566 u=append(u,NewBIGcopy(w)) 567 if SIGN_OF_X==NEGATIVEX { 568 u[1].copy(Modneg(u[1],q)); 569 u[3].copy(Modneg(u[3],q)); 570 } 571 } 572 return u 573 } 574 575 /* Multiply P by e in group G1 */ 576 func G1mul(P *ECP,e *BIG) *ECP { 577 var R *ECP 578 if (USE_GLV) { 579 //P.Affine() 580 R=NewECP() 581 R.Copy(P) 582 Q:=NewECP() 583 Q.Copy(P); Q.Affine() 584 q:=NewBIGints(CURVE_Order) 585 cru:=NewFPbig(NewBIGints(CURVE_Cru)) 586 t:=NewBIGint(0) 587 u:=glv(e) 588 Q.getx().mul(cru) 589 590 np:=u[0].nbits() 591 t.copy(Modneg(u[0],q)) 592 nn:=t.nbits() 593 if nn<np { 594 u[0].copy(t) 595 R.neg() 596 } 597 598 np=u[1].nbits() 599 t.copy(Modneg(u[1],q)) 600 nn=t.nbits() 601 if nn<np { 602 u[1].copy(t) 603 Q.neg() 604 } 605 u[0].norm() 606 u[1].norm() 607 R=R.Mul2(u[0],Q,u[1]) 608 609 } else { 610 R=P.mul(e) 611 } 612 return R 613 } 614 615 /* Multiply P by e in group G2 */ 616 func G2mul(P *ECP2,e *BIG) *ECP2 { 617 var R *ECP2 618 if (USE_GS_G2) { 619 var Q []*ECP2 620 f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) 621 622 if SEXTIC_TWIST==M_TYPE { 623 f.inverse(); 624 f.norm(); 625 } 626 627 q:=NewBIGints(CURVE_Order) 628 u:=gs(e) 629 630 t:=NewBIGint(0) 631 //P.Affine() 632 Q=append(Q,NewECP2()); Q[0].Copy(P); 633 for i:=1;i<4;i++ { 634 Q=append(Q,NewECP2()); Q[i].Copy(Q[i-1]) 635 Q[i].frob(f) 636 } 637 for i:=0;i<4;i++ { 638 np:=u[i].nbits() 639 t.copy(Modneg(u[i],q)) 640 nn:=t.nbits() 641 if nn<np { 642 u[i].copy(t) 643 Q[i].neg() 644 } 645 u[i].norm() 646 } 647 648 R=mul4(Q,u) 649 650 } else { 651 R=P.mul(e) 652 } 653 return R 654 } 655 656 /* f=f^e */ 657 /* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */ 658 func GTpow(d *FP12,e *BIG) *FP12 { 659 var r *FP12 660 if USE_GS_GT { 661 var g []*FP12 662 f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) 663 q:=NewBIGints(CURVE_Order) 664 t:=NewBIGint(0) 665 666 u:=gs(e) 667 668 g=append(g,NewFP12copy(d)) 669 for i:=1;i<4;i++ { 670 g=append(g,NewFP12int(0)) 671 g[i].Copy(g[i-1]) 672 g[i].frob(f) 673 } 674 for i:=0;i<4;i++ { 675 np:=u[i].nbits() 676 t.copy(Modneg(u[i],q)) 677 nn:=t.nbits() 678 if nn<np { 679 u[i].copy(t) 680 g[i].conj() 681 } 682 u[i].norm() 683 } 684 r=pow4(g,u) 685 } else { 686 r=d.Pow(e) 687 } 688 return r 689 } 690 691 /* test group membership - no longer needed*/ 692 /* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */ 693 /* 694 func GTmember(m *FP12) bool { 695 if m.Isunity() {return false} 696 r:=NewFP12copy(m) 697 r.conj() 698 r.Mul(m) 699 if !r.Isunity() {return false} 700 701 f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) 702 703 r.Copy(m); r.frob(f); r.frob(f) 704 w:=NewFP12copy(r); w.frob(f); w.frob(f) 705 w.Mul(m) 706 if !GT_STRONG { 707 if !w.Equals(r) {return false} 708 x:=NewBIGints(CURVE_Bnx); 709 r.Copy(m); w=r.Pow(x); w=w.Pow(x) 710 r.Copy(w); r.sqr(); r.Mul(w); r.sqr() 711 w.Copy(m); w.frob(f) 712 } 713 return w.Equals(r) 714 } 715 */ 716 /* 717 func main() { 718 719 Q:=NewECPbigs(NewBIGints(CURVE_Gx),NewBIGints(CURVE_Gy)) 720 P:=NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa),NewBIGints(CURVE_Pxb)),NewFP2bigs(NewBIGints(CURVE_Pya),NewBIGints(CURVE_Pyb))) 721 722 //r:=NewBIGints(CURVE_Order) 723 //xa:=NewBIGints(CURVE_Pxa) 724 725 fmt.Printf("P= "+P.toString()) 726 fmt.Printf("\n"); 727 fmt.Printf("Q= "+Q.toString()); 728 fmt.Printf("\n"); 729 730 //m:=NewBIGint(17) 731 732 e:=Ate(P,Q) 733 e=Fexp(e) 734 for i:=1;i<1000;i++ { 735 e=Ate(P,Q) 736 // fmt.Printf("\ne= "+e.toString()) 737 // fmt.Printf("\n") 738 739 e=Fexp(e) 740 } 741 // e=GTpow(e,m); 742 743 fmt.Printf("\ne= "+e.toString()) 744 fmt.Printf("\n"); 745 GLV:=glv(r) 746 747 fmt.Printf("GLV[0]= "+GLV[0].toString()) 748 fmt.Printf("\n") 749 750 fmt.Printf("GLV[0]= "+GLV[1].toString()) 751 fmt.Printf("\n") 752 753 G:=NewECP(); G.Copy(Q) 754 R:=NewECP2(); R.Copy(P) 755 756 757 e=Ate(R,Q) 758 e=Fexp(e) 759 760 e=GTpow(e,xa) 761 fmt.Printf("\ne= "+e.toString()); 762 fmt.Printf("\n") 763 764 R=G2mul(R,xa) 765 e=Ate(R,G) 766 e=Fexp(e) 767 768 fmt.Printf("\ne= "+e.toString()) 769 fmt.Printf("\n") 770 771 G=G1mul(G,xa) 772 e=Ate(P,G) 773 e=Fexp(e) 774 fmt.Printf("\ne= "+e.toString()) 775 fmt.Printf("\n") 776 } 777 */