bn.js 4.12.0 → 5.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +31 -3
  3. package/lib/bn.js +224 -134
  4. package/package.json +24 -18
  5. package/LICENSE +0 -19
package/CHANGELOG.md ADDED
@@ -0,0 +1,40 @@
1
+ 5.1.2 / 2020-05-20
2
+ ------------------
3
+
4
+ - Fix BN v5/v4 interoperability issue (#249)
5
+
6
+ 5.1.1 / 2019-12-24
7
+ ------------------
8
+
9
+ - Temporary workaround for BN#_move (#236)
10
+ - Add eslintrc instead config in package.json (#237)
11
+
12
+ 5.1.0 / 2019-12-23
13
+ ------------------
14
+
15
+ - Benchmark for BigInt (#226)
16
+ - Add documentation for max/min (#232)
17
+ - Update BN#inspect for Symbols (#225)
18
+ - Improve performance of toArrayLike (#222)
19
+ - temporary disable jumboMulTo in BN#mulTo (#221)
20
+ - optimize toBitArray function (#212)
21
+ - fix iaddn sign issue (#216)
22
+
23
+ 5.0.0 / 2019-07-04
24
+ ------------------
25
+
26
+ - travis: update node versions (#205)
27
+ - Refactor buffer constructor (#200)
28
+ - lib: fix for negative numbers: imuln, modrn, idivn (#185)
29
+ - bn: fix Red#imod (#178)
30
+ - check unexpected high bits for invalid characters (#173)
31
+ - document support very large integers (#158)
32
+ - only define toBuffer if Buffer is defined (#172)
33
+ - lib: better validation of string input (#151)
34
+ - tests: reject decimal input in constructor (#91)
35
+ - bn: make .strip() an internal method (#105)
36
+ - lib: deprecate `.modn()` introduce `.modrn()` (#112 #129 #130)
37
+ - bn: don't accept invalid characters (#141)
38
+ - package: use `files` insteadof `.npmignore` (#152)
39
+ - bn: improve allocation speed for buffers (#167)
40
+ - toJSON to default to interoperable hex (length % 2) (#164)
package/README.md CHANGED
@@ -37,10 +37,10 @@ is the list of them in the order of appearance in the function name:
37
37
 
38
38
  ### Postfixes
39
39
 
40
- The only available postfix at the moment is:
41
-
42
- * `n` - which means that the argument of the function must be a plain JavaScript
40
+ * `n` - the argument of the function must be a plain JavaScript
43
41
  Number. Decimals are not supported.
42
+ * `rn` - both argument and return value of the function are plain JavaScript
43
+ Numbers. Decimals are not supported.
44
44
 
45
45
  ### Examples
46
46
 
@@ -84,6 +84,8 @@ either `le` (little-endian) or `be` (big-endian).
84
84
  * `a.toTwos(width)` - convert to two's complement representation, where `width` is bit width
85
85
  * `a.fromTwos(width)` - convert from two's complement representation, where `width` is the bit width
86
86
  * `BN.isBN(object)` - returns true if the supplied `object` is a BN.js instance
87
+ * `BN.max(a, b)` - return `a` if `a` bigger than `b`
88
+ * `BN.min(a, b)` - return `a` if `a` less than `b`
87
89
 
88
90
  ### Arithmetics
89
91
 
@@ -192,9 +194,35 @@ counterparts in red context:
192
194
  * `a.redNeg()`
193
195
  * `a.redPow(b)` - modular exponentiation
194
196
 
197
+ ### Number Size
198
+
199
+ Optimized for elliptic curves that work with 256-bit numbers.
200
+ There is no limitation on the size of the numbers.
201
+
195
202
  ## LICENSE
196
203
 
197
204
  This software is licensed under the MIT License.
198
205
 
206
+ Copyright Fedor Indutny, 2015.
207
+
208
+ Permission is hereby granted, free of charge, to any person obtaining a
209
+ copy of this software and associated documentation files (the
210
+ "Software"), to deal in the Software without restriction, including
211
+ without limitation the rights to use, copy, modify, merge, publish,
212
+ distribute, sublicense, and/or sell copies of the Software, and to permit
213
+ persons to whom the Software is furnished to do so, subject to the
214
+ following conditions:
215
+
216
+ The above copyright notice and this permission notice shall be included
217
+ in all copies or substantial portions of the Software.
218
+
219
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
220
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
221
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
222
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
223
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
224
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
225
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
226
+
199
227
  [0]: https://en.wikipedia.org/wiki/Montgomery_modular_multiplication
200
228
  [1]: https://en.wikipedia.org/wiki/Mersenne_prime
package/lib/bn.js CHANGED
@@ -50,11 +50,7 @@
50
50
 
51
51
  var Buffer;
52
52
  try {
53
- if (typeof window !== 'undefined' && typeof window.Buffer !== 'undefined') {
54
- Buffer = window.Buffer;
55
- } else {
56
- Buffer = require('buffer').Buffer;
57
- }
53
+ Buffer = require('buffer').Buffer;
58
54
  } catch (e) {
59
55
  }
60
56
 
@@ -95,19 +91,23 @@
95
91
  var start = 0;
96
92
  if (number[0] === '-') {
97
93
  start++;
98
- this.negative = 1;
99
94
  }
100
95
 
101
- if (start < number.length) {
102
- if (base === 16) {
103
- this._parseHex(number, start, endian);
104
- } else {
105
- this._parseBase(number, base, start);
106
- if (endian === 'le') {
107
- this._initArray(this.toArray(), base, endian);
108
- }
109
- }
96
+ if (base === 16) {
97
+ this._parseHex(number, start);
98
+ } else {
99
+ this._parseBase(number, base, start);
110
100
  }
101
+
102
+ if (number[0] === '-') {
103
+ this.negative = 1;
104
+ }
105
+
106
+ this._strip();
107
+
108
+ if (endian !== 'le') return;
109
+
110
+ this._initArray(this.toArray(), base, endian);
111
111
  };
112
112
 
113
113
  BN.prototype._initNumber = function _initNumber (number, base, endian) {
@@ -116,7 +116,7 @@
116
116
  number = -number;
117
117
  }
118
118
  if (number < 0x4000000) {
119
- this.words = [ number & 0x3ffffff ];
119
+ this.words = [number & 0x3ffffff];
120
120
  this.length = 1;
121
121
  } else if (number < 0x10000000000000) {
122
122
  this.words = [
@@ -144,7 +144,7 @@
144
144
  // Perhaps a Uint8Array
145
145
  assert(typeof number.length === 'number');
146
146
  if (number.length <= 0) {
147
- this.words = [ 0 ];
147
+ this.words = [0];
148
148
  this.length = 1;
149
149
  return this;
150
150
  }
@@ -180,32 +180,42 @@
180
180
  }
181
181
  }
182
182
  }
183
- return this.strip();
183
+ return this._strip();
184
184
  };
185
185
 
186
- function parseHex4Bits (string, index) {
187
- var c = string.charCodeAt(index);
188
- // 'A' - 'F'
189
- if (c >= 65 && c <= 70) {
190
- return c - 55;
191
- // 'a' - 'f'
192
- } else if (c >= 97 && c <= 102) {
193
- return c - 87;
194
- // '0' - '9'
195
- } else {
196
- return (c - 48) & 0xf;
197
- }
198
- }
186
+ function parseHex (str, start, end) {
187
+ var r = 0;
188
+ var len = Math.min(str.length, end);
189
+ var z = 0;
190
+ for (var i = start; i < len; i++) {
191
+ var c = str.charCodeAt(i) - 48;
192
+
193
+ r <<= 4;
194
+
195
+ var b;
199
196
 
200
- function parseHexByte (string, lowerBound, index) {
201
- var r = parseHex4Bits(string, index);
202
- if (index - 1 >= lowerBound) {
203
- r |= parseHex4Bits(string, index - 1) << 4;
197
+ // 'a' - 'f'
198
+ if (c >= 49 && c <= 54) {
199
+ b = c - 49 + 0xa;
200
+
201
+ // 'A' - 'F'
202
+ } else if (c >= 17 && c <= 22) {
203
+ b = c - 17 + 0xa;
204
+
205
+ // '0' - '9'
206
+ } else {
207
+ b = c;
208
+ }
209
+
210
+ r |= b;
211
+ z |= b;
204
212
  }
213
+
214
+ assert(!(z & 0xf0), 'Invalid character in ' + str);
205
215
  return r;
206
216
  }
207
217
 
208
- BN.prototype._parseHex = function _parseHex (number, start, endian) {
218
+ BN.prototype._parseHex = function _parseHex (number, start) {
209
219
  // Create possibly bigger array to ensure that it fits the number
210
220
  this.length = Math.ceil((number.length - start) / 6);
211
221
  this.words = new Array(this.length);
@@ -213,43 +223,31 @@
213
223
  this.words[i] = 0;
214
224
  }
215
225
 
216
- // 24-bits chunks
226
+ var j, w;
227
+ // Scan 24-bit chunks and add them to the number
217
228
  var off = 0;
218
- var j = 0;
219
-
220
- var w;
221
- if (endian === 'be') {
222
- for (i = number.length - 1; i >= start; i -= 2) {
223
- w = parseHexByte(number, start, i) << off;
224
- this.words[j] |= w & 0x3ffffff;
225
- if (off >= 18) {
226
- off -= 18;
227
- j += 1;
228
- this.words[j] |= w >>> 26;
229
- } else {
230
- off += 8;
231
- }
232
- }
233
- } else {
234
- var parseLength = number.length - start;
235
- for (i = parseLength % 2 === 0 ? start + 1 : start; i < number.length; i += 2) {
236
- w = parseHexByte(number, start, i) << off;
237
- this.words[j] |= w & 0x3ffffff;
238
- if (off >= 18) {
239
- off -= 18;
240
- j += 1;
241
- this.words[j] |= w >>> 26;
242
- } else {
243
- off += 8;
244
- }
229
+ for (i = number.length - 6, j = 0; i >= start; i -= 6) {
230
+ w = parseHex(number, i, i + 6);
231
+ this.words[j] |= (w << off) & 0x3ffffff;
232
+ // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
233
+ this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
234
+ off += 24;
235
+ if (off >= 26) {
236
+ off -= 26;
237
+ j++;
245
238
  }
246
239
  }
247
-
248
- this.strip();
240
+ if (i + 6 !== start) {
241
+ w = parseHex(number, start, i + 6);
242
+ this.words[j] |= (w << off) & 0x3ffffff;
243
+ this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
244
+ }
245
+ this._strip();
249
246
  };
250
247
 
251
248
  function parseBase (str, start, end, mul) {
252
249
  var r = 0;
250
+ var b = 0;
253
251
  var len = Math.min(str.length, end);
254
252
  for (var i = start; i < len; i++) {
255
253
  var c = str.charCodeAt(i) - 48;
@@ -258,23 +256,25 @@
258
256
 
259
257
  // 'a'
260
258
  if (c >= 49) {
261
- r += c - 49 + 0xa;
259
+ b = c - 49 + 0xa;
262
260
 
263
261
  // 'A'
264
262
  } else if (c >= 17) {
265
- r += c - 17 + 0xa;
263
+ b = c - 17 + 0xa;
266
264
 
267
265
  // '0' - '9'
268
266
  } else {
269
- r += c;
267
+ b = c;
270
268
  }
269
+ assert(c >= 0 && b < mul, 'Invalid character');
270
+ r += b;
271
271
  }
272
272
  return r;
273
273
  }
274
274
 
275
275
  BN.prototype._parseBase = function _parseBase (number, base, start) {
276
276
  // Initialize as zero
277
- this.words = [ 0 ];
277
+ this.words = [0];
278
278
  this.length = 1;
279
279
 
280
280
  // Find length of limb in base
@@ -315,8 +315,6 @@
315
315
  this._iaddn(word);
316
316
  }
317
317
  }
318
-
319
- this.strip();
320
318
  };
321
319
 
322
320
  BN.prototype.copy = function copy (dest) {
@@ -329,6 +327,17 @@
329
327
  dest.red = this.red;
330
328
  };
331
329
 
330
+ function move (dest, src) {
331
+ dest.words = src.words;
332
+ dest.length = src.length;
333
+ dest.negative = src.negative;
334
+ dest.red = src.red;
335
+ }
336
+
337
+ BN.prototype._move = function _move (dest) {
338
+ move(dest, this);
339
+ };
340
+
332
341
  BN.prototype.clone = function clone () {
333
342
  var r = new BN(null);
334
343
  this.copy(r);
@@ -343,7 +352,7 @@
343
352
  };
344
353
 
345
354
  // Remove leading `0` from `this`
346
- BN.prototype.strip = function strip () {
355
+ BN.prototype._strip = function strip () {
347
356
  while (this.length > 1 && this.words[this.length - 1] === 0) {
348
357
  this.length--;
349
358
  }
@@ -358,9 +367,17 @@
358
367
  return this;
359
368
  };
360
369
 
361
- BN.prototype.inspect = function inspect () {
370
+ // Check Symbol.for because not everywhere where Symbol defined
371
+ // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Browser_compatibility
372
+ if (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') {
373
+ BN.prototype[Symbol.for('nodejs.util.inspect.custom')] = inspect;
374
+ } else {
375
+ BN.prototype.inspect = inspect;
376
+ }
377
+
378
+ function inspect () {
362
379
  return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
363
- };
380
+ }
364
381
 
365
382
  /*
366
383
 
@@ -484,7 +501,7 @@
484
501
  var c = this.clone();
485
502
  c.negative = 0;
486
503
  while (!c.isZero()) {
487
- var r = c.modn(groupBase).toString(base);
504
+ var r = c.modrn(groupBase).toString(base);
488
505
  c = c.idivn(groupBase);
489
506
 
490
507
  if (!c.isZero()) {
@@ -522,56 +539,110 @@
522
539
  };
523
540
 
524
541
  BN.prototype.toJSON = function toJSON () {
525
- return this.toString(16);
542
+ return this.toString(16, 2);
526
543
  };
527
544
 
528
- BN.prototype.toBuffer = function toBuffer (endian, length) {
529
- assert(typeof Buffer !== 'undefined');
530
- return this.toArrayLike(Buffer, endian, length);
531
- };
545
+ if (Buffer) {
546
+ BN.prototype.toBuffer = function toBuffer (endian, length) {
547
+ return this.toArrayLike(Buffer, endian, length);
548
+ };
549
+ }
532
550
 
533
551
  BN.prototype.toArray = function toArray (endian, length) {
534
552
  return this.toArrayLike(Array, endian, length);
535
553
  };
536
554
 
555
+ var allocate = function allocate (ArrayType, size) {
556
+ if (ArrayType.allocUnsafe) {
557
+ return ArrayType.allocUnsafe(size);
558
+ }
559
+ return new ArrayType(size);
560
+ };
561
+
537
562
  BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
563
+ this._strip();
564
+
538
565
  var byteLength = this.byteLength();
539
566
  var reqLength = length || Math.max(1, byteLength);
540
567
  assert(byteLength <= reqLength, 'byte array longer than desired length');
541
568
  assert(reqLength > 0, 'Requested array length <= 0');
542
569
 
543
- this.strip();
544
- var littleEndian = endian === 'le';
545
- var res = new ArrayType(reqLength);
570
+ var res = allocate(ArrayType, reqLength);
571
+ var postfix = endian === 'le' ? 'LE' : 'BE';
572
+ this['_toArrayLike' + postfix](res, byteLength);
573
+ return res;
574
+ };
575
+
576
+ BN.prototype._toArrayLikeLE = function _toArrayLikeLE (res, byteLength) {
577
+ var position = 0;
578
+ var carry = 0;
579
+
580
+ for (var i = 0, shift = 0; i < this.length; i++) {
581
+ var word = (this.words[i] << shift) | carry;
546
582
 
547
- var b, i;
548
- var q = this.clone();
549
- if (!littleEndian) {
550
- // Assume big-endian
551
- for (i = 0; i < reqLength - byteLength; i++) {
552
- res[i] = 0;
583
+ res[position++] = word & 0xff;
584
+ if (position < res.length) {
585
+ res[position++] = (word >> 8) & 0xff;
586
+ }
587
+ if (position < res.length) {
588
+ res[position++] = (word >> 16) & 0xff;
589
+ }
590
+
591
+ if (shift === 6) {
592
+ if (position < res.length) {
593
+ res[position++] = (word >> 24) & 0xff;
594
+ }
595
+ carry = 0;
596
+ shift = 0;
597
+ } else {
598
+ carry = word >>> 24;
599
+ shift += 2;
553
600
  }
601
+ }
554
602
 
555
- for (i = 0; !q.isZero(); i++) {
556
- b = q.andln(0xff);
557
- q.iushrn(8);
603
+ if (position < res.length) {
604
+ res[position++] = carry;
558
605
 
559
- res[reqLength - i - 1] = b;
606
+ while (position < res.length) {
607
+ res[position++] = 0;
560
608
  }
561
- } else {
562
- for (i = 0; !q.isZero(); i++) {
563
- b = q.andln(0xff);
564
- q.iushrn(8);
609
+ }
610
+ };
611
+
612
+ BN.prototype._toArrayLikeBE = function _toArrayLikeBE (res, byteLength) {
613
+ var position = res.length - 1;
614
+ var carry = 0;
565
615
 
566
- res[i] = b;
616
+ for (var i = 0, shift = 0; i < this.length; i++) {
617
+ var word = (this.words[i] << shift) | carry;
618
+
619
+ res[position--] = word & 0xff;
620
+ if (position >= 0) {
621
+ res[position--] = (word >> 8) & 0xff;
622
+ }
623
+ if (position >= 0) {
624
+ res[position--] = (word >> 16) & 0xff;
567
625
  }
568
626
 
569
- for (; i < reqLength; i++) {
570
- res[i] = 0;
627
+ if (shift === 6) {
628
+ if (position >= 0) {
629
+ res[position--] = (word >> 24) & 0xff;
630
+ }
631
+ carry = 0;
632
+ shift = 0;
633
+ } else {
634
+ carry = word >>> 24;
635
+ shift += 2;
571
636
  }
572
637
  }
573
638
 
574
- return res;
639
+ if (position >= 0) {
640
+ res[position--] = carry;
641
+
642
+ while (position >= 0) {
643
+ res[position--] = 0;
644
+ }
645
+ }
575
646
  };
576
647
 
577
648
  if (Math.clz32) {
@@ -644,7 +715,7 @@
644
715
  var off = (bit / 26) | 0;
645
716
  var wbit = bit % 26;
646
717
 
647
- w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
718
+ w[bit] = (num.words[off] >>> wbit) & 0x01;
648
719
  }
649
720
 
650
721
  return w;
@@ -708,7 +779,7 @@
708
779
  this.words[i] = this.words[i] | num.words[i];
709
780
  }
710
781
 
711
- return this.strip();
782
+ return this._strip();
712
783
  };
713
784
 
714
785
  BN.prototype.ior = function ior (num) {
@@ -743,7 +814,7 @@
743
814
 
744
815
  this.length = b.length;
745
816
 
746
- return this.strip();
817
+ return this._strip();
747
818
  };
748
819
 
749
820
  BN.prototype.iand = function iand (num) {
@@ -787,7 +858,7 @@
787
858
 
788
859
  this.length = a.length;
789
860
 
790
- return this.strip();
861
+ return this._strip();
791
862
  };
792
863
 
793
864
  BN.prototype.ixor = function ixor (num) {
@@ -831,7 +902,7 @@
831
902
  }
832
903
 
833
904
  // And remove leading zeroes
834
- return this.strip();
905
+ return this._strip();
835
906
  };
836
907
 
837
908
  BN.prototype.notn = function notn (width) {
@@ -853,7 +924,7 @@
853
924
  this.words[off] = this.words[off] & ~(1 << wbit);
854
925
  }
855
926
 
856
- return this.strip();
927
+ return this._strip();
857
928
  };
858
929
 
859
930
  // Add `num` to `this` in-place
@@ -994,7 +1065,7 @@
994
1065
  this.negative = 1;
995
1066
  }
996
1067
 
997
- return this.strip();
1068
+ return this._strip();
998
1069
  };
999
1070
 
1000
1071
  // Subtract `num` from `this`
@@ -1040,7 +1111,7 @@
1040
1111
  out.length--;
1041
1112
  }
1042
1113
 
1043
- return out.strip();
1114
+ return out._strip();
1044
1115
  }
1045
1116
 
1046
1117
  // TODO(indutny): it may be reasonable to omit it for users who don't need
@@ -1662,12 +1733,14 @@
1662
1733
  out.length--;
1663
1734
  }
1664
1735
 
1665
- return out.strip();
1736
+ return out._strip();
1666
1737
  }
1667
1738
 
1668
1739
  function jumboMulTo (self, num, out) {
1669
- var fftm = new FFTM();
1670
- return fftm.mulp(self, num, out);
1740
+ // Temporary disable, see https://github.com/indutny/bn.js/issues/211
1741
+ // var fftm = new FFTM();
1742
+ // return fftm.mulp(self, num, out);
1743
+ return bigMulTo(self, num, out);
1671
1744
  }
1672
1745
 
1673
1746
  BN.prototype.mulTo = function mulTo (num, out) {
@@ -1879,7 +1952,7 @@
1879
1952
 
1880
1953
  out.negative = x.negative ^ y.negative;
1881
1954
  out.length = x.length + y.length;
1882
- return out.strip();
1955
+ return out._strip();
1883
1956
  };
1884
1957
 
1885
1958
  // Multiply `this` by `num`
@@ -1902,6 +1975,9 @@
1902
1975
  };
1903
1976
 
1904
1977
  BN.prototype.imuln = function imuln (num) {
1978
+ var isNegNum = num < 0;
1979
+ if (isNegNum) num = -num;
1980
+
1905
1981
  assert(typeof num === 'number');
1906
1982
  assert(num < 0x4000000);
1907
1983
 
@@ -1922,7 +1998,7 @@
1922
1998
  this.length++;
1923
1999
  }
1924
2000
 
1925
- return this;
2001
+ return isNegNum ? this.ineg() : this;
1926
2002
  };
1927
2003
 
1928
2004
  BN.prototype.muln = function muln (num) {
@@ -1997,7 +2073,7 @@
1997
2073
  this.length += s;
1998
2074
  }
1999
2075
 
2000
- return this.strip();
2076
+ return this._strip();
2001
2077
  };
2002
2078
 
2003
2079
  BN.prototype.ishln = function ishln (bits) {
@@ -2063,7 +2139,7 @@
2063
2139
  this.length = 1;
2064
2140
  }
2065
2141
 
2066
- return this.strip();
2142
+ return this._strip();
2067
2143
  };
2068
2144
 
2069
2145
  BN.prototype.ishrn = function ishrn (bits, hint, extended) {
@@ -2128,7 +2204,7 @@
2128
2204
  this.words[this.length - 1] &= mask;
2129
2205
  }
2130
2206
 
2131
- return this.strip();
2207
+ return this._strip();
2132
2208
  };
2133
2209
 
2134
2210
  // Return only lowers bits of number
@@ -2144,7 +2220,7 @@
2144
2220
 
2145
2221
  // Possible sign change
2146
2222
  if (this.negative !== 0) {
2147
- if (this.length === 1 && (this.words[0] | 0) < num) {
2223
+ if (this.length === 1 && (this.words[0] | 0) <= num) {
2148
2224
  this.words[0] = num - (this.words[0] | 0);
2149
2225
  this.negative = 0;
2150
2226
  return this;
@@ -2203,7 +2279,7 @@
2203
2279
  }
2204
2280
  }
2205
2281
 
2206
- return this.strip();
2282
+ return this._strip();
2207
2283
  };
2208
2284
 
2209
2285
  BN.prototype.addn = function addn (num) {
@@ -2245,7 +2321,7 @@
2245
2321
  this.words[i + shift] = w & 0x3ffffff;
2246
2322
  }
2247
2323
 
2248
- if (carry === 0) return this.strip();
2324
+ if (carry === 0) return this._strip();
2249
2325
 
2250
2326
  // Subtraction overflow
2251
2327
  assert(carry === -1);
@@ -2257,7 +2333,7 @@
2257
2333
  }
2258
2334
  this.negative = 1;
2259
2335
 
2260
- return this.strip();
2336
+ return this._strip();
2261
2337
  };
2262
2338
 
2263
2339
  BN.prototype._wordDiv = function _wordDiv (num, mode) {
@@ -2319,9 +2395,9 @@
2319
2395
  }
2320
2396
  }
2321
2397
  if (q) {
2322
- q.strip();
2398
+ q._strip();
2323
2399
  }
2324
- a.strip();
2400
+ a._strip();
2325
2401
 
2326
2402
  // Denormalize
2327
2403
  if (mode !== 'div' && shift !== 0) {
@@ -2420,13 +2496,13 @@
2420
2496
  if (mode === 'mod') {
2421
2497
  return {
2422
2498
  div: null,
2423
- mod: new BN(this.modn(num.words[0]))
2499
+ mod: new BN(this.modrn(num.words[0]))
2424
2500
  };
2425
2501
  }
2426
2502
 
2427
2503
  return {
2428
2504
  div: this.divn(num.words[0]),
2429
- mod: new BN(this.modn(num.words[0]))
2505
+ mod: new BN(this.modrn(num.words[0]))
2430
2506
  };
2431
2507
  }
2432
2508
 
@@ -2461,13 +2537,16 @@
2461
2537
  var cmp = mod.cmp(half);
2462
2538
 
2463
2539
  // Round down
2464
- if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
2540
+ if (cmp < 0 || (r2 === 1 && cmp === 0)) return dm.div;
2465
2541
 
2466
2542
  // Round up
2467
2543
  return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
2468
2544
  };
2469
2545
 
2470
- BN.prototype.modn = function modn (num) {
2546
+ BN.prototype.modrn = function modrn (num) {
2547
+ var isNegNum = num < 0;
2548
+ if (isNegNum) num = -num;
2549
+
2471
2550
  assert(num <= 0x3ffffff);
2472
2551
  var p = (1 << 26) % num;
2473
2552
 
@@ -2476,11 +2555,19 @@
2476
2555
  acc = (p * acc + (this.words[i] | 0)) % num;
2477
2556
  }
2478
2557
 
2479
- return acc;
2558
+ return isNegNum ? -acc : acc;
2559
+ };
2560
+
2561
+ // WARNING: DEPRECATED
2562
+ BN.prototype.modn = function modn (num) {
2563
+ return this.modrn(num);
2480
2564
  };
2481
2565
 
2482
2566
  // In-place division by number
2483
2567
  BN.prototype.idivn = function idivn (num) {
2568
+ var isNegNum = num < 0;
2569
+ if (isNegNum) num = -num;
2570
+
2484
2571
  assert(num <= 0x3ffffff);
2485
2572
 
2486
2573
  var carry = 0;
@@ -2490,7 +2577,8 @@
2490
2577
  carry = w % num;
2491
2578
  }
2492
2579
 
2493
- return this.strip();
2580
+ this._strip();
2581
+ return isNegNum ? this.ineg() : this;
2494
2582
  };
2495
2583
 
2496
2584
  BN.prototype.divn = function divn (num) {
@@ -2742,7 +2830,7 @@
2742
2830
  if (this.negative !== 0 && !negative) return -1;
2743
2831
  if (this.negative === 0 && negative) return 1;
2744
2832
 
2745
- this.strip();
2833
+ this._strip();
2746
2834
 
2747
2835
  var res;
2748
2836
  if (this.length > 1) {
@@ -2986,10 +3074,10 @@
2986
3074
  r.isub(this.p);
2987
3075
  } else {
2988
3076
  if (r.strip !== undefined) {
2989
- // r is BN v4 instance
3077
+ // r is a BN v4 instance
2990
3078
  r.strip();
2991
3079
  } else {
2992
- // r is BN v5 instance
3080
+ // r is a BN v5 instance
2993
3081
  r._strip();
2994
3082
  }
2995
3083
  }
@@ -3164,7 +3252,9 @@
3164
3252
 
3165
3253
  Red.prototype.imod = function imod (a) {
3166
3254
  if (this.prime) return this.prime.ireduce(a)._forceRed(this);
3167
- return a.umod(this.m)._forceRed(this);
3255
+
3256
+ move(a, a.umod(this.m)._forceRed(this));
3257
+ return a;
3168
3258
  };
3169
3259
 
3170
3260
  Red.prototype.neg = function neg (a) {
package/package.json CHANGED
@@ -1,36 +1,42 @@
1
1
  {
2
2
  "name": "bn.js",
3
- "version": "4.12.0",
3
+ "version": "5.1.2",
4
4
  "description": "Big number implementation in pure javascript",
5
- "main": "lib/bn.js",
6
- "scripts": {
7
- "lint": "semistandard",
8
- "unit": "mocha --reporter=spec test/*-test.js",
9
- "test": "npm run lint && npm run unit"
10
- },
11
- "repository": {
12
- "type": "git",
13
- "url": "git@github.com:indutny/bn.js"
14
- },
15
5
  "keywords": [
16
6
  "BN",
17
- "BigNum",
18
7
  "Big number",
8
+ "BigNum",
19
9
  "Modulo",
20
10
  "Montgomery"
21
11
  ],
22
- "author": "Fedor Indutny <fedor@indutny.com>",
23
- "license": "MIT",
12
+ "homepage": "https://github.com/indutny/bn.js",
24
13
  "bugs": {
25
14
  "url": "https://github.com/indutny/bn.js/issues"
26
15
  },
27
- "homepage": "https://github.com/indutny/bn.js",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git@github.com:indutny/bn.js"
19
+ },
20
+ "license": "MIT",
21
+ "author": "Fedor Indutny <fedor@indutny.com>",
22
+ "files": [
23
+ "lib/bn.js"
24
+ ],
25
+ "main": "lib/bn.js",
28
26
  "browser": {
29
27
  "buffer": false
30
28
  },
29
+ "scripts": {
30
+ "lint": "standardx",
31
+ "test": "npm run lint && npm run unit",
32
+ "unit": "mocha --reporter=spec test/*-test.js"
33
+ },
31
34
  "devDependencies": {
32
- "istanbul": "^0.3.5",
33
- "mocha": "^2.1.0",
34
- "semistandard": "^7.0.4"
35
+ "babel-eslint": "^10.0.3",
36
+ "mocha": "^7.0.1",
37
+ "standardx": "^5.0.0"
38
+ },
39
+ "standardx": {
40
+ "parser": "babel-eslint"
35
41
  }
36
42
  }
package/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright Fedor Indutny, 2015.
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in all
11
- copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- SOFTWARE.