1 package org.bouncycastle.math.raw; 2 3 import java.math.BigInteger; 4 5 import org.bouncycastle.util.Pack; 6 7 public abstract class Nat256 8 { 9 private static final long M = 0xFFFFFFFFL; 10 add(int[] x, int[] y, int[] z)11 public static int add(int[] x, int[] y, int[] z) 12 { 13 long c = 0; 14 c += (x[0] & M) + (y[0] & M); 15 z[0] = (int)c; 16 c >>>= 32; 17 c += (x[1] & M) + (y[1] & M); 18 z[1] = (int)c; 19 c >>>= 32; 20 c += (x[2] & M) + (y[2] & M); 21 z[2] = (int)c; 22 c >>>= 32; 23 c += (x[3] & M) + (y[3] & M); 24 z[3] = (int)c; 25 c >>>= 32; 26 c += (x[4] & M) + (y[4] & M); 27 z[4] = (int)c; 28 c >>>= 32; 29 c += (x[5] & M) + (y[5] & M); 30 z[5] = (int)c; 31 c >>>= 32; 32 c += (x[6] & M) + (y[6] & M); 33 z[6] = (int)c; 34 c >>>= 32; 35 c += (x[7] & M) + (y[7] & M); 36 z[7] = (int)c; 37 c >>>= 32; 38 return (int)c; 39 } 40 add(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)41 public static int add(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff) 42 { 43 long c = 0; 44 c += (x[xOff + 0] & M) + (y[yOff + 0] & M); 45 z[zOff + 0] = (int)c; 46 c >>>= 32; 47 c += (x[xOff + 1] & M) + (y[yOff + 1] & M); 48 z[zOff + 1] = (int)c; 49 c >>>= 32; 50 c += (x[xOff + 2] & M) + (y[yOff + 2] & M); 51 z[zOff + 2] = (int)c; 52 c >>>= 32; 53 c += (x[xOff + 3] & M) + (y[yOff + 3] & M); 54 z[zOff + 3] = (int)c; 55 c >>>= 32; 56 c += (x[xOff + 4] & M) + (y[yOff + 4] & M); 57 z[zOff + 4] = (int)c; 58 c >>>= 32; 59 c += (x[xOff + 5] & M) + (y[yOff + 5] & M); 60 z[zOff + 5] = (int)c; 61 c >>>= 32; 62 c += (x[xOff + 6] & M) + (y[yOff + 6] & M); 63 z[zOff + 6] = (int)c; 64 c >>>= 32; 65 c += (x[xOff + 7] & M) + (y[yOff + 7] & M); 66 z[zOff + 7] = (int)c; 67 c >>>= 32; 68 return (int)c; 69 } 70 addBothTo(int[] x, int[] y, int[] z)71 public static int addBothTo(int[] x, int[] y, int[] z) 72 { 73 long c = 0; 74 c += (x[0] & M) + (y[0] & M) + (z[0] & M); 75 z[0] = (int)c; 76 c >>>= 32; 77 c += (x[1] & M) + (y[1] & M) + (z[1] & M); 78 z[1] = (int)c; 79 c >>>= 32; 80 c += (x[2] & M) + (y[2] & M) + (z[2] & M); 81 z[2] = (int)c; 82 c >>>= 32; 83 c += (x[3] & M) + (y[3] & M) + (z[3] & M); 84 z[3] = (int)c; 85 c >>>= 32; 86 c += (x[4] & M) + (y[4] & M) + (z[4] & M); 87 z[4] = (int)c; 88 c >>>= 32; 89 c += (x[5] & M) + (y[5] & M) + (z[5] & M); 90 z[5] = (int)c; 91 c >>>= 32; 92 c += (x[6] & M) + (y[6] & M) + (z[6] & M); 93 z[6] = (int)c; 94 c >>>= 32; 95 c += (x[7] & M) + (y[7] & M) + (z[7] & M); 96 z[7] = (int)c; 97 c >>>= 32; 98 return (int)c; 99 } 100 addBothTo(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)101 public static int addBothTo(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff) 102 { 103 long c = 0; 104 c += (x[xOff + 0] & M) + (y[yOff + 0] & M) + (z[zOff + 0] & M); 105 z[zOff + 0] = (int)c; 106 c >>>= 32; 107 c += (x[xOff + 1] & M) + (y[yOff + 1] & M) + (z[zOff + 1] & M); 108 z[zOff + 1] = (int)c; 109 c >>>= 32; 110 c += (x[xOff + 2] & M) + (y[yOff + 2] & M) + (z[zOff + 2] & M); 111 z[zOff + 2] = (int)c; 112 c >>>= 32; 113 c += (x[xOff + 3] & M) + (y[yOff + 3] & M) + (z[zOff + 3] & M); 114 z[zOff + 3] = (int)c; 115 c >>>= 32; 116 c += (x[xOff + 4] & M) + (y[yOff + 4] & M) + (z[zOff + 4] & M); 117 z[zOff + 4] = (int)c; 118 c >>>= 32; 119 c += (x[xOff + 5] & M) + (y[yOff + 5] & M) + (z[zOff + 5] & M); 120 z[zOff + 5] = (int)c; 121 c >>>= 32; 122 c += (x[xOff + 6] & M) + (y[yOff + 6] & M) + (z[zOff + 6] & M); 123 z[zOff + 6] = (int)c; 124 c >>>= 32; 125 c += (x[xOff + 7] & M) + (y[yOff + 7] & M) + (z[zOff + 7] & M); 126 z[zOff + 7] = (int)c; 127 c >>>= 32; 128 return (int)c; 129 } 130 addTo(int[] x, int[] z)131 public static int addTo(int[] x, int[] z) 132 { 133 long c = 0; 134 c += (x[0] & M) + (z[0] & M); 135 z[0] = (int)c; 136 c >>>= 32; 137 c += (x[1] & M) + (z[1] & M); 138 z[1] = (int)c; 139 c >>>= 32; 140 c += (x[2] & M) + (z[2] & M); 141 z[2] = (int)c; 142 c >>>= 32; 143 c += (x[3] & M) + (z[3] & M); 144 z[3] = (int)c; 145 c >>>= 32; 146 c += (x[4] & M) + (z[4] & M); 147 z[4] = (int)c; 148 c >>>= 32; 149 c += (x[5] & M) + (z[5] & M); 150 z[5] = (int)c; 151 c >>>= 32; 152 c += (x[6] & M) + (z[6] & M); 153 z[6] = (int)c; 154 c >>>= 32; 155 c += (x[7] & M) + (z[7] & M); 156 z[7] = (int)c; 157 c >>>= 32; 158 return (int)c; 159 } 160 addTo(int[] x, int xOff, int[] z, int zOff, int cIn)161 public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn) 162 { 163 long c = cIn & M; 164 c += (x[xOff + 0] & M) + (z[zOff + 0] & M); 165 z[zOff + 0] = (int)c; 166 c >>>= 32; 167 c += (x[xOff + 1] & M) + (z[zOff + 1] & M); 168 z[zOff + 1] = (int)c; 169 c >>>= 32; 170 c += (x[xOff + 2] & M) + (z[zOff + 2] & M); 171 z[zOff + 2] = (int)c; 172 c >>>= 32; 173 c += (x[xOff + 3] & M) + (z[zOff + 3] & M); 174 z[zOff + 3] = (int)c; 175 c >>>= 32; 176 c += (x[xOff + 4] & M) + (z[zOff + 4] & M); 177 z[zOff + 4] = (int)c; 178 c >>>= 32; 179 c += (x[xOff + 5] & M) + (z[zOff + 5] & M); 180 z[zOff + 5] = (int)c; 181 c >>>= 32; 182 c += (x[xOff + 6] & M) + (z[zOff + 6] & M); 183 z[zOff + 6] = (int)c; 184 c >>>= 32; 185 c += (x[xOff + 7] & M) + (z[zOff + 7] & M); 186 z[zOff + 7] = (int)c; 187 c >>>= 32; 188 return (int)c; 189 } 190 addToEachOther(int[] u, int uOff, int[] v, int vOff)191 public static int addToEachOther(int[] u, int uOff, int[] v, int vOff) 192 { 193 long c = 0; 194 c += (u[uOff + 0] & M) + (v[vOff + 0] & M); 195 u[uOff + 0] = (int)c; 196 v[vOff + 0] = (int)c; 197 c >>>= 32; 198 c += (u[uOff + 1] & M) + (v[vOff + 1] & M); 199 u[uOff + 1] = (int)c; 200 v[vOff + 1] = (int)c; 201 c >>>= 32; 202 c += (u[uOff + 2] & M) + (v[vOff + 2] & M); 203 u[uOff + 2] = (int)c; 204 v[vOff + 2] = (int)c; 205 c >>>= 32; 206 c += (u[uOff + 3] & M) + (v[vOff + 3] & M); 207 u[uOff + 3] = (int)c; 208 v[vOff + 3] = (int)c; 209 c >>>= 32; 210 c += (u[uOff + 4] & M) + (v[vOff + 4] & M); 211 u[uOff + 4] = (int)c; 212 v[vOff + 4] = (int)c; 213 c >>>= 32; 214 c += (u[uOff + 5] & M) + (v[vOff + 5] & M); 215 u[uOff + 5] = (int)c; 216 v[vOff + 5] = (int)c; 217 c >>>= 32; 218 c += (u[uOff + 6] & M) + (v[vOff + 6] & M); 219 u[uOff + 6] = (int)c; 220 v[vOff + 6] = (int)c; 221 c >>>= 32; 222 c += (u[uOff + 7] & M) + (v[vOff + 7] & M); 223 u[uOff + 7] = (int)c; 224 v[vOff + 7] = (int)c; 225 c >>>= 32; 226 return (int)c; 227 } 228 copy(int[] x, int[] z)229 public static void copy(int[] x, int[] z) 230 { 231 z[0] = x[0]; 232 z[1] = x[1]; 233 z[2] = x[2]; 234 z[3] = x[3]; 235 z[4] = x[4]; 236 z[5] = x[5]; 237 z[6] = x[6]; 238 z[7] = x[7]; 239 } 240 copy64(long[] x, long[] z)241 public static void copy64(long[] x, long[] z) 242 { 243 z[0] = x[0]; 244 z[1] = x[1]; 245 z[2] = x[2]; 246 z[3] = x[3]; 247 } 248 create()249 public static int[] create() 250 { 251 return new int[8]; 252 } 253 create64()254 public static long[] create64() 255 { 256 return new long[4]; 257 } 258 createExt()259 public static int[] createExt() 260 { 261 return new int[16]; 262 } 263 createExt64()264 public static long[] createExt64() 265 { 266 return new long[8]; 267 } 268 diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)269 public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff) 270 { 271 boolean pos = gte(x, xOff, y, yOff); 272 if (pos) 273 { 274 sub(x, xOff, y, yOff, z, zOff); 275 } 276 else 277 { 278 sub(y, yOff, x, xOff, z, zOff); 279 } 280 return pos; 281 } 282 eq(int[] x, int[] y)283 public static boolean eq(int[] x, int[] y) 284 { 285 for (int i = 7; i >= 0; --i) 286 { 287 if (x[i] != y[i]) 288 { 289 return false; 290 } 291 } 292 return true; 293 } 294 eq64(long[] x, long[] y)295 public static boolean eq64(long[] x, long[] y) 296 { 297 for (int i = 3; i >= 0; --i) 298 { 299 if (x[i] != y[i]) 300 { 301 return false; 302 } 303 } 304 return true; 305 } 306 fromBigInteger(BigInteger x)307 public static int[] fromBigInteger(BigInteger x) 308 { 309 if (x.signum() < 0 || x.bitLength() > 256) 310 { 311 throw new IllegalArgumentException(); 312 } 313 314 int[] z = create(); 315 int i = 0; 316 while (x.signum() != 0) 317 { 318 z[i++] = x.intValue(); 319 x = x.shiftRight(32); 320 } 321 return z; 322 } 323 fromBigInteger64(BigInteger x)324 public static long[] fromBigInteger64(BigInteger x) 325 { 326 if (x.signum() < 0 || x.bitLength() > 256) 327 { 328 throw new IllegalArgumentException(); 329 } 330 331 long[] z = create64(); 332 int i = 0; 333 while (x.signum() != 0) 334 { 335 z[i++] = x.longValue(); 336 x = x.shiftRight(64); 337 } 338 return z; 339 } 340 getBit(int[] x, int bit)341 public static int getBit(int[] x, int bit) 342 { 343 if (bit == 0) 344 { 345 return x[0] & 1; 346 } 347 if ((bit & 255) != bit) 348 { 349 return 0; 350 } 351 int w = bit >>> 5; 352 int b = bit & 31; 353 return (x[w] >>> b) & 1; 354 } 355 gte(int[] x, int[] y)356 public static boolean gte(int[] x, int[] y) 357 { 358 for (int i = 7; i >= 0; --i) 359 { 360 int x_i = x[i] ^ Integer.MIN_VALUE; 361 int y_i = y[i] ^ Integer.MIN_VALUE; 362 if (x_i < y_i) 363 return false; 364 if (x_i > y_i) 365 return true; 366 } 367 return true; 368 } 369 gte(int[] x, int xOff, int[] y, int yOff)370 public static boolean gte(int[] x, int xOff, int[] y, int yOff) 371 { 372 for (int i = 7; i >= 0; --i) 373 { 374 int x_i = x[xOff + i] ^ Integer.MIN_VALUE; 375 int y_i = y[yOff + i] ^ Integer.MIN_VALUE; 376 if (x_i < y_i) 377 return false; 378 if (x_i > y_i) 379 return true; 380 } 381 return true; 382 } 383 isOne(int[] x)384 public static boolean isOne(int[] x) 385 { 386 if (x[0] != 1) 387 { 388 return false; 389 } 390 for (int i = 1; i < 8; ++i) 391 { 392 if (x[i] != 0) 393 { 394 return false; 395 } 396 } 397 return true; 398 } 399 isOne64(long[] x)400 public static boolean isOne64(long[] x) 401 { 402 if (x[0] != 1L) 403 { 404 return false; 405 } 406 for (int i = 1; i < 4; ++i) 407 { 408 if (x[i] != 0L) 409 { 410 return false; 411 } 412 } 413 return true; 414 } 415 isZero(int[] x)416 public static boolean isZero(int[] x) 417 { 418 for (int i = 0; i < 8; ++i) 419 { 420 if (x[i] != 0) 421 { 422 return false; 423 } 424 } 425 return true; 426 } 427 isZero64(long[] x)428 public static boolean isZero64(long[] x) 429 { 430 for (int i = 0; i < 4; ++i) 431 { 432 if (x[i] != 0L) 433 { 434 return false; 435 } 436 } 437 return true; 438 } 439 mul(int[] x, int[] y, int[] zz)440 public static void mul(int[] x, int[] y, int[] zz) 441 { 442 long y_0 = y[0] & M; 443 long y_1 = y[1] & M; 444 long y_2 = y[2] & M; 445 long y_3 = y[3] & M; 446 long y_4 = y[4] & M; 447 long y_5 = y[5] & M; 448 long y_6 = y[6] & M; 449 long y_7 = y[7] & M; 450 451 { 452 long c = 0, x_0 = x[0] & M; 453 c += x_0 * y_0; 454 zz[0] = (int)c; 455 c >>>= 32; 456 c += x_0 * y_1; 457 zz[1] = (int)c; 458 c >>>= 32; 459 c += x_0 * y_2; 460 zz[2] = (int)c; 461 c >>>= 32; 462 c += x_0 * y_3; 463 zz[3] = (int)c; 464 c >>>= 32; 465 c += x_0 * y_4; 466 zz[4] = (int)c; 467 c >>>= 32; 468 c += x_0 * y_5; 469 zz[5] = (int)c; 470 c >>>= 32; 471 c += x_0 * y_6; 472 zz[6] = (int)c; 473 c >>>= 32; 474 c += x_0 * y_7; 475 zz[7] = (int)c; 476 c >>>= 32; 477 zz[8] = (int)c; 478 } 479 480 for (int i = 1; i < 8; ++i) 481 { 482 long c = 0, x_i = x[i] & M; 483 c += x_i * y_0 + (zz[i + 0] & M); 484 zz[i + 0] = (int)c; 485 c >>>= 32; 486 c += x_i * y_1 + (zz[i + 1] & M); 487 zz[i + 1] = (int)c; 488 c >>>= 32; 489 c += x_i * y_2 + (zz[i + 2] & M); 490 zz[i + 2] = (int)c; 491 c >>>= 32; 492 c += x_i * y_3 + (zz[i + 3] & M); 493 zz[i + 3] = (int)c; 494 c >>>= 32; 495 c += x_i * y_4 + (zz[i + 4] & M); 496 zz[i + 4] = (int)c; 497 c >>>= 32; 498 c += x_i * y_5 + (zz[i + 5] & M); 499 zz[i + 5] = (int)c; 500 c >>>= 32; 501 c += x_i * y_6 + (zz[i + 6] & M); 502 zz[i + 6] = (int)c; 503 c >>>= 32; 504 c += x_i * y_7 + (zz[i + 7] & M); 505 zz[i + 7] = (int)c; 506 c >>>= 32; 507 zz[i + 8] = (int)c; 508 } 509 } 510 mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)511 public static void mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff) 512 { 513 long y_0 = y[yOff + 0] & M; 514 long y_1 = y[yOff + 1] & M; 515 long y_2 = y[yOff + 2] & M; 516 long y_3 = y[yOff + 3] & M; 517 long y_4 = y[yOff + 4] & M; 518 long y_5 = y[yOff + 5] & M; 519 long y_6 = y[yOff + 6] & M; 520 long y_7 = y[yOff + 7] & M; 521 522 { 523 long c = 0, x_0 = x[xOff + 0] & M; 524 c += x_0 * y_0; 525 zz[zzOff + 0] = (int)c; 526 c >>>= 32; 527 c += x_0 * y_1; 528 zz[zzOff + 1] = (int)c; 529 c >>>= 32; 530 c += x_0 * y_2; 531 zz[zzOff + 2] = (int)c; 532 c >>>= 32; 533 c += x_0 * y_3; 534 zz[zzOff + 3] = (int)c; 535 c >>>= 32; 536 c += x_0 * y_4; 537 zz[zzOff + 4] = (int)c; 538 c >>>= 32; 539 c += x_0 * y_5; 540 zz[zzOff + 5] = (int)c; 541 c >>>= 32; 542 c += x_0 * y_6; 543 zz[zzOff + 6] = (int)c; 544 c >>>= 32; 545 c += x_0 * y_7; 546 zz[zzOff + 7] = (int)c; 547 c >>>= 32; 548 zz[zzOff + 8] = (int)c; 549 } 550 551 for (int i = 1; i < 8; ++i) 552 { 553 ++zzOff; 554 long c = 0, x_i = x[xOff + i] & M; 555 c += x_i * y_0 + (zz[zzOff + 0] & M); 556 zz[zzOff + 0] = (int)c; 557 c >>>= 32; 558 c += x_i * y_1 + (zz[zzOff + 1] & M); 559 zz[zzOff + 1] = (int)c; 560 c >>>= 32; 561 c += x_i * y_2 + (zz[zzOff + 2] & M); 562 zz[zzOff + 2] = (int)c; 563 c >>>= 32; 564 c += x_i * y_3 + (zz[zzOff + 3] & M); 565 zz[zzOff + 3] = (int)c; 566 c >>>= 32; 567 c += x_i * y_4 + (zz[zzOff + 4] & M); 568 zz[zzOff + 4] = (int)c; 569 c >>>= 32; 570 c += x_i * y_5 + (zz[zzOff + 5] & M); 571 zz[zzOff + 5] = (int)c; 572 c >>>= 32; 573 c += x_i * y_6 + (zz[zzOff + 6] & M); 574 zz[zzOff + 6] = (int)c; 575 c >>>= 32; 576 c += x_i * y_7 + (zz[zzOff + 7] & M); 577 zz[zzOff + 7] = (int)c; 578 c >>>= 32; 579 zz[zzOff + 8] = (int)c; 580 } 581 } 582 mulAddTo(int[] x, int[] y, int[] zz)583 public static int mulAddTo(int[] x, int[] y, int[] zz) 584 { 585 long y_0 = y[0] & M; 586 long y_1 = y[1] & M; 587 long y_2 = y[2] & M; 588 long y_3 = y[3] & M; 589 long y_4 = y[4] & M; 590 long y_5 = y[5] & M; 591 long y_6 = y[6] & M; 592 long y_7 = y[7] & M; 593 594 long zc = 0; 595 for (int i = 0; i < 8; ++i) 596 { 597 long c = 0, x_i = x[i] & M; 598 c += x_i * y_0 + (zz[i + 0] & M); 599 zz[i + 0] = (int)c; 600 c >>>= 32; 601 c += x_i * y_1 + (zz[i + 1] & M); 602 zz[i + 1] = (int)c; 603 c >>>= 32; 604 c += x_i * y_2 + (zz[i + 2] & M); 605 zz[i + 2] = (int)c; 606 c >>>= 32; 607 c += x_i * y_3 + (zz[i + 3] & M); 608 zz[i + 3] = (int)c; 609 c >>>= 32; 610 c += x_i * y_4 + (zz[i + 4] & M); 611 zz[i + 4] = (int)c; 612 c >>>= 32; 613 c += x_i * y_5 + (zz[i + 5] & M); 614 zz[i + 5] = (int)c; 615 c >>>= 32; 616 c += x_i * y_6 + (zz[i + 6] & M); 617 zz[i + 6] = (int)c; 618 c >>>= 32; 619 c += x_i * y_7 + (zz[i + 7] & M); 620 zz[i + 7] = (int)c; 621 c >>>= 32; 622 c += zc + (zz[i + 8] & M); 623 zz[i + 8] = (int)c; 624 zc = c >>> 32; 625 } 626 return (int)zc; 627 } 628 mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)629 public static int mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff) 630 { 631 long y_0 = y[yOff + 0] & M; 632 long y_1 = y[yOff + 1] & M; 633 long y_2 = y[yOff + 2] & M; 634 long y_3 = y[yOff + 3] & M; 635 long y_4 = y[yOff + 4] & M; 636 long y_5 = y[yOff + 5] & M; 637 long y_6 = y[yOff + 6] & M; 638 long y_7 = y[yOff + 7] & M; 639 640 long zc = 0; 641 for (int i = 0; i < 8; ++i) 642 { 643 long c = 0, x_i = x[xOff + i] & M; 644 c += x_i * y_0 + (zz[zzOff + 0] & M); 645 zz[zzOff + 0] = (int)c; 646 c >>>= 32; 647 c += x_i * y_1 + (zz[zzOff + 1] & M); 648 zz[zzOff + 1] = (int)c; 649 c >>>= 32; 650 c += x_i * y_2 + (zz[zzOff + 2] & M); 651 zz[zzOff + 2] = (int)c; 652 c >>>= 32; 653 c += x_i * y_3 + (zz[zzOff + 3] & M); 654 zz[zzOff + 3] = (int)c; 655 c >>>= 32; 656 c += x_i * y_4 + (zz[zzOff + 4] & M); 657 zz[zzOff + 4] = (int)c; 658 c >>>= 32; 659 c += x_i * y_5 + (zz[zzOff + 5] & M); 660 zz[zzOff + 5] = (int)c; 661 c >>>= 32; 662 c += x_i * y_6 + (zz[zzOff + 6] & M); 663 zz[zzOff + 6] = (int)c; 664 c >>>= 32; 665 c += x_i * y_7 + (zz[zzOff + 7] & M); 666 zz[zzOff + 7] = (int)c; 667 c >>>= 32; 668 c += zc + (zz[zzOff + 8] & M); 669 zz[zzOff + 8] = (int)c; 670 zc = c >>> 32; 671 ++zzOff; 672 } 673 return (int)zc; 674 } 675 mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)676 public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff) 677 { 678 // assert w >>> 31 == 0; 679 680 long c = 0, wVal = w & M; 681 long x0 = x[xOff + 0] & M; 682 c += wVal * x0 + (y[yOff + 0] & M); 683 z[zOff + 0] = (int)c; 684 c >>>= 32; 685 long x1 = x[xOff + 1] & M; 686 c += wVal * x1 + x0 + (y[yOff + 1] & M); 687 z[zOff + 1] = (int)c; 688 c >>>= 32; 689 long x2 = x[xOff + 2] & M; 690 c += wVal * x2 + x1 + (y[yOff + 2] & M); 691 z[zOff + 2] = (int)c; 692 c >>>= 32; 693 long x3 = x[xOff + 3] & M; 694 c += wVal * x3 + x2 + (y[yOff + 3] & M); 695 z[zOff + 3] = (int)c; 696 c >>>= 32; 697 long x4 = x[xOff + 4] & M; 698 c += wVal * x4 + x3 + (y[yOff + 4] & M); 699 z[zOff + 4] = (int)c; 700 c >>>= 32; 701 long x5 = x[xOff + 5] & M; 702 c += wVal * x5 + x4 + (y[yOff + 5] & M); 703 z[zOff + 5] = (int)c; 704 c >>>= 32; 705 long x6 = x[xOff + 6] & M; 706 c += wVal * x6 + x5 + (y[yOff + 6] & M); 707 z[zOff + 6] = (int)c; 708 c >>>= 32; 709 long x7 = x[xOff + 7] & M; 710 c += wVal * x7 + x6 + (y[yOff + 7] & M); 711 z[zOff + 7] = (int)c; 712 c >>>= 32; 713 c += x7; 714 return c; 715 } 716 mulByWord(int x, int[] z)717 public static int mulByWord(int x, int[] z) 718 { 719 long c = 0, xVal = x & M; 720 c += xVal * (z[0] & M); 721 z[0] = (int)c; 722 c >>>= 32; 723 c += xVal * (z[1] & M); 724 z[1] = (int)c; 725 c >>>= 32; 726 c += xVal * (z[2] & M); 727 z[2] = (int)c; 728 c >>>= 32; 729 c += xVal * (z[3] & M); 730 z[3] = (int)c; 731 c >>>= 32; 732 c += xVal * (z[4] & M); 733 z[4] = (int)c; 734 c >>>= 32; 735 c += xVal * (z[5] & M); 736 z[5] = (int)c; 737 c >>>= 32; 738 c += xVal * (z[6] & M); 739 z[6] = (int)c; 740 c >>>= 32; 741 c += xVal * (z[7] & M); 742 z[7] = (int)c; 743 c >>>= 32; 744 return (int)c; 745 } 746 mulByWordAddTo(int x, int[] y, int[] z)747 public static int mulByWordAddTo(int x, int[] y, int[] z) 748 { 749 long c = 0, xVal = x & M; 750 c += xVal * (z[0] & M) + (y[0] & M); 751 z[0] = (int)c; 752 c >>>= 32; 753 c += xVal * (z[1] & M) + (y[1] & M); 754 z[1] = (int)c; 755 c >>>= 32; 756 c += xVal * (z[2] & M) + (y[2] & M); 757 z[2] = (int)c; 758 c >>>= 32; 759 c += xVal * (z[3] & M) + (y[3] & M); 760 z[3] = (int)c; 761 c >>>= 32; 762 c += xVal * (z[4] & M) + (y[4] & M); 763 z[4] = (int)c; 764 c >>>= 32; 765 c += xVal * (z[5] & M) + (y[5] & M); 766 z[5] = (int)c; 767 c >>>= 32; 768 c += xVal * (z[6] & M) + (y[6] & M); 769 z[6] = (int)c; 770 c >>>= 32; 771 c += xVal * (z[7] & M) + (y[7] & M); 772 z[7] = (int)c; 773 c >>>= 32; 774 return (int)c; 775 } 776 mulWordAddTo(int x, int[] y, int yOff, int[] z, int zOff)777 public static int mulWordAddTo(int x, int[] y, int yOff, int[] z, int zOff) 778 { 779 long c = 0, xVal = x & M; 780 c += xVal * (y[yOff + 0] & M) + (z[zOff + 0] & M); 781 z[zOff + 0] = (int)c; 782 c >>>= 32; 783 c += xVal * (y[yOff + 1] & M) + (z[zOff + 1] & M); 784 z[zOff + 1] = (int)c; 785 c >>>= 32; 786 c += xVal * (y[yOff + 2] & M) + (z[zOff + 2] & M); 787 z[zOff + 2] = (int)c; 788 c >>>= 32; 789 c += xVal * (y[yOff + 3] & M) + (z[zOff + 3] & M); 790 z[zOff + 3] = (int)c; 791 c >>>= 32; 792 c += xVal * (y[yOff + 4] & M) + (z[zOff + 4] & M); 793 z[zOff + 4] = (int)c; 794 c >>>= 32; 795 c += xVal * (y[yOff + 5] & M) + (z[zOff + 5] & M); 796 z[zOff + 5] = (int)c; 797 c >>>= 32; 798 c += xVal * (y[yOff + 6] & M) + (z[zOff + 6] & M); 799 z[zOff + 6] = (int)c; 800 c >>>= 32; 801 c += xVal * (y[yOff + 7] & M) + (z[zOff + 7] & M); 802 z[zOff + 7] = (int)c; 803 c >>>= 32; 804 return (int)c; 805 } 806 mul33DWordAdd(int x, long y, int[] z, int zOff)807 public static int mul33DWordAdd(int x, long y, int[] z, int zOff) 808 { 809 // assert x >>> 31 == 0; 810 // assert zOff <= 4; 811 812 long c = 0, xVal = x & M; 813 long y00 = y & M; 814 c += xVal * y00 + (z[zOff + 0] & M); 815 z[zOff + 0] = (int)c; 816 c >>>= 32; 817 long y01 = y >>> 32; 818 c += xVal * y01 + y00 + (z[zOff + 1] & M); 819 z[zOff + 1] = (int)c; 820 c >>>= 32; 821 c += y01 + (z[zOff + 2] & M); 822 z[zOff + 2] = (int)c; 823 c >>>= 32; 824 c += (z[zOff + 3] & M); 825 z[zOff + 3] = (int)c; 826 c >>>= 32; 827 return c == 0 ? 0 : Nat.incAt(8, z, zOff, 4); 828 } 829 mul33WordAdd(int x, int y, int[] z, int zOff)830 public static int mul33WordAdd(int x, int y, int[] z, int zOff) 831 { 832 // assert x >>> 31 == 0; 833 // assert zOff <= 5; 834 835 long c = 0, xVal = x & M, yVal = y & M; 836 c += yVal * xVal + (z[zOff + 0] & M); 837 z[zOff + 0] = (int)c; 838 c >>>= 32; 839 c += yVal + (z[zOff + 1] & M); 840 z[zOff + 1] = (int)c; 841 c >>>= 32; 842 c += (z[zOff + 2] & M); 843 z[zOff + 2] = (int)c; 844 c >>>= 32; 845 return c == 0 ? 0 : Nat.incAt(8, z, zOff, 3); 846 } 847 mulWordDwordAdd(int x, long y, int[] z, int zOff)848 public static int mulWordDwordAdd(int x, long y, int[] z, int zOff) 849 { 850 // assert zOff <= 5; 851 long c = 0, xVal = x & M; 852 c += xVal * (y & M) + (z[zOff + 0] & M); 853 z[zOff + 0] = (int)c; 854 c >>>= 32; 855 c += xVal * (y >>> 32) + (z[zOff + 1] & M); 856 z[zOff + 1] = (int)c; 857 c >>>= 32; 858 c += (z[zOff + 2] & M); 859 z[zOff + 2] = (int)c; 860 c >>>= 32; 861 return c == 0 ? 0 : Nat.incAt(8, z, zOff, 3); 862 } 863 mulWord(int x, int[] y, int[] z, int zOff)864 public static int mulWord(int x, int[] y, int[] z, int zOff) 865 { 866 long c = 0, xVal = x & M; 867 int i = 0; 868 do 869 { 870 c += xVal * (y[i] & M); 871 z[zOff + i] = (int)c; 872 c >>>= 32; 873 } 874 while (++i < 8); 875 return (int)c; 876 } 877 square(int[] x, int[] zz)878 public static void square(int[] x, int[] zz) 879 { 880 long x_0 = x[0] & M; 881 long zz_1; 882 883 int c = 0, w; 884 { 885 int i = 7, j = 16; 886 do 887 { 888 long xVal = (x[i--] & M); 889 long p = xVal * xVal; 890 zz[--j] = (c << 31) | (int)(p >>> 33); 891 zz[--j] = (int)(p >>> 1); 892 c = (int)p; 893 } 894 while (i > 0); 895 896 { 897 long p = x_0 * x_0; 898 zz_1 = ((c << 31) & M) | (p >>> 33); 899 zz[0] = (int)p; 900 c = (int)(p >>> 32) & 1; 901 } 902 } 903 904 long x_1 = x[1] & M; 905 long zz_2 = zz[2] & M; 906 907 { 908 zz_1 += x_1 * x_0; 909 w = (int)zz_1; 910 zz[1] = (w << 1) | c; 911 c = w >>> 31; 912 zz_2 += zz_1 >>> 32; 913 } 914 915 long x_2 = x[2] & M; 916 long zz_3 = zz[3] & M; 917 long zz_4 = zz[4] & M; 918 { 919 zz_2 += x_2 * x_0; 920 w = (int)zz_2; 921 zz[2] = (w << 1) | c; 922 c = w >>> 31; 923 zz_3 += (zz_2 >>> 32) + x_2 * x_1; 924 zz_4 += zz_3 >>> 32; 925 zz_3 &= M; 926 } 927 928 long x_3 = x[3] & M; 929 long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M; 930 long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M; 931 { 932 zz_3 += x_3 * x_0; 933 w = (int)zz_3; 934 zz[3] = (w << 1) | c; 935 c = w >>> 31; 936 zz_4 += (zz_3 >>> 32) + x_3 * x_1; 937 zz_5 += (zz_4 >>> 32) + x_3 * x_2; 938 zz_4 &= M; 939 zz_6 += zz_5 >>> 32; 940 zz_5 &= M; 941 } 942 943 long x_4 = x[4] & M; 944 long zz_7 = (zz[7] & M) + (zz_6 >>> 32); zz_6 &= M; 945 long zz_8 = (zz[8] & M) + (zz_7 >>> 32); zz_7 &= M; 946 { 947 zz_4 += x_4 * x_0; 948 w = (int)zz_4; 949 zz[4] = (w << 1) | c; 950 c = w >>> 31; 951 zz_5 += (zz_4 >>> 32) + x_4 * x_1; 952 zz_6 += (zz_5 >>> 32) + x_4 * x_2; 953 zz_5 &= M; 954 zz_7 += (zz_6 >>> 32) + x_4 * x_3; 955 zz_6 &= M; 956 zz_8 += zz_7 >>> 32; 957 zz_7 &= M; 958 } 959 960 long x_5 = x[5] & M; 961 long zz_9 = (zz[9] & M) + (zz_8 >>> 32); zz_8 &= M; 962 long zz_10 = (zz[10] & M) + (zz_9 >>> 32); zz_9 &= M; 963 { 964 zz_5 += x_5 * x_0; 965 w = (int)zz_5; 966 zz[5] = (w << 1) | c; 967 c = w >>> 31; 968 zz_6 += (zz_5 >>> 32) + x_5 * x_1; 969 zz_7 += (zz_6 >>> 32) + x_5 * x_2; 970 zz_6 &= M; 971 zz_8 += (zz_7 >>> 32) + x_5 * x_3; 972 zz_7 &= M; 973 zz_9 += (zz_8 >>> 32) + x_5 * x_4; 974 zz_8 &= M; 975 zz_10 += zz_9 >>> 32; 976 zz_9 &= M; 977 } 978 979 long x_6 = x[6] & M; 980 long zz_11 = (zz[11] & M) + (zz_10 >>> 32); zz_10 &= M; 981 long zz_12 = (zz[12] & M) + (zz_11 >>> 32); zz_11 &= M; 982 { 983 zz_6 += x_6 * x_0; 984 w = (int)zz_6; 985 zz[6] = (w << 1) | c; 986 c = w >>> 31; 987 zz_7 += (zz_6 >>> 32) + x_6 * x_1; 988 zz_8 += (zz_7 >>> 32) + x_6 * x_2; 989 zz_7 &= M; 990 zz_9 += (zz_8 >>> 32) + x_6 * x_3; 991 zz_8 &= M; 992 zz_10 += (zz_9 >>> 32) + x_6 * x_4; 993 zz_9 &= M; 994 zz_11 += (zz_10 >>> 32) + x_6 * x_5; 995 zz_10 &= M; 996 zz_12 += zz_11 >>> 32; 997 zz_11 &= M; 998 } 999 1000 long x_7 = x[7] & M; 1001 long zz_13 = (zz[13] & M) + (zz_12 >>> 32); zz_12 &= M; 1002 long zz_14 = (zz[14] & M) + (zz_13 >>> 32); zz_13 &= M; 1003 { 1004 zz_7 += x_7 * x_0; 1005 w = (int)zz_7; 1006 zz[7] = (w << 1) | c; 1007 c = w >>> 31; 1008 zz_8 += (zz_7 >>> 32) + x_7 * x_1; 1009 zz_9 += (zz_8 >>> 32) + x_7 * x_2; 1010 zz_10 += (zz_9 >>> 32) + x_7 * x_3; 1011 zz_11 += (zz_10 >>> 32) + x_7 * x_4; 1012 zz_12 += (zz_11 >>> 32) + x_7 * x_5; 1013 zz_13 += (zz_12 >>> 32) + x_7 * x_6; 1014 zz_14 += zz_13 >>> 32; 1015 } 1016 1017 w = (int)zz_8; 1018 zz[8] = (w << 1) | c; 1019 c = w >>> 31; 1020 w = (int)zz_9; 1021 zz[9] = (w << 1) | c; 1022 c = w >>> 31; 1023 w = (int)zz_10; 1024 zz[10] = (w << 1) | c; 1025 c = w >>> 31; 1026 w = (int)zz_11; 1027 zz[11] = (w << 1) | c; 1028 c = w >>> 31; 1029 w = (int)zz_12; 1030 zz[12] = (w << 1) | c; 1031 c = w >>> 31; 1032 w = (int)zz_13; 1033 zz[13] = (w << 1) | c; 1034 c = w >>> 31; 1035 w = (int)zz_14; 1036 zz[14] = (w << 1) | c; 1037 c = w >>> 31; 1038 w = zz[15] + (int)(zz_14 >>> 32); 1039 zz[15] = (w << 1) | c; 1040 } 1041 square(int[] x, int xOff, int[] zz, int zzOff)1042 public static void square(int[] x, int xOff, int[] zz, int zzOff) 1043 { 1044 long x_0 = x[xOff + 0] & M; 1045 long zz_1; 1046 1047 int c = 0, w; 1048 { 1049 int i = 7, j = 16; 1050 do 1051 { 1052 long xVal = (x[xOff + i--] & M); 1053 long p = xVal * xVal; 1054 zz[zzOff + --j] = (c << 31) | (int)(p >>> 33); 1055 zz[zzOff + --j] = (int)(p >>> 1); 1056 c = (int)p; 1057 } 1058 while (i > 0); 1059 1060 { 1061 long p = x_0 * x_0; 1062 zz_1 = ((c << 31) & M) | (p >>> 33); 1063 zz[zzOff + 0] = (int)p; 1064 c = (int)(p >>> 32) & 1; 1065 } 1066 } 1067 1068 long x_1 = x[xOff + 1] & M; 1069 long zz_2 = zz[zzOff + 2] & M; 1070 1071 { 1072 zz_1 += x_1 * x_0; 1073 w = (int)zz_1; 1074 zz[zzOff + 1] = (w << 1) | c; 1075 c = w >>> 31; 1076 zz_2 += zz_1 >>> 32; 1077 } 1078 1079 long x_2 = x[xOff + 2] & M; 1080 long zz_3 = zz[zzOff + 3] & M; 1081 long zz_4 = zz[zzOff + 4] & M; 1082 { 1083 zz_2 += x_2 * x_0; 1084 w = (int)zz_2; 1085 zz[zzOff + 2] = (w << 1) | c; 1086 c = w >>> 31; 1087 zz_3 += (zz_2 >>> 32) + x_2 * x_1; 1088 zz_4 += zz_3 >>> 32; 1089 zz_3 &= M; 1090 } 1091 1092 long x_3 = x[xOff + 3] & M; 1093 long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M; 1094 long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M; 1095 { 1096 zz_3 += x_3 * x_0; 1097 w = (int)zz_3; 1098 zz[zzOff + 3] = (w << 1) | c; 1099 c = w >>> 31; 1100 zz_4 += (zz_3 >>> 32) + x_3 * x_1; 1101 zz_5 += (zz_4 >>> 32) + x_3 * x_2; 1102 zz_4 &= M; 1103 zz_6 += zz_5 >>> 32; 1104 zz_5 &= M; 1105 } 1106 1107 long x_4 = x[xOff + 4] & M; 1108 long zz_7 = (zz[zzOff + 7] & M) + (zz_6 >>> 32); zz_6 &= M; 1109 long zz_8 = (zz[zzOff + 8] & M) + (zz_7 >>> 32); zz_7 &= M; 1110 { 1111 zz_4 += x_4 * x_0; 1112 w = (int)zz_4; 1113 zz[zzOff + 4] = (w << 1) | c; 1114 c = w >>> 31; 1115 zz_5 += (zz_4 >>> 32) + x_4 * x_1; 1116 zz_6 += (zz_5 >>> 32) + x_4 * x_2; 1117 zz_5 &= M; 1118 zz_7 += (zz_6 >>> 32) + x_4 * x_3; 1119 zz_6 &= M; 1120 zz_8 += zz_7 >>> 32; 1121 zz_7 &= M; 1122 } 1123 1124 long x_5 = x[xOff + 5] & M; 1125 long zz_9 = (zz[zzOff + 9] & M) + (zz_8 >>> 32); zz_8 &= M; 1126 long zz_10 = (zz[zzOff + 10] & M) + (zz_9 >>> 32); zz_9 &= M; 1127 { 1128 zz_5 += x_5 * x_0; 1129 w = (int)zz_5; 1130 zz[zzOff + 5] = (w << 1) | c; 1131 c = w >>> 31; 1132 zz_6 += (zz_5 >>> 32) + x_5 * x_1; 1133 zz_7 += (zz_6 >>> 32) + x_5 * x_2; 1134 zz_6 &= M; 1135 zz_8 += (zz_7 >>> 32) + x_5 * x_3; 1136 zz_7 &= M; 1137 zz_9 += (zz_8 >>> 32) + x_5 * x_4; 1138 zz_8 &= M; 1139 zz_10 += zz_9 >>> 32; 1140 zz_9 &= M; 1141 } 1142 1143 long x_6 = x[xOff + 6] & M; 1144 long zz_11 = (zz[zzOff + 11] & M) + (zz_10 >>> 32); zz_10 &= M; 1145 long zz_12 = (zz[zzOff + 12] & M) + (zz_11 >>> 32); zz_11 &= M; 1146 { 1147 zz_6 += x_6 * x_0; 1148 w = (int)zz_6; 1149 zz[zzOff + 6] = (w << 1) | c; 1150 c = w >>> 31; 1151 zz_7 += (zz_6 >>> 32) + x_6 * x_1; 1152 zz_8 += (zz_7 >>> 32) + x_6 * x_2; 1153 zz_7 &= M; 1154 zz_9 += (zz_8 >>> 32) + x_6 * x_3; 1155 zz_8 &= M; 1156 zz_10 += (zz_9 >>> 32) + x_6 * x_4; 1157 zz_9 &= M; 1158 zz_11 += (zz_10 >>> 32) + x_6 * x_5; 1159 zz_10 &= M; 1160 zz_12 += zz_11 >>> 32; 1161 zz_11 &= M; 1162 } 1163 1164 long x_7 = x[xOff + 7] & M; 1165 long zz_13 = (zz[zzOff + 13] & M) + (zz_12 >>> 32); zz_12 &= M; 1166 long zz_14 = (zz[zzOff + 14] & M) + (zz_13 >>> 32); zz_13 &= M; 1167 { 1168 zz_7 += x_7 * x_0; 1169 w = (int)zz_7; 1170 zz[zzOff + 7] = (w << 1) | c; 1171 c = w >>> 31; 1172 zz_8 += (zz_7 >>> 32) + x_7 * x_1; 1173 zz_9 += (zz_8 >>> 32) + x_7 * x_2; 1174 zz_10 += (zz_9 >>> 32) + x_7 * x_3; 1175 zz_11 += (zz_10 >>> 32) + x_7 * x_4; 1176 zz_12 += (zz_11 >>> 32) + x_7 * x_5; 1177 zz_13 += (zz_12 >>> 32) + x_7 * x_6; 1178 zz_14 += zz_13 >>> 32; 1179 } 1180 1181 w = (int)zz_8; 1182 zz[zzOff + 8] = (w << 1) | c; 1183 c = w >>> 31; 1184 w = (int)zz_9; 1185 zz[zzOff + 9] = (w << 1) | c; 1186 c = w >>> 31; 1187 w = (int)zz_10; 1188 zz[zzOff + 10] = (w << 1) | c; 1189 c = w >>> 31; 1190 w = (int)zz_11; 1191 zz[zzOff + 11] = (w << 1) | c; 1192 c = w >>> 31; 1193 w = (int)zz_12; 1194 zz[zzOff + 12] = (w << 1) | c; 1195 c = w >>> 31; 1196 w = (int)zz_13; 1197 zz[zzOff + 13] = (w << 1) | c; 1198 c = w >>> 31; 1199 w = (int)zz_14; 1200 zz[zzOff + 14] = (w << 1) | c; 1201 c = w >>> 31; 1202 w = zz[zzOff + 15] + (int)(zz_14 >>> 32); 1203 zz[zzOff + 15] = (w << 1) | c; 1204 } 1205 sub(int[] x, int[] y, int[] z)1206 public static int sub(int[] x, int[] y, int[] z) 1207 { 1208 long c = 0; 1209 c += (x[0] & M) - (y[0] & M); 1210 z[0] = (int)c; 1211 c >>= 32; 1212 c += (x[1] & M) - (y[1] & M); 1213 z[1] = (int)c; 1214 c >>= 32; 1215 c += (x[2] & M) - (y[2] & M); 1216 z[2] = (int)c; 1217 c >>= 32; 1218 c += (x[3] & M) - (y[3] & M); 1219 z[3] = (int)c; 1220 c >>= 32; 1221 c += (x[4] & M) - (y[4] & M); 1222 z[4] = (int)c; 1223 c >>= 32; 1224 c += (x[5] & M) - (y[5] & M); 1225 z[5] = (int)c; 1226 c >>= 32; 1227 c += (x[6] & M) - (y[6] & M); 1228 z[6] = (int)c; 1229 c >>= 32; 1230 c += (x[7] & M) - (y[7] & M); 1231 z[7] = (int)c; 1232 c >>= 32; 1233 return (int)c; 1234 } 1235 sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)1236 public static int sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff) 1237 { 1238 long c = 0; 1239 c += (x[xOff + 0] & M) - (y[yOff + 0] & M); 1240 z[zOff + 0] = (int)c; 1241 c >>= 32; 1242 c += (x[xOff + 1] & M) - (y[yOff + 1] & M); 1243 z[zOff + 1] = (int)c; 1244 c >>= 32; 1245 c += (x[xOff + 2] & M) - (y[yOff + 2] & M); 1246 z[zOff + 2] = (int)c; 1247 c >>= 32; 1248 c += (x[xOff + 3] & M) - (y[yOff + 3] & M); 1249 z[zOff + 3] = (int)c; 1250 c >>= 32; 1251 c += (x[xOff + 4] & M) - (y[yOff + 4] & M); 1252 z[zOff + 4] = (int)c; 1253 c >>= 32; 1254 c += (x[xOff + 5] & M) - (y[yOff + 5] & M); 1255 z[zOff + 5] = (int)c; 1256 c >>= 32; 1257 c += (x[xOff + 6] & M) - (y[yOff + 6] & M); 1258 z[zOff + 6] = (int)c; 1259 c >>= 32; 1260 c += (x[xOff + 7] & M) - (y[yOff + 7] & M); 1261 z[zOff + 7] = (int)c; 1262 c >>= 32; 1263 return (int)c; 1264 } 1265 subBothFrom(int[] x, int[] y, int[] z)1266 public static int subBothFrom(int[] x, int[] y, int[] z) 1267 { 1268 long c = 0; 1269 c += (z[0] & M) - (x[0] & M) - (y[0] & M); 1270 z[0] = (int)c; 1271 c >>= 32; 1272 c += (z[1] & M) - (x[1] & M) - (y[1] & M); 1273 z[1] = (int)c; 1274 c >>= 32; 1275 c += (z[2] & M) - (x[2] & M) - (y[2] & M); 1276 z[2] = (int)c; 1277 c >>= 32; 1278 c += (z[3] & M) - (x[3] & M) - (y[3] & M); 1279 z[3] = (int)c; 1280 c >>= 32; 1281 c += (z[4] & M) - (x[4] & M) - (y[4] & M); 1282 z[4] = (int)c; 1283 c >>= 32; 1284 c += (z[5] & M) - (x[5] & M) - (y[5] & M); 1285 z[5] = (int)c; 1286 c >>= 32; 1287 c += (z[6] & M) - (x[6] & M) - (y[6] & M); 1288 z[6] = (int)c; 1289 c >>= 32; 1290 c += (z[7] & M) - (x[7] & M) - (y[7] & M); 1291 z[7] = (int)c; 1292 c >>= 32; 1293 return (int)c; 1294 } 1295 subFrom(int[] x, int[] z)1296 public static int subFrom(int[] x, int[] z) 1297 { 1298 long c = 0; 1299 c += (z[0] & M) - (x[0] & M); 1300 z[0] = (int)c; 1301 c >>= 32; 1302 c += (z[1] & M) - (x[1] & M); 1303 z[1] = (int)c; 1304 c >>= 32; 1305 c += (z[2] & M) - (x[2] & M); 1306 z[2] = (int)c; 1307 c >>= 32; 1308 c += (z[3] & M) - (x[3] & M); 1309 z[3] = (int)c; 1310 c >>= 32; 1311 c += (z[4] & M) - (x[4] & M); 1312 z[4] = (int)c; 1313 c >>= 32; 1314 c += (z[5] & M) - (x[5] & M); 1315 z[5] = (int)c; 1316 c >>= 32; 1317 c += (z[6] & M) - (x[6] & M); 1318 z[6] = (int)c; 1319 c >>= 32; 1320 c += (z[7] & M) - (x[7] & M); 1321 z[7] = (int)c; 1322 c >>= 32; 1323 return (int)c; 1324 } 1325 subFrom(int[] x, int xOff, int[] z, int zOff)1326 public static int subFrom(int[] x, int xOff, int[] z, int zOff) 1327 { 1328 long c = 0; 1329 c += (z[zOff + 0] & M) - (x[xOff + 0] & M); 1330 z[zOff + 0] = (int)c; 1331 c >>= 32; 1332 c += (z[zOff + 1] & M) - (x[xOff + 1] & M); 1333 z[zOff + 1] = (int)c; 1334 c >>= 32; 1335 c += (z[zOff + 2] & M) - (x[xOff + 2] & M); 1336 z[zOff + 2] = (int)c; 1337 c >>= 32; 1338 c += (z[zOff + 3] & M) - (x[xOff + 3] & M); 1339 z[zOff + 3] = (int)c; 1340 c >>= 32; 1341 c += (z[zOff + 4] & M) - (x[xOff + 4] & M); 1342 z[zOff + 4] = (int)c; 1343 c >>= 32; 1344 c += (z[zOff + 5] & M) - (x[xOff + 5] & M); 1345 z[zOff + 5] = (int)c; 1346 c >>= 32; 1347 c += (z[zOff + 6] & M) - (x[xOff + 6] & M); 1348 z[zOff + 6] = (int)c; 1349 c >>= 32; 1350 c += (z[zOff + 7] & M) - (x[xOff + 7] & M); 1351 z[zOff + 7] = (int)c; 1352 c >>= 32; 1353 return (int)c; 1354 } 1355 toBigInteger(int[] x)1356 public static BigInteger toBigInteger(int[] x) 1357 { 1358 byte[] bs = new byte[32]; 1359 for (int i = 0; i < 8; ++i) 1360 { 1361 int x_i = x[i]; 1362 if (x_i != 0) 1363 { 1364 Pack.intToBigEndian(x_i, bs, (7 - i) << 2); 1365 } 1366 } 1367 return new BigInteger(1, bs); 1368 } 1369 toBigInteger64(long[] x)1370 public static BigInteger toBigInteger64(long[] x) 1371 { 1372 byte[] bs = new byte[32]; 1373 for (int i = 0; i < 4; ++i) 1374 { 1375 long x_i = x[i]; 1376 if (x_i != 0L) 1377 { 1378 Pack.longToBigEndian(x_i, bs, (3 - i) << 3); 1379 } 1380 } 1381 return new BigInteger(1, bs); 1382 } 1383 zero(int[] z)1384 public static void zero(int[] z) 1385 { 1386 z[0] = 0; 1387 z[1] = 0; 1388 z[2] = 0; 1389 z[3] = 0; 1390 z[4] = 0; 1391 z[5] = 0; 1392 z[6] = 0; 1393 z[7] = 0; 1394 } 1395 } 1396