github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/FP256BN/ECP.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 package FP256BN 21 22 23 const WEIERSTRASS int=0 24 const EDWARDS int=1 25 const MONTGOMERY int=2 26 const NOT int=0 27 const BN int=1 28 const BLS int=2 29 const D_TYPE int=0 30 const M_TYPE int=1 31 const POSITIVEX int=0 32 const NEGATIVEX int=1 33 34 const CURVETYPE int=WEIERSTRASS 35 const CURVE_PAIRING_TYPE int=BN 36 const SEXTIC_TWIST int=M_TYPE 37 const SIGN_OF_X int=NEGATIVEX 38 39 const HASH_TYPE int=32 40 const AESKEY int=16 41 42 /* Elliptic Curve Point Structure */ 43 44 type ECP struct { 45 x *FP 46 y *FP 47 z *FP 48 // INF bool 49 } 50 51 /* Constructors */ 52 func NewECP() *ECP { 53 E:=new(ECP) 54 E.x=NewFPint(0) 55 E.y=NewFPint(1) 56 if CURVETYPE==EDWARDS { 57 E.z=NewFPint(1) 58 } else { 59 E.z=NewFPint(0) 60 } 61 // E.INF=true 62 return E 63 } 64 65 /* set (x,y) from two BIGs */ 66 func NewECPbigs(ix *BIG,iy *BIG) *ECP { 67 E:=new(ECP) 68 E.x=NewFPbig(ix) 69 E.y=NewFPbig(iy) 70 E.z=NewFPint(1) 71 rhs:=RHS(E.x) 72 73 if CURVETYPE==MONTGOMERY { 74 if rhs.jacobi()!=1 { 75 E.inf() 76 } 77 } else { 78 y2:=NewFPcopy(E.y) 79 y2.sqr() 80 if !y2.Equals(rhs) { 81 E.inf() 82 } 83 } 84 return E 85 } 86 87 /* set (x,y) from BIG and a bit */ 88 func NewECPbigint(ix *BIG,s int) *ECP { 89 E:=new(ECP) 90 E.x=NewFPbig(ix) 91 E.y=NewFPint(0) 92 rhs:=RHS(E.x) 93 E.z=NewFPint(1) 94 if rhs.jacobi()==1 { 95 ny:=rhs.sqrt() 96 if ny.redc().parity()!=s {ny.neg()} 97 E.y.copy(ny) 98 //E.INF=false 99 } else {E.inf()} 100 return E; 101 } 102 103 /* set from x - calculate y from curve equation */ 104 func NewECPbig(ix *BIG) *ECP { 105 E:=new(ECP) 106 E.x=NewFPbig(ix) 107 E.y=NewFPint(0) 108 rhs:=RHS(E.x) 109 E.z=NewFPint(1) 110 if rhs.jacobi()==1 { 111 if CURVETYPE!=MONTGOMERY {E.y.copy(rhs.sqrt())} 112 //E.INF=false 113 } else {E.inf()} 114 return E 115 } 116 117 /* test for O point-at-infinity */ 118 func (E *ECP) Is_infinity() bool { 119 // if E.INF {return true} 120 E.x.reduce(); E.z.reduce() 121 if CURVETYPE==EDWARDS { 122 E.y.reduce(); 123 return (E.x.iszilch() && E.y.Equals(E.z)) 124 } 125 if CURVETYPE==WEIERSTRASS { 126 E.y.reduce(); 127 return (E.x.iszilch() && E.z.iszilch()) 128 } 129 if CURVETYPE==MONTGOMERY { 130 return E.z.iszilch() 131 } 132 return true 133 } 134 135 /* Conditional swap of P and Q dependant on d */ 136 func (E *ECP) cswap(Q *ECP,d int) { 137 E.x.cswap(Q.x,d) 138 if CURVETYPE!=MONTGOMERY {E.y.cswap(Q.y,d)} 139 E.z.cswap(Q.z,d) 140 /* 141 bd:=true 142 if d==0 {bd=false} 143 bd=bd&&(E.INF!=Q.INF) 144 E.INF=(bd!=E.INF) 145 Q.INF=(bd!=Q.INF) 146 */ 147 } 148 149 /* Conditional move of Q to P dependant on d */ 150 func (E *ECP) cmove(Q *ECP,d int) { 151 E.x.cmove(Q.x,d) 152 if CURVETYPE!=MONTGOMERY {E.y.cmove(Q.y,d)} 153 E.z.cmove(Q.z,d); 154 /* 155 bd:=true 156 if d==0 {bd=false} 157 E.INF=(E.INF!=((E.INF!=Q.INF)&&bd)) 158 */ 159 } 160 161 /* return 1 if b==c, no branching */ 162 func teq(b int32,c int32) int { 163 x:=b^c 164 x-=1 // if x=0, x now -1 165 return int((x>>31)&1) 166 } 167 168 /* this=P */ 169 func (E *ECP) Copy(P *ECP) { 170 E.x.copy(P.x); 171 if CURVETYPE!=MONTGOMERY {E.y.copy(P.y)} 172 E.z.copy(P.z); 173 // E.INF=P.INF; 174 } 175 176 /* this=-this */ 177 func (E *ECP) neg() { 178 // if E.Is_infinity() {return} 179 if CURVETYPE==WEIERSTRASS { 180 E.y.neg(); E.y.norm() 181 } 182 if CURVETYPE==EDWARDS { 183 E.x.neg(); E.x.norm() 184 } 185 return; 186 } 187 188 /* Constant time select from pre-computed table */ 189 func (E *ECP) selector(W []*ECP,b int32) { 190 MP:=NewECP() 191 m:=b>>31; 192 babs:=(b^m)-m; 193 194 babs=(babs-1)/2 195 196 E.cmove(W[0],teq(babs,0)) // conditional move 197 E.cmove(W[1],teq(babs,1)) 198 E.cmove(W[2],teq(babs,2)) 199 E.cmove(W[3],teq(babs,3)) 200 E.cmove(W[4],teq(babs,4)) 201 E.cmove(W[5],teq(babs,5)) 202 E.cmove(W[6],teq(babs,6)) 203 E.cmove(W[7],teq(babs,7)) 204 205 MP.Copy(E); 206 MP.neg() 207 E.cmove(MP,int(m&1)); 208 } 209 210 /* set this=O */ 211 func (E *ECP) inf() { 212 // E.INF=true; 213 E.x.zero() 214 if CURVETYPE!=MONTGOMERY {E.y.one()} 215 if CURVETYPE!=EDWARDS { 216 E.z.zero() 217 } else {E.z.one()} 218 } 219 220 /* Test P == Q */ 221 func( E *ECP) Equals(Q *ECP) bool { 222 // if E.Is_infinity() && Q.Is_infinity() {return true} 223 // if E.Is_infinity() || Q.Is_infinity() {return false} 224 225 a:=NewFPint(0) 226 b:=NewFPint(0) 227 a.copy(E.x); a.mul(Q.z); a.reduce() 228 b.copy(Q.x); b.mul(E.z); b.reduce() 229 if !a.Equals(b) {return false} 230 if CURVETYPE!=MONTGOMERY { 231 a.copy(E.y); a.mul(Q.z); a.reduce() 232 b.copy(Q.y); b.mul(E.z); b.reduce() 233 if !a.Equals(b) {return false} 234 } 235 236 return true 237 } 238 239 /* Calculate RHS of curve equation */ 240 func RHS(x *FP) *FP { 241 x.norm() 242 r:=NewFPcopy(x) 243 r.sqr(); 244 245 if CURVETYPE==WEIERSTRASS { // x^3+Ax+B 246 b:=NewFPbig(NewBIGints(CURVE_B)) 247 r.mul(x); 248 if CURVE_A==-3 { 249 cx:=NewFPcopy(x) 250 cx.imul(3) 251 cx.neg(); cx.norm() 252 r.add(cx) 253 } 254 r.add(b) 255 } 256 if CURVETYPE==EDWARDS { // (Ax^2-1)/(Bx^2-1) 257 b:=NewFPbig(NewBIGints(CURVE_B)) 258 259 one:=NewFPint(1) 260 b.mul(r) 261 b.sub(one) 262 b.norm() 263 if CURVE_A==-1 {r.neg()} 264 r.sub(one); r.norm() 265 b.inverse() 266 r.mul(b) 267 } 268 if CURVETYPE==MONTGOMERY { // x^3+Ax^2+x 269 x3:=NewFPint(0) 270 x3.copy(r) 271 x3.mul(x) 272 r.imul(CURVE_A) 273 r.add(x3) 274 r.add(x) 275 } 276 r.reduce() 277 return r 278 } 279 280 /* set to affine - from (x,y,z) to (x,y) */ 281 func (E *ECP) Affine() { 282 if E.Is_infinity() {return} 283 one:=NewFPint(1) 284 if E.z.Equals(one) {return} 285 E.z.inverse() 286 E.x.mul(E.z); E.x.reduce() 287 288 if CURVETYPE!=MONTGOMERY { 289 E.y.mul(E.z); E.y.reduce() 290 } 291 E.z.copy(one) 292 } 293 294 /* extract x as a BIG */ 295 func (E *ECP) GetX() *BIG { 296 W:=NewECP(); W.Copy(E) 297 W.Affine() 298 return W.x.redc() 299 } 300 /* extract y as a BIG */ 301 func (E *ECP) GetY() *BIG { 302 W:=NewECP(); W.Copy(E) 303 W.Affine() 304 return W.y.redc() 305 } 306 307 /* get sign of Y */ 308 func (E *ECP) GetS() int { 309 //E.Affine() 310 y:=E.GetY() 311 return y.parity() 312 } 313 /* extract x as an FP */ 314 func (E *ECP) getx() *FP { 315 return E.x; 316 } 317 /* extract y as an FP */ 318 func (E *ECP) gety() *FP { 319 return E.y 320 } 321 /* extract z as an FP */ 322 func (E *ECP) getz() *FP { 323 return E.z 324 } 325 326 /* convert to byte array */ 327 func (E *ECP) ToBytes(b []byte,compress bool) { 328 var t [int(MODBYTES)]byte 329 MB:=int(MODBYTES) 330 W:=NewECP(); W.Copy(E); 331 W.Affine() 332 W.x.redc().ToBytes(t[:]) 333 for i:=0;i<MB;i++ {b[i+1]=t[i]} 334 335 if CURVETYPE==MONTGOMERY { 336 b[0]=0x06 337 return; 338 } 339 340 if compress { 341 b[0]=0x02 342 if W.y.redc().parity()==1 {b[0]=0x03} 343 return; 344 } 345 346 b[0]=0x04 347 348 W.y.redc().ToBytes(t[:]) 349 for i:=0;i<MB;i++ {b[i+MB+1]=t[i]} 350 } 351 352 /* convert from byte array to point */ 353 func ECP_fromBytes(b []byte) *ECP { 354 var t [int(MODBYTES)]byte 355 MB:=int(MODBYTES) 356 p:=NewBIGints(Modulus) 357 358 for i:=0;i<MB;i++ {t[i]=b[i+1]} 359 px:=FromBytes(t[:]) 360 if comp(px,p)>=0 {return NewECP()} 361 362 if CURVETYPE==MONTGOMERY { 363 return NewECPbig(px) 364 } 365 366 if b[0]==0x04 { 367 for i:=0;i<MB;i++ {t[i]=b[i+MB+1]} 368 py:=FromBytes(t[:]) 369 if comp(py,p)>=0 {return NewECP()} 370 return NewECPbigs(px,py) 371 } 372 373 if b[0]==0x02 || b[0]==0x03 { 374 return NewECPbigint(px,int(b[0]&1)) 375 } 376 377 return NewECP() 378 } 379 380 /* convert to hex string */ 381 func (E *ECP) toString() string { 382 W:=NewECP(); W.Copy(E); 383 W.Affine() 384 if W.Is_infinity() {return "infinity"} 385 if CURVETYPE==MONTGOMERY { 386 return "("+W.x.redc().toString()+")" 387 } else {return "("+W.x.redc().toString()+","+W.y.redc().toString()+")"} 388 } 389 390 /* this*=2 */ 391 func (E *ECP) dbl() { 392 393 // if E.INF {return} 394 if CURVETYPE==WEIERSTRASS { 395 if CURVE_A==0 { 396 t0:=NewFPcopy(E.y) /*** Change ***/ // Edits made 397 t0.sqr() 398 t1:=NewFPcopy(E.y) 399 t1.mul(E.z) 400 t2:=NewFPcopy(E.z) 401 t2.sqr() 402 403 E.z.copy(t0) 404 E.z.add(t0); E.z.norm(); 405 E.z.add(E.z); E.z.add(E.z); E.z.norm() 406 t2.imul(3*CURVE_B_I) 407 408 x3:=NewFPcopy(t2) 409 x3.mul(E.z) 410 411 y3:=NewFPcopy(t0) 412 y3.add(t2); y3.norm() 413 E.z.mul(t1) 414 t1.copy(t2); t1.add(t2); t2.add(t1) 415 t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3) 416 t1.copy(E.x); t1.mul(E.y) 417 E.x.copy(t0); E.x.norm(); E.x.mul(t1); E.x.add(E.x) 418 E.x.norm(); 419 E.y.copy(y3); E.y.norm(); 420 } else { 421 t0:=NewFPcopy(E.x) 422 t1:=NewFPcopy(E.y) 423 t2:=NewFPcopy(E.z) 424 t3:=NewFPcopy(E.x) 425 z3:=NewFPcopy(E.z) 426 y3:=NewFPint(0) 427 x3:=NewFPint(0) 428 b:=NewFPint(0) 429 430 if CURVE_B_I==0 {b.copy(NewFPbig(NewBIGints(CURVE_B)))} 431 432 t0.sqr() //1 x^2 433 t1.sqr() //2 y^2 434 t2.sqr() //3 435 436 t3.mul(E.y) //4 437 t3.add(t3); t3.norm() //5 438 z3.mul(E.x); //6 439 z3.add(z3); z3.norm()//7 440 y3.copy(t2) 441 442 if CURVE_B_I==0 { 443 y3.mul(b) 444 } else { 445 y3.imul(CURVE_B_I) 446 } 447 448 y3.sub(z3) //y3.norm(); //9 *** 449 x3.copy(y3); x3.add(y3); x3.norm() //10 450 451 y3.add(x3) //y3.norm();//11 452 x3.copy(t1); x3.sub(y3); x3.norm() //12 453 y3.add(t1); y3.norm() //13 454 y3.mul(x3) //14 455 x3.mul(t3) //15 456 t3.copy(t2); t3.add(t2) //t3.norm(); //16 457 t2.add(t3) //t2.norm(); //17 458 459 if CURVE_B_I==0 { 460 z3.mul(b) 461 } else { 462 z3.imul(CURVE_B_I) 463 } 464 465 z3.sub(t2) //z3.norm();//19 466 z3.sub(t0); z3.norm()//20 *** 467 t3.copy(z3); t3.add(z3) //t3.norm();//21 468 469 z3.add(t3); z3.norm() //22 470 t3.copy(t0); t3.add(t0) //t3.norm(); //23 471 t0.add(t3) //t0.norm();//24 472 t0.sub(t2); t0.norm() //25 473 474 t0.mul(z3) //26 475 y3.add(t0) //y3.norm();//27 476 t0.copy(E.y); t0.mul(E.z)//28 477 t0.add(t0); t0.norm() //29 478 z3.mul(t0)//30 479 x3.sub(z3) //x3.norm();//31 480 t0.add(t0); t0.norm() //32 481 t1.add(t1); t1.norm() //33 482 z3.copy(t0); z3.mul(t1) //34 483 484 E.x.copy(x3); E.x.norm() 485 E.y.copy(y3); E.y.norm() 486 E.z.copy(z3); E.z.norm() 487 } 488 } 489 490 if CURVETYPE==EDWARDS { 491 C:=NewFPcopy(E.x) 492 D:=NewFPcopy(E.y) 493 H:=NewFPcopy(E.z) 494 J:=NewFPint(0) 495 496 E.x.mul(E.y); E.x.add(E.x); E.x.norm() 497 C.sqr() 498 D.sqr() 499 if CURVE_A==-1 {C.neg()} 500 E.y.copy(C); E.y.add(D); E.y.norm() 501 502 H.sqr(); H.add(H) 503 E.z.copy(E.y) 504 J.copy(E.y); J.sub(H); J.norm() 505 E.x.mul(J) 506 C.sub(D); C.norm() 507 E.y.mul(C) 508 E.z.mul(J) 509 510 511 } 512 if CURVETYPE==MONTGOMERY { 513 A:=NewFPcopy(E.x) 514 B:=NewFPcopy(E.x) 515 AA:=NewFPint(0) 516 BB:=NewFPint(0) 517 C:=NewFPint(0) 518 519 // if E.INF {return} 520 521 A.add(E.z); A.norm() 522 AA.copy(A); AA.sqr() 523 B.sub(E.z); B.norm() 524 BB.copy(B); BB.sqr() 525 C.copy(AA); C.sub(BB) 526 C.norm() 527 528 E.x.copy(AA); E.x.mul(BB) 529 530 A.copy(C); A.imul((CURVE_A+2)/4) 531 532 BB.add(A); BB.norm() 533 E.z.copy(BB); E.z.mul(C) 534 } 535 return; 536 } 537 538 /* this+=Q */ 539 func (E *ECP) Add(Q *ECP) { 540 /* 541 if E.INF { 542 E.Copy(Q) 543 return 544 } 545 if Q.INF {return} 546 */ 547 if CURVETYPE==WEIERSTRASS { 548 if CURVE_A==0 { 549 b:=3*CURVE_B_I 550 t0:=NewFPcopy(E.x) 551 t0.mul(Q.x) 552 t1:=NewFPcopy(E.y) 553 t1.mul(Q.y) 554 t2:=NewFPcopy(E.z) 555 t2.mul(Q.z) 556 t3:=NewFPcopy(E.x) 557 t3.add(E.y); t3.norm() 558 t4:=NewFPcopy(Q.x) 559 t4.add(Q.y); t4.norm() 560 t3.mul(t4) 561 t4.copy(t0); t4.add(t1) 562 563 t3.sub(t4); t3.norm() 564 t4.copy(E.y) 565 t4.add(E.z); t4.norm() 566 x3:=NewFPcopy(Q.y) 567 x3.add(Q.z); x3.norm() 568 569 t4.mul(x3) 570 x3.copy(t1) 571 x3.add(t2) 572 573 t4.sub(x3); t4.norm() 574 x3.copy(E.x); x3.add(E.z); x3.norm() 575 y3:=NewFPcopy(Q.x) 576 y3.add(Q.z); y3.norm() 577 x3.mul(y3) 578 y3.copy(t0) 579 y3.add(t2) 580 y3.rsub(x3); y3.norm() 581 x3.copy(t0); x3.add(t0) 582 t0.add(x3); t0.norm() 583 t2.imul(b) 584 585 z3:=NewFPcopy(t1); z3.add(t2); z3.norm() 586 t1.sub(t2); t1.norm() 587 y3.imul(b) 588 589 x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2) 590 y3.mul(t0); t1.mul(z3); y3.add(t1) 591 t0.mul(t3); z3.mul(t4); z3.add(t0) 592 593 E.x.copy(x3); E.x.norm() 594 E.y.copy(y3); E.y.norm() 595 E.z.copy(z3); E.z.norm() 596 } else { 597 598 t0:=NewFPcopy(E.x) 599 t1:=NewFPcopy(E.y) 600 t2:=NewFPcopy(E.z) 601 t3:=NewFPcopy(E.x) 602 t4:=NewFPcopy(Q.x) 603 z3:=NewFPint(0) 604 y3:=NewFPcopy(Q.x) 605 x3:=NewFPcopy(Q.y) 606 b:=NewFPint(0) 607 608 if CURVE_B_I==0 {b.copy(NewFPbig(NewBIGints(CURVE_B)))} 609 610 t0.mul(Q.x) //1 611 t1.mul(Q.y) //2 612 t2.mul(Q.z) //3 613 614 t3.add(E.y); t3.norm() //4 615 t4.add(Q.y); t4.norm() //5 616 t3.mul(t4) //6 617 t4.copy(t0); t4.add(t1) //t4.norm(); //7 618 t3.sub(t4); t3.norm() //8 619 t4.copy(E.y); t4.add(E.z); t4.norm() //9 620 x3.add(Q.z); x3.norm() //10 621 t4.mul(x3) //11 622 x3.copy(t1); x3.add(t2) //x3.norm();//12 623 624 t4.sub(x3); t4.norm() //13 625 x3.copy(E.x); x3.add(E.z); x3.norm() //14 626 y3.add(Q.z); y3.norm() //15 627 628 x3.mul(y3) //16 629 y3.copy(t0); y3.add(t2) //y3.norm();//17 630 631 y3.rsub(x3); y3.norm() //18 632 z3.copy(t2) 633 634 if CURVE_B_I==0 { 635 z3.mul(b) 636 } else { 637 z3.imul(CURVE_B_I) 638 } 639 640 x3.copy(y3); x3.sub(z3); x3.norm() //20 641 z3.copy(x3); z3.add(x3) //z3.norm(); //21 642 643 x3.add(z3) //x3.norm(); //22 644 z3.copy(t1); z3.sub(x3); z3.norm() //23 645 x3.add(t1); x3.norm() //24 646 647 if CURVE_B_I==0 { 648 y3.mul(b) 649 } else { 650 y3.imul(CURVE_B_I) 651 } 652 653 t1.copy(t2); t1.add(t2); //t1.norm();//26 654 t2.add(t1) //t2.norm();//27 655 656 y3.sub(t2) //y3.norm(); //28 657 658 y3.sub(t0); y3.norm() //29 659 t1.copy(y3); t1.add(y3) //t1.norm();//30 660 y3.add(t1); y3.norm() //31 661 662 t1.copy(t0); t1.add(t0) //t1.norm(); //32 663 t0.add(t1) //t0.norm();//33 664 t0.sub(t2); t0.norm() //34 665 t1.copy(t4); t1.mul(y3) //35 666 t2.copy(t0); t2.mul(y3) //36 667 y3.copy(x3); y3.mul(z3) //37 668 y3.add(t2) //y3.norm();//38 669 x3.mul(t3) //39 670 x3.sub(t1) //40 671 z3.mul(t4) //41 672 t1.copy(t3); t1.mul(t0) //42 673 z3.add(t1) 674 E.x.copy(x3); E.x.norm() 675 E.y.copy(y3); E.y.norm() 676 E.z.copy(z3); E.z.norm() 677 678 } 679 } 680 if CURVETYPE==EDWARDS { 681 b:=NewFPbig(NewBIGints(CURVE_B)) 682 A:=NewFPcopy(E.z) 683 B:=NewFPint(0) 684 C:=NewFPcopy(E.x) 685 D:=NewFPcopy(E.y) 686 EE:=NewFPint(0) 687 F:=NewFPint(0) 688 G:=NewFPint(0) 689 690 A.mul(Q.z); 691 B.copy(A); B.sqr() 692 C.mul(Q.x) 693 D.mul(Q.y) 694 695 EE.copy(C); EE.mul(D); EE.mul(b) 696 F.copy(B); F.sub(EE) 697 G.copy(B); G.add(EE) 698 699 if CURVE_A==1 { 700 EE.copy(D); EE.sub(C) 701 } 702 C.add(D) 703 704 B.copy(E.x); B.add(E.y) 705 D.copy(Q.x); D.add(Q.y) 706 B.norm(); D.norm() 707 B.mul(D) 708 B.sub(C) 709 B.norm(); F.norm() 710 B.mul(F) 711 E.x.copy(A); E.x.mul(B) 712 G.norm() 713 if CURVE_A==1 { 714 EE.norm(); C.copy(EE); C.mul(G) 715 } 716 if CURVE_A==-1 { 717 C.norm(); C.mul(G) 718 } 719 E.y.copy(A); E.y.mul(C) 720 E.z.copy(F); E.z.mul(G) 721 } 722 return 723 } 724 725 /* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */ 726 func (E *ECP) dadd(Q *ECP,W *ECP) { 727 A:=NewFPcopy(E.x) 728 B:=NewFPcopy(E.x) 729 C:=NewFPcopy(Q.x) 730 D:=NewFPcopy(Q.x) 731 DA:=NewFPint(0) 732 CB:=NewFPint(0) 733 734 A.add(E.z) 735 B.sub(E.z) 736 737 C.add(Q.z) 738 D.sub(Q.z) 739 A.norm(); D.norm() 740 741 DA.copy(D); DA.mul(A) 742 C.norm(); B.norm() 743 744 CB.copy(C); CB.mul(B) 745 746 A.copy(DA); A.add(CB); A.norm(); A.sqr() 747 B.copy(DA); B.sub(CB); B.norm(); B.sqr() 748 749 E.x.copy(A) 750 E.z.copy(W.x); E.z.mul(B) 751 752 // if E.z.iszilch() { 753 // E.inf() 754 // } else {E.INF=false;} 755 756 } 757 758 /* this-=Q */ 759 func (E *ECP) Sub(Q *ECP) { 760 NQ:=NewECP(); NQ.Copy(Q); 761 NQ.neg() 762 E.Add(NQ) 763 } 764 765 /* constant time multiply by small integer of length bts - use ladder */ 766 func (E *ECP) pinmul(e int32,bts int32) *ECP { 767 if CURVETYPE==MONTGOMERY { 768 return E.mul(NewBIGint(int(e))) 769 } else { 770 P:=NewECP() 771 R0:=NewECP() 772 R1:=NewECP(); R1.Copy(E) 773 774 for i:=bts-1;i>=0;i-- { 775 b:=int((e>>uint32(i))&1) 776 P.Copy(R1) 777 P.Add(R0) 778 R0.cswap(R1,b) 779 R1.Copy(P) 780 R0.dbl() 781 R0.cswap(R1,b) 782 } 783 P.Copy(R0) 784 P.Affine() 785 return P 786 } 787 } 788 789 /* return e.this */ 790 791 func (E *ECP) mul(e *BIG) *ECP { 792 if (e.iszilch() || E.Is_infinity()) {return NewECP()} 793 P:=NewECP() 794 if CURVETYPE==MONTGOMERY { 795 /* use Ladder */ 796 D:=NewECP(); 797 R0:=NewECP(); R0.Copy(E) 798 R1:=NewECP(); R1.Copy(E) 799 R1.dbl() 800 D.Copy(E); D.Affine() 801 nb:=e.nbits() 802 for i:=nb-2;i>=0;i-- { 803 b:=int(e.bit(i)) 804 P.Copy(R1) 805 P.dadd(R0,D) 806 R0.cswap(R1,b) 807 R1.Copy(P) 808 R0.dbl() 809 R0.cswap(R1,b) 810 } 811 P.Copy(R0) 812 } else { 813 // fixed size windows 814 mt:=NewBIG() 815 t:=NewBIG() 816 Q:=NewECP() 817 C:=NewECP() 818 819 var W []*ECP 820 var w [1+(NLEN*int(BASEBITS)+3)/4]int8 821 822 //E.Affine(); 823 824 Q.Copy(E); 825 Q.dbl(); 826 827 W=append(W,NewECP()); 828 W[0].Copy(E); 829 830 for i:=1;i<8;i++ { 831 W=append(W,NewECP()) 832 W[i].Copy(W[i-1]) 833 W[i].Add(Q) 834 } 835 836 // make exponent odd - add 2P if even, P if odd 837 t.copy(e) 838 s:=int(t.parity()) 839 t.inc(1); t.norm(); ns:=int(t.parity()); mt.copy(t); mt.inc(1); mt.norm() 840 t.cmove(mt,s) 841 Q.cmove(E,ns) 842 C.Copy(Q) 843 844 nb:=1+(t.nbits()+3)/4 845 846 // convert exponent to signed 4-bit window 847 for i:=0;i<nb;i++ { 848 w[i]=int8(t.lastbits(5)-16) 849 t.dec(int(w[i])); t.norm() 850 t.fshr(4) 851 } 852 w[nb]=int8(t.lastbits(5)) 853 854 P.Copy(W[(int(w[nb])-1)/2]) 855 for i:=nb-1;i>=0;i-- { 856 Q.selector(W,int32(w[i])) 857 P.dbl() 858 P.dbl() 859 P.dbl() 860 P.dbl() 861 P.Add(Q) 862 } 863 P.Sub(C) /* apply correction */ 864 } 865 P.Affine() 866 return P 867 } 868 869 /* Public version */ 870 func (E *ECP) Mul(e *BIG) *ECP { 871 return E.mul(e) 872 } 873 874 /* Return e.this+f.Q */ 875 876 func (E *ECP) Mul2(e *BIG,Q *ECP,f *BIG) *ECP { 877 te:=NewBIG() 878 tf:=NewBIG() 879 mt:=NewBIG() 880 S:=NewECP() 881 T:=NewECP() 882 C:=NewECP() 883 var W [] *ECP 884 //ECP[] W=new ECP[8]; 885 var w [1+(NLEN*int(BASEBITS)+1)/2]int8 886 887 //E.Affine() 888 //Q.Affine() 889 890 te.copy(e) 891 tf.copy(f) 892 893 // precompute table 894 for i:=0;i<8;i++ { 895 W=append(W,NewECP()) 896 } 897 W[1].Copy(E); W[1].Sub(Q) 898 W[2].Copy(E); W[2].Add(Q); 899 S.Copy(Q); S.dbl(); 900 W[0].Copy(W[1]); W[0].Sub(S); 901 W[3].Copy(W[2]); W[3].Add(S); 902 T.Copy(E); T.dbl(); 903 W[5].Copy(W[1]); W[5].Add(T); 904 W[6].Copy(W[2]); W[6].Add(T); 905 W[4].Copy(W[5]); W[4].Sub(S); 906 W[7].Copy(W[6]); W[7].Add(S); 907 908 // if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 909 910 s:=int(te.parity()); 911 te.inc(1); te.norm(); ns:=int(te.parity()); mt.copy(te); mt.inc(1); mt.norm() 912 te.cmove(mt,s) 913 T.cmove(E,ns) 914 C.Copy(T) 915 916 s=int(tf.parity()) 917 tf.inc(1); tf.norm(); ns=int(tf.parity()); mt.copy(tf); mt.inc(1); mt.norm() 918 tf.cmove(mt,s) 919 S.cmove(Q,ns) 920 C.Add(S) 921 922 mt.copy(te); mt.add(tf); mt.norm() 923 nb:=1+(mt.nbits()+1)/2 924 925 // convert exponent to signed 2-bit window 926 for i:=0;i<nb;i++ { 927 a:=(te.lastbits(3)-4) 928 te.dec(int(a)); te.norm() 929 te.fshr(2) 930 b:=(tf.lastbits(3)-4) 931 tf.dec(int(b)); tf.norm() 932 tf.fshr(2) 933 w[i]=int8(4*a+b) 934 } 935 w[nb]=int8(4*te.lastbits(3)+tf.lastbits(3)) 936 S.Copy(W[(w[nb]-1)/2]) 937 938 for i:=nb-1;i>=0;i-- { 939 T.selector(W,int32(w[i])); 940 S.dbl() 941 S.dbl() 942 S.Add(T) 943 } 944 S.Sub(C) /* apply correction */ 945 S.Affine() 946 return S 947 } 948 949 func (E *ECP) cfp() { 950 cf:=CURVE_Cof_I; 951 if cf==1 {return} 952 if cf==4 { 953 E.dbl(); E.dbl() 954 //E.Affine(); 955 return; 956 } 957 if cf==8 { 958 E.dbl(); E.dbl(); E.dbl() 959 //E.Affine(); 960 return; 961 } 962 c:=NewBIGints(CURVE_Cof); 963 E.Copy(E.mul(c)); 964 } 965 966 func ECP_mapit(h []byte) *ECP { 967 q:=NewBIGints(Modulus) 968 x:=FromBytes(h[:]) 969 x.Mod(q) 970 var P *ECP 971 972 for true { 973 for true { 974 if CURVETYPE!=MONTGOMERY { 975 P=NewECPbigint(x,0) 976 } else { 977 P=NewECPbig(x) 978 } 979 x.inc(1); x.norm() 980 if !P.Is_infinity() {break} 981 } 982 P.cfp() 983 if !P.Is_infinity() {break} 984 } 985 986 return P 987 } 988 989 func ECP_generator() *ECP { 990 var G *ECP 991 992 gx:=NewBIGints(CURVE_Gx) 993 if CURVETYPE!=MONTGOMERY { 994 gy:=NewBIGints(CURVE_Gy) 995 G=NewECPbigs(gx,gy) 996 } else { 997 G=NewECPbig(gx) 998 } 999 return G 1000 } 1001 1002 /* 1003 func main() { 1004 Gx:=NewBIGints(CURVE_Gx); 1005 var Gy *BIG 1006 var P *ECP 1007 1008 if CURVETYPE!=MONTGOMERY {Gy=NewBIGints(CURVE_Gy)} 1009 r:=NewBIGints(CURVE_Order) 1010 1011 //r.dec(7); 1012 1013 fmt.Printf("Gx= "+Gx.toString()) 1014 fmt.Printf("\n") 1015 1016 if CURVETYPE!=MONTGOMERY { 1017 fmt.Printf("Gy= "+Gy.toString()) 1018 fmt.Printf("\n") 1019 } 1020 1021 if CURVETYPE!=MONTGOMERY { 1022 P=NewECPbigs(Gx,Gy) 1023 } else {P=NewECPbig(Gx)} 1024 1025 fmt.Printf("P= "+P.toString()); 1026 fmt.Printf("\n") 1027 1028 R:=P.mul(r); 1029 //for (int i=0;i<10000;i++) 1030 // R=P.mul(r); 1031 1032 fmt.Printf("R= "+R.toString()) 1033 fmt.Printf("\n") 1034 } 1035 */