| 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 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 _lShiftTo(nsh, r); | 1031 _lShiftTo(nsh, r); |
| 1032 } | 1032 } |
| 1033 else { | 1033 else { |
| 1034 a._copyTo(y); | 1034 a._copyTo(y); |
| 1035 _copyTo(r); | 1035 _copyTo(r); |
| 1036 } | 1036 } |
| 1037 // We consider this and a positive. Ignore the copied sign. | 1037 // We consider this and a positive. Ignore the copied sign. |
| 1038 y._neg = false; | 1038 y._neg = false; |
| 1039 r._neg = false; | 1039 r._neg = false; |
| 1040 var y_used = y._used; | 1040 var y_used = y._used; |
| 1041 assert((y_used & 1) == 0); |
| 1041 var y_digits = y._digits; | 1042 var y_digits = y._digits; |
| 1042 Uint32List args = new Uint32List(4); | 1043 Uint32List args = new Uint32List(4); |
| 1043 args[_YT_LO] = y_digits[y_used - 2]; | 1044 args[_YT_LO] = y_digits[y_used - 2]; |
| 1044 args[_YT] = y_digits[y_used - 1]; | 1045 args[_YT] = y_digits[y_used - 1]; |
| 1046 var r_digits = r._digits; |
| 1045 var i = r._used; | 1047 var i = r._used; |
| 1048 if ((i & 1) == 1) { |
| 1049 // For 64-bit processing, make sure r has an even number of digits. |
| 1050 r_digits[i++] = 0; |
| 1051 } |
| 1046 var j = i - y_used; | 1052 var j = i - y_used; |
| 1047 _Bigint t = (q == null) ? new _Bigint() : q; | 1053 _Bigint t = (q == null) ? new _Bigint() : q; |
| 1048 y._dlShiftTo(j, t); | 1054 y._dlShiftTo(j, t); |
| 1049 var r_digits = r._digits; | |
| 1050 if (r._compareTo(t) >= 0) { | 1055 if (r._compareTo(t) >= 0) { |
| 1051 r_digits[r._used++] = 1; | 1056 r_digits[r._used++] = 1; |
| 1052 r_digits[r._used] = 0; // Set leading zero for 64-bit processing. | 1057 r_digits[r._used] = 0; // Set leading zero for 64-bit processing. |
| 1053 r._subTo(t, r); | 1058 r._subTo(t, r); |
| 1054 } | 1059 } |
| 1055 ONE._dlShiftTo(y_used, t); | 1060 ONE._dlShiftTo(y_used, t); |
| 1056 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later. | 1061 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later. |
| 1057 while (y._used < y_used) { | 1062 while (y._used < y_used) { |
| 1058 y_digits[y._used++] = 0; | 1063 y_digits[y._used++] = 0; |
| 1059 } | 1064 } |
| 1060 y_digits[y._used] = 0; // Set leading zero for 64-bit processing. | 1065 y_digits[y._used] = 0; // Set leading zero for 64-bit processing. |
| 1061 while (--j >= 0) { | 1066 while (j > 0) { |
| 1062 var d0 = _estQuotientDigit(args, r_digits, --i); | 1067 var d0 = _estQuotientDigit(args, r_digits, --i); |
| 1068 j -= d0; |
| 1063 var d1 = _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used); | 1069 var d1 = _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used); |
| 1064 // _estQuotientDigit and _mulAdd must agree on the number of digits to | 1070 // _estQuotientDigit and _mulAdd must agree on the number of digits to |
| 1065 // process. | 1071 // process. |
| 1066 assert(d0 == d1); | 1072 assert(d0 == d1); |
| 1067 if (d0 == 1) { | 1073 if (d0 == 1) { |
| 1068 if (r_digits[i] < args[_QD]) { | 1074 if (r_digits[i] < args[_QD]) { |
| 1069 y._dlShiftTo(j, t); | 1075 y._dlShiftTo(j, t); |
| 1070 r._subTo(t, r); | 1076 r._subTo(t, r); |
| 1071 while (r_digits[i] < --args[_QD]) { | 1077 while (r_digits[i] < --args[_QD]) { |
| 1072 r._subTo(t, r); | 1078 r._subTo(t, r); |
| 1073 } | 1079 } |
| 1074 } | 1080 } |
| 1075 } else { | 1081 } else { |
| 1076 // TODO(regis): Is this necessary, since intrinsified estimation is more | 1082 assert(d0 == 2); |
| 1077 // accurate? | 1083 assert(r_digits[i] <= args[_QD_HI]); |
| 1078 if ((r_digits[i] < args[_QD_HI]) || | 1084 if ((r_digits[i] < args[_QD_HI]) || (r_digits[i-1] < args[_QD])) { |
| 1079 ((r_digits[i] == args[_QD_HI]) && (r_digits[i-1] < args[_QD]))) { | |
| 1080 y._dlShiftTo(j, t); | 1085 y._dlShiftTo(j, t); |
| 1081 r._subTo(t, r); | 1086 r._subTo(t, r); |
| 1082 assert(args[_QD] > 0); | 1087 if (args[_QD] == 0) { |
| 1083 while (r_digits[i] < --args[_QD]) { | 1088 --args[_QD_HI]; |
| 1089 } |
| 1090 --args[_QD]; |
| 1091 assert(r_digits[i] <= args[_QD_HI]); |
| 1092 while ((r_digits[i] < args[_QD_HI]) || (r_digits[i-1] < args[_QD])) { |
| 1084 r._subTo(t, r); | 1093 r._subTo(t, r); |
| 1094 if (args[_QD] == 0) { |
| 1095 --args[_QD_HI]; |
| 1096 } |
| 1097 --args[_QD]; |
| 1098 assert(r_digits[i] <= args[_QD_HI]); |
| 1085 } | 1099 } |
| 1086 } | 1100 } |
| 1101 --i; |
| 1087 } | 1102 } |
| 1088 } | 1103 } |
| 1089 if (q != null) { | 1104 if (q != null) { |
| 1090 r._drShiftTo(y_used, q); | 1105 r._drShiftTo(y_used, q); |
| 1091 if (_neg != a._neg && q._used > 0) { | 1106 if (_neg != a._neg && q._used > 0) { |
| 1092 q._neg = !q._neg; | 1107 q._neg = !q._neg; |
| 1093 } | 1108 } |
| 1094 } | 1109 } |
| 1095 r._used = y_used; | 1110 r._used = y_used; |
| 1096 r._clamp(); | 1111 r._clamp(); |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 static const int _X_HI = 1; // Index of high 32-bits of x (64-bit only). | 1463 static const int _X_HI = 1; // Index of high 32-bits of x (64-bit only). |
| 1449 static const int _RHO = 2; // Index of rho. | 1464 static const int _RHO = 2; // Index of rho. |
| 1450 static const int _RHO_HI = 3; // Index of high 32-bits of rho (64-bit only). | 1465 static const int _RHO_HI = 3; // Index of high 32-bits of rho (64-bit only). |
| 1451 static const int _MU = 4; // Index of mu. | 1466 static const int _MU = 4; // Index of mu. |
| 1452 static const int _MU_HI = 5; // Index of high 32-bits of mu (64-bit only). | 1467 static const int _MU_HI = 5; // Index of high 32-bits of mu (64-bit only). |
| 1453 | 1468 |
| 1454 _Montgomery(m) { | 1469 _Montgomery(m) { |
| 1455 _m = m._toBigint(); | 1470 _m = m._toBigint(); |
| 1456 _mused2 = 2*_m._used; | 1471 _mused2 = 2*_m._used; |
| 1457 _args = new Uint32List(6); | 1472 _args = new Uint32List(6); |
| 1473 // Determine if we can process digit pairs by calling an intrinsic. |
| 1474 _digits_per_step = _mulMod(_args, _args, 0); |
| 1458 _args[_X] = _m._digits[0]; | 1475 _args[_X] = _m._digits[0]; |
| 1459 _args[_X_HI] = _m._digits[1]; | 1476 if (_digits_per_step == 1) { |
| 1460 _digits_per_step = _invDigit(_args); | 1477 _invDigit(_args); |
| 1478 } else { |
| 1479 assert(_digits_per_step == 2); |
| 1480 _args[_X_HI] = _m._digits[1]; |
| 1481 _invDigitPair(_args); |
| 1482 } |
| 1461 } | 1483 } |
| 1462 | 1484 |
| 1463 // Return -1/this % DIGIT_BASE, useful for Montgomery reduction. | 1485 // Calculates -1/x % DIGIT_BASE, x is 32-bit digit. |
| 1464 // | |
| 1465 // xy == 1 (mod m) | 1486 // xy == 1 (mod m) |
| 1466 // xy = 1+km | 1487 // xy = 1+km |
| 1467 // xy(2-xy) = (1+km)(1-km) | 1488 // xy(2-xy) = (1+km)(1-km) |
| 1468 // x(y(2-xy)) = 1-k^2 m^2 | 1489 // x(y(2-xy)) = 1-k^2 m^2 |
| 1469 // x(y(2-xy)) == 1 (mod m^2) | 1490 // x(y(2-xy)) == 1 (mod m^2) |
| 1470 // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 | 1491 // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 |
| 1471 // Should reduce x and y(2-xy) by m^2 at each step to keep size bounded. | 1492 // Should reduce x and y(2-xy) by m^2 at each step to keep size bounded. |
| 1472 // | 1493 // |
| 1473 // TODO(regis): Intrinsify this method and provide a 64-bit inverse digit pair | |
| 1474 // on 64-bit platforms. | |
| 1475 // | |
| 1476 // Operation: | 1494 // Operation: |
| 1477 // args[_RHO] = 1/args[_X] mod DIGIT_BASE. | 1495 // args[_RHO] = 1/args[_X] mod DIGIT_BASE. |
| 1478 // return 1. | 1496 static void _invDigit(Uint32List args) { |
| 1479 // Note: intrinsics on 64-bit platform process a digit pair: | |
| 1480 // args[_RHO.._RHO_HI] = 1/args[_X.._X_HI] mod DIGIT_BASE^2. | |
| 1481 // return 2. | |
| 1482 static int _invDigit(Uint32List args) { | |
| 1483 var x = args[_X]; | 1497 var x = args[_X]; |
| 1484 var y = x & 3; // y == 1/x mod 2^2 | 1498 var y = x & 3; // y == 1/x mod 2^2 |
| 1485 y = (y*(2 - (x & 0xf)*y)) & 0xf; // y == 1/x mod 2^4 | 1499 y = (y*(2 - (x & 0xf)*y)) & 0xf; // y == 1/x mod 2^4 |
| 1486 y = (y*(2 - (x & 0xff)*y)) & 0xff; // y == 1/x mod 2^8 | 1500 y = (y*(2 - (x & 0xff)*y)) & 0xff; // y == 1/x mod 2^8 |
| 1487 y = (y*(2 - (((x & 0xffff)*y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 | 1501 y = (y*(2 - (((x & 0xffff)*y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 |
| 1488 // Last step - calculate inverse mod DIGIT_BASE directly; | 1502 // Last step - calculate inverse mod DIGIT_BASE directly; |
| 1489 // Assumes 16 < DIGIT_BITS <= 32 and assumes ability to handle 48-bit ints. | 1503 // Assumes 16 < DIGIT_BITS <= 32 and assumes ability to handle 48-bit ints. |
| 1490 y = (y*(2 - x*y % _Bigint.DIGIT_BASE)) % _Bigint.DIGIT_BASE; | 1504 y = (y*(2 - x*y % _Bigint.DIGIT_BASE)) % _Bigint.DIGIT_BASE; |
| 1491 // y == 1/x mod DIGIT_BASE | 1505 // y == 1/x mod DIGIT_BASE |
| 1492 // We really want the negative inverse, and - DIGIT_BASE < y < DIGIT_BASE. | 1506 y = -y; // We really want the negative inverse. |
| 1493 args[_RHO] = (y > 0) ? _Bigint.DIGIT_BASE - y : -y; | 1507 args[_RHO] = y & _Bigint.DIGIT_MASK; |
| 1494 return 1; | |
| 1495 } | 1508 } |
| 1496 | 1509 |
| 1510 |
| 1511 // Calculates -1/x % DIGIT_BASE^2, x is a pair of 32-bit digits. |
| 1512 // Operation: |
| 1513 // args[_RHO.._RHO_HI] = 1/args[_X.._X_HI] mod DIGIT_BASE^2. |
| 1514 static void _invDigitPair(Uint32List args) { |
| 1515 var xl = args[_X]; // Lower 32-bit digit of x. |
| 1516 var y = xl & 3; // y == 1/x mod 2^2 |
| 1517 y = (y*(2 - (xl & 0xf)*y)) & 0xf; // y == 1/x mod 2^4 |
| 1518 y = (y*(2 - (xl & 0xff)*y)) & 0xff; // y == 1/x mod 2^8 |
| 1519 y = (y*(2 - (((xl & 0xffff)*y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 |
| 1520 y = (y*(2 - ((xl*y) & 0xffffffff))) & 0xffffffff; // y == 1/x mod 2^32 |
| 1521 var x = (args[_X_HI] << _Bigint.DIGIT_BITS) | xl; |
| 1522 y = (y*(2 - ((x*y) & 0xffffffffffffffff))) & 0xffffffffffffffff; |
| 1523 // y == 1/x mod DIGIT_BASE^2 |
| 1524 y = -y; // We really want the negative inverse. |
| 1525 args[_RHO] = y & _Bigint.DIGIT_MASK; |
| 1526 args[_RHO_HI] = (y >> _Bigint.DIGIT_BITS) & _Bigint.DIGIT_MASK; |
| 1527 } |
| 1528 |
| 1529 |
| 1497 // Operation: | 1530 // Operation: |
| 1498 // args[_MU] = args[_RHO]*digits[i] mod DIGIT_BASE. | 1531 // args[_MU] = args[_RHO]*digits[i] mod DIGIT_BASE. |
| 1499 // return 1. | 1532 // return 1. |
| 1500 // Note: intrinsics on 64-bit platform may process a digit pair: | 1533 // Note: intrinsics on 64-bit platform may process a digit pair: |
| 1501 // args[_MU.._MU_HI] = args[_RHO.._RHO_HI]*digits[i..i+1] mod DIGIT_BASE^2. | 1534 // args[_MU.._MU_HI] = args[_RHO.._RHO_HI]*digits[i..i+1] mod DIGIT_BASE^2. |
| 1502 // return 2. | 1535 // return 2. |
| 1503 static int _mulMod(Uint32List args, Uint32List digits, int i) { | 1536 static int _mulMod(Uint32List args, Uint32List digits, int i) { |
| 1504 const int MU_MASK = (1 << (_Bigint.DIGIT_BITS - _Bigint.DIGIT2_BITS)) - 1; | 1537 const int MU_MASK = (1 << (_Bigint.DIGIT_BITS - _Bigint.DIGIT2_BITS)) - 1; |
| 1505 var rhol = args[_RHO] & _Bigint.DIGIT2_MASK; | 1538 var rhol = args[_RHO] & _Bigint.DIGIT2_MASK; |
| 1506 var rhoh = args[_RHO] >> _Bigint.DIGIT2_BITS; | 1539 var rhoh = args[_RHO] >> _Bigint.DIGIT2_BITS; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 void _sqrTo(_Bigint x, _Bigint r) { | 1633 void _sqrTo(_Bigint x, _Bigint r) { |
| 1601 x._sqrTo(r); | 1634 x._sqrTo(r); |
| 1602 _reduce(r); | 1635 _reduce(r); |
| 1603 } | 1636 } |
| 1604 | 1637 |
| 1605 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { | 1638 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { |
| 1606 x._mulTo(y, r); | 1639 x._mulTo(y, r); |
| 1607 _reduce(r); | 1640 _reduce(r); |
| 1608 } | 1641 } |
| 1609 } | 1642 } |
| OLD | NEW |