Chromium Code Reviews| 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 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1071 // concatenated quotient and normalized remainder. | 1071 // concatenated quotient and normalized remainder. |
| 1072 // Output: | 1072 // Output: |
| 1073 // r_digits[0..r_used-1]: positive remainder. | 1073 // r_digits[0..r_used-1]: positive remainder. |
| 1074 // Returns r_used. | 1074 // Returns r_used. |
| 1075 static int _remDigits(Uint32List x_digits, int x_used, | 1075 static int _remDigits(Uint32List x_digits, int x_used, |
| 1076 Uint32List y_digits, int y_used, Uint32List ny_digits, | 1076 Uint32List y_digits, int y_used, Uint32List ny_digits, |
| 1077 int nsh, | 1077 int nsh, |
| 1078 Uint32List yt_qd, | 1078 Uint32List yt_qd, |
| 1079 Uint32List t_digits, | 1079 Uint32List t_digits, |
| 1080 Uint32List r_digits) { | 1080 Uint32List r_digits) { |
| 1081 assert(y_used > 0 && x_used >= y_used); | |
| 1082 // Initialize r_digits to normalized positive dividend. | 1081 // Initialize r_digits to normalized positive dividend. |
| 1083 var r_used = _lShiftDigits(x_digits, x_used, nsh, r_digits); | 1082 var r_used = _lShiftDigits(x_digits, x_used, nsh, r_digits); |
| 1084 // For 64-bit processing, make sure y_used, i, and j are even. | 1083 // For 64-bit processing, make sure y_used, i, and j are even. |
| 1085 assert(y_used.isEven); | 1084 assert(y_used.isEven); |
| 1086 var i = r_used + (r_used & 1); | 1085 var i = r_used + (r_used & 1); |
| 1087 var j = i - y_used; | 1086 var j = i - y_used; |
| 1088 var t_used = _dlShiftDigits(y_digits, y_used, j, t_digits); | 1087 var t_used = _dlShiftDigits(y_digits, y_used, j, t_digits); |
| 1089 // Explicit first division step in case normalized dividend is larger or | 1088 // Explicit first division step in case normalized dividend is larger or |
| 1090 // equal to shifted normalized divisor. | 1089 // equal to shifted normalized divisor. |
| 1091 if (_compareDigits(r_digits, r_used, t_digits, t_used) >= 0) { | 1090 if (_compareDigits(r_digits, r_used, t_digits, t_used) >= 0) { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1338 return other._toBigint()._compare(this) == 0; | 1337 return other._toBigint()._compare(this) == 0; |
| 1339 } | 1338 } |
| 1340 | 1339 |
| 1341 // Returns pow(this, e) % m, with e >= 0, m > 0. | 1340 // Returns pow(this, e) % m, with e >= 0, m > 0. |
| 1342 int modPow(int e, int m) { | 1341 int modPow(int e, int m) { |
| 1343 if (e is! int) throw new ArgumentError(e); | 1342 if (e is! int) throw new ArgumentError(e); |
| 1344 if (m is! int) throw new ArgumentError(m); | 1343 if (m is! int) throw new ArgumentError(m); |
| 1345 if (e < 0) throw new RangeError(e); | 1344 if (e < 0) throw new RangeError(e); |
| 1346 if (m <= 0) throw new RangeError(m); | 1345 if (m <= 0) throw new RangeError(m); |
| 1347 if (e == 0) return 1; | 1346 if (e == 0) return 1; |
| 1348 e = e._toBigint(); | |
| 1349 m = m._toBigint(); | 1347 m = m._toBigint(); |
| 1350 final m_used = m._used; | 1348 final m_used = m._used; |
| 1351 final m_used2p2 = 2*m_used + 2; | 1349 final m_used2p2 = 2*m_used + 2; |
| 1352 final e_bitlen = e.bitLength; | 1350 final e_bitlen = e.bitLength; |
| 1353 if (e_bitlen <= 0) return 1; | 1351 if (e_bitlen <= 0) return 1; |
| 1354 if ((e is! _Bigint) || m.isEven) { | 1352 final bool cannot_use_montgomery = m.isEven || _abs() >= m; |
| 1355 _Reduction z = (e_bitlen < 8 || m.isEven) ? | 1353 if (cannot_use_montgomery || e_bitlen < 64) { |
| 1354 _Reduction z = (cannot_use_montgomery || e_bitlen < 8) ? | |
|
srdjan
2015/02/17 19:15:37
Dart style guide says to use camelBack instead of
regis
2015/02/17 19:32:15
I renamed the new variable cannot_use_montgomery t
| |
| 1356 new _Classic(m) : new _Montgomery(m); | 1355 new _Classic(m) : new _Montgomery(m); |
| 1357 // TODO(regis): Should we use Barrett reduction for an even modulus? | 1356 // TODO(regis): Should we use Barrett reduction for an even modulus and a |
| 1357 // large exponent? | |
| 1358 var r_digits = new Uint32List(m_used2p2); | 1358 var r_digits = new Uint32List(m_used2p2); |
| 1359 var r2_digits = new Uint32List(m_used2p2); | 1359 var r2_digits = new Uint32List(m_used2p2); |
| 1360 var g_digits = new Uint32List(m_used + (m_used & 1)); | 1360 var g_digits = new Uint32List(m_used + (m_used & 1)); |
| 1361 var g_used = z._convert(this, g_digits); | 1361 var g_used = z._convert(this, g_digits); |
| 1362 // Initialize r with g. | 1362 // Initialize r with g. |
| 1363 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. |
| 1364 while (--j >= 0) { | 1364 while (--j >= 0) { |
| 1365 r_digits[j] = g_digits[j]; | 1365 r_digits[j] = g_digits[j]; |
| 1366 } | 1366 } |
| 1367 var r_used = g_used; | 1367 var r_used = g_used; |
| 1368 var r2_used; | 1368 var r2_used; |
| 1369 var i = e_bitlen - 1; | 1369 var i = e_bitlen - 1; |
| 1370 while (--i >= 0) { | 1370 while (--i >= 0) { |
| 1371 r2_used = z._sqr(r_digits, r_used, r2_digits); | 1371 r2_used = z._sqr(r_digits, r_used, r2_digits); |
| 1372 if ((e & (1 << i)) != 0) { | 1372 if ((e & (1 << i)) != 0) { |
| 1373 r_used = z._mul(r2_digits, r2_used, g_digits, g_used, r_digits); | 1373 r_used = z._mul(r2_digits, r2_used, g_digits, g_used, r_digits); |
| 1374 } else { | 1374 } else { |
| 1375 var t_digits = r_digits; | 1375 var t_digits = r_digits; |
| 1376 var t_used = r_used; | 1376 var t_used = r_used; |
| 1377 r_digits = r2_digits; | 1377 r_digits = r2_digits; |
| 1378 r_used = r2_used; | 1378 r_used = r2_used; |
| 1379 r2_digits = t_digits; | 1379 r2_digits = t_digits; |
| 1380 r2_used = t_used; | 1380 r2_used = t_used; |
| 1381 } | 1381 } |
| 1382 } | 1382 } |
| 1383 return z._revert(r_digits, r_used)._toValidInt(); | 1383 return z._revert(r_digits, r_used)._toValidInt(); |
| 1384 } | 1384 } |
| 1385 e = e._toBigint(); | |
| 1385 var k; | 1386 var k; |
| 1386 if (e_bitlen < 18) k = 1; | 1387 if (e_bitlen < 18) k = 1; |
| 1387 else if (e_bitlen < 48) k = 3; | 1388 else if (e_bitlen < 48) k = 3; |
| 1388 else if (e_bitlen < 144) k = 4; | 1389 else if (e_bitlen < 144) k = 4; |
| 1389 else if (e_bitlen < 768) k = 5; | 1390 else if (e_bitlen < 768) k = 5; |
| 1390 else k = 6; | 1391 else k = 6; |
| 1391 _Reduction z = new _Montgomery(m); | 1392 _Reduction z = new _Montgomery(m); |
| 1392 var n = 3; | 1393 var n = 3; |
| 1393 final k1 = k - 1; | 1394 final k1 = k - 1; |
| 1394 final km = (1 << k) - 1; | 1395 final km = (1 << k) - 1; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1581 var dl = digits[i] & _Bigint._DIGIT2_MASK; | 1582 var dl = digits[i] & _Bigint._DIGIT2_MASK; |
| 1582 args[_MU] = | 1583 args[_MU] = |
| 1583 (dl*rhol + (((dl*rhoh + dh*rhol) & MU_MASK) << _Bigint._DIGIT2_BITS)) | 1584 (dl*rhol + (((dl*rhoh + dh*rhol) & MU_MASK) << _Bigint._DIGIT2_BITS)) |
| 1584 & _Bigint._DIGIT_MASK; | 1585 & _Bigint._DIGIT_MASK; |
| 1585 return 1; | 1586 return 1; |
| 1586 } | 1587 } |
| 1587 | 1588 |
| 1588 // r = x*R mod _m. | 1589 // r = x*R mod _m. |
| 1589 // Return r_used. | 1590 // Return r_used. |
| 1590 int _convert(_Bigint x, Uint32List r_digits) { | 1591 int _convert(_Bigint x, Uint32List r_digits) { |
| 1592 // Montgomery reduction only works if abs(x) < _m. | |
| 1593 assert(x._abs() < _m); | |
| 1591 var r = x._abs()._dlShift(_m._used)._rem(_m); | 1594 var r = x._abs()._dlShift(_m._used)._rem(_m); |
| 1592 if (x._neg && !r._neg && r._used > 0) { | 1595 if (x._neg && !r._neg && r._used > 0) { |
| 1593 r = _m._sub(r); | 1596 r = _m._sub(r); |
| 1594 } | 1597 } |
| 1595 var used = r._used; | 1598 var used = r._used; |
| 1596 var digits = r._digits; | 1599 var digits = r._digits; |
| 1597 var i = used + (used & 1); | 1600 var i = used + (used & 1); |
| 1598 while (--i >= 0) { | 1601 while (--i >= 0) { |
| 1599 r_digits[i] = digits[i]; | 1602 r_digits[i] = digits[i]; |
| 1600 } | 1603 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1688 var neg_norm_m = _Bigint._ONE._dlShift(nm_used)._sub(_norm_m); | 1691 var neg_norm_m = _Bigint._ONE._dlShift(nm_used)._sub(_norm_m); |
| 1689 if (neg_norm_m._used < nm_used) { | 1692 if (neg_norm_m._used < nm_used) { |
| 1690 _neg_norm_m_digits = | 1693 _neg_norm_m_digits = |
| 1691 _Bigint._cloneDigits(neg_norm_m._digits, 0, nm_used, nm_used); | 1694 _Bigint._cloneDigits(neg_norm_m._digits, 0, nm_used, nm_used); |
| 1692 } else { | 1695 } else { |
| 1693 _neg_norm_m_digits = neg_norm_m._digits; | 1696 _neg_norm_m_digits = neg_norm_m._digits; |
| 1694 } | 1697 } |
| 1695 // _neg_norm_m_digits is read-only and has nm_used digits (possibly | 1698 // _neg_norm_m_digits is read-only and has nm_used digits (possibly |
| 1696 // including several leading zeros) plus a leading zero for 64-bit | 1699 // including several leading zeros) plus a leading zero for 64-bit |
| 1697 // processing. | 1700 // processing. |
| 1698 _t_digits = new Uint32List(2*nm_used); | 1701 _t_digits = new Uint32List(2*nm_used + 2); |
| 1699 } | 1702 } |
| 1700 | 1703 |
| 1701 int _convert(_Bigint x, Uint32List r_digits) { | 1704 int _convert(_Bigint x, Uint32List r_digits) { |
| 1702 var digits; | 1705 var digits; |
| 1703 var used; | 1706 var used; |
| 1704 if (x._neg || x._compare(_m) >= 0) { | 1707 if (x._neg || x._compare(_m) >= 0) { |
| 1705 var r = x._rem(_m); | 1708 var r = x._rem(_m); |
| 1706 if (x._neg && !r._neg && r._used > 0) { | 1709 if (x._neg && !r._neg && r._used > 0) { |
| 1707 r = _m._sub(r); | 1710 r = _m._sub(r); |
| 1708 } | 1711 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1743 | 1746 |
| 1744 int _mul(Uint32List x_digits, int x_used, | 1747 int _mul(Uint32List x_digits, int x_used, |
| 1745 Uint32List y_digits, int y_used, | 1748 Uint32List y_digits, int y_used, |
| 1746 Uint32List r_digits) { | 1749 Uint32List r_digits) { |
| 1747 var r_used = _Bigint._mulDigits(x_digits, x_used, | 1750 var r_used = _Bigint._mulDigits(x_digits, x_used, |
| 1748 y_digits, y_used, | 1751 y_digits, y_used, |
| 1749 r_digits); | 1752 r_digits); |
| 1750 return _reduce(r_digits, r_used); | 1753 return _reduce(r_digits, r_used); |
| 1751 } | 1754 } |
| 1752 } | 1755 } |
| OLD | NEW |