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 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 729 r_neg = !r_neg; | 729 r_neg = !r_neg; |
| 730 a._absSubTo(this, r); | 730 a._absSubTo(this, r); |
| 731 } | 731 } |
| 732 } | 732 } |
| 733 r._neg = r_neg; | 733 r._neg = r_neg; |
| 734 return r; | 734 return r; |
| 735 } | 735 } |
| 736 | 736 |
| 737 // Accumulate multiply. | 737 // Accumulate multiply. |
| 738 // this[i..i+n-1]: bigint multiplicand. | 738 // this[i..i+n-1]: bigint multiplicand. |
| 739 // x: digit multiplier. | 739 // x: digit multiplier, 0 <= x < DIGIT_BASE (i.e. 32-bit multiplier). |
| 740 // w[j..j+n-1]: bigint accumulator. | |
| 741 // Returns carry out. | |
| 742 // w[j..j+n-1] += this[i..i+n-1] * x. | |
| 743 // Returns carry out. | |
| 744 int _am(int i, int x, _Bigint w, int j, int n) { | |
| 745 if (x == 0) { | |
| 746 // No-op if x is 0. | |
| 747 return 0; | |
| 748 } | |
| 749 int c = 0; | |
| 750 int xl = x & DIGIT2_MASK; | |
| 751 int xh = x >> DIGIT2_BITS; | |
| 752 while (--n >= 0) { | |
| 753 int l = _digits[i] & DIGIT2_MASK; | |
| 754 int h = _digits[i++] >> DIGIT2_BITS; | |
| 755 int m = xh*l + h*xl; | |
| 756 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + w._digits[j] + c; | |
| 757 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; | |
| 758 w._digits[j++] = l & DIGIT_MASK; | |
| 759 } | |
| 760 return c; | |
| 761 } | |
| 762 | |
| 763 // Accumulate multiply with carry. | |
| 764 // this[i..i+n-1]: bigint multiplicand. | |
| 765 // x: digit multiplier, 0 <= x < 2*DIGIT_BASE (i.e. 33-bit multiplier). | |
| 740 // w[j..j+n-1]: bigint accumulator. | 766 // w[j..j+n-1]: bigint accumulator. |
| 741 // c: int carry in. | 767 // c: int carry in. |
| 742 // Returns carry out. | 768 // Returns carry out. |
| 743 // w[j..j+n-1] += this[i..i+n-1] * x + c. | 769 // w[j..j+n-1] += this[i..i+n-1] * x + c. |
| 744 // Returns carry out. | 770 // Returns carry out. |
| 745 // TODO(regis): _sqrTo is the only caller passing an x possibly larger than | 771 int _amc(int i, int x, _Bigint w, int j, int c, int n) { |
| 746 // a digit (2*digit) and passing a non-zero carry in. Refactor? | |
| 747 int _am(int i, int x, _Bigint w, int j, int c, int n) { | |
| 748 if (x == 0 && c == 0) { | 772 if (x == 0 && c == 0) { |
| 749 // No-op if both x and c are 0. | 773 // No-op if both x and c are 0. |
| 750 return 0; | 774 return 0; |
| 751 } | 775 } |
| 752 int xl = x & DIGIT2_MASK; | 776 int xl = x & DIGIT2_MASK; |
| 753 int xh = x >> DIGIT2_BITS; | 777 int xh = x >> DIGIT2_BITS; |
| 754 while (--n >= 0) { | 778 while (--n >= 0) { |
| 755 int l = _digits[i] & DIGIT2_MASK; | 779 int l = _digits[i] & DIGIT2_MASK; |
| 756 int h = _digits[i++] >> DIGIT2_BITS; | 780 int h = _digits[i++] >> DIGIT2_BITS; |
| 757 int m = xh*l + h*xl; | 781 int m = xh*l + h*xl; |
| 758 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + w._digits[j] + c; | 782 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + w._digits[j] + c; |
| 759 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; | 783 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; |
| 760 w._digits[j++] = l & DIGIT_MASK; | 784 w._digits[j++] = l & DIGIT_MASK; |
| 761 } | 785 } |
| 762 return c; | 786 return c; |
| 763 } | 787 } |
| 764 | 788 |
| 765 // r = this * a. | 789 // r = this * a. |
| 766 void _mulTo(_Bigint a, _Bigint r) { | 790 void _mulTo(_Bigint a, _Bigint r) { |
| 767 // TODO(regis): Use karatsuba multiplication when appropriate. | 791 // TODO(regis): Use karatsuba multiplication when appropriate. |
| 768 var i = _used; | 792 var i = _used; |
| 769 r._ensureLength(i + a._used); | 793 r._ensureLength(i + a._used); |
| 770 r._used = i + a._used; | 794 r._used = i + a._used; |
| 771 while (--i >= 0) { | 795 while (--i >= 0) { |
| 772 r._digits[i] = 0; | 796 r._digits[i] = 0; |
| 773 } | 797 } |
| 774 for (i = 0; i < a._used; ++i) { | 798 for (i = 0; i < a._used; ++i) { |
| 775 // TODO(regis): Replace _am with addMulVVW. | 799 r._digits[i + _used] = _am(0, a._digits[i], r, i, _used); |
| 776 r._digits[i + _used] = _am(0, a._digits[i], r, i, 0, _used); | |
| 777 } | 800 } |
| 778 r._clamp(); | 801 r._clamp(); |
| 779 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. | 802 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. |
| 780 } | 803 } |
| 781 | 804 |
| 782 // r = this^2, r != this. | 805 // r = this^2, r != this. |
| 783 void _sqrTo(_Bigint r) { | 806 void _sqrTo(_Bigint r) { |
| 784 var i = 2 * _used; | 807 var i = 2 * _used; |
| 785 r._ensureLength(i); | 808 r._ensureLength(i); |
| 786 r._used = i; | 809 r._used = i; |
| 787 while (--i >= 0) { | 810 while (--i >= 0) { |
| 788 r._digits[i] = 0; | 811 r._digits[i] = 0; |
| 789 } | 812 } |
| 790 for (i = 0; i < _used - 1; ++i) { | 813 for (i = 0; i < _used - 1; ++i) { |
| 791 var c = _am(i, _digits[i], r, 2*i, 0, 1); | 814 var c = _am(i, _digits[i], r, 2*i, 1); |
| 792 var d = r._digits[i + _used]; | 815 var d = r._digits[i + _used]; |
| 793 d += _am(i + 1, _digits[i] << 1, r, 2*i + 1, c, _used - i - 1); | 816 d += _amc(i + 1, _digits[i] << 1, r, 2*i + 1, c, _used - i - 1); |
| 794 if (d >= DIGIT_BASE) { | 817 if (d >= DIGIT_BASE) { |
| 795 r._digits[i + _used] = d - DIGIT_BASE; | 818 r._digits[i + _used] = d - DIGIT_BASE; |
| 796 r._digits[i + _used + 1] = 1; | 819 r._digits[i + _used + 1] = 1; |
| 797 } else { | 820 } else { |
| 798 r._digits[i + _used] = d; | 821 r._digits[i + _used] = d; |
| 799 } | 822 } |
| 800 } | 823 } |
| 801 if (r._used > 0) { | 824 if (r._used > 0) { |
| 802 r._digits[r._used - 1] += _am(i, _digits[i], r, 2*i, 0, 1); | 825 r._digits[r._used - 1] += _am(i, _digits[i], r, 2*i, 1); |
| 803 } | 826 } |
| 804 r._neg = false; | 827 r._neg = false; |
| 805 r._clamp(); | 828 r._clamp(); |
| 806 } | 829 } |
| 807 | 830 |
| 808 // Truncating division and remainder. | 831 // Truncating division and remainder. |
| 809 // If q != null, q = trunc(this / a). | 832 // If q != null, q = trunc(this / a). |
| 810 // If r != null, r = this - a * trunc(this / a). | 833 // If r != null, r = this - a * trunc(this / a). |
| 811 void _divRemTo(_Bigint a, _Bigint q, _Bigint r) { | 834 void _divRemTo(_Bigint a, _Bigint q, _Bigint r) { |
| 812 if (a._used == 0) return; | 835 if (a._used == 0) return; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 ONE._dlShiftTo(y_used, t); | 880 ONE._dlShiftTo(y_used, t); |
| 858 t._subTo(y, y); // "negative" y so we can replace sub with _am later | 881 t._subTo(y, y); // "negative" y so we can replace sub with _am later |
| 859 while (y._used < y_used) { | 882 while (y._used < y_used) { |
| 860 y._digits[y._used++] = 0; | 883 y._digits[y._used++] = 0; |
| 861 } | 884 } |
| 862 while (--j >= 0) { | 885 while (--j >= 0) { |
| 863 // Estimate quotient digit | 886 // Estimate quotient digit |
| 864 var qd = (r._digits[--i] == y0) | 887 var qd = (r._digits[--i] == y0) |
| 865 ? DIGIT_MASK | 888 ? DIGIT_MASK |
| 866 : (r._digits[i]*d1 + (r._digits[i - 1] + e)*d2).floor(); | 889 : (r._digits[i]*d1 + (r._digits[i - 1] + e)*d2).floor(); |
| 867 if ((r._digits[i] += y._am(0, qd, r, j, 0, y_used)) < qd) { // Try it out | 890 if ((r._digits[i] += y._amc(0, qd, r, j, 0, y_used)) < qd) { // Try it ou t |
| 868 y._dlShiftTo(j, t); | 891 y._dlShiftTo(j, t); |
| 869 r._subTo(t, r); | 892 r._subTo(t, r); |
| 870 while (r._digits[i] < --qd) { | 893 while (r._digits[i] < --qd) { |
| 871 r._subTo(t, r); | 894 r._subTo(t, r); |
| 872 } | 895 } |
| 873 } | 896 } |
| 874 } | 897 } |
| 875 if (q != null) { | 898 if (q != null) { |
| 876 r._drShiftTo(y_used, q); | 899 r._drShiftTo(y_used, q); |
| 877 if (_neg != a._neg) { | 900 if (_neg != a._neg) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 933 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) { | 956 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) { |
| 934 throw new OutOfMemoryError(); | 957 throw new OutOfMemoryError(); |
| 935 } else { | 958 } else { |
| 936 shift = ((_used == 2) ? (_digits[1] << DIGIT_BITS) : 0) + _digits[0]; | 959 shift = ((_used == 2) ? (_digits[1] << DIGIT_BITS) : 0) + _digits[0]; |
| 937 } | 960 } |
| 938 _Bigint result = new _Bigint(); | 961 _Bigint result = new _Bigint(); |
| 939 other._toBigint()._lShiftTo(shift, result); | 962 other._toBigint()._lShiftTo(shift, result); |
| 940 return result._toValidInt(); | 963 return result._toValidInt(); |
| 941 } | 964 } |
| 942 | 965 |
| 943 int pow(int exponent) { | |
| 944 throw "Bigint.pow not implemented"; | |
| 945 } | |
| 946 | |
| 947 // Overriden operators and methods. | 966 // Overriden operators and methods. |
| 948 | 967 |
| 949 // The following operators override operators of _IntegerImplementation for | 968 // The following operators override operators of _IntegerImplementation for |
| 950 // efficiency, but are not necessary for correctness. They shortcut native | 969 // efficiency, but are not necessary for correctness. They shortcut native |
| 951 // calls that would return null because the receiver is _Bigint. | 970 // calls that would return null because the receiver is _Bigint. |
| 952 num operator +(num other) { | 971 num operator +(num other) { |
| 953 return other._toBigintOrDouble()._addFromInteger(this); | 972 return other._toBigintOrDouble()._addFromInteger(this); |
| 954 } | 973 } |
| 955 num operator -(num other) { | 974 num operator -(num other) { |
| 956 return other._toBigintOrDouble()._subFromInteger(this); | 975 return other._toBigintOrDouble()._subFromInteger(this); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1067 other._toBigint()._divRemTo(this, null, result); | 1086 other._toBigint()._divRemTo(this, null, result); |
| 1068 return result._toValidInt(); | 1087 return result._toValidInt(); |
| 1069 } | 1088 } |
| 1070 bool _greaterThanFromInteger(int other) { | 1089 bool _greaterThanFromInteger(int other) { |
| 1071 return other._toBigint()._compareTo(this) > 0; | 1090 return other._toBigint()._compareTo(this) > 0; |
| 1072 } | 1091 } |
| 1073 bool _equalToInteger(int other) { | 1092 bool _equalToInteger(int other) { |
| 1074 return other._toBigint()._compareTo(this) == 0; | 1093 return other._toBigint()._compareTo(this) == 0; |
| 1075 } | 1094 } |
| 1076 | 1095 |
| 1077 // New method to support crypto. | 1096 // New methods to support crypto. |
|
srdjan
2014/09/15 18:10:52
Maybe remove this comment?
regis
2014/09/15 19:29:31
Done.
| |
| 1078 | 1097 |
| 1079 // Return this.pow(e) mod m, with 256 <= e < 1<<32. | 1098 // Return -1/this % DIGIT_BASE, useful for Montgomery reduction. |
| 1099 // | |
| 1100 // xy == 1 (mod m) | |
| 1101 // xy = 1+km | |
| 1102 // xy(2-xy) = (1+km)(1-km) | |
| 1103 // x(y(2-xy)) = 1-k^2 m^2 | |
| 1104 // x(y(2-xy)) == 1 (mod m^2) | |
| 1105 // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 | |
| 1106 // Should reduce x and y(2-xy) by m^2 at each step to keep size bounded. | |
| 1107 int _invDigit() { | |
| 1108 if (_used == 0) return 0; | |
| 1109 var x = _digits[0]; | |
| 1110 if ((x & 1) == 0) return 0; | |
| 1111 var y = x & 3; // y == 1/x mod 2^2 | |
| 1112 y = (y*(2 - (x & 0xf)*y)) & 0xf; // y == 1/x mod 2^4 | |
| 1113 y = (y*(2 - (x & 0xff)*y)) & 0xff; // y == 1/x mod 2^8 | |
| 1114 y = (y*(2 - (((x & 0xffff)*y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 | |
| 1115 // Last step - calculate inverse mod DIGIT_BASE directly; | |
| 1116 // Assumes 16 < DIGIT_BITS <= 32 and assumes ability to handle 48-bit ints. | |
| 1117 y = (y*(2 - x*y % DIGIT_BASE)) % DIGIT_BASE; // y == 1/x mod DIGIT_BASE | |
| 1118 // We really want the negative inverse, and - DIGIT_BASE < y < DIGIT_BASE. | |
| 1119 return (y > 0) ? DIGIT_BASE - y : -y; | |
| 1120 } | |
| 1121 | |
| 1122 // TODO(regis): Make this method private once the plumbing to invoke it from | |
| 1123 // dart:math is in place. | |
| 1124 // Return pow(this, e) % m. | |
| 1080 int modPow(int e, int m) { | 1125 int modPow(int e, int m) { |
|
srdjan
2014/09/15 18:10:52
Maybe in a later CL: You may also implement a modP
regis
2014/09/15 19:29:31
Will do.
| |
| 1126 // TODO(regis): Where/how do we handle values of e smaller than 256? | |
| 1127 // TODO(regis): Where/how do we handle even values of m? | |
| 1081 assert(e >= 256 && !m.isEven()); | 1128 assert(e >= 256 && !m.isEven()); |
| 1082 if (e >= (1 << 32)) { | 1129 if (e is! _Bigint) { |
| 1083 throw "Bigint.modPow with exponent larger than 32-bit not implemented"; | 1130 _Reduction z = new _Montgomery(m); |
| 1131 var r = new _Bigint(); | |
| 1132 var r2 = new _Bigint(); | |
| 1133 var g = z._convert(this); | |
| 1134 int i = _nbits(e) - 1; | |
| 1135 g._copyTo(r); | |
| 1136 while (--i >= 0) { | |
| 1137 z._sqrTo(r, r2); | |
| 1138 if ((e & (1 << i)) > 0) { | |
| 1139 z._mulTo(r2, g, r); | |
| 1140 } else { | |
| 1141 var t = r; | |
| 1142 r = r2; | |
| 1143 r2 = t; | |
| 1144 } | |
| 1145 } | |
| 1146 return z._revert(r)._toValidInt(); | |
| 1084 } | 1147 } |
| 1148 var i = e.bitLength; | |
| 1149 var k; | |
| 1150 var r = new _Bigint()._setInt(1); | |
| 1151 if (i <= 0) return r; | |
| 1152 // TODO(regis): Are these values of k really optimal for our implementation? | |
| 1153 else if (i < 18) k = 1; | |
| 1154 else if (i < 48) k = 3; | |
| 1155 else if (i < 144) k = 4; | |
| 1156 else if (i < 768) k = 5; | |
| 1157 else k = 6; | |
| 1085 _Reduction z = new _Montgomery(m); | 1158 _Reduction z = new _Montgomery(m); |
| 1086 var r = new _Bigint(); | 1159 var n = 3; |
| 1160 var k1 = k - 1; | |
| 1161 var km = (1 << k) - 1; | |
| 1162 List g = new List(km + 1); | |
| 1163 g[1] = z._convert(this); | |
| 1164 if (k > 1) { | |
| 1165 var g2 = new _Bigint(); | |
| 1166 z._sqrTo(g[1], g2); | |
| 1167 while (n <= km) { | |
| 1168 g[n] = new _Bigint(); | |
| 1169 z._mulTo(g2, g[n - 2], g[n]); | |
| 1170 n += 2; | |
| 1171 } | |
| 1172 } | |
| 1173 var j = e._used - 1; | |
| 1174 var w; | |
| 1175 var is1 = true; | |
| 1087 var r2 = new _Bigint(); | 1176 var r2 = new _Bigint(); |
| 1088 var g = z.convert(this); | 1177 var t; |
| 1089 int i = _nbits(e) - 1; | 1178 i = _nbits(e._digits[j]) - 1; |
| 1090 g._copyTo(r); | 1179 while (j >= 0) { |
| 1091 while (--i >= 0) { | 1180 if (i >= k1) { |
| 1092 z.sqrTo(r, r2); | 1181 w = (e._digits[j] >> (i - k1)) & km; |
| 1093 if ((e & (1 << i)) > 0) { | |
| 1094 z.mulTo(r2, g, r); | |
| 1095 } else { | 1182 } else { |
| 1096 var t = r; | 1183 w = (e._digits[j] & ((1 << (i + 1)) - 1)) << (k1 - i); |
| 1184 if (j > 0) { | |
| 1185 w |= e._digits[j - 1] >> (DIGIT_BITS + i - k1); | |
| 1186 } | |
| 1187 } | |
| 1188 n = k; | |
| 1189 while ((w & 1) == 0) { | |
| 1190 w >>= 1; | |
| 1191 --n; | |
| 1192 } | |
| 1193 if ((i -= n) < 0) { | |
| 1194 i += DIGIT_BITS; | |
| 1195 --j; | |
| 1196 } | |
| 1197 if (is1) { // r == 1, don't bother squaring or multiplying it. | |
| 1198 g[w]._copyTo(r); | |
| 1199 is1 = false; | |
| 1200 } | |
| 1201 else { | |
| 1202 while (n > 1) { | |
| 1203 z._sqrTo(r, r2); | |
| 1204 z._sqrTo(r2, r); | |
| 1205 n -= 2; | |
| 1206 } | |
| 1207 if (n > 0) { | |
| 1208 z._sqrTo(r, r2); | |
| 1209 } else { | |
| 1210 t = r; | |
| 1211 r = r2; | |
| 1212 r2 = t; | |
| 1213 } | |
| 1214 z._mulTo(r2,g[w], r); | |
| 1215 } | |
| 1216 | |
| 1217 while (j >= 0 && (e._digits[j] & (1 << i)) == 0) { | |
| 1218 z._sqrTo(r, r2); | |
| 1219 t = r; | |
| 1097 r = r2; | 1220 r = r2; |
| 1098 r2 = t; | 1221 r2 = t; |
| 1222 if (--i < 0) { | |
| 1223 i = DIGIT_BITS - 1; | |
| 1224 --j; | |
| 1225 } | |
| 1099 } | 1226 } |
| 1100 } | 1227 } |
| 1101 return z.revert(r)._toValidInt(); | 1228 return z._revert(r)._toValidInt(); |
| 1102 } | 1229 } |
| 1103 } | 1230 } |
| 1104 | 1231 |
| 1105 // New classes to support crypto (modPow method). | 1232 // New classes to support crypto (modPow method). |
| 1106 | 1233 |
| 1107 class _Reduction { | 1234 class _Reduction { |
| 1108 const _Reduction(); | 1235 const _Reduction(); |
| 1109 _Bigint _convert(_Bigint x) => x; | 1236 _Bigint _convert(_Bigint x) => x; |
| 1110 _Bigint _revert(_Bigint x) => x; | 1237 _Bigint _revert(_Bigint x) => x; |
| 1111 | 1238 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1161 x._digits[x._used++] = 0; | 1288 x._digits[x._used++] = 0; |
| 1162 } | 1289 } |
| 1163 for (var i = 0; i < _m._used; ++i) { | 1290 for (var i = 0; i < _m._used; ++i) { |
| 1164 // Faster way of calculating u0 = x[i]*mp mod DIGIT_BASE. | 1291 // Faster way of calculating u0 = x[i]*mp mod DIGIT_BASE. |
| 1165 var j = x._digits[i] & _Bigint.DIGIT2_MASK; | 1292 var j = x._digits[i] & _Bigint.DIGIT2_MASK; |
| 1166 var u0 = (j*_mpl + (((j*_mph + (x._digits[i] >> _Bigint.DIGIT2_BITS) | 1293 var u0 = (j*_mpl + (((j*_mph + (x._digits[i] >> _Bigint.DIGIT2_BITS) |
| 1167 *_mpl) & _um) << _Bigint.DIGIT2_BITS)) & _Bigint.DIGIT_MASK; | 1294 *_mpl) & _um) << _Bigint.DIGIT2_BITS)) & _Bigint.DIGIT_MASK; |
| 1168 // Use _am to combine the multiply-shift-add into one call. | 1295 // Use _am to combine the multiply-shift-add into one call. |
| 1169 j = i + _m._used; | 1296 j = i + _m._used; |
| 1170 var digit = x._digits[j]; | 1297 var digit = x._digits[j]; |
| 1171 digit += _m ._am(0, u0, x, i, 0, _m ._used); | 1298 digit += _m ._am(0, u0, x, i, _m._used); |
| 1172 // propagate carry | 1299 // Propagate carry. |
| 1173 while (digit >= _Bigint.DIGIT_BASE) { | 1300 while (digit >= _Bigint.DIGIT_BASE) { |
| 1174 digit -= _Bigint.DIGIT_BASE; | 1301 digit -= _Bigint.DIGIT_BASE; |
| 1175 x._digits[j++] = digit; | 1302 x._digits[j++] = digit; |
| 1176 digit = x._digits[j]; | 1303 digit = x._digits[j]; |
| 1177 digit++; | 1304 digit++; |
| 1178 } | 1305 } |
| 1179 x._digits[j] = digit; | 1306 x._digits[j] = digit; |
| 1180 } | 1307 } |
| 1181 x._clamp(); | 1308 x._clamp(); |
| 1182 x._drShiftTo(_m ._used, x); | 1309 x._drShiftTo(_m ._used, x); |
| 1183 if (x._compareTo(_m ) >= 0) { | 1310 if (x._compareTo(_m ) >= 0) { |
| 1184 x._subTo(_m , x); | 1311 x._subTo(_m , x); |
| 1185 } | 1312 } |
| 1186 } | 1313 } |
| 1187 | 1314 |
| 1188 // r = x^2/R mod _m ; x != r | 1315 // r = x^2/R mod _m ; x != r |
| 1189 void _sqrTo(_Bigint x, _Bigint r) { | 1316 void _sqrTo(_Bigint x, _Bigint r) { |
| 1190 x._sqrTo(r); | 1317 x._sqrTo(r); |
| 1191 _reduce(r); | 1318 _reduce(r); |
| 1192 } | 1319 } |
| 1193 | 1320 |
| 1194 // r = x*y/R mod _m ; x, y != r | 1321 // r = x*y/R mod _m ; x, y != r |
| 1195 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { | 1322 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { |
| 1196 x._mulTo(y, r); | 1323 x._mulTo(y, r); |
| 1197 _reduce(r); | 1324 _reduce(r); |
| 1198 } | 1325 } |
| 1199 } | 1326 } |
| 1200 | 1327 |
| OLD | NEW |