| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Copyright 2009 The Go Authors. All rights reserved. | 5 // Copyright 2009 The Go Authors. All rights reserved. |
| 6 // Use of this source code is governed by a BSD-style | 6 // Use of this source code is governed by a BSD-style |
| 7 // license that can be found in the LICENSE file. | 7 // license that can be found in the LICENSE file. |
| 8 | 8 |
| 9 /* | 9 /* |
| 10 * Copyright (c) 2003-2005 Tom Wu | 10 * Copyright (c) 2003-2005 Tom Wu |
| (...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 | 1160 |
| 1161 int get bitLength { | 1161 int get bitLength { |
| 1162 if (_used == 0) return 0; | 1162 if (_used == 0) return 0; |
| 1163 if (_neg) return (~this).bitLength; | 1163 if (_neg) return (~this).bitLength; |
| 1164 return _DIGIT_BITS*(_used - 1) + _nbits(_digits[_used - 1]); | 1164 return _DIGIT_BITS*(_used - 1) + _nbits(_digits[_used - 1]); |
| 1165 } | 1165 } |
| 1166 | 1166 |
| 1167 // This method must support smi._toBigint()._shrFromInt(int). | 1167 // This method must support smi._toBigint()._shrFromInt(int). |
| 1168 int _shrFromInt(int other) { | 1168 int _shrFromInt(int other) { |
| 1169 if (_used == 0) return other; // Shift amount is zero. | 1169 if (_used == 0) return other; // Shift amount is zero. |
| 1170 if (_neg) throw "negative shift amount"; // TODO(regis): What exception? | 1170 if (_neg) throw new RangeError(this); |
| 1171 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. | 1171 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. |
| 1172 var shift; | 1172 var shift; |
| 1173 if ((_used > 2) || ((_used == 2) && (_digits[1] > 0x10000000))) { | 1173 if ((_used > 2) || ((_used == 2) && (_digits[1] > 0x10000000))) { |
| 1174 if (other < 0) { | 1174 if (other < 0) { |
| 1175 return -1; | 1175 return -1; |
| 1176 } else { | 1176 } else { |
| 1177 return 0; | 1177 return 0; |
| 1178 } | 1178 } |
| 1179 } else { | 1179 } else { |
| 1180 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; | 1180 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; |
| 1181 } | 1181 } |
| 1182 return other._toBigint()._rShift(shift)._toValidInt(); | 1182 return other._toBigint()._rShift(shift)._toValidInt(); |
| 1183 } | 1183 } |
| 1184 | 1184 |
| 1185 // This method must support smi._toBigint()._shlFromInt(int). | 1185 // This method must support smi._toBigint()._shlFromInt(int). |
| 1186 // An out of memory exception is thrown if the result cannot be allocated. | 1186 // An out of memory exception is thrown if the result cannot be allocated. |
| 1187 int _shlFromInt(int other) { | 1187 int _shlFromInt(int other) { |
| 1188 if (_used == 0) return other; // Shift amount is zero. | 1188 if (_used == 0) return other; // Shift amount is zero. |
| 1189 if (_neg) throw "negative shift amount"; // TODO(regis): What exception? | 1189 if (_neg) throw new RangeError(this); |
| 1190 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. | 1190 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. |
| 1191 var shift; | 1191 var shift; |
| 1192 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) { | 1192 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) { |
| 1193 throw new OutOfMemoryError(); | 1193 throw new OutOfMemoryError(); |
| 1194 } else { | 1194 } else { |
| 1195 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; | 1195 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; |
| 1196 } | 1196 } |
| 1197 return other._toBigint()._lShift(shift)._toValidInt(); | 1197 return other._toBigint()._lShift(shift)._toValidInt(); |
| 1198 } | 1198 } |
| 1199 | 1199 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1338 return other._toBigint()._compare(this) == 0; | 1338 return other._toBigint()._compare(this) == 0; |
| 1339 } | 1339 } |
| 1340 | 1340 |
| 1341 // Returns pow(this, e) % m, with e >= 0, m > 0. | 1341 // Returns pow(this, e) % m, with e >= 0, m > 0. |
| 1342 int modPow(int e, int m) { | 1342 int modPow(int e, int m) { |
| 1343 if (e is! int) throw new ArgumentError(e); | 1343 if (e is! int) throw new ArgumentError(e); |
| 1344 if (m is! int) throw new ArgumentError(m); | 1344 if (m is! int) throw new ArgumentError(m); |
| 1345 if (e < 0) throw new RangeError(e); | 1345 if (e < 0) throw new RangeError(e); |
| 1346 if (m <= 0) throw new RangeError(m); | 1346 if (m <= 0) throw new RangeError(m); |
| 1347 if (e == 0) return 1; | 1347 if (e == 0) return 1; |
| 1348 e = e._toBigint(); |
| 1349 m = m._toBigint(); |
| 1348 final m_used = m._used; | 1350 final m_used = m._used; |
| 1349 final m_used2p2 = 2*m_used + 1 + 1; // +1 for leading zero. | 1351 final m_used2p2 = 2*m_used + 2; |
| 1350 final e_bitlen = e.bitLength; | 1352 final e_bitlen = e.bitLength; |
| 1351 if (e_bitlen <= 0) return 1; | 1353 if (e_bitlen <= 0) return 1; |
| 1352 if ((e is! _Bigint) || m.isEven) { | 1354 if ((e is! _Bigint) || m.isEven) { |
| 1353 _Reduction z = (e_bitlen < 8 || m.isEven) ? | 1355 _Reduction z = (e_bitlen < 8 || m.isEven) ? |
| 1354 new _Classic(m) : new _Montgomery(m); | 1356 new _Classic(m) : new _Montgomery(m); |
| 1355 // TODO(regis): Should we use Barrett reduction for an even modulus? | 1357 // TODO(regis): Should we use Barrett reduction for an even modulus? |
| 1356 var m_used = m._used; | |
| 1357 var r_digits = new Uint32List(m_used2p2); | 1358 var r_digits = new Uint32List(m_used2p2); |
| 1358 var r2_digits = new Uint32List(m_used2p2); | 1359 var r2_digits = new Uint32List(m_used2p2); |
| 1359 var g_digits = new Uint32List(m_used + (m_used & 1)); | 1360 var g_digits = new Uint32List(m_used + (m_used & 1)); |
| 1360 var g_used = z._convert(this, g_digits); | 1361 var g_used = z._convert(this, g_digits); |
| 1361 // Initialize r with g. | 1362 // Initialize r with g. |
| 1362 var j = g_used + (g_used & 1); // Copy leading zero if any. | 1363 var j = g_used + (g_used & 1); // Copy leading zero if any. |
| 1363 while (--j >= 0) { | 1364 while (--j >= 0) { |
| 1364 r_digits[j] = g_digits[j]; | 1365 r_digits[j] = g_digits[j]; |
| 1365 } | 1366 } |
| 1366 var r_used = g_used; | 1367 var r_used = g_used; |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1623 var d = _mulMod(_args, x_digits, i); | 1624 var d = _mulMod(_args, x_digits, i); |
| 1624 assert(d == _digits_per_step); | 1625 assert(d == _digits_per_step); |
| 1625 d = _Bigint._mulAdd(_args, _MU, m_digits, 0, x_digits, i, m_used); | 1626 d = _Bigint._mulAdd(_args, _MU, m_digits, 0, x_digits, i, m_used); |
| 1626 assert(d == _digits_per_step); | 1627 assert(d == _digits_per_step); |
| 1627 i += d; | 1628 i += d; |
| 1628 } | 1629 } |
| 1629 // Clamp x. | 1630 // Clamp x. |
| 1630 while (x_used > 0 && x_digits[x_used - 1] == 0) { | 1631 while (x_used > 0 && x_digits[x_used - 1] == 0) { |
| 1631 --x_used; | 1632 --x_used; |
| 1632 } | 1633 } |
| 1633 x_used = _Bigint._drShiftDigits(x_digits, x_used, m_used, x_digits); | 1634 // Shift right by m_used digits or, if processing pairs, by i (even) digits. |
| 1635 x_used = _Bigint._drShiftDigits(x_digits, x_used, i, x_digits); |
| 1634 if (_Bigint._compareDigits(x_digits, x_used, m_digits, m_used) >= 0) { | 1636 if (_Bigint._compareDigits(x_digits, x_used, m_digits, m_used) >= 0) { |
| 1635 _Bigint._absSub(x_digits, x_used, m_digits, m_used, x_digits); | 1637 _Bigint._absSub(x_digits, x_used, m_digits, m_used, x_digits); |
| 1636 } | 1638 } |
| 1637 // Clamp x. | 1639 // Clamp x. |
| 1638 while (x_used > 0 && x_digits[x_used - 1] == 0) { | 1640 while (x_used > 0 && x_digits[x_used - 1] == 0) { |
| 1639 --x_used; | 1641 --x_used; |
| 1640 } | 1642 } |
| 1641 return x_used; | 1643 return x_used; |
| 1642 } | 1644 } |
| 1643 | 1645 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1693 // _neg_norm_m_digits is read-only and has nm_used digits (possibly | 1695 // _neg_norm_m_digits is read-only and has nm_used digits (possibly |
| 1694 // including several leading zeros) plus a leading zero for 64-bit | 1696 // including several leading zeros) plus a leading zero for 64-bit |
| 1695 // processing. | 1697 // processing. |
| 1696 _t_digits = new Uint32List(2*nm_used); | 1698 _t_digits = new Uint32List(2*nm_used); |
| 1697 } | 1699 } |
| 1698 | 1700 |
| 1699 int _convert(_Bigint x, Uint32List r_digits) { | 1701 int _convert(_Bigint x, Uint32List r_digits) { |
| 1700 var digits; | 1702 var digits; |
| 1701 var used; | 1703 var used; |
| 1702 if (x._neg || x._compare(_m) >= 0) { | 1704 if (x._neg || x._compare(_m) >= 0) { |
| 1703 var r = x.rem(_m); | 1705 var r = x._rem(_m); |
| 1704 if (x._neg && !r._neg && r._used > 0) { | 1706 if (x._neg && !r._neg && r._used > 0) { |
| 1705 r = _m._sub(r); | 1707 r = _m._sub(r); |
| 1706 } | 1708 } |
| 1707 assert(!r._neg); | 1709 assert(!r._neg); |
| 1708 used = r._used; | 1710 used = r._used; |
| 1709 digits = r._digits; | 1711 digits = r._digits; |
| 1710 } else { | 1712 } else { |
| 1711 used = x._used; | 1713 used = x._used; |
| 1712 digits = x._digits; | 1714 digits = x._digits; |
| 1713 } | 1715 } |
| 1714 var i = used + (used + 1); // Copy leading zero if any. | 1716 var i = used + (used & 1); // Copy leading zero if any. |
| 1715 while (--i >= 0) { | 1717 while (--i >= 0) { |
| 1716 r_digits[i] = digits[i]; | 1718 r_digits[i] = digits[i]; |
| 1717 } | 1719 } |
| 1718 return used; | 1720 return used; |
| 1719 } | 1721 } |
| 1720 | 1722 |
| 1721 _Bigint _revert(Uint32List x_digits, int x_used) { | 1723 _Bigint _revert(Uint32List x_digits, int x_used) { |
| 1722 return new _Bigint(false, x_used, x_digits); | 1724 return new _Bigint(false, x_used, x_digits); |
| 1723 } | 1725 } |
| 1724 | 1726 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1741 | 1743 |
| 1742 int _mul(Uint32List x_digits, int x_used, | 1744 int _mul(Uint32List x_digits, int x_used, |
| 1743 Uint32List y_digits, int y_used, | 1745 Uint32List y_digits, int y_used, |
| 1744 Uint32List r_digits) { | 1746 Uint32List r_digits) { |
| 1745 var r_used = _Bigint._mulDigits(x_digits, x_used, | 1747 var r_used = _Bigint._mulDigits(x_digits, x_used, |
| 1746 y_digits, y_used, | 1748 y_digits, y_used, |
| 1747 r_digits); | 1749 r_digits); |
| 1748 return _reduce(r_digits, r_used); | 1750 return _reduce(r_digits, r_used); |
| 1749 } | 1751 } |
| 1750 } | 1752 } |
| OLD | NEW |