github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/FP256BN/BIG.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 /* AMCL BIG number class */ 21 22 package FP256BN 23 24 import "strconv" 25 import "github.com/hellobchain/third_party/hyperledger/fabric-amcl/amcl" 26 27 const MODBYTES uint = 32 28 const BASEBITS uint = 56 29 30 const NLEN int = int((1 + ((8*MODBYTES - 1) / BASEBITS))) 31 const DNLEN int = 2 * NLEN 32 const BMASK Chunk = ((Chunk(1) << BASEBITS) - 1) 33 const HBITS uint = (BASEBITS / 2) 34 const HMASK Chunk = ((Chunk(1) << HBITS) - 1) 35 36 //const NEXCESS int=4 37 const NEXCESS int = (1 << (uint(CHUNK) - BASEBITS - 1)) 38 39 const BIGBITS int = int(MODBYTES * 8) 40 41 type BIG struct { 42 w [NLEN]Chunk 43 } 44 45 type DBIG struct { 46 w [2 * NLEN]Chunk 47 } 48 49 /* 50 func (r *BIG) isok() bool { 51 ok:=true 52 for i:=0;i<NLEN;i++ { 53 if (r.w[i]>>BASEBITS)!=0 { 54 ok=false 55 } 56 } 57 return ok; 58 } 59 */ 60 /***************** 64-bit specific code ****************/ 61 62 /* First the 32/64-bit dependent BIG code */ 63 /* Note that because of the lack of a 128-bit integer, 32 and 64-bit code needs to be done differently */ 64 65 /* return a*b as DBIG */ 66 func mul(a *BIG, b *BIG) *DBIG { 67 c := NewDBIG() 68 carry := Chunk(0) 69 // a.norm() 70 // b.norm() 71 72 // if !a.isok() || !b.isok() {fmt.Printf("Problem in mul\n")} 73 74 for i := 0; i < NLEN; i++ { 75 carry = 0 76 for j := 0; j < NLEN; j++ { 77 carry, c.w[i+j] = muladd(a.w[i], b.w[j], carry, c.w[i+j]) 78 //carry=c.muladd(a.w[i],b.w[j],carry,i+j) 79 } 80 c.w[NLEN+i] = carry 81 } 82 83 return c 84 } 85 86 /* return a^2 as DBIG */ 87 func sqr(a *BIG) *DBIG { 88 c := NewDBIG() 89 carry := Chunk(0) 90 // a.norm() 91 92 //if !a.isok() {fmt.Printf("Problem in sqr")} 93 94 for i := 0; i < NLEN; i++ { 95 carry = 0 96 for j := i + 1; j < NLEN; j++ { 97 carry, c.w[i+j] = muladd(2*a.w[i], a.w[j], carry, c.w[i+j]) 98 //carry=c.muladd(2*a.w[i],a.w[j],carry,i+j) 99 } 100 c.w[NLEN+i] = carry 101 } 102 103 for i := 0; i < NLEN; i++ { 104 top, bot := muladd(a.w[i], a.w[i], 0, c.w[2*i]) 105 c.w[2*i] = bot 106 c.w[2*i+1] += top 107 //c.w[2*i+1]+=c.muladd(a.w[i],a.w[i],0,2*i) 108 109 } 110 c.norm() 111 return c 112 } 113 114 func monty(md *BIG, mc Chunk, d *DBIG) *BIG { 115 carry := Chunk(0) 116 m := Chunk(0) 117 for i := 0; i < NLEN; i++ { 118 if mc == -1 { 119 m = (-d.w[i]) & BMASK 120 } else { 121 if mc == 1 { 122 m = d.w[i] 123 } else { 124 m = (mc * d.w[i]) & BMASK 125 } 126 } 127 128 carry = 0 129 for j := 0; j < NLEN; j++ { 130 carry, d.w[i+j] = muladd(m, md.w[j], carry, d.w[i+j]) 131 //carry=d.muladd(m,md.w[j],carry,i+j) 132 } 133 d.w[NLEN+i] += carry 134 } 135 136 b := NewBIG() 137 for i := 0; i < NLEN; i++ { 138 b.w[i] = d.w[NLEN+i] 139 } 140 b.norm() 141 return b 142 } 143 144 /* set this[i]+=x*y+c, and return high part */ 145 func muladd(a Chunk, b Chunk, c Chunk, r Chunk) (Chunk, Chunk) { 146 x0 := a & HMASK 147 x1 := (a >> HBITS) 148 y0 := b & HMASK 149 y1 := (b >> HBITS) 150 bot := x0 * y0 151 top := x1 * y1 152 mid := x0*y1 + x1*y0 153 x0 = mid & HMASK 154 x1 = (mid >> HBITS) 155 bot += x0 << HBITS 156 bot += c 157 bot += r 158 top += x1 159 carry := bot >> BASEBITS 160 bot &= BMASK 161 top += carry 162 return top, bot 163 } 164 165 /************************************************************/ 166 167 func (r *BIG) get(i int) Chunk { 168 return r.w[i] 169 } 170 171 func (r *BIG) set(i int, x Chunk) { 172 r.w[i] = x 173 } 174 175 func (r *BIG) xortop(x Chunk) { 176 r.w[NLEN-1] ^= x 177 } 178 179 /* normalise BIG - force all digits < 2^BASEBITS */ 180 func (r *BIG) norm() Chunk { 181 carry := Chunk(0) 182 for i := 0; i < NLEN-1; i++ { 183 d := r.w[i] + carry 184 r.w[i] = d & BMASK 185 carry = d >> BASEBITS 186 } 187 r.w[NLEN-1] = (r.w[NLEN-1] + carry) 188 return (r.w[NLEN-1] >> ((8 * MODBYTES) % BASEBITS)) 189 } 190 191 /* Shift right by less than a word */ 192 func (r *BIG) fshr(k uint) int { 193 w := r.w[0] & ((Chunk(1) << k) - 1) /* shifted out part */ 194 for i := 0; i < NLEN-1; i++ { 195 r.w[i] = (r.w[i] >> k) | ((r.w[i+1] << (BASEBITS - k)) & BMASK) 196 } 197 r.w[NLEN-1] = r.w[NLEN-1] >> k 198 return int(w) 199 } 200 201 /* Shift right by less than a word */ 202 func (r *BIG) fshl(k uint) int { 203 r.w[NLEN-1] = (r.w[NLEN-1] << k) | (r.w[NLEN-2] >> (BASEBITS - k)) 204 for i := NLEN - 2; i > 0; i-- { 205 r.w[i] = ((r.w[i] << k) & BMASK) | (r.w[i-1] >> (BASEBITS - k)) 206 } 207 r.w[0] = (r.w[0] << k) & BMASK 208 return int(r.w[NLEN-1] >> ((8 * MODBYTES) % BASEBITS)) /* return excess - only used in ff.c */ 209 } 210 211 func NewBIG() *BIG { 212 b := new(BIG) 213 for i := 0; i < NLEN; i++ { 214 b.w[i] = 0 215 } 216 return b 217 } 218 219 func NewBIGints(x [NLEN]Chunk) *BIG { 220 b := new(BIG) 221 for i := 0; i < NLEN; i++ { 222 b.w[i] = x[i] 223 } 224 return b 225 } 226 227 func NewBIGint(x int) *BIG { 228 b := new(BIG) 229 b.w[0] = Chunk(x) 230 for i := 1; i < NLEN; i++ { 231 b.w[i] = 0 232 } 233 return b 234 } 235 236 func NewBIGcopy(x *BIG) *BIG { 237 b := new(BIG) 238 for i := 0; i < NLEN; i++ { 239 b.w[i] = x.w[i] 240 } 241 return b 242 } 243 244 func NewBIGdcopy(x *DBIG) *BIG { 245 b := new(BIG) 246 for i := 0; i < NLEN; i++ { 247 b.w[i] = x.w[i] 248 } 249 return b 250 } 251 252 /* test for zero */ 253 func (r *BIG) iszilch() bool { 254 for i := 0; i < NLEN; i++ { 255 if r.w[i] != 0 { 256 return false 257 } 258 } 259 return true 260 } 261 262 /* set to zero */ 263 func (r *BIG) zero() { 264 for i := 0; i < NLEN; i++ { 265 r.w[i] = 0 266 } 267 } 268 269 /* Test for equal to one */ 270 func (r *BIG) isunity() bool { 271 for i := 1; i < NLEN; i++ { 272 if r.w[i] != 0 { 273 return false 274 } 275 } 276 if r.w[0] != 1 { 277 return false 278 } 279 return true 280 } 281 282 /* set to one */ 283 func (r *BIG) one() { 284 r.w[0] = 1 285 for i := 1; i < NLEN; i++ { 286 r.w[i] = 0 287 } 288 } 289 290 /* Copy from another BIG */ 291 func (r *BIG) copy(x *BIG) { 292 for i := 0; i < NLEN; i++ { 293 r.w[i] = x.w[i] 294 } 295 } 296 297 /* Copy from another DBIG */ 298 func (r *BIG) dcopy(x *DBIG) { 299 for i := 0; i < NLEN; i++ { 300 r.w[i] = x.w[i] 301 } 302 } 303 304 /* Conditional swap of two bigs depending on d using XOR - no branches */ 305 func (r *BIG) cswap(b *BIG, d int) { 306 c := Chunk(d) 307 c = ^(c - 1) 308 309 for i := 0; i < NLEN; i++ { 310 t := c & (r.w[i] ^ b.w[i]) 311 r.w[i] ^= t 312 b.w[i] ^= t 313 } 314 } 315 316 func (r *BIG) cmove(g *BIG, d int) { 317 b := Chunk(-d) 318 319 for i := 0; i < NLEN; i++ { 320 r.w[i] ^= (r.w[i] ^ g.w[i]) & b 321 } 322 } 323 324 /* general shift right */ 325 func (r *BIG) shr(k uint) { 326 n := (k % BASEBITS) 327 m := int(k / BASEBITS) 328 for i := 0; i < NLEN-m-1; i++ { 329 r.w[i] = (r.w[m+i] >> n) | ((r.w[m+i+1] << (BASEBITS - n)) & BMASK) 330 } 331 r.w[NLEN-m-1] = r.w[NLEN-1] >> n 332 for i := NLEN - m; i < NLEN; i++ { 333 r.w[i] = 0 334 } 335 } 336 337 /* general shift left */ 338 func (r *BIG) shl(k uint) { 339 n := k % BASEBITS 340 m := int(k / BASEBITS) 341 342 r.w[NLEN-1] = (r.w[NLEN-1-m] << n) 343 if NLEN >= m+2 { 344 r.w[NLEN-1] |= (r.w[NLEN-m-2] >> (BASEBITS - n)) 345 } 346 for i := NLEN - 2; i > m; i-- { 347 r.w[i] = ((r.w[i-m] << n) & BMASK) | (r.w[i-m-1] >> (BASEBITS - n)) 348 } 349 r.w[m] = (r.w[0] << n) & BMASK 350 for i := 0; i < m; i++ { 351 r.w[i] = 0 352 } 353 } 354 355 /* return number of bits */ 356 func (r *BIG) nbits() int { 357 t := NewBIGcopy(r) 358 k := NLEN - 1 359 t.norm() 360 for k >= 0 && t.w[k] == 0 { 361 k-- 362 } 363 if k < 0 { 364 return 0 365 } 366 bts := int(BASEBITS) * k 367 c := t.w[k] 368 for c != 0 { 369 c /= 2 370 bts++ 371 } 372 return bts 373 } 374 375 /* Convert to Hex String */ 376 func (r *BIG) toString() string { 377 s := "" 378 len := r.nbits() 379 380 if len%4 == 0 { 381 len /= 4 382 } else { 383 len /= 4 384 len++ 385 386 } 387 MB := int(MODBYTES * 2) 388 if len < MB { 389 len = MB 390 } 391 392 for i := len - 1; i >= 0; i-- { 393 b := NewBIGcopy(r) 394 395 b.shr(uint(i * 4)) 396 s += strconv.FormatInt(int64(b.w[0]&15), 16) 397 } 398 return s 399 } 400 401 func (r *BIG) add(x *BIG) { 402 for i := 0; i < NLEN; i++ { 403 r.w[i] = r.w[i] + x.w[i] 404 } 405 } 406 407 func (r *BIG) or(x *BIG) { 408 for i := 0; i < NLEN; i++ { 409 r.w[i] = r.w[i] | x.w[i] 410 } 411 } 412 413 /* return this+x */ 414 func (r *BIG) Plus(x *BIG) *BIG { 415 s := new(BIG) 416 for i := 0; i < NLEN; i++ { 417 s.w[i] = r.w[i] + x.w[i] 418 } 419 return s 420 } 421 422 /* this+=x, where x is int */ 423 func (r *BIG) inc(x int) { 424 r.norm() 425 r.w[0] += Chunk(x) 426 } 427 428 /* this*=c and catch overflow in DBIG */ 429 func (r *BIG) pxmul(c int) *DBIG { 430 m := NewDBIG() 431 carry := Chunk(0) 432 for j := 0; j < NLEN; j++ { 433 carry, m.w[j] = muladd(r.w[j], Chunk(c), carry, m.w[j]) 434 } 435 m.w[NLEN] = carry 436 return m 437 } 438 439 /* return this-x */ 440 func (r *BIG) Minus(x *BIG) *BIG { 441 d := new(BIG) 442 for i := 0; i < NLEN; i++ { 443 d.w[i] = r.w[i] - x.w[i] 444 } 445 return d 446 } 447 448 /* this-=x */ 449 func (r *BIG) sub(x *BIG) { 450 for i := 0; i < NLEN; i++ { 451 r.w[i] = r.w[i] - x.w[i] 452 } 453 } 454 455 /* reverse subtract this=x-this */ 456 func (r *BIG) rsub(x *BIG) { 457 for i := 0; i < NLEN; i++ { 458 r.w[i] = x.w[i] - r.w[i] 459 } 460 } 461 462 /* this-=x, where x is int */ 463 func (r *BIG) dec(x int) { 464 r.norm() 465 r.w[0] -= Chunk(x) 466 } 467 468 /* this*=x, where x is small int<NEXCESS */ 469 func (r *BIG) imul(c int) { 470 for i := 0; i < NLEN; i++ { 471 r.w[i] *= Chunk(c) 472 } 473 } 474 475 /* this*=x, where x is >NEXCESS */ 476 func (r *BIG) pmul(c int) Chunk { 477 carry := Chunk(0) 478 // r.norm(); 479 for i := 0; i < NLEN; i++ { 480 ak := r.w[i] 481 r.w[i] = 0 482 carry, r.w[i] = muladd(ak, Chunk(c), carry, r.w[i]) 483 } 484 return carry 485 } 486 487 /* convert this BIG to byte array */ 488 func (r *BIG) tobytearray(b []byte, n int) { 489 //r.norm(); 490 c := NewBIGcopy(r) 491 c.norm() 492 493 for i := int(MODBYTES) - 1; i >= 0; i-- { 494 b[i+n] = byte(c.w[0]) 495 c.fshr(8) 496 } 497 } 498 499 /* convert from byte array to BIG */ 500 func frombytearray(b []byte, n int) *BIG { 501 m := NewBIG() 502 for i := 0; i < int(MODBYTES); i++ { 503 m.fshl(8) 504 m.w[0] += Chunk(int(b[i+n] & 0xff)) 505 } 506 return m 507 } 508 509 func (r *BIG) ToBytes(b []byte) { 510 r.tobytearray(b, 0) 511 } 512 513 func FromBytes(b []byte) *BIG { 514 return frombytearray(b, 0) 515 } 516 517 /* divide by 3 */ 518 func (r *BIG) div3() int { 519 carry := Chunk(0) 520 r.norm() 521 base := (Chunk(1) << BASEBITS) 522 for i := NLEN - 1; i >= 0; i-- { 523 ak := (carry*base + r.w[i]) 524 r.w[i] = ak / 3 525 carry = ak % 3 526 } 527 return int(carry) 528 } 529 530 /* return a*b where result fits in a BIG */ 531 func smul(a *BIG, b *BIG) *BIG { 532 carry := Chunk(0) 533 c := NewBIG() 534 for i := 0; i < NLEN; i++ { 535 carry = 0 536 for j := 0; j < NLEN; j++ { 537 if i+j < NLEN { 538 carry, c.w[i+j] = muladd(a.w[i], b.w[j], carry, c.w[i+j]) 539 //carry=c.muladd(a.w[i],b.w[j],carry,i+j) 540 } 541 } 542 } 543 return c 544 } 545 546 /* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ 547 func comp(a *BIG, b *BIG) int { 548 for i := NLEN - 1; i >= 0; i-- { 549 if a.w[i] == b.w[i] { 550 continue 551 } 552 if a.w[i] > b.w[i] { 553 return 1 554 } else { 555 return -1 556 } 557 } 558 return 0 559 } 560 561 /* return parity */ 562 func (r *BIG) parity() int { 563 return int(r.w[0] % 2) 564 } 565 566 /* return n-th bit */ 567 func (r *BIG) bit(n int) int { 568 if (r.w[n/int(BASEBITS)] & (Chunk(1) << (uint(n) % BASEBITS))) > 0 { 569 return 1 570 } 571 return 0 572 } 573 574 /* return n last bits */ 575 func (r *BIG) lastbits(n int) int { 576 msk := (1 << uint(n)) - 1 577 r.norm() 578 return (int(r.w[0])) & msk 579 } 580 581 /* set x = x mod 2^m */ 582 func (r *BIG) mod2m(m uint) { 583 wd := int(m / BASEBITS) 584 bt := m % BASEBITS 585 msk := (Chunk(1) << bt) - 1 586 r.w[wd] &= msk 587 for i := wd + 1; i < NLEN; i++ { 588 r.w[i] = 0 589 } 590 } 591 592 /* a=1/a mod 2^256. This is very fast! */ 593 func (r *BIG) invmod2m() { 594 U := NewBIG() 595 b := NewBIG() 596 c := NewBIG() 597 598 U.inc(invmod256(r.lastbits(8))) 599 600 for i := 8; i < BIGBITS; i <<= 1 { 601 U.norm() 602 ui := uint(i) 603 b.copy(r) 604 b.mod2m(ui) 605 t1 := smul(U, b) 606 t1.shr(ui) 607 c.copy(r) 608 c.shr(ui) 609 c.mod2m(ui) 610 611 t2 := smul(U, c) 612 t2.mod2m(ui) 613 t1.add(t2) 614 t1.norm() 615 b = smul(t1, U) 616 t1.copy(b) 617 t1.mod2m(ui) 618 619 t2.one() 620 t2.shl(ui) 621 t1.rsub(t2) 622 t1.norm() 623 t1.shl(ui) 624 U.add(t1) 625 } 626 U.mod2m(8 * MODBYTES) 627 r.copy(U) 628 r.norm() 629 } 630 631 /* reduce this mod m */ 632 func (r *BIG) Mod(m1 *BIG) { 633 m := NewBIGcopy(m1) 634 sr := NewBIG() 635 r.norm() 636 if comp(r, m) < 0 { 637 return 638 } 639 640 m.fshl(1) 641 k := 1 642 643 for comp(r, m) >= 0 { 644 m.fshl(1) 645 k++ 646 } 647 648 for k > 0 { 649 m.fshr(1) 650 651 sr.copy(r) 652 sr.sub(m) 653 sr.norm() 654 r.cmove(sr, int(1-((sr.w[NLEN-1]>>uint(CHUNK-1))&1))) 655 /* 656 if comp(r,m)>=0 { 657 r.sub(m) 658 r.norm() 659 } */ 660 k-- 661 } 662 } 663 664 /* divide this by m */ 665 func (r *BIG) div(m1 *BIG) { 666 m := NewBIGcopy(m1) 667 var d int 668 k := 0 669 r.norm() 670 sr := NewBIG() 671 e := NewBIGint(1) 672 b := NewBIGcopy(r) 673 r.zero() 674 675 for comp(b, m) >= 0 { 676 e.fshl(1) 677 m.fshl(1) 678 k++ 679 } 680 681 for k > 0 { 682 m.fshr(1) 683 e.fshr(1) 684 685 sr.copy(b) 686 sr.sub(m) 687 sr.norm() 688 d = int(1 - ((sr.w[NLEN-1] >> uint(CHUNK-1)) & 1)) 689 b.cmove(sr, d) 690 sr.copy(r) 691 sr.add(e) 692 sr.norm() 693 r.cmove(sr, d) 694 /* 695 if comp(b,m)>=0 { 696 r.add(e) 697 r.norm() 698 b.sub(m) 699 b.norm() 700 } */ 701 k-- 702 } 703 } 704 705 /* get 8*MODBYTES size random number */ 706 func random(rng *amcl.RAND) *BIG { 707 m := NewBIG() 708 var j int = 0 709 var r byte = 0 710 /* generate random BIG */ 711 for i := 0; i < 8*int(MODBYTES); i++ { 712 if j == 0 { 713 r = rng.GetByte() 714 } else { 715 r >>= 1 716 } 717 718 b := Chunk(int(r & 1)) 719 m.shl(1) 720 m.w[0] += b // m.inc(b) 721 j++ 722 j &= 7 723 } 724 return m 725 } 726 727 /* Create random BIG in portable way, one bit at a time */ 728 func Randomnum(q *BIG, rng *amcl.RAND) *BIG { 729 d := NewDBIG() 730 var j int = 0 731 var r byte = 0 732 for i := 0; i < 2*q.nbits(); i++ { 733 if j == 0 { 734 r = rng.GetByte() 735 } else { 736 r >>= 1 737 } 738 739 b := Chunk(int(r & 1)) 740 d.shl(1) 741 d.w[0] += b // m.inc(b); 742 j++ 743 j &= 7 744 } 745 m := d.mod(q) 746 return m 747 } 748 749 /* return NAF value as +/- 1, 3 or 5. x and x3 should be normed. 750 nbs is number of bits processed, and nzs is number of trailing 0s detected */ 751 /* 752 func nafbits(x *BIG,x3 *BIG ,i int) [3]int { 753 var n [3]int 754 var j int 755 nb:=x3.bit(i)-x.bit(i) 756 757 758 n[1]=1 759 n[0]=0 760 if nb==0 {n[0]=0; return n} 761 if i==0 {n[0]=nb; return n} 762 if nb>0 { 763 n[0]=1; 764 } else {n[0]=(-1)} 765 766 for j=i-1;j>0;j-- { 767 n[1]++ 768 n[0]*=2 769 nb=x3.bit(j)-x.bit(j) 770 if nb>0 {n[0]+=1} 771 if nb<0 {n[0]-=1} 772 if (n[0]>5 || n[0] < -5) {break} 773 } 774 775 if n[0]%2!=0 && j!=0 { // backtrack 776 if nb>0 {n[0]=(n[0]-1)/2} 777 if nb<0 {n[0]=(n[0]+1)/2} 778 n[1]-- 779 } 780 for n[0]%2==0 { // remove trailing zeros 781 n[0]/=2 782 n[2]++ 783 n[1]-- 784 } 785 return n; 786 } 787 */ 788 789 /* return a*b mod m */ 790 func Modmul(a1, b1, m *BIG) *BIG { 791 a := NewBIGcopy(a1) 792 b := NewBIGcopy(b1) 793 a.Mod(m) 794 b.Mod(m) 795 d := mul(a, b) 796 return d.mod(m) 797 } 798 799 /* return a^2 mod m */ 800 func Modsqr(a1, m *BIG) *BIG { 801 a := NewBIGcopy(a1) 802 a.Mod(m) 803 d := sqr(a) 804 return d.mod(m) 805 } 806 807 /* return -a mod m */ 808 func Modneg(a1, m *BIG) *BIG { 809 a := NewBIGcopy(a1) 810 a.Mod(m) 811 return m.Minus(a) 812 } 813 814 /* Jacobi Symbol (this/p). Returns 0, 1 or -1 */ 815 func (r *BIG) Jacobi(p *BIG) int { 816 m := 0 817 t := NewBIGint(0) 818 x := NewBIGint(0) 819 n := NewBIGint(0) 820 zilch := NewBIGint(0) 821 one := NewBIGint(1) 822 if p.parity() == 0 || comp(r, zilch) == 0 || comp(p, one) <= 0 { 823 return 0 824 } 825 r.norm() 826 x.copy(r) 827 n.copy(p) 828 x.Mod(p) 829 830 for comp(n, one) > 0 { 831 if comp(x, zilch) == 0 { 832 return 0 833 } 834 n8 := n.lastbits(3) 835 k := 0 836 for x.parity() == 0 { 837 k++ 838 x.shr(1) 839 } 840 if k%2 == 1 { 841 m += (n8*n8 - 1) / 8 842 } 843 m += (n8 - 1) * (x.lastbits(2) - 1) / 4 844 t.copy(n) 845 t.Mod(x) 846 n.copy(x) 847 x.copy(t) 848 m %= 2 849 850 } 851 if m == 0 { 852 return 1 853 } 854 return -1 855 } 856 857 /* this=1/this mod p. Binary method */ 858 func (r *BIG) Invmodp(p *BIG) { 859 r.Mod(p) 860 u := NewBIGcopy(r) 861 862 v := NewBIGcopy(p) 863 x1 := NewBIGint(1) 864 x2 := NewBIGint(0) 865 t := NewBIGint(0) 866 one := NewBIGint(1) 867 for comp(u, one) != 0 && comp(v, one) != 0 { 868 for u.parity() == 0 { 869 u.fshr(1) 870 if x1.parity() != 0 { 871 x1.add(p) 872 x1.norm() 873 } 874 x1.fshr(1) 875 } 876 for v.parity() == 0 { 877 v.fshr(1) 878 if x2.parity() != 0 { 879 x2.add(p) 880 x2.norm() 881 } 882 x2.fshr(1) 883 } 884 if comp(u, v) >= 0 { 885 u.sub(v) 886 u.norm() 887 if comp(x1, x2) >= 0 { 888 x1.sub(x2) 889 } else { 890 t.copy(p) 891 t.sub(x2) 892 x1.add(t) 893 } 894 x1.norm() 895 } else { 896 v.sub(u) 897 v.norm() 898 if comp(x2, x1) >= 0 { 899 x2.sub(x1) 900 } else { 901 t.copy(p) 902 t.sub(x1) 903 x2.add(t) 904 } 905 x2.norm() 906 } 907 } 908 if comp(u, one) == 0 { 909 r.copy(x1) 910 } else { 911 r.copy(x2) 912 } 913 } 914 915 /* return this^e mod m */ 916 func (r *BIG) powmod(e1 *BIG, m *BIG) *BIG { 917 e := NewBIGcopy(e1) 918 r.norm() 919 e.norm() 920 a := NewBIGint(1) 921 z := NewBIGcopy(e) 922 s := NewBIGcopy(r) 923 for true { 924 bt := z.parity() 925 z.fshr(1) 926 if bt == 1 { 927 a = Modmul(a, s, m) 928 } 929 if z.iszilch() { 930 break 931 } 932 s = Modsqr(s, m) 933 } 934 return a 935 } 936 937 /* Arazi and Qi inversion mod 256 */ 938 func invmod256(a int) int { 939 var t1 int = 0 940 c := (a >> 1) & 1 941 t1 += c 942 t1 &= 1 943 t1 = 2 - t1 944 t1 <<= 1 945 U := t1 + 1 946 947 // i=2 948 b := a & 3 949 t1 = U * b 950 t1 >>= 2 951 c = (a >> 2) & 3 952 t2 := (U * c) & 3 953 t1 += t2 954 t1 *= U 955 t1 &= 3 956 t1 = 4 - t1 957 t1 <<= 2 958 U += t1 959 960 // i=4 961 b = a & 15 962 t1 = U * b 963 t1 >>= 4 964 c = (a >> 4) & 15 965 t2 = (U * c) & 15 966 t1 += t2 967 t1 *= U 968 t1 &= 15 969 t1 = 16 - t1 970 t1 <<= 4 971 U += t1 972 973 return U 974 } 975 976 func logb2(w uint32) uint { 977 v := w 978 v |= (v >> 1) 979 v |= (v >> 2) 980 v |= (v >> 4) 981 v |= (v >> 8) 982 v |= (v >> 16) 983 984 v = v - ((v >> 1) & 0x55555555) 985 v = (v & 0x33333333) + ((v >> 2) & 0x33333333) 986 r := uint((((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24) 987 return (r) 988 } 989 990 /* 991 func main() { 992 a := NewBIGint(3) 993 m := NewBIGints(Modulus) 994 995 fmt.Printf("Modulus= "+m.toString()) 996 fmt.Printf("\n") 997 998 999 e := NewBIGcopy(m); 1000 e.dec(1); e.norm(); 1001 fmt.Printf("Exponent= "+e.toString()) 1002 fmt.Printf("\n") 1003 a=a.powmod(e,m); 1004 fmt.Printf("Result= "+a.toString()) 1005 } 1006 */