| 1617 | } |
| 1618 | |
| 1619 | txBigInt *fxBigInt_exp(txMachine* the, txBigInt *r, txBigInt *a, txBigInt *b) |
| 1620 | { |
| 1621 | #ifndef mxCompile |
| 1622 | if (b->sign) |
| 1623 | mxRangeError("negative exponent"); |
| 1624 | #endif |
| 1625 | if (fxBigInt_iszero(b)) { |
| 1626 | if (r == NULL) |
| 1627 | r = fxBigInt_alloc(the, 1); |
| 1628 | else { |
| 1629 | r->size = 1; |
| 1630 | r->sign = 0; |
| 1631 | } |
| 1632 | r->data[0] = 1; |
| 1633 | } |
| 1634 | else { |
| 1635 | int i = fxBigInt_bitsize(b) - 1; |
| 1636 | int odd = fxBigInt_isset(b, i); |
| 1637 | txU4 c = fxBigInt_bitsize(a); |
| 1638 | txBigInt *t = fxBigInt_umul1(the, NULL, b, c); |
| 1639 | t = fxBigInt_ulsr1(the, t, t, 5); |
| 1640 | #ifndef mxCompile |
| 1641 | if ((t->size > 1) || (t->data[0] > 0xFFFF)) |
| 1642 | mxRangeError("too big exponent"); |
| 1643 | #endif |
| 1644 | c = 2 + t->data[0]; |
| 1645 | fxBigInt_free(the, t); |
| 1646 | if (r == NULL) |
| 1647 | r = fxBigInt_alloc(the, c); |
| 1648 | t = fxBigInt_alloc(the, c); |
| 1649 | fxBigInt_copy(r, a); |
| 1650 | while (i > 0) { |
| 1651 | i--; |
| 1652 | t = fxBigInt_sqr(the, t, r); |
| 1653 | if ((odd = fxBigInt_isset(b, i))) { |
| 1654 | r->size = c; |
| 1655 | r = fxBigInt_umul(the, r, t, a); |
| 1656 | } |
| 1657 | else { |
| 1658 | txBigInt u = *r; |
| 1659 | *r = *t; |
| 1660 | *t = u; |
| 1661 | } |
| 1662 | t->size = c; |
| 1663 | } |
| 1664 | r->sign = a->sign & odd; |
| 1665 | fxBigInt_free(the, t); |
| 1666 | } |
| 1667 | mxBigInt_meter(r->size); |
| 1668 | return(r); |
| 1669 | } |
| 1670 | |
| 1671 | txBigInt *fxBigInt_sqr(txMachine* the, txBigInt *r, txBigInt *a) |
| 1672 | { |
nothing calls this directly
no test coverage detected