Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: runtime/lib/bigint.dart

Issue 918403002: Add modPow tests. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/corelib/big_integer_arith_vm_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/corelib/big_integer_arith_vm_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698