1 package org.bouncycastle.math.raw; 2 3 import java.math.BigInteger; 4 5 import org.bouncycastle.util.Pack; 6 7 public abstract class Nat 8 { 9 private static final long M = 0xFFFFFFFFL; 10 add(int len, int[] x, int[] y, int[] z)11 public static int add(int len, int[] x, int[] y, int[] z) 12 { 13 long c = 0; 14 for (int i = 0; i < len; ++i) 15 { 16 c += (x[i] & M) + (y[i] & M); 17 z[i] = (int)c; 18 c >>>= 32; 19 } 20 return (int)c; 21 } 22 add33At(int len, int x, int[] z, int zPos)23 public static int add33At(int len, int x, int[] z, int zPos) 24 { 25 // assert zPos <= (len - 2); 26 long c = (z[zPos + 0] & M) + (x & M); 27 z[zPos + 0] = (int)c; 28 c >>>= 32; 29 c += (z[zPos + 1] & M) + 1L; 30 z[zPos + 1] = (int)c; 31 c >>>= 32; 32 return c == 0 ? 0 : incAt(len, z, zPos + 2); 33 } 34 add33At(int len, int x, int[] z, int zOff, int zPos)35 public static int add33At(int len, int x, int[] z, int zOff, int zPos) 36 { 37 // assert zPos <= (len - 2); 38 long c = (z[zOff + zPos] & M) + (x & M); 39 z[zOff + zPos] = (int)c; 40 c >>>= 32; 41 c += (z[zOff + zPos + 1] & M) + 1L; 42 z[zOff + zPos + 1] = (int)c; 43 c >>>= 32; 44 return c == 0 ? 0 : incAt(len, z, zOff, zPos + 2); 45 } 46 add33To(int len, int x, int[] z)47 public static int add33To(int len, int x, int[] z) 48 { 49 long c = (z[0] & M) + (x & M); 50 z[0] = (int)c; 51 c >>>= 32; 52 c += (z[1] & M) + 1L; 53 z[1] = (int)c; 54 c >>>= 32; 55 return c == 0 ? 0 : incAt(len, z, 2); 56 } 57 add33To(int len, int x, int[] z, int zOff)58 public static int add33To(int len, int x, int[] z, int zOff) 59 { 60 long c = (z[zOff + 0] & M) + (x & M); 61 z[zOff + 0] = (int)c; 62 c >>>= 32; 63 c += (z[zOff + 1] & M) + 1L; 64 z[zOff + 1] = (int)c; 65 c >>>= 32; 66 return c == 0 ? 0 : incAt(len, z, zOff, 2); 67 } 68 addBothTo(int len, int[] x, int[] y, int[] z)69 public static int addBothTo(int len, int[] x, int[] y, int[] z) 70 { 71 long c = 0; 72 for (int i = 0; i < len; ++i) 73 { 74 c += (x[i] & M) + (y[i] & M) + (z[i] & M); 75 z[i] = (int)c; 76 c >>>= 32; 77 } 78 return (int)c; 79 } 80 addBothTo(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)81 public static int addBothTo(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff) 82 { 83 long c = 0; 84 for (int i = 0; i < len; ++i) 85 { 86 c += (x[xOff + i] & M) + (y[yOff + i] & M) + (z[zOff + i] & M); 87 z[zOff + i] = (int)c; 88 c >>>= 32; 89 } 90 return (int)c; 91 } 92 addDWordAt(int len, long x, int[] z, int zPos)93 public static int addDWordAt(int len, long x, int[] z, int zPos) 94 { 95 // assert zPos <= (len - 2); 96 long c = (z[zPos + 0] & M) + (x & M); 97 z[zPos + 0] = (int)c; 98 c >>>= 32; 99 c += (z[zPos + 1] & M) + (x >>> 32); 100 z[zPos + 1] = (int)c; 101 c >>>= 32; 102 return c == 0 ? 0 : incAt(len, z, zPos + 2); 103 } 104 addDWordAt(int len, long x, int[] z, int zOff, int zPos)105 public static int addDWordAt(int len, long x, int[] z, int zOff, int zPos) 106 { 107 // assert zPos <= (len - 2); 108 long c = (z[zOff + zPos] & M) + (x & M); 109 z[zOff + zPos] = (int)c; 110 c >>>= 32; 111 c += (z[zOff + zPos + 1] & M) + (x >>> 32); 112 z[zOff + zPos + 1] = (int)c; 113 c >>>= 32; 114 return c == 0 ? 0 : incAt(len, z, zOff, zPos + 2); 115 } 116 addDWordTo(int len, long x, int[] z)117 public static int addDWordTo(int len, long x, int[] z) 118 { 119 long c = (z[0] & M) + (x & M); 120 z[0] = (int)c; 121 c >>>= 32; 122 c += (z[1] & M) + (x >>> 32); 123 z[1] = (int)c; 124 c >>>= 32; 125 return c == 0 ? 0 : incAt(len, z, 2); 126 } 127 addDWordTo(int len, long x, int[] z, int zOff)128 public static int addDWordTo(int len, long x, int[] z, int zOff) 129 { 130 long c = (z[zOff + 0] & M) + (x & M); 131 z[zOff + 0] = (int)c; 132 c >>>= 32; 133 c += (z[zOff + 1] & M) + (x >>> 32); 134 z[zOff + 1] = (int)c; 135 c >>>= 32; 136 return c == 0 ? 0 : incAt(len, z, zOff, 2); 137 } 138 addTo(int len, int[] x, int[] z)139 public static int addTo(int len, int[] x, int[] z) 140 { 141 long c = 0; 142 for (int i = 0; i < len; ++i) 143 { 144 c += (x[i] & M) + (z[i] & M); 145 z[i] = (int)c; 146 c >>>= 32; 147 } 148 return (int)c; 149 } 150 addTo(int len, int[] x, int xOff, int[] z, int zOff)151 public static int addTo(int len, int[] x, int xOff, int[] z, int zOff) 152 { 153 long c = 0; 154 for (int i = 0; i < len; ++i) 155 { 156 c += (x[xOff + i] & M) + (z[zOff + i] & M); 157 z[zOff + i] = (int)c; 158 c >>>= 32; 159 } 160 return (int)c; 161 } 162 addWordAt(int len, int x, int[] z, int zPos)163 public static int addWordAt(int len, int x, int[] z, int zPos) 164 { 165 // assert zPos <= (len - 1); 166 long c = (x & M) + (z[zPos] & M); 167 z[zPos] = (int)c; 168 c >>>= 32; 169 return c == 0 ? 0 : incAt(len, z, zPos + 1); 170 } 171 addWordAt(int len, int x, int[] z, int zOff, int zPos)172 public static int addWordAt(int len, int x, int[] z, int zOff, int zPos) 173 { 174 // assert zPos <= (len - 1); 175 long c = (x & M) + (z[zOff + zPos] & M); 176 z[zOff + zPos] = (int)c; 177 c >>>= 32; 178 return c == 0 ? 0 : incAt(len, z, zOff, zPos + 1); 179 } 180 addWordTo(int len, int x, int[] z)181 public static int addWordTo(int len, int x, int[] z) 182 { 183 long c = (x & M) + (z[0] & M); 184 z[0] = (int)c; 185 c >>>= 32; 186 return c == 0 ? 0 : incAt(len, z, 1); 187 } 188 addWordTo(int len, int x, int[] z, int zOff)189 public static int addWordTo(int len, int x, int[] z, int zOff) 190 { 191 long c = (x & M) + (z[zOff] & M); 192 z[zOff] = (int)c; 193 c >>>= 32; 194 return c == 0 ? 0 : incAt(len, z, zOff, 1); 195 } 196 copy(int len, int[] x)197 public static int[] copy(int len, int[] x) 198 { 199 int[] z = new int[len]; 200 System.arraycopy(x, 0, z, 0, len); 201 return z; 202 } 203 copy(int len, int[] x, int[] z)204 public static void copy(int len, int[] x, int[] z) 205 { 206 System.arraycopy(x, 0, z, 0, len); 207 } 208 create(int len)209 public static int[] create(int len) 210 { 211 return new int[len]; 212 } 213 create64(int len)214 public static long[] create64(int len) 215 { 216 return new long[len]; 217 } 218 dec(int len, int[] z)219 public static int dec(int len, int[] z) 220 { 221 for (int i = 0; i < len; ++i) 222 { 223 if (--z[i] != -1) 224 { 225 return 0; 226 } 227 } 228 return -1; 229 } 230 dec(int len, int[] x, int[] z)231 public static int dec(int len, int[] x, int[] z) 232 { 233 int i = 0; 234 while (i < len) 235 { 236 int c = x[i] - 1; 237 z[i] = c; 238 ++i; 239 if (c != -1) 240 { 241 while (i < len) 242 { 243 z[i] = x[i]; 244 ++i; 245 } 246 return 0; 247 } 248 } 249 return -1; 250 } 251 decAt(int len, int[] z, int zPos)252 public static int decAt(int len, int[] z, int zPos) 253 { 254 // assert zPos <= len; 255 for (int i = zPos; i < len; ++i) 256 { 257 if (--z[i] != -1) 258 { 259 return 0; 260 } 261 } 262 return -1; 263 } 264 decAt(int len, int[] z, int zOff, int zPos)265 public static int decAt(int len, int[] z, int zOff, int zPos) 266 { 267 // assert zPos <= len; 268 for (int i = zPos; i < len; ++i) 269 { 270 if (--z[zOff + i] != -1) 271 { 272 return 0; 273 } 274 } 275 return -1; 276 } 277 eq(int len, int[] x, int[] y)278 public static boolean eq(int len, int[] x, int[] y) 279 { 280 for (int i = len - 1; i >= 0; --i) 281 { 282 if (x[i] != y[i]) 283 { 284 return false; 285 } 286 } 287 return true; 288 } 289 fromBigInteger(int bits, BigInteger x)290 public static int[] fromBigInteger(int bits, BigInteger x) 291 { 292 if (x.signum() < 0 || x.bitLength() > bits) 293 { 294 throw new IllegalArgumentException(); 295 } 296 297 int len = (bits + 31) >> 5; 298 int[] z = create(len); 299 int i = 0; 300 while (x.signum() != 0) 301 { 302 z[i++] = x.intValue(); 303 x = x.shiftRight(32); 304 } 305 return z; 306 } 307 getBit(int[] x, int bit)308 public static int getBit(int[] x, int bit) 309 { 310 if (bit == 0) 311 { 312 return x[0] & 1; 313 } 314 int w = bit >> 5; 315 if (w < 0 || w >= x.length) 316 { 317 return 0; 318 } 319 int b = bit & 31; 320 return (x[w] >>> b) & 1; 321 } 322 gte(int len, int[] x, int[] y)323 public static boolean gte(int len, int[] x, int[] y) 324 { 325 for (int i = len - 1; i >= 0; --i) 326 { 327 int x_i = x[i] ^ Integer.MIN_VALUE; 328 int y_i = y[i] ^ Integer.MIN_VALUE; 329 if (x_i < y_i) 330 return false; 331 if (x_i > y_i) 332 return true; 333 } 334 return true; 335 } 336 inc(int len, int[] z)337 public static int inc(int len, int[] z) 338 { 339 for (int i = 0; i < len; ++i) 340 { 341 if (++z[i] != 0) 342 { 343 return 0; 344 } 345 } 346 return 1; 347 } 348 inc(int len, int[] x, int[] z)349 public static int inc(int len, int[] x, int[] z) 350 { 351 int i = 0; 352 while (i < len) 353 { 354 int c = x[i] + 1; 355 z[i] = c; 356 ++i; 357 if (c != 0) 358 { 359 while (i < len) 360 { 361 z[i] = x[i]; 362 ++i; 363 } 364 return 0; 365 } 366 } 367 return 1; 368 } 369 incAt(int len, int[] z, int zPos)370 public static int incAt(int len, int[] z, int zPos) 371 { 372 // assert zPos <= len; 373 for (int i = zPos; i < len; ++i) 374 { 375 if (++z[i] != 0) 376 { 377 return 0; 378 } 379 } 380 return 1; 381 } 382 incAt(int len, int[] z, int zOff, int zPos)383 public static int incAt(int len, int[] z, int zOff, int zPos) 384 { 385 // assert zPos <= len; 386 for (int i = zPos; i < len; ++i) 387 { 388 if (++z[zOff + i] != 0) 389 { 390 return 0; 391 } 392 } 393 return 1; 394 } 395 isOne(int len, int[] x)396 public static boolean isOne(int len, int[] x) 397 { 398 if (x[0] != 1) 399 { 400 return false; 401 } 402 for (int i = 1; i < len; ++i) 403 { 404 if (x[i] != 0) 405 { 406 return false; 407 } 408 } 409 return true; 410 } 411 isZero(int len, int[] x)412 public static boolean isZero(int len, int[] x) 413 { 414 for (int i = 0; i < len; ++i) 415 { 416 if (x[i] != 0) 417 { 418 return false; 419 } 420 } 421 return true; 422 } 423 mul(int len, int[] x, int[] y, int[] zz)424 public static void mul(int len, int[] x, int[] y, int[] zz) 425 { 426 zz[len] = mulWord(len, x[0], y, zz); 427 428 for (int i = 1; i < len; ++i) 429 { 430 zz[i + len] = mulWordAddTo(len, x[i], y, 0, zz, i); 431 } 432 } 433 mul(int len, int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)434 public static void mul(int len, int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff) 435 { 436 zz[zzOff + len] = mulWord(len, x[xOff], y, yOff, zz, zzOff); 437 438 for (int i = 1; i < len; ++i) 439 { 440 zz[zzOff + i + len] = mulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff + i); 441 } 442 } 443 mulAddTo(int len, int[] x, int[] y, int[] zz)444 public static int mulAddTo(int len, int[] x, int[] y, int[] zz) 445 { 446 long zc = 0; 447 for (int i = 0; i < len; ++i) 448 { 449 long c = mulWordAddTo(len, x[i], y, 0, zz, i) & M; 450 c += zc + (zz[i + len] & M); 451 zz[i + len] = (int)c; 452 zc = c >>> 32; 453 } 454 return (int)zc; 455 } 456 mulAddTo(int len, int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)457 public static int mulAddTo(int len, int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff) 458 { 459 long zc = 0; 460 for (int i = 0; i < len; ++i) 461 { 462 long c = mulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M; 463 c += zc + (zz[zzOff + len] & M); 464 zz[zzOff + len] = (int)c; 465 zc = c >>> 32; 466 ++zzOff; 467 } 468 return (int)zc; 469 } 470 mul31BothAdd(int len, int a, int[] x, int b, int[] y, int[] z, int zOff)471 public static int mul31BothAdd(int len, int a, int[] x, int b, int[] y, int[] z, int zOff) 472 { 473 long c = 0, aVal = a & M, bVal = b & M; 474 int i = 0; 475 do 476 { 477 c += aVal * (x[i] & M) + bVal * (y[i] & M) + (z[zOff + i] & M); 478 z[zOff + i] = (int)c; 479 c >>>= 32; 480 } 481 while (++i < len); 482 return (int)c; 483 } 484 mulWord(int len, int x, int[] y, int[] z)485 public static int mulWord(int len, int x, int[] y, int[] z) 486 { 487 long c = 0, xVal = x & M; 488 int i = 0; 489 do 490 { 491 c += xVal * (y[i] & M); 492 z[i] = (int)c; 493 c >>>= 32; 494 } 495 while (++i < len); 496 return (int)c; 497 } 498 mulWord(int len, int x, int[] y, int yOff, int[] z, int zOff)499 public static int mulWord(int len, int x, int[] y, int yOff, int[] z, int zOff) 500 { 501 long c = 0, xVal = x & M; 502 int i = 0; 503 do 504 { 505 c += xVal * (y[yOff + i] & M); 506 z[zOff + i] = (int)c; 507 c >>>= 32; 508 } 509 while (++i < len); 510 return (int)c; 511 } 512 mulWordAddTo(int len, int x, int[] y, int yOff, int[] z, int zOff)513 public static int mulWordAddTo(int len, int x, int[] y, int yOff, int[] z, int zOff) 514 { 515 long c = 0, xVal = x & M; 516 int i = 0; 517 do 518 { 519 c += xVal * (y[yOff + i] & M) + (z[zOff + i] & M); 520 z[zOff + i] = (int)c; 521 c >>>= 32; 522 } 523 while (++i < len); 524 return (int)c; 525 } 526 mulWordDwordAddAt(int len, int x, long y, int[] z, int zPos)527 public static int mulWordDwordAddAt(int len, int x, long y, int[] z, int zPos) 528 { 529 // assert zPos <= (len - 3); 530 long c = 0, xVal = x & M; 531 c += xVal * (y & M) + (z[zPos + 0] & M); 532 z[zPos + 0] = (int)c; 533 c >>>= 32; 534 c += xVal * (y >>> 32) + (z[zPos + 1] & M); 535 z[zPos + 1] = (int)c; 536 c >>>= 32; 537 c += (z[zPos + 2] & M); 538 z[zPos + 2] = (int)c; 539 c >>>= 32; 540 return c == 0 ? 0 : incAt(len, z, zPos + 3); 541 } 542 shiftDownBit(int len, int[] z, int c)543 public static int shiftDownBit(int len, int[] z, int c) 544 { 545 int i = len; 546 while (--i >= 0) 547 { 548 int next = z[i]; 549 z[i] = (next >>> 1) | (c << 31); 550 c = next; 551 } 552 return c << 31; 553 } 554 shiftDownBit(int len, int[] z, int zOff, int c)555 public static int shiftDownBit(int len, int[] z, int zOff, int c) 556 { 557 int i = len; 558 while (--i >= 0) 559 { 560 int next = z[zOff + i]; 561 z[zOff + i] = (next >>> 1) | (c << 31); 562 c = next; 563 } 564 return c << 31; 565 } 566 shiftDownBit(int len, int[] x, int c, int[] z)567 public static int shiftDownBit(int len, int[] x, int c, int[] z) 568 { 569 int i = len; 570 while (--i >= 0) 571 { 572 int next = x[i]; 573 z[i] = (next >>> 1) | (c << 31); 574 c = next; 575 } 576 return c << 31; 577 } 578 shiftDownBit(int len, int[] x, int xOff, int c, int[] z, int zOff)579 public static int shiftDownBit(int len, int[] x, int xOff, int c, int[] z, int zOff) 580 { 581 int i = len; 582 while (--i >= 0) 583 { 584 int next = x[xOff + i]; 585 z[zOff + i] = (next >>> 1) | (c << 31); 586 c = next; 587 } 588 return c << 31; 589 } 590 shiftDownBits(int len, int[] z, int bits, int c)591 public static int shiftDownBits(int len, int[] z, int bits, int c) 592 { 593 // assert bits > 0 && bits < 32; 594 int i = len; 595 while (--i >= 0) 596 { 597 int next = z[i]; 598 z[i] = (next >>> bits) | (c << -bits); 599 c = next; 600 } 601 return c << -bits; 602 } 603 shiftDownBits(int len, int[] z, int zOff, int bits, int c)604 public static int shiftDownBits(int len, int[] z, int zOff, int bits, int c) 605 { 606 // assert bits > 0 && bits < 32; 607 int i = len; 608 while (--i >= 0) 609 { 610 int next = z[zOff + i]; 611 z[zOff + i] = (next >>> bits) | (c << -bits); 612 c = next; 613 } 614 return c << -bits; 615 } 616 shiftDownBits(int len, int[] x, int bits, int c, int[] z)617 public static int shiftDownBits(int len, int[] x, int bits, int c, int[] z) 618 { 619 // assert bits > 0 && bits < 32; 620 int i = len; 621 while (--i >= 0) 622 { 623 int next = x[i]; 624 z[i] = (next >>> bits) | (c << -bits); 625 c = next; 626 } 627 return c << -bits; 628 } 629 shiftDownBits(int len, int[] x, int xOff, int bits, int c, int[] z, int zOff)630 public static int shiftDownBits(int len, int[] x, int xOff, int bits, int c, int[] z, int zOff) 631 { 632 // assert bits > 0 && bits < 32; 633 int i = len; 634 while (--i >= 0) 635 { 636 int next = x[xOff + i]; 637 z[zOff + i] = (next >>> bits) | (c << -bits); 638 c = next; 639 } 640 return c << -bits; 641 } 642 shiftDownWord(int len, int[] z, int c)643 public static int shiftDownWord(int len, int[] z, int c) 644 { 645 int i = len; 646 while (--i >= 0) 647 { 648 int next = z[i]; 649 z[i] = c; 650 c = next; 651 } 652 return c; 653 } 654 shiftUpBit(int len, int[] z, int c)655 public static int shiftUpBit(int len, int[] z, int c) 656 { 657 for (int i = 0; i < len; ++i) 658 { 659 int next = z[i]; 660 z[i] = (next << 1) | (c >>> 31); 661 c = next; 662 } 663 return c >>> 31; 664 } 665 shiftUpBit(int len, int[] z, int zOff, int c)666 public static int shiftUpBit(int len, int[] z, int zOff, int c) 667 { 668 for (int i = 0; i < len; ++i) 669 { 670 int next = z[zOff + i]; 671 z[zOff + i] = (next << 1) | (c >>> 31); 672 c = next; 673 } 674 return c >>> 31; 675 } 676 shiftUpBit(int len, int[] x, int c, int[] z)677 public static int shiftUpBit(int len, int[] x, int c, int[] z) 678 { 679 for (int i = 0; i < len; ++i) 680 { 681 int next = x[i]; 682 z[i] = (next << 1) | (c >>> 31); 683 c = next; 684 } 685 return c >>> 31; 686 } 687 shiftUpBit(int len, int[] x, int xOff, int c, int[] z, int zOff)688 public static int shiftUpBit(int len, int[] x, int xOff, int c, int[] z, int zOff) 689 { 690 for (int i = 0; i < len; ++i) 691 { 692 int next = x[xOff + i]; 693 z[zOff + i] = (next << 1) | (c >>> 31); 694 c = next; 695 } 696 return c >>> 31; 697 } 698 shiftUpBit64(int len, long[] x, int xOff, long c, long[] z, int zOff)699 public static long shiftUpBit64(int len, long[] x, int xOff, long c, long[] z, int zOff) 700 { 701 for (int i = 0; i < len; ++i) 702 { 703 long next = x[xOff + i]; 704 z[zOff + i] = (next << 1) | (c >>> 63); 705 c = next; 706 } 707 return c >>> 63; 708 } 709 shiftUpBits(int len, int[] z, int bits, int c)710 public static int shiftUpBits(int len, int[] z, int bits, int c) 711 { 712 // assert bits > 0 && bits < 32; 713 for (int i = 0; i < len; ++i) 714 { 715 int next = z[i]; 716 z[i] = (next << bits) | (c >>> -bits); 717 c = next; 718 } 719 return c >>> -bits; 720 } 721 shiftUpBits(int len, int[] z, int zOff, int bits, int c)722 public static int shiftUpBits(int len, int[] z, int zOff, int bits, int c) 723 { 724 // assert bits > 0 && bits < 32; 725 for (int i = 0; i < len; ++i) 726 { 727 int next = z[zOff + i]; 728 z[zOff + i] = (next << bits) | (c >>> -bits); 729 c = next; 730 } 731 return c >>> -bits; 732 } 733 shiftUpBits64(int len, long[] z, int zOff, int bits, long c)734 public static long shiftUpBits64(int len, long[] z, int zOff, int bits, long c) 735 { 736 // assert bits > 0 && bits < 64; 737 for (int i = 0; i < len; ++i) 738 { 739 long next = z[zOff + i]; 740 z[zOff + i] = (next << bits) | (c >>> -bits); 741 c = next; 742 } 743 return c >>> -bits; 744 } 745 shiftUpBits(int len, int[] x, int bits, int c, int[] z)746 public static int shiftUpBits(int len, int[] x, int bits, int c, int[] z) 747 { 748 // assert bits > 0 && bits < 32; 749 for (int i = 0; i < len; ++i) 750 { 751 int next = x[i]; 752 z[i] = (next << bits) | (c >>> -bits); 753 c = next; 754 } 755 return c >>> -bits; 756 } 757 shiftUpBits(int len, int[] x, int xOff, int bits, int c, int[] z, int zOff)758 public static int shiftUpBits(int len, int[] x, int xOff, int bits, int c, int[] z, int zOff) 759 { 760 // assert bits > 0 && bits < 32; 761 for (int i = 0; i < len; ++i) 762 { 763 int next = x[xOff + i]; 764 z[zOff + i] = (next << bits) | (c >>> -bits); 765 c = next; 766 } 767 return c >>> -bits; 768 } 769 shiftUpBits64(int len, long[] x, int xOff, int bits, long c, long[] z, int zOff)770 public static long shiftUpBits64(int len, long[] x, int xOff, int bits, long c, long[] z, int zOff) 771 { 772 // assert bits > 0 && bits < 64; 773 for (int i = 0; i < len; ++i) 774 { 775 long next = x[xOff + i]; 776 z[zOff + i] = (next << bits) | (c >>> -bits); 777 c = next; 778 } 779 return c >>> -bits; 780 } 781 square(int len, int[] x, int[] zz)782 public static void square(int len, int[] x, int[] zz) 783 { 784 int extLen = len << 1; 785 int c = 0; 786 int j = len, k = extLen; 787 do 788 { 789 long xVal = (x[--j] & M); 790 long p = xVal * xVal; 791 zz[--k] = (c << 31) | (int)(p >>> 33); 792 zz[--k] = (int)(p >>> 1); 793 c = (int)p; 794 } 795 while (j > 0); 796 797 for (int i = 1; i < len; ++i) 798 { 799 c = squareWordAdd(x, i, zz); 800 addWordAt(extLen, c, zz, i << 1); 801 } 802 803 shiftUpBit(extLen, zz, x[0] << 31); 804 } 805 square(int len, int[] x, int xOff, int[] zz, int zzOff)806 public static void square(int len, int[] x, int xOff, int[] zz, int zzOff) 807 { 808 int extLen = len << 1; 809 int c = 0; 810 int j = len, k = extLen; 811 do 812 { 813 long xVal = (x[xOff + --j] & M); 814 long p = xVal * xVal; 815 zz[zzOff + --k] = (c << 31) | (int)(p >>> 33); 816 zz[zzOff + --k] = (int)(p >>> 1); 817 c = (int)p; 818 } 819 while (j > 0); 820 821 for (int i = 1; i < len; ++i) 822 { 823 c = squareWordAdd(x, xOff, i, zz, zzOff); 824 addWordAt(extLen, c, zz, zzOff, i << 1); 825 } 826 827 shiftUpBit(extLen, zz, zzOff, x[xOff] << 31); 828 } 829 squareWordAdd(int[] x, int xPos, int[] z)830 public static int squareWordAdd(int[] x, int xPos, int[] z) 831 { 832 long c = 0, xVal = x[xPos] & M; 833 int i = 0; 834 do 835 { 836 c += xVal * (x[i] & M) + (z[xPos + i] & M); 837 z[xPos + i] = (int)c; 838 c >>>= 32; 839 } 840 while (++i < xPos); 841 return (int)c; 842 } 843 squareWordAdd(int[] x, int xOff, int xPos, int[] z, int zOff)844 public static int squareWordAdd(int[] x, int xOff, int xPos, int[] z, int zOff) 845 { 846 long c = 0, xVal = x[xOff + xPos] & M; 847 int i = 0; 848 do 849 { 850 c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M); 851 z[xPos + zOff] = (int)c; 852 c >>>= 32; 853 ++zOff; 854 } 855 while (++i < xPos); 856 return (int)c; 857 } 858 sub(int len, int[] x, int[] y, int[] z)859 public static int sub(int len, int[] x, int[] y, int[] z) 860 { 861 long c = 0; 862 for (int i = 0; i < len; ++i) 863 { 864 c += (x[i] & M) - (y[i] & M); 865 z[i] = (int)c; 866 c >>= 32; 867 } 868 return (int)c; 869 } 870 sub(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)871 public static int sub(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff) 872 { 873 long c = 0; 874 for (int i = 0; i < len; ++i) 875 { 876 c += (x[xOff + i] & M) - (y[yOff + i] & M); 877 z[zOff + i] = (int)c; 878 c >>= 32; 879 } 880 return (int)c; 881 } 882 sub33At(int len, int x, int[] z, int zPos)883 public static int sub33At(int len, int x, int[] z, int zPos) 884 { 885 // assert zPos <= (len - 2); 886 long c = (z[zPos + 0] & M) - (x & M); 887 z[zPos + 0] = (int)c; 888 c >>= 32; 889 c += (z[zPos + 1] & M) - 1; 890 z[zPos + 1] = (int)c; 891 c >>= 32; 892 return c == 0 ? 0 : decAt(len, z, zPos + 2); 893 } 894 sub33At(int len, int x, int[] z, int zOff, int zPos)895 public static int sub33At(int len, int x, int[] z, int zOff, int zPos) 896 { 897 // assert zPos <= (len - 2); 898 long c = (z[zOff + zPos] & M) - (x & M); 899 z[zOff + zPos] = (int)c; 900 c >>= 32; 901 c += (z[zOff + zPos + 1] & M) - 1; 902 z[zOff + zPos + 1] = (int)c; 903 c >>= 32; 904 return c == 0 ? 0 : decAt(len, z, zOff, zPos + 2); 905 } 906 sub33From(int len, int x, int[] z)907 public static int sub33From(int len, int x, int[] z) 908 { 909 long c = (z[0] & M) - (x & M); 910 z[0] = (int)c; 911 c >>= 32; 912 c += (z[1] & M) - 1; 913 z[1] = (int)c; 914 c >>= 32; 915 return c == 0 ? 0 : decAt(len, z, 2); 916 } 917 sub33From(int len, int x, int[] z, int zOff)918 public static int sub33From(int len, int x, int[] z, int zOff) 919 { 920 long c = (z[zOff + 0] & M) - (x & M); 921 z[zOff + 0] = (int)c; 922 c >>= 32; 923 c += (z[zOff + 1] & M) - 1; 924 z[zOff + 1] = (int)c; 925 c >>= 32; 926 return c == 0 ? 0 : decAt(len, z, zOff, 2); 927 } 928 subBothFrom(int len, int[] x, int[] y, int[] z)929 public static int subBothFrom(int len, int[] x, int[] y, int[] z) 930 { 931 long c = 0; 932 for (int i = 0; i < len; ++i) 933 { 934 c += (z[i] & M) - (x[i] & M) - (y[i] & M); 935 z[i] = (int)c; 936 c >>= 32; 937 } 938 return (int)c; 939 } 940 subBothFrom(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)941 public static int subBothFrom(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff) 942 { 943 long c = 0; 944 for (int i = 0; i < len; ++i) 945 { 946 c += (z[zOff + i] & M) - (x[xOff + i] & M) - (y[yOff + i] & M); 947 z[zOff + i] = (int)c; 948 c >>= 32; 949 } 950 return (int)c; 951 } 952 subDWordAt(int len, long x, int[] z, int zPos)953 public static int subDWordAt(int len, long x, int[] z, int zPos) 954 { 955 // assert zPos <= (len - 2); 956 long c = (z[zPos + 0] & M) - (x & M); 957 z[zPos + 0] = (int)c; 958 c >>= 32; 959 c += (z[zPos + 1] & M) - (x >>> 32); 960 z[zPos + 1] = (int)c; 961 c >>= 32; 962 return c == 0 ? 0 : decAt(len, z, zPos + 2); 963 } 964 subDWordAt(int len, long x, int[] z, int zOff, int zPos)965 public static int subDWordAt(int len, long x, int[] z, int zOff, int zPos) 966 { 967 // assert zPos <= (len - 2); 968 long c = (z[zOff + zPos] & M) - (x & M); 969 z[zOff + zPos] = (int)c; 970 c >>= 32; 971 c += (z[zOff + zPos + 1] & M) - (x >>> 32); 972 z[zOff + zPos + 1] = (int)c; 973 c >>= 32; 974 return c == 0 ? 0 : decAt(len, z, zOff, zPos + 2); 975 } 976 subDWordFrom(int len, long x, int[] z)977 public static int subDWordFrom(int len, long x, int[] z) 978 { 979 long c = (z[0] & M) - (x & M); 980 z[0] = (int)c; 981 c >>= 32; 982 c += (z[1] & M) - (x >>> 32); 983 z[1] = (int)c; 984 c >>= 32; 985 return c == 0 ? 0 : decAt(len, z, 2); 986 } 987 subDWordFrom(int len, long x, int[] z, int zOff)988 public static int subDWordFrom(int len, long x, int[] z, int zOff) 989 { 990 long c = (z[zOff + 0] & M) - (x & M); 991 z[zOff + 0] = (int)c; 992 c >>= 32; 993 c += (z[zOff + 1] & M) - (x >>> 32); 994 z[zOff + 1] = (int)c; 995 c >>= 32; 996 return c == 0 ? 0 : decAt(len, z, zOff, 2); 997 } 998 subFrom(int len, int[] x, int[] z)999 public static int subFrom(int len, int[] x, int[] z) 1000 { 1001 long c = 0; 1002 for (int i = 0; i < len; ++i) 1003 { 1004 c += (z[i] & M) - (x[i] & M); 1005 z[i] = (int)c; 1006 c >>= 32; 1007 } 1008 return (int)c; 1009 } 1010 subFrom(int len, int[] x, int xOff, int[] z, int zOff)1011 public static int subFrom(int len, int[] x, int xOff, int[] z, int zOff) 1012 { 1013 long c = 0; 1014 for (int i = 0; i < len; ++i) 1015 { 1016 c += (z[zOff + i] & M) - (x[xOff + i] & M); 1017 z[zOff + i] = (int)c; 1018 c >>= 32; 1019 } 1020 return (int)c; 1021 } 1022 subWordAt(int len, int x, int[] z, int zPos)1023 public static int subWordAt(int len, int x, int[] z, int zPos) 1024 { 1025 // assert zPos <= (len - 1); 1026 long c = (z[zPos] & M) - (x & M); 1027 z[zPos] = (int)c; 1028 c >>= 32; 1029 return c == 0 ? 0 : decAt(len, z, zPos + 1); 1030 } 1031 subWordAt(int len, int x, int[] z, int zOff, int zPos)1032 public static int subWordAt(int len, int x, int[] z, int zOff, int zPos) 1033 { 1034 // assert zPos <= (len - 1); 1035 long c = (z[zOff + zPos] & M) - (x & M); 1036 z[zOff + zPos] = (int)c; 1037 c >>= 32; 1038 return c == 0 ? 0 : decAt(len, z, zOff, zPos + 1); 1039 } 1040 subWordFrom(int len, int x, int[] z)1041 public static int subWordFrom(int len, int x, int[] z) 1042 { 1043 long c = (z[0] & M) - (x & M); 1044 z[0] = (int)c; 1045 c >>= 32; 1046 return c == 0 ? 0 : decAt(len, z, 1); 1047 } 1048 subWordFrom(int len, int x, int[] z, int zOff)1049 public static int subWordFrom(int len, int x, int[] z, int zOff) 1050 { 1051 long c = (z[zOff + 0] & M) - (x & M); 1052 z[zOff + 0] = (int)c; 1053 c >>= 32; 1054 return c == 0 ? 0 : decAt(len, z, zOff, 1); 1055 } 1056 toBigInteger(int len, int[] x)1057 public static BigInteger toBigInteger(int len, int[] x) 1058 { 1059 byte[] bs = new byte[len << 2]; 1060 for (int i = 0; i < len; ++i) 1061 { 1062 int x_i = x[i]; 1063 if (x_i != 0) 1064 { 1065 Pack.intToBigEndian(x_i, bs, (len - 1 - i) << 2); 1066 } 1067 } 1068 return new BigInteger(1, bs); 1069 } 1070 zero(int len, int[] z)1071 public static void zero(int len, int[] z) 1072 { 1073 for (int i = 0; i < len; ++i) 1074 { 1075 z[i] = 0; 1076 } 1077 } 1078 zero64(int len, long[] z)1079 public static void zero64(int len, long[] z) 1080 { 1081 for (int i = 0; i < len; ++i) 1082 { 1083 z[i] = 0L; 1084 } 1085 } 1086 } 1087