| 537 | } |
| 538 | |
| 539 | txBigInt *fxBigInt_mont_exp_SW(txMachine *the, txBigInt *r, txBigInt *b, txBigInt *e, txBigInt *m, int param) |
| 540 | { |
| 541 | unsigned int expLen; |
| 542 | int i, k, gsize; |
| 543 | txBigInt *A; |
| 544 | txBigInt *g[64]; |
| 545 | txU4 u; |
| 546 | pool_t pool; |
| 547 | |
| 548 | if (r == NULL) |
| 549 | r = fxBigInt_alloc(the, m->size); |
| 550 | pool_init(&pool); |
| 551 | u = mont_init(m); |
| 552 | A = mont_exp_init(the, pool_get(the, m->size, &pool), m, &pool); |
| 553 | if (fxBigInt_ucomp(b, m) > 0) |
| 554 | b = fxBigInt_mod(the, pool_get(the, m->size, &pool), b, m); |
| 555 | b = mont_in(the, pool_get(the, m->size, &pool), b, m); |
| 556 | expLen = fxBigInt_bitsize(e); |
| 557 | if (param > 0) |
| 558 | k = param; |
| 559 | else |
| 560 | k = (expLen <= 18 ? 1 : (expLen <= 36 ? 2 : (expLen <= 134 ? 3 : (expLen <= 536 ? 4 : (expLen <= 1224 ? 5 : (expLen <= 1342 ? 6 : 7)))))); |
| 561 | gsize = 1 << (k - 1); |
| 562 | for (i = 0; i < gsize; i++) |
| 563 | g[i] = pool_get(the, m->size, &pool); |
| 564 | fxBigInt_copy(g[0], b); |
| 565 | if (k > 1) { |
| 566 | txBigInt *t = mont_square(the, pool_get(the, m->size, &pool), b, m, u, &pool); |
| 567 | for (i = gsize; --i >= 1;) |
| 568 | mont_mul(the, g[i], t, g[i - 1], m, u, &pool); |
| 569 | } |
| 570 | for (i = expLen - 1; i >= 0;) { |
| 571 | if (!fxBigInt_isset(e, i)) { |
| 572 | mont_square(the, A, A, m, u, &pool); |
| 573 | --i; |
| 574 | } |
| 575 | else { |
| 576 | int j, l; |
| 577 | int power = 0; |
| 578 | int shift = 0; |
| 579 | for (j = l = i; j >= 0 && i - j + 1 <= k; --j) { |
| 580 | if (fxBigInt_isset(e, j)) { |
| 581 | l = j; |
| 582 | power = (power << (shift + 1)) | 1; |
| 583 | shift = 0; |
| 584 | } |
| 585 | else |
| 586 | shift++; |
| 587 | } |
| 588 | mont_square(the, A, A, m, u, &pool); |
| 589 | for (j = 1; j < i - l + 1; j++) |
| 590 | mont_square(the, A, A, m, u, &pool); |
| 591 | mont_mul(the, A, A, g[(power-1)>>1], m, u, &pool); |
| 592 | i = l - 1; |
| 593 | } |
| 594 | } |
| 595 | mont_out(the, r, A, m, u); |
| 596 | pool_dispose(the, &pool); |
no test coverage detected