Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80559 views
1
(function (module, exports) {
2
3
'use strict';
4
5
// Utils
6
7
function assert(val, msg) {
8
if (!val)
9
throw new Error(msg || 'Assertion failed');
10
}
11
12
// Could use `inherits` module, but don't want to move from single file
13
// architecture yet.
14
function inherits(ctor, superCtor) {
15
ctor.super_ = superCtor;
16
var TempCtor = function () {};
17
TempCtor.prototype = superCtor.prototype;
18
ctor.prototype = new TempCtor();
19
ctor.prototype.constructor = ctor;
20
}
21
22
// BN
23
24
function BN(number, base, endian) {
25
// May be `new BN(bn)` ?
26
if (number !== null &&
27
typeof number === 'object' &&
28
Array.isArray(number.words)) {
29
return number;
30
}
31
32
this.sign = false;
33
this.words = null;
34
this.length = 0;
35
36
// Reduction context
37
this.red = null;
38
39
if (base === 'le' || base === 'be') {
40
endian = base;
41
base = 10;
42
}
43
44
if (number !== null)
45
this._init(number || 0, base || 10, endian || 'be');
46
}
47
if (typeof module === 'object')
48
module.exports = BN;
49
else
50
exports.BN = BN;
51
52
BN.BN = BN;
53
BN.wordSize = 26;
54
55
BN.prototype._init = function init(number, base, endian) {
56
if (typeof number === 'number') {
57
if (number < 0) {
58
this.sign = true;
59
number = -number;
60
}
61
if (number < 0x4000000) {
62
this.words = [ number & 0x3ffffff ];
63
this.length = 1;
64
} else if (number < 0x10000000000000) {
65
this.words = [
66
number & 0x3ffffff,
67
(number / 0x4000000) & 0x3ffffff
68
];
69
this.length = 2;
70
} else {
71
assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
72
this.words = [
73
number & 0x3ffffff,
74
(number / 0x4000000) & 0x3ffffff,
75
1
76
];
77
this.length = 3;
78
}
79
return;
80
} else if (typeof number === 'object') {
81
return this._initArray(number, base, endian);
82
}
83
if (base === 'hex')
84
base = 16;
85
assert(base === (base | 0) && base >= 2 && base <= 36);
86
87
number = number.toString().replace(/\s+/g, '');
88
var start = 0;
89
if (number[0] === '-')
90
start++;
91
92
if (base === 16)
93
this._parseHex(number, start);
94
else
95
this._parseBase(number, base, start);
96
97
if (number[0] === '-')
98
this.sign = true;
99
100
this.strip();
101
};
102
103
BN.prototype._initArray = function _initArray(number, base, endian) {
104
// Perhaps a Uint8Array
105
assert(typeof number.length === 'number');
106
if (number.length <= 0) {
107
this.words = [ 0 ];
108
this.length = 1;
109
return this;
110
}
111
112
this.length = Math.ceil(number.length / 3);
113
this.words = new Array(this.length);
114
for (var i = 0; i < this.length; i++)
115
this.words[i] = 0;
116
117
var off = 0;
118
if (endian === 'be') {
119
for (var i = number.length - 1, j = 0; i >= 0; i -= 3) {
120
var w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
121
this.words[j] |= (w << off) & 0x3ffffff;
122
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
123
off += 24;
124
if (off >= 26) {
125
off -= 26;
126
j++;
127
}
128
}
129
} else if (endian === 'le') {
130
for (var i = 0, j = 0; i < number.length; i += 3) {
131
var w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
132
this.words[j] |= (w << off) & 0x3ffffff;
133
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
134
off += 24;
135
if (off >= 26) {
136
off -= 26;
137
j++;
138
}
139
}
140
}
141
return this.strip();
142
};
143
144
function parseHex(str, start, end) {
145
var r = 0;
146
var len = Math.min(str.length, end);
147
for (var i = start; i < len; i++) {
148
var c = str.charCodeAt(i) - 48;
149
150
r <<= 4;
151
152
// 'a' - 'f'
153
if (c >= 49 && c <= 54)
154
r |= c - 49 + 0xa;
155
156
// 'A' - 'F'
157
else if (c >= 17 && c <= 22)
158
r |= c - 17 + 0xa;
159
160
// '0' - '9'
161
else
162
r |= c & 0xf;
163
}
164
return r;
165
}
166
167
BN.prototype._parseHex = function _parseHex(number, start) {
168
// Create possibly bigger array to ensure that it fits the number
169
this.length = Math.ceil((number.length - start) / 6);
170
this.words = new Array(this.length);
171
for (var i = 0; i < this.length; i++)
172
this.words[i] = 0;
173
174
// Scan 24-bit chunks and add them to the number
175
var off = 0;
176
for (var i = number.length - 6, j = 0; i >= start; i -= 6) {
177
var w = parseHex(number, i, i + 6);
178
this.words[j] |= (w << off) & 0x3ffffff;
179
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
180
off += 24;
181
if (off >= 26) {
182
off -= 26;
183
j++;
184
}
185
}
186
if (i + 6 !== start) {
187
var w = parseHex(number, start, i + 6);
188
this.words[j] |= (w << off) & 0x3ffffff;
189
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
190
}
191
this.strip();
192
};
193
194
function parseBase(str, start, end, mul) {
195
var r = 0;
196
var len = Math.min(str.length, end);
197
for (var i = start; i < len; i++) {
198
var c = str.charCodeAt(i) - 48;
199
200
r *= mul;
201
202
// 'a'
203
if (c >= 49)
204
r += c - 49 + 0xa;
205
206
// 'A'
207
else if (c >= 17)
208
r += c - 17 + 0xa;
209
210
// '0' - '9'
211
else
212
r += c;
213
}
214
return r;
215
}
216
217
BN.prototype._parseBase = function _parseBase(number, base, start) {
218
// Initialize as zero
219
this.words = [ 0 ];
220
this.length = 1;
221
222
// Find length of limb in base
223
for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base)
224
limbLen++;
225
limbLen--;
226
limbPow = (limbPow / base) | 0;
227
228
var total = number.length - start;
229
var mod = total % limbLen;
230
var end = Math.min(total, total - mod) + start;
231
232
var word = 0;
233
for (var i = start; i < end; i += limbLen) {
234
word = parseBase(number, i, i + limbLen, base);
235
236
this.imuln(limbPow);
237
if (this.words[0] + word < 0x4000000)
238
this.words[0] += word;
239
else
240
this._iaddn(word);
241
}
242
243
if (mod !== 0) {
244
var pow = 1;
245
var word = parseBase(number, i, number.length, base);
246
247
for (var i = 0; i < mod; i++)
248
pow *= base;
249
this.imuln(pow);
250
if (this.words[0] + word < 0x4000000)
251
this.words[0] += word;
252
else
253
this._iaddn(word);
254
}
255
};
256
257
BN.prototype.copy = function copy(dest) {
258
dest.words = new Array(this.length);
259
for (var i = 0; i < this.length; i++)
260
dest.words[i] = this.words[i];
261
dest.length = this.length;
262
dest.sign = this.sign;
263
dest.red = this.red;
264
};
265
266
BN.prototype.clone = function clone() {
267
var r = new BN(null);
268
this.copy(r);
269
return r;
270
};
271
272
// Remove leading `0` from `this`
273
BN.prototype.strip = function strip() {
274
while (this.length > 1 && this.words[this.length - 1] === 0)
275
this.length--;
276
return this._normSign();
277
};
278
279
BN.prototype._normSign = function _normSign() {
280
// -0 = 0
281
if (this.length === 1 && this.words[0] === 0)
282
this.sign = false;
283
return this;
284
};
285
286
BN.prototype.inspect = function inspect() {
287
return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
288
};
289
290
/*
291
292
var zeros = [];
293
var groupSizes = [];
294
var groupBases = [];
295
296
var s = '';
297
var i = -1;
298
while (++i < BN.wordSize) {
299
zeros[i] = s;
300
s += '0';
301
}
302
groupSizes[0] = 0;
303
groupSizes[1] = 0;
304
groupBases[0] = 0;
305
groupBases[1] = 0;
306
var base = 2 - 1;
307
while (++base < 36 + 1) {
308
var groupSize = 0;
309
var groupBase = 1;
310
while (groupBase < (1 << BN.wordSize) / base) {
311
groupBase *= base;
312
groupSize += 1;
313
}
314
groupSizes[base] = groupSize;
315
groupBases[base] = groupBase;
316
}
317
318
*/
319
320
var zeros = [
321
'',
322
'0',
323
'00',
324
'000',
325
'0000',
326
'00000',
327
'000000',
328
'0000000',
329
'00000000',
330
'000000000',
331
'0000000000',
332
'00000000000',
333
'000000000000',
334
'0000000000000',
335
'00000000000000',
336
'000000000000000',
337
'0000000000000000',
338
'00000000000000000',
339
'000000000000000000',
340
'0000000000000000000',
341
'00000000000000000000',
342
'000000000000000000000',
343
'0000000000000000000000',
344
'00000000000000000000000',
345
'000000000000000000000000',
346
'0000000000000000000000000'
347
];
348
349
var groupSizes = [
350
0, 0,
351
25, 16, 12, 11, 10, 9, 8,
352
8, 7, 7, 7, 7, 6, 6,
353
6, 6, 6, 6, 6, 5, 5,
354
5, 5, 5, 5, 5, 5, 5,
355
5, 5, 5, 5, 5, 5, 5
356
];
357
358
var groupBases = [
359
0, 0,
360
33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
361
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
362
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
363
6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
364
24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
365
];
366
367
BN.prototype.toString = function toString(base, padding) {
368
base = base || 10;
369
if (base === 16 || base === 'hex') {
370
var out = '';
371
var off = 0;
372
var padding = padding | 0 || 1;
373
var carry = 0;
374
for (var i = 0; i < this.length; i++) {
375
var w = this.words[i];
376
var word = (((w << off) | carry) & 0xffffff).toString(16);
377
carry = (w >>> (24 - off)) & 0xffffff;
378
if (carry !== 0 || i !== this.length - 1)
379
out = zeros[6 - word.length] + word + out;
380
else
381
out = word + out;
382
off += 2;
383
if (off >= 26) {
384
off -= 26;
385
i--;
386
}
387
}
388
if (carry !== 0)
389
out = carry.toString(16) + out;
390
while (out.length % padding !== 0)
391
out = '0' + out;
392
if (this.sign)
393
out = '-' + out;
394
return out;
395
} else if (base === (base | 0) && base >= 2 && base <= 36) {
396
// var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
397
var groupSize = groupSizes[base];
398
// var groupBase = Math.pow(base, groupSize);
399
var groupBase = groupBases[base];
400
var out = '';
401
var c = this.clone();
402
c.sign = false;
403
while (c.cmpn(0) !== 0) {
404
var r = c.modn(groupBase).toString(base);
405
c = c.idivn(groupBase);
406
407
if (c.cmpn(0) !== 0)
408
out = zeros[groupSize - r.length] + r + out;
409
else
410
out = r + out;
411
}
412
if (this.cmpn(0) === 0)
413
out = '0' + out;
414
if (this.sign)
415
out = '-' + out;
416
return out;
417
} else {
418
assert(false, 'Base should be between 2 and 36');
419
}
420
};
421
422
BN.prototype.toJSON = function toJSON() {
423
return this.toString(16);
424
};
425
426
BN.prototype.toArray = function toArray() {
427
this.strip();
428
var res = new Array(this.byteLength());
429
res[0] = 0;
430
431
var q = this.clone();
432
for (var i = 0; q.cmpn(0) !== 0; i++) {
433
var b = q.andln(0xff);
434
q.ishrn(8);
435
436
// Assume big-endian
437
res[res.length - i - 1] = b;
438
}
439
440
return res;
441
};
442
443
if (Math.clz32) {
444
BN.prototype._countBits = function _countBits(w) {
445
return 32 - Math.clz32(w);
446
};
447
} else {
448
BN.prototype._countBits = function _countBits(w) {
449
var t = w;
450
var r = 0;
451
if (t >= 0x1000) {
452
r += 13;
453
t >>>= 13;
454
}
455
if (t >= 0x40) {
456
r += 7;
457
t >>>= 7;
458
}
459
if (t >= 0x8) {
460
r += 4;
461
t >>>= 4;
462
}
463
if (t >= 0x02) {
464
r += 2;
465
t >>>= 2;
466
}
467
return r + t;
468
};
469
}
470
471
BN.prototype._zeroBits = function _zeroBits(w) {
472
// Short-cut
473
if (w === 0)
474
return 26;
475
476
var t = w;
477
var r = 0;
478
if ((t & 0x1fff) === 0) {
479
r += 13;
480
t >>>= 13;
481
}
482
if ((t & 0x7f) === 0) {
483
r += 7;
484
t >>>= 7;
485
}
486
if ((t & 0xf) === 0) {
487
r += 4;
488
t >>>= 4;
489
}
490
if ((t & 0x3) === 0) {
491
r += 2;
492
t >>>= 2;
493
}
494
if ((t & 0x1) === 0)
495
r++;
496
return r;
497
};
498
499
// Return number of used bits in a BN
500
BN.prototype.bitLength = function bitLength() {
501
var hi = 0;
502
var w = this.words[this.length - 1];
503
var hi = this._countBits(w);
504
return (this.length - 1) * 26 + hi;
505
};
506
507
// Number of trailing zero bits
508
BN.prototype.zeroBits = function zeroBits() {
509
if (this.cmpn(0) === 0)
510
return 0;
511
512
var r = 0;
513
for (var i = 0; i < this.length; i++) {
514
var b = this._zeroBits(this.words[i]);
515
r += b;
516
if (b !== 26)
517
break;
518
}
519
return r;
520
};
521
522
BN.prototype.byteLength = function byteLength() {
523
return Math.ceil(this.bitLength() / 8);
524
};
525
526
// Return negative clone of `this`
527
BN.prototype.neg = function neg() {
528
if (this.cmpn(0) === 0)
529
return this.clone();
530
531
var r = this.clone();
532
r.sign = !this.sign;
533
return r;
534
};
535
536
537
// Or `num` with `this` in-place
538
BN.prototype.ior = function ior(num) {
539
this.sign = this.sign || num.sign;
540
541
while (this.length < num.length)
542
this.words[this.length++] = 0;
543
544
for (var i = 0; i < num.length; i++)
545
this.words[i] = this.words[i] | num.words[i];
546
547
return this.strip();
548
};
549
550
551
// Or `num` with `this`
552
BN.prototype.or = function or(num) {
553
if (this.length > num.length)
554
return this.clone().ior(num);
555
else
556
return num.clone().ior(this);
557
};
558
559
560
// And `num` with `this` in-place
561
BN.prototype.iand = function iand(num) {
562
this.sign = this.sign && num.sign;
563
564
// b = min-length(num, this)
565
var b;
566
if (this.length > num.length)
567
b = num;
568
else
569
b = this;
570
571
for (var i = 0; i < b.length; i++)
572
this.words[i] = this.words[i] & num.words[i];
573
574
this.length = b.length;
575
576
return this.strip();
577
};
578
579
580
// And `num` with `this`
581
BN.prototype.and = function and(num) {
582
if (this.length > num.length)
583
return this.clone().iand(num);
584
else
585
return num.clone().iand(this);
586
};
587
588
589
// Xor `num` with `this` in-place
590
BN.prototype.ixor = function ixor(num) {
591
this.sign = this.sign || num.sign;
592
593
// a.length > b.length
594
var a;
595
var b;
596
if (this.length > num.length) {
597
a = this;
598
b = num;
599
} else {
600
a = num;
601
b = this;
602
}
603
604
for (var i = 0; i < b.length; i++)
605
this.words[i] = a.words[i] ^ b.words[i];
606
607
if (this !== a)
608
for (; i < a.length; i++)
609
this.words[i] = a.words[i];
610
611
this.length = a.length;
612
613
return this.strip();
614
};
615
616
617
// Xor `num` with `this`
618
BN.prototype.xor = function xor(num) {
619
if (this.length > num.length)
620
return this.clone().ixor(num);
621
else
622
return num.clone().ixor(this);
623
};
624
625
626
// Set `bit` of `this`
627
BN.prototype.setn = function setn(bit, val) {
628
assert(typeof bit === 'number' && bit >= 0);
629
630
var off = (bit / 26) | 0;
631
var wbit = bit % 26;
632
633
while (this.length <= off)
634
this.words[this.length++] = 0;
635
636
if (val)
637
this.words[off] = this.words[off] | (1 << wbit);
638
else
639
this.words[off] = this.words[off] & ~(1 << wbit);
640
641
return this.strip();
642
};
643
644
645
// Add `num` to `this` in-place
646
BN.prototype.iadd = function iadd(num) {
647
// negative + positive
648
if (this.sign && !num.sign) {
649
this.sign = false;
650
var r = this.isub(num);
651
this.sign = !this.sign;
652
return this._normSign();
653
654
// positive + negative
655
} else if (!this.sign && num.sign) {
656
num.sign = false;
657
var r = this.isub(num);
658
num.sign = true;
659
return r._normSign();
660
}
661
662
// a.length > b.length
663
var a;
664
var b;
665
if (this.length > num.length) {
666
a = this;
667
b = num;
668
} else {
669
a = num;
670
b = this;
671
}
672
673
var carry = 0;
674
for (var i = 0; i < b.length; i++) {
675
var r = a.words[i] + b.words[i] + carry;
676
this.words[i] = r & 0x3ffffff;
677
carry = r >>> 26;
678
}
679
for (; carry !== 0 && i < a.length; i++) {
680
var r = a.words[i] + carry;
681
this.words[i] = r & 0x3ffffff;
682
carry = r >>> 26;
683
}
684
685
this.length = a.length;
686
if (carry !== 0) {
687
this.words[this.length] = carry;
688
this.length++;
689
// Copy the rest of the words
690
} else if (a !== this) {
691
for (; i < a.length; i++)
692
this.words[i] = a.words[i];
693
}
694
695
return this;
696
};
697
698
// Add `num` to `this`
699
BN.prototype.add = function add(num) {
700
if (num.sign && !this.sign) {
701
num.sign = false;
702
var res = this.sub(num);
703
num.sign = true;
704
return res;
705
} else if (!num.sign && this.sign) {
706
this.sign = false;
707
var res = num.sub(this);
708
this.sign = true;
709
return res;
710
}
711
712
if (this.length > num.length)
713
return this.clone().iadd(num);
714
else
715
return num.clone().iadd(this);
716
};
717
718
// Subtract `num` from `this` in-place
719
BN.prototype.isub = function isub(num) {
720
// this - (-num) = this + num
721
if (num.sign) {
722
num.sign = false;
723
var r = this.iadd(num);
724
num.sign = true;
725
return r._normSign();
726
727
// -this - num = -(this + num)
728
} else if (this.sign) {
729
this.sign = false;
730
this.iadd(num);
731
this.sign = true;
732
return this._normSign();
733
}
734
735
// At this point both numbers are positive
736
var cmp = this.cmp(num);
737
738
// Optimization - zeroify
739
if (cmp === 0) {
740
this.sign = false;
741
this.length = 1;
742
this.words[0] = 0;
743
return this;
744
}
745
746
// a > b
747
var a;
748
var b;
749
if (cmp > 0) {
750
a = this;
751
b = num;
752
} else {
753
a = num;
754
b = this;
755
}
756
757
var carry = 0;
758
for (var i = 0; i < b.length; i++) {
759
var r = a.words[i] - b.words[i] + carry;
760
carry = r >> 26;
761
this.words[i] = r & 0x3ffffff;
762
}
763
for (; carry !== 0 && i < a.length; i++) {
764
var r = a.words[i] + carry;
765
carry = r >> 26;
766
this.words[i] = r & 0x3ffffff;
767
}
768
769
// Copy rest of the words
770
if (carry === 0 && i < a.length && a !== this)
771
for (; i < a.length; i++)
772
this.words[i] = a.words[i];
773
this.length = Math.max(this.length, i);
774
775
if (a !== this)
776
this.sign = true;
777
778
return this.strip();
779
};
780
781
// Subtract `num` from `this`
782
BN.prototype.sub = function sub(num) {
783
return this.clone().isub(num);
784
};
785
786
/*
787
// NOTE: This could be potentionally used to generate loop-less multiplications
788
function _genCombMulTo(alen, blen) {
789
var len = alen + blen - 1;
790
var src = [
791
'var a = this.words, b = num.words, o = out.words, c = 0, w, ' +
792
'mask = 0x3ffffff, shift = 0x4000000;',
793
'out.length = ' + len + ';'
794
];
795
for (var k = 0; k < len; k++) {
796
var minJ = Math.max(0, k - alen + 1);
797
var maxJ = Math.min(k, blen - 1);
798
799
for (var j = minJ; j <= maxJ; j++) {
800
var i = k - j;
801
var mul = 'a[' + i + '] * b[' + j + ']';
802
803
if (j === minJ) {
804
src.push('w = ' + mul + ' + c;');
805
src.push('c = (w / shift) | 0;');
806
} else {
807
src.push('w += ' + mul + ';');
808
src.push('c += (w / shift) | 0;');
809
}
810
src.push('w &= mask;');
811
}
812
src.push('o[' + k + '] = w;');
813
}
814
src.push('if (c !== 0) {',
815
' o[' + k + '] = c;',
816
' out.length++;',
817
'}',
818
'return out;');
819
820
return src.join('\n');
821
}
822
*/
823
824
BN.prototype._smallMulTo = function _smallMulTo(num, out) {
825
out.sign = num.sign !== this.sign;
826
out.length = this.length + num.length;
827
828
var carry = 0;
829
for (var k = 0; k < out.length - 1; k++) {
830
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
831
// note that ncarry could be >= 0x3ffffff
832
var ncarry = carry >>> 26;
833
var rword = carry & 0x3ffffff;
834
var maxJ = Math.min(k, num.length - 1);
835
for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) {
836
var i = k - j;
837
var a = this.words[i] | 0;
838
var b = num.words[j] | 0;
839
var r = a * b;
840
841
var lo = r & 0x3ffffff;
842
ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
843
lo = (lo + rword) | 0;
844
rword = lo & 0x3ffffff;
845
ncarry = (ncarry + (lo >>> 26)) | 0;
846
}
847
out.words[k] = rword;
848
carry = ncarry;
849
}
850
if (carry !== 0) {
851
out.words[k] = carry;
852
} else {
853
out.length--;
854
}
855
856
return out.strip();
857
};
858
859
BN.prototype._bigMulTo = function _bigMulTo(num, out) {
860
out.sign = num.sign !== this.sign;
861
out.length = this.length + num.length;
862
863
var carry = 0;
864
var hncarry = 0;
865
for (var k = 0; k < out.length - 1; k++) {
866
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
867
// note that ncarry could be >= 0x3ffffff
868
var ncarry = hncarry;
869
hncarry = 0;
870
var rword = carry & 0x3ffffff;
871
var maxJ = Math.min(k, num.length - 1);
872
for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) {
873
var i = k - j;
874
var a = this.words[i] | 0;
875
var b = num.words[j] | 0;
876
var r = a * b;
877
878
var lo = r & 0x3ffffff;
879
ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
880
lo = (lo + rword) | 0;
881
rword = lo & 0x3ffffff;
882
ncarry = (ncarry + (lo >>> 26)) | 0;
883
884
hncarry += ncarry >>> 26;
885
ncarry &= 0x3ffffff;
886
}
887
out.words[k] = rword;
888
carry = ncarry;
889
ncarry = hncarry;
890
}
891
if (carry !== 0) {
892
out.words[k] = carry;
893
} else {
894
out.length--;
895
}
896
897
return out.strip();
898
};
899
900
BN.prototype.mulTo = function mulTo(num, out) {
901
var res;
902
if (this.length + num.length < 63)
903
res = this._smallMulTo(num, out);
904
else
905
res = this._bigMulTo(num, out);
906
return res;
907
};
908
909
// Multiply `this` by `num`
910
BN.prototype.mul = function mul(num) {
911
var out = new BN(null);
912
out.words = new Array(this.length + num.length);
913
return this.mulTo(num, out);
914
};
915
916
// In-place Multiplication
917
BN.prototype.imul = function imul(num) {
918
if (this.cmpn(0) === 0 || num.cmpn(0) === 0) {
919
this.words[0] = 0;
920
this.length = 1;
921
return this;
922
}
923
924
var tlen = this.length;
925
var nlen = num.length;
926
927
this.sign = num.sign !== this.sign;
928
this.length = this.length + num.length;
929
this.words[this.length - 1] = 0;
930
931
for (var k = this.length - 2; k >= 0; k--) {
932
// Sum all words with the same `i + j = k` and accumulate `carry`,
933
// note that carry could be >= 0x3ffffff
934
var carry = 0;
935
var rword = 0;
936
var maxJ = Math.min(k, nlen - 1);
937
for (var j = Math.max(0, k - tlen + 1); j <= maxJ; j++) {
938
var i = k - j;
939
var a = this.words[i];
940
var b = num.words[j];
941
var r = a * b;
942
943
var lo = r & 0x3ffffff;
944
carry += (r / 0x4000000) | 0;
945
lo += rword;
946
rword = lo & 0x3ffffff;
947
carry += lo >>> 26;
948
}
949
this.words[k] = rword;
950
this.words[k + 1] += carry;
951
carry = 0;
952
}
953
954
// Propagate overflows
955
var carry = 0;
956
for (var i = 1; i < this.length; i++) {
957
var w = this.words[i] + carry;
958
this.words[i] = w & 0x3ffffff;
959
carry = w >>> 26;
960
}
961
962
return this.strip();
963
};
964
965
BN.prototype.imuln = function imuln(num) {
966
assert(typeof num === 'number');
967
968
// Carry
969
var carry = 0;
970
for (var i = 0; i < this.length; i++) {
971
var w = this.words[i] * num;
972
var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
973
carry >>= 26;
974
carry += (w / 0x4000000) | 0;
975
// NOTE: lo is 27bit maximum
976
carry += lo >>> 26;
977
this.words[i] = lo & 0x3ffffff;
978
}
979
980
if (carry !== 0) {
981
this.words[i] = carry;
982
this.length++;
983
}
984
985
return this;
986
};
987
988
// `this` * `this`
989
BN.prototype.sqr = function sqr() {
990
return this.mul(this);
991
};
992
993
// `this` * `this` in-place
994
BN.prototype.isqr = function isqr() {
995
return this.mul(this);
996
};
997
998
// Shift-left in-place
999
BN.prototype.ishln = function ishln(bits) {
1000
assert(typeof bits === 'number' && bits >= 0);
1001
var r = bits % 26;
1002
var s = (bits - r) / 26;
1003
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
1004
1005
if (r !== 0) {
1006
var carry = 0;
1007
for (var i = 0; i < this.length; i++) {
1008
var newCarry = this.words[i] & carryMask;
1009
var c = (this.words[i] - newCarry) << r;
1010
this.words[i] = c | carry;
1011
carry = newCarry >>> (26 - r);
1012
}
1013
if (carry) {
1014
this.words[i] = carry;
1015
this.length++;
1016
}
1017
}
1018
1019
if (s !== 0) {
1020
for (var i = this.length - 1; i >= 0; i--)
1021
this.words[i + s] = this.words[i];
1022
for (var i = 0; i < s; i++)
1023
this.words[i] = 0;
1024
this.length += s;
1025
}
1026
1027
return this.strip();
1028
};
1029
1030
// Shift-right in-place
1031
// NOTE: `hint` is a lowest bit before trailing zeroes
1032
// NOTE: if `extended` is present - it will be filled with destroyed bits
1033
BN.prototype.ishrn = function ishrn(bits, hint, extended) {
1034
assert(typeof bits === 'number' && bits >= 0);
1035
var h;
1036
if (hint)
1037
h = (hint - (hint % 26)) / 26;
1038
else
1039
h = 0;
1040
1041
var r = bits % 26;
1042
var s = Math.min((bits - r) / 26, this.length);
1043
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
1044
var maskedWords = extended;
1045
1046
h -= s;
1047
h = Math.max(0, h);
1048
1049
// Extended mode, copy masked part
1050
if (maskedWords) {
1051
for (var i = 0; i < s; i++)
1052
maskedWords.words[i] = this.words[i];
1053
maskedWords.length = s;
1054
}
1055
1056
if (s === 0) {
1057
// No-op, we should not move anything at all
1058
} else if (this.length > s) {
1059
this.length -= s;
1060
for (var i = 0; i < this.length; i++)
1061
this.words[i] = this.words[i + s];
1062
} else {
1063
this.words[0] = 0;
1064
this.length = 1;
1065
}
1066
1067
var carry = 0;
1068
for (var i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
1069
var word = this.words[i];
1070
this.words[i] = (carry << (26 - r)) | (word >>> r);
1071
carry = word & mask;
1072
}
1073
1074
// Push carried bits as a mask
1075
if (maskedWords && carry !== 0)
1076
maskedWords.words[maskedWords.length++] = carry;
1077
1078
if (this.length === 0) {
1079
this.words[0] = 0;
1080
this.length = 1;
1081
}
1082
1083
this.strip();
1084
1085
return this;
1086
};
1087
1088
// Shift-left
1089
BN.prototype.shln = function shln(bits) {
1090
return this.clone().ishln(bits);
1091
};
1092
1093
// Shift-right
1094
BN.prototype.shrn = function shrn(bits) {
1095
return this.clone().ishrn(bits);
1096
};
1097
1098
// Test if n bit is set
1099
BN.prototype.testn = function testn(bit) {
1100
assert(typeof bit === 'number' && bit >= 0);
1101
var r = bit % 26;
1102
var s = (bit - r) / 26;
1103
var q = 1 << r;
1104
1105
// Fast case: bit is much higher than all existing words
1106
if (this.length <= s) {
1107
return false;
1108
}
1109
1110
// Check bit and return
1111
var w = this.words[s];
1112
1113
return !!(w & q);
1114
};
1115
1116
// Return only lowers bits of number (in-place)
1117
BN.prototype.imaskn = function imaskn(bits) {
1118
assert(typeof bits === 'number' && bits >= 0);
1119
var r = bits % 26;
1120
var s = (bits - r) / 26;
1121
1122
assert(!this.sign, 'imaskn works only with positive numbers');
1123
1124
if (r !== 0)
1125
s++;
1126
this.length = Math.min(s, this.length);
1127
1128
if (r !== 0) {
1129
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
1130
this.words[this.length - 1] &= mask;
1131
}
1132
1133
return this.strip();
1134
};
1135
1136
// Return only lowers bits of number
1137
BN.prototype.maskn = function maskn(bits) {
1138
return this.clone().imaskn(bits);
1139
};
1140
1141
// Add plain number `num` to `this`
1142
BN.prototype.iaddn = function iaddn(num) {
1143
assert(typeof num === 'number');
1144
if (num < 0)
1145
return this.isubn(-num);
1146
1147
// Possible sign change
1148
if (this.sign) {
1149
if (this.length === 1 && this.words[0] < num) {
1150
this.words[0] = num - this.words[0];
1151
this.sign = false;
1152
return this;
1153
}
1154
1155
this.sign = false;
1156
this.isubn(num);
1157
this.sign = true;
1158
return this;
1159
}
1160
1161
// Add without checks
1162
return this._iaddn(num);
1163
};
1164
1165
BN.prototype._iaddn = function _iaddn(num) {
1166
this.words[0] += num;
1167
1168
// Carry
1169
for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
1170
this.words[i] -= 0x4000000;
1171
if (i === this.length - 1)
1172
this.words[i + 1] = 1;
1173
else
1174
this.words[i + 1]++;
1175
}
1176
this.length = Math.max(this.length, i + 1);
1177
1178
return this;
1179
};
1180
1181
// Subtract plain number `num` from `this`
1182
BN.prototype.isubn = function isubn(num) {
1183
assert(typeof num === 'number');
1184
if (num < 0)
1185
return this.iaddn(-num);
1186
1187
if (this.sign) {
1188
this.sign = false;
1189
this.iaddn(num);
1190
this.sign = true;
1191
return this;
1192
}
1193
1194
this.words[0] -= num;
1195
1196
// Carry
1197
for (var i = 0; i < this.length && this.words[i] < 0; i++) {
1198
this.words[i] += 0x4000000;
1199
this.words[i + 1] -= 1;
1200
}
1201
1202
return this.strip();
1203
};
1204
1205
BN.prototype.addn = function addn(num) {
1206
return this.clone().iaddn(num);
1207
};
1208
1209
BN.prototype.subn = function subn(num) {
1210
return this.clone().isubn(num);
1211
};
1212
1213
BN.prototype.iabs = function iabs() {
1214
this.sign = false;
1215
1216
return this;
1217
};
1218
1219
BN.prototype.abs = function abs() {
1220
return this.clone().iabs();
1221
};
1222
1223
BN.prototype._ishlnsubmul = function _ishlnsubmul(num, mul, shift) {
1224
// Bigger storage is needed
1225
var len = num.length + shift;
1226
var i;
1227
if (this.words.length < len) {
1228
var t = new Array(len);
1229
for (var i = 0; i < this.length; i++)
1230
t[i] = this.words[i];
1231
this.words = t;
1232
} else {
1233
i = this.length;
1234
}
1235
1236
// Zeroify rest
1237
this.length = Math.max(this.length, len);
1238
for (; i < this.length; i++)
1239
this.words[i] = 0;
1240
1241
var carry = 0;
1242
for (var i = 0; i < num.length; i++) {
1243
var w = this.words[i + shift] + carry;
1244
var right = num.words[i] * mul;
1245
w -= right & 0x3ffffff;
1246
carry = (w >> 26) - ((right / 0x4000000) | 0);
1247
this.words[i + shift] = w & 0x3ffffff;
1248
}
1249
for (; i < this.length - shift; i++) {
1250
var w = this.words[i + shift] + carry;
1251
carry = w >> 26;
1252
this.words[i + shift] = w & 0x3ffffff;
1253
}
1254
1255
if (carry === 0)
1256
return this.strip();
1257
1258
// Subtraction overflow
1259
assert(carry === -1);
1260
carry = 0;
1261
for (var i = 0; i < this.length; i++) {
1262
var w = -this.words[i] + carry;
1263
carry = w >> 26;
1264
this.words[i] = w & 0x3ffffff;
1265
}
1266
this.sign = true;
1267
1268
return this.strip();
1269
};
1270
1271
BN.prototype._wordDiv = function _wordDiv(num, mode) {
1272
var shift = this.length - num.length;
1273
1274
var a = this.clone();
1275
var b = num;
1276
1277
// Normalize
1278
var bhi = b.words[b.length - 1];
1279
var bhiBits = this._countBits(bhi);
1280
shift = 26 - bhiBits;
1281
if (shift !== 0) {
1282
b = b.shln(shift);
1283
a.ishln(shift);
1284
bhi = b.words[b.length - 1];
1285
}
1286
1287
// Initialize quotient
1288
var m = a.length - b.length;
1289
var q;
1290
1291
if (mode !== 'mod') {
1292
q = new BN(null);
1293
q.length = m + 1;
1294
q.words = new Array(q.length);
1295
for (var i = 0; i < q.length; i++)
1296
q.words[i] = 0;
1297
}
1298
1299
var diff = a.clone()._ishlnsubmul(b, 1, m);
1300
if (!diff.sign) {
1301
a = diff;
1302
if (q)
1303
q.words[m] = 1;
1304
}
1305
1306
for (var j = m - 1; j >= 0; j--) {
1307
var qj = a.words[b.length + j] * 0x4000000 + a.words[b.length + j - 1];
1308
1309
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
1310
// (0x7ffffff)
1311
qj = Math.min((qj / bhi) | 0, 0x3ffffff);
1312
1313
a._ishlnsubmul(b, qj, j);
1314
while (a.sign) {
1315
qj--;
1316
a.sign = false;
1317
a._ishlnsubmul(b, 1, j);
1318
if (a.cmpn(0) !== 0)
1319
a.sign = !a.sign;
1320
}
1321
if (q)
1322
q.words[j] = qj;
1323
}
1324
if (q)
1325
q.strip();
1326
a.strip();
1327
1328
// Denormalize
1329
if (mode !== 'div' && shift !== 0)
1330
a.ishrn(shift);
1331
return { div: q ? q : null, mod: a };
1332
};
1333
1334
BN.prototype.divmod = function divmod(num, mode) {
1335
assert(num.cmpn(0) !== 0);
1336
1337
if (this.sign && !num.sign) {
1338
var res = this.neg().divmod(num, mode);
1339
var div;
1340
var mod;
1341
if (mode !== 'mod')
1342
div = res.div.neg();
1343
if (mode !== 'div')
1344
mod = res.mod.cmpn(0) === 0 ? res.mod : num.sub(res.mod);
1345
return {
1346
div: div,
1347
mod: mod
1348
};
1349
} else if (!this.sign && num.sign) {
1350
var res = this.divmod(num.neg(), mode);
1351
var div;
1352
if (mode !== 'mod')
1353
div = res.div.neg();
1354
return { div: div, mod: res.mod };
1355
} else if (this.sign && num.sign) {
1356
return this.neg().divmod(num.neg(), mode);
1357
}
1358
1359
// Both numbers are positive at this point
1360
1361
// Strip both numbers to approximate shift value
1362
if (num.length > this.length || this.cmp(num) < 0)
1363
return { div: new BN(0), mod: this };
1364
1365
// Very short reduction
1366
if (num.length === 1) {
1367
if (mode === 'div')
1368
return { div: this.divn(num.words[0]), mod: null };
1369
else if (mode === 'mod')
1370
return { div: null, mod: new BN(this.modn(num.words[0])) };
1371
return {
1372
div: this.divn(num.words[0]),
1373
mod: new BN(this.modn(num.words[0]))
1374
};
1375
}
1376
1377
return this._wordDiv(num, mode);
1378
};
1379
1380
// Find `this` / `num`
1381
BN.prototype.div = function div(num) {
1382
return this.divmod(num, 'div').div;
1383
};
1384
1385
// Find `this` % `num`
1386
BN.prototype.mod = function mod(num) {
1387
return this.divmod(num, 'mod').mod;
1388
};
1389
1390
// Find Round(`this` / `num`)
1391
BN.prototype.divRound = function divRound(num) {
1392
var dm = this.divmod(num);
1393
1394
// Fast case - exact division
1395
if (dm.mod.cmpn(0) === 0)
1396
return dm.div;
1397
1398
var mod = dm.div.sign ? dm.mod.isub(num) : dm.mod;
1399
1400
var half = num.shrn(1);
1401
var r2 = num.andln(1);
1402
var cmp = mod.cmp(half);
1403
1404
// Round down
1405
if (cmp < 0 || r2 === 1 && cmp === 0)
1406
return dm.div;
1407
1408
// Round up
1409
return dm.div.sign ? dm.div.isubn(1) : dm.div.iaddn(1);
1410
};
1411
1412
BN.prototype.modn = function modn(num) {
1413
assert(num <= 0x3ffffff);
1414
var p = (1 << 26) % num;
1415
1416
var acc = 0;
1417
for (var i = this.length - 1; i >= 0; i--)
1418
acc = (p * acc + this.words[i]) % num;
1419
1420
return acc;
1421
};
1422
1423
// In-place division by number
1424
BN.prototype.idivn = function idivn(num) {
1425
assert(num <= 0x3ffffff);
1426
1427
var carry = 0;
1428
for (var i = this.length - 1; i >= 0; i--) {
1429
var w = this.words[i] + carry * 0x4000000;
1430
this.words[i] = (w / num) | 0;
1431
carry = w % num;
1432
}
1433
1434
return this.strip();
1435
};
1436
1437
BN.prototype.divn = function divn(num) {
1438
return this.clone().idivn(num);
1439
};
1440
1441
BN.prototype.egcd = function egcd(p) {
1442
assert(!p.sign);
1443
assert(p.cmpn(0) !== 0);
1444
1445
var x = this;
1446
var y = p.clone();
1447
1448
if (x.sign)
1449
x = x.mod(p);
1450
else
1451
x = x.clone();
1452
1453
// A * x + B * y = x
1454
var A = new BN(1);
1455
var B = new BN(0);
1456
1457
// C * x + D * y = y
1458
var C = new BN(0);
1459
var D = new BN(1);
1460
1461
var g = 0;
1462
1463
while (x.isEven() && y.isEven()) {
1464
x.ishrn(1);
1465
y.ishrn(1);
1466
++g;
1467
}
1468
1469
var yp = y.clone();
1470
var xp = x.clone();
1471
1472
while (x.cmpn(0) !== 0) {
1473
while (x.isEven()) {
1474
x.ishrn(1);
1475
if (A.isEven() && B.isEven()) {
1476
A.ishrn(1);
1477
B.ishrn(1);
1478
} else {
1479
A.iadd(yp).ishrn(1);
1480
B.isub(xp).ishrn(1);
1481
}
1482
}
1483
1484
while (y.isEven()) {
1485
y.ishrn(1);
1486
if (C.isEven() && D.isEven()) {
1487
C.ishrn(1);
1488
D.ishrn(1);
1489
} else {
1490
C.iadd(yp).ishrn(1);
1491
D.isub(xp).ishrn(1);
1492
}
1493
}
1494
1495
if (x.cmp(y) >= 0) {
1496
x.isub(y);
1497
A.isub(C);
1498
B.isub(D);
1499
} else {
1500
y.isub(x);
1501
C.isub(A);
1502
D.isub(B);
1503
}
1504
}
1505
1506
return {
1507
a: C,
1508
b: D,
1509
gcd: y.ishln(g)
1510
};
1511
};
1512
1513
// This is reduced incarnation of the binary EEA
1514
// above, designated to invert members of the
1515
// _prime_ fields F(p) at a maximal speed
1516
BN.prototype._invmp = function _invmp(p) {
1517
assert(!p.sign);
1518
assert(p.cmpn(0) !== 0);
1519
1520
var a = this;
1521
var b = p.clone();
1522
1523
if (a.sign)
1524
a = a.mod(p);
1525
else
1526
a = a.clone();
1527
1528
var x1 = new BN(1);
1529
var x2 = new BN(0);
1530
1531
var delta = b.clone();
1532
1533
while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
1534
while (a.isEven()) {
1535
a.ishrn(1);
1536
if (x1.isEven())
1537
x1.ishrn(1);
1538
else
1539
x1.iadd(delta).ishrn(1);
1540
}
1541
while (b.isEven()) {
1542
b.ishrn(1);
1543
if (x2.isEven())
1544
x2.ishrn(1);
1545
else
1546
x2.iadd(delta).ishrn(1);
1547
}
1548
if (a.cmp(b) >= 0) {
1549
a.isub(b);
1550
x1.isub(x2);
1551
} else {
1552
b.isub(a);
1553
x2.isub(x1);
1554
}
1555
}
1556
if (a.cmpn(1) === 0)
1557
return x1;
1558
else
1559
return x2;
1560
};
1561
1562
BN.prototype.gcd = function gcd(num) {
1563
if (this.cmpn(0) === 0)
1564
return num.clone();
1565
if (num.cmpn(0) === 0)
1566
return this.clone();
1567
1568
var a = this.clone();
1569
var b = num.clone();
1570
a.sign = false;
1571
b.sign = false;
1572
1573
// Remove common factor of two
1574
for (var shift = 0; a.isEven() && b.isEven(); shift++) {
1575
a.ishrn(1);
1576
b.ishrn(1);
1577
}
1578
1579
do {
1580
while (a.isEven())
1581
a.ishrn(1);
1582
while (b.isEven())
1583
b.ishrn(1);
1584
1585
var r = a.cmp(b);
1586
if (r < 0) {
1587
// Swap `a` and `b` to make `a` always bigger than `b`
1588
var t = a;
1589
a = b;
1590
b = t;
1591
} else if (r === 0 || b.cmpn(1) === 0) {
1592
break;
1593
}
1594
1595
a.isub(b);
1596
} while (true);
1597
1598
return b.ishln(shift);
1599
};
1600
1601
// Invert number in the field F(num)
1602
BN.prototype.invm = function invm(num) {
1603
return this.egcd(num).a.mod(num);
1604
};
1605
1606
BN.prototype.isEven = function isEven() {
1607
return (this.words[0] & 1) === 0;
1608
};
1609
1610
BN.prototype.isOdd = function isOdd() {
1611
return (this.words[0] & 1) === 1;
1612
};
1613
1614
// And first word and num
1615
BN.prototype.andln = function andln(num) {
1616
return this.words[0] & num;
1617
};
1618
1619
// Increment at the bit position in-line
1620
BN.prototype.bincn = function bincn(bit) {
1621
assert(typeof bit === 'number');
1622
var r = bit % 26;
1623
var s = (bit - r) / 26;
1624
var q = 1 << r;
1625
1626
// Fast case: bit is much higher than all existing words
1627
if (this.length <= s) {
1628
for (var i = this.length; i < s + 1; i++)
1629
this.words[i] = 0;
1630
this.words[s] |= q;
1631
this.length = s + 1;
1632
return this;
1633
}
1634
1635
// Add bit and propagate, if needed
1636
var carry = q;
1637
for (var i = s; carry !== 0 && i < this.length; i++) {
1638
var w = this.words[i];
1639
w += carry;
1640
carry = w >>> 26;
1641
w &= 0x3ffffff;
1642
this.words[i] = w;
1643
}
1644
if (carry !== 0) {
1645
this.words[i] = carry;
1646
this.length++;
1647
}
1648
return this;
1649
};
1650
1651
BN.prototype.cmpn = function cmpn(num) {
1652
var sign = num < 0;
1653
if (sign)
1654
num = -num;
1655
1656
if (this.sign && !sign)
1657
return -1;
1658
else if (!this.sign && sign)
1659
return 1;
1660
1661
num &= 0x3ffffff;
1662
this.strip();
1663
1664
var res;
1665
if (this.length > 1) {
1666
res = 1;
1667
} else {
1668
var w = this.words[0];
1669
res = w === num ? 0 : w < num ? -1 : 1;
1670
}
1671
if (this.sign)
1672
res = -res;
1673
return res;
1674
};
1675
1676
// Compare two numbers and return:
1677
// 1 - if `this` > `num`
1678
// 0 - if `this` == `num`
1679
// -1 - if `this` < `num`
1680
BN.prototype.cmp = function cmp(num) {
1681
if (this.sign && !num.sign)
1682
return -1;
1683
else if (!this.sign && num.sign)
1684
return 1;
1685
1686
var res = this.ucmp(num);
1687
if (this.sign)
1688
return -res;
1689
else
1690
return res;
1691
};
1692
1693
// Unsigned comparison
1694
BN.prototype.ucmp = function ucmp(num) {
1695
// At this point both numbers have the same sign
1696
if (this.length > num.length)
1697
return 1;
1698
else if (this.length < num.length)
1699
return -1;
1700
1701
var res = 0;
1702
for (var i = this.length - 1; i >= 0; i--) {
1703
var a = this.words[i];
1704
var b = num.words[i];
1705
1706
if (a === b)
1707
continue;
1708
if (a < b)
1709
res = -1;
1710
else if (a > b)
1711
res = 1;
1712
break;
1713
}
1714
return res;
1715
};
1716
1717
//
1718
// A reduce context, could be using montgomery or something better, depending
1719
// on the `m` itself.
1720
//
1721
BN.red = function red(num) {
1722
return new Red(num);
1723
};
1724
1725
BN.prototype.toRed = function toRed(ctx) {
1726
assert(!this.red, 'Already a number in reduction context');
1727
assert(!this.sign, 'red works only with positives');
1728
return ctx.convertTo(this)._forceRed(ctx);
1729
};
1730
1731
BN.prototype.fromRed = function fromRed() {
1732
assert(this.red, 'fromRed works only with numbers in reduction context');
1733
return this.red.convertFrom(this);
1734
};
1735
1736
BN.prototype._forceRed = function _forceRed(ctx) {
1737
this.red = ctx;
1738
return this;
1739
};
1740
1741
BN.prototype.forceRed = function forceRed(ctx) {
1742
assert(!this.red, 'Already a number in reduction context');
1743
return this._forceRed(ctx);
1744
};
1745
1746
BN.prototype.redAdd = function redAdd(num) {
1747
assert(this.red, 'redAdd works only with red numbers');
1748
return this.red.add(this, num);
1749
};
1750
1751
BN.prototype.redIAdd = function redIAdd(num) {
1752
assert(this.red, 'redIAdd works only with red numbers');
1753
return this.red.iadd(this, num);
1754
};
1755
1756
BN.prototype.redSub = function redSub(num) {
1757
assert(this.red, 'redSub works only with red numbers');
1758
return this.red.sub(this, num);
1759
};
1760
1761
BN.prototype.redISub = function redISub(num) {
1762
assert(this.red, 'redISub works only with red numbers');
1763
return this.red.isub(this, num);
1764
};
1765
1766
BN.prototype.redShl = function redShl(num) {
1767
assert(this.red, 'redShl works only with red numbers');
1768
return this.red.shl(this, num);
1769
};
1770
1771
BN.prototype.redMul = function redMul(num) {
1772
assert(this.red, 'redMul works only with red numbers');
1773
this.red._verify2(this, num);
1774
return this.red.mul(this, num);
1775
};
1776
1777
BN.prototype.redIMul = function redIMul(num) {
1778
assert(this.red, 'redMul works only with red numbers');
1779
this.red._verify2(this, num);
1780
return this.red.imul(this, num);
1781
};
1782
1783
BN.prototype.redSqr = function redSqr() {
1784
assert(this.red, 'redSqr works only with red numbers');
1785
this.red._verify1(this);
1786
return this.red.sqr(this);
1787
};
1788
1789
BN.prototype.redISqr = function redISqr() {
1790
assert(this.red, 'redISqr works only with red numbers');
1791
this.red._verify1(this);
1792
return this.red.isqr(this);
1793
};
1794
1795
// Square root over p
1796
BN.prototype.redSqrt = function redSqrt() {
1797
assert(this.red, 'redSqrt works only with red numbers');
1798
this.red._verify1(this);
1799
return this.red.sqrt(this);
1800
};
1801
1802
BN.prototype.redInvm = function redInvm() {
1803
assert(this.red, 'redInvm works only with red numbers');
1804
this.red._verify1(this);
1805
return this.red.invm(this);
1806
};
1807
1808
// Return negative clone of `this` % `red modulo`
1809
BN.prototype.redNeg = function redNeg() {
1810
assert(this.red, 'redNeg works only with red numbers');
1811
this.red._verify1(this);
1812
return this.red.neg(this);
1813
};
1814
1815
BN.prototype.redPow = function redPow(num) {
1816
assert(this.red && !num.red, 'redPow(normalNum)');
1817
this.red._verify1(this);
1818
return this.red.pow(this, num);
1819
};
1820
1821
// Prime numbers with efficient reduction
1822
var primes = {
1823
k256: null,
1824
p224: null,
1825
p192: null,
1826
p25519: null
1827
};
1828
1829
// Pseudo-Mersenne prime
1830
function MPrime(name, p) {
1831
// P = 2 ^ N - K
1832
this.name = name;
1833
this.p = new BN(p, 16);
1834
this.n = this.p.bitLength();
1835
this.k = new BN(1).ishln(this.n).isub(this.p);
1836
1837
this.tmp = this._tmp();
1838
}
1839
1840
MPrime.prototype._tmp = function _tmp() {
1841
var tmp = new BN(null);
1842
tmp.words = new Array(Math.ceil(this.n / 13));
1843
return tmp;
1844
};
1845
1846
MPrime.prototype.ireduce = function ireduce(num) {
1847
// Assumes that `num` is less than `P^2`
1848
// num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
1849
var r = num;
1850
var rlen;
1851
1852
do {
1853
this.split(r, this.tmp);
1854
r = this.imulK(r);
1855
r = r.iadd(this.tmp);
1856
rlen = r.bitLength();
1857
} while (rlen > this.n);
1858
1859
var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
1860
if (cmp === 0) {
1861
r.words[0] = 0;
1862
r.length = 1;
1863
} else if (cmp > 0) {
1864
r.isub(this.p);
1865
} else {
1866
r.strip();
1867
}
1868
1869
return r;
1870
};
1871
1872
MPrime.prototype.split = function split(input, out) {
1873
input.ishrn(this.n, 0, out);
1874
};
1875
1876
MPrime.prototype.imulK = function imulK(num) {
1877
return num.imul(this.k);
1878
};
1879
1880
function K256() {
1881
MPrime.call(
1882
this,
1883
'k256',
1884
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
1885
}
1886
inherits(K256, MPrime);
1887
1888
K256.prototype.split = function split(input, output) {
1889
// 256 = 9 * 26 + 22
1890
var mask = 0x3fffff;
1891
1892
var outLen = Math.min(input.length, 9);
1893
for (var i = 0; i < outLen; i++)
1894
output.words[i] = input.words[i];
1895
output.length = outLen;
1896
1897
if (input.length <= 9) {
1898
input.words[0] = 0;
1899
input.length = 1;
1900
return;
1901
}
1902
1903
// Shift by 9 limbs
1904
var prev = input.words[9];
1905
output.words[output.length++] = prev & mask;
1906
1907
for (var i = 10; i < input.length; i++) {
1908
var next = input.words[i];
1909
input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
1910
prev = next;
1911
}
1912
input.words[i - 10] = prev >>> 22;
1913
input.length -= 9;
1914
};
1915
1916
K256.prototype.imulK = function imulK(num) {
1917
// K = 0x1000003d1 = [ 0x40, 0x3d1 ]
1918
num.words[num.length] = 0;
1919
num.words[num.length + 1] = 0;
1920
num.length += 2;
1921
1922
// bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
1923
var hi;
1924
var lo = 0;
1925
for (var i = 0; i < num.length; i++) {
1926
var w = num.words[i];
1927
hi = w * 0x40;
1928
lo += w * 0x3d1;
1929
hi += (lo / 0x4000000) | 0;
1930
lo &= 0x3ffffff;
1931
1932
num.words[i] = lo;
1933
1934
lo = hi;
1935
}
1936
1937
// Fast length reduction
1938
if (num.words[num.length - 1] === 0) {
1939
num.length--;
1940
if (num.words[num.length - 1] === 0)
1941
num.length--;
1942
}
1943
return num;
1944
};
1945
1946
function P224() {
1947
MPrime.call(
1948
this,
1949
'p224',
1950
'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
1951
}
1952
inherits(P224, MPrime);
1953
1954
function P192() {
1955
MPrime.call(
1956
this,
1957
'p192',
1958
'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
1959
}
1960
inherits(P192, MPrime);
1961
1962
function P25519() {
1963
// 2 ^ 255 - 19
1964
MPrime.call(
1965
this,
1966
'25519',
1967
'7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
1968
}
1969
inherits(P25519, MPrime);
1970
1971
P25519.prototype.imulK = function imulK(num) {
1972
// K = 0x13
1973
var carry = 0;
1974
for (var i = 0; i < num.length; i++) {
1975
var hi = num.words[i] * 0x13 + carry;
1976
var lo = hi & 0x3ffffff;
1977
hi >>>= 26;
1978
1979
num.words[i] = lo;
1980
carry = hi;
1981
}
1982
if (carry !== 0)
1983
num.words[num.length++] = carry;
1984
return num;
1985
};
1986
1987
// Exported mostly for testing purposes, use plain name instead
1988
BN._prime = function prime(name) {
1989
// Cached version of prime
1990
if (primes[name])
1991
return primes[name];
1992
1993
var prime;
1994
if (name === 'k256')
1995
prime = new K256();
1996
else if (name === 'p224')
1997
prime = new P224();
1998
else if (name === 'p192')
1999
prime = new P192();
2000
else if (name === 'p25519')
2001
prime = new P25519();
2002
else
2003
throw new Error('Unknown prime ' + name);
2004
primes[name] = prime;
2005
2006
return prime;
2007
};
2008
2009
//
2010
// Base reduction engine
2011
//
2012
function Red(m) {
2013
if (typeof m === 'string') {
2014
var prime = BN._prime(m);
2015
this.m = prime.p;
2016
this.prime = prime;
2017
} else {
2018
this.m = m;
2019
this.prime = null;
2020
}
2021
}
2022
2023
Red.prototype._verify1 = function _verify1(a) {
2024
assert(!a.sign, 'red works only with positives');
2025
assert(a.red, 'red works only with red numbers');
2026
};
2027
2028
Red.prototype._verify2 = function _verify2(a, b) {
2029
assert(!a.sign && !b.sign, 'red works only with positives');
2030
assert(a.red && a.red === b.red,
2031
'red works only with red numbers');
2032
};
2033
2034
Red.prototype.imod = function imod(a) {
2035
if (this.prime)
2036
return this.prime.ireduce(a)._forceRed(this);
2037
return a.mod(this.m)._forceRed(this);
2038
};
2039
2040
Red.prototype.neg = function neg(a) {
2041
var r = a.clone();
2042
r.sign = !r.sign;
2043
return r.iadd(this.m)._forceRed(this);
2044
};
2045
2046
Red.prototype.add = function add(a, b) {
2047
this._verify2(a, b);
2048
2049
var res = a.add(b);
2050
if (res.cmp(this.m) >= 0)
2051
res.isub(this.m);
2052
return res._forceRed(this);
2053
};
2054
2055
Red.prototype.iadd = function iadd(a, b) {
2056
this._verify2(a, b);
2057
2058
var res = a.iadd(b);
2059
if (res.cmp(this.m) >= 0)
2060
res.isub(this.m);
2061
return res;
2062
};
2063
2064
Red.prototype.sub = function sub(a, b) {
2065
this._verify2(a, b);
2066
2067
var res = a.sub(b);
2068
if (res.cmpn(0) < 0)
2069
res.iadd(this.m);
2070
return res._forceRed(this);
2071
};
2072
2073
Red.prototype.isub = function isub(a, b) {
2074
this._verify2(a, b);
2075
2076
var res = a.isub(b);
2077
if (res.cmpn(0) < 0)
2078
res.iadd(this.m);
2079
return res;
2080
};
2081
2082
Red.prototype.shl = function shl(a, num) {
2083
this._verify1(a);
2084
return this.imod(a.shln(num));
2085
};
2086
2087
Red.prototype.imul = function imul(a, b) {
2088
this._verify2(a, b);
2089
return this.imod(a.imul(b));
2090
};
2091
2092
Red.prototype.mul = function mul(a, b) {
2093
this._verify2(a, b);
2094
return this.imod(a.mul(b));
2095
};
2096
2097
Red.prototype.isqr = function isqr(a) {
2098
return this.imul(a, a);
2099
};
2100
2101
Red.prototype.sqr = function sqr(a) {
2102
return this.mul(a, a);
2103
};
2104
2105
Red.prototype.sqrt = function sqrt(a) {
2106
if (a.cmpn(0) === 0)
2107
return a.clone();
2108
2109
var mod3 = this.m.andln(3);
2110
assert(mod3 % 2 === 1);
2111
2112
// Fast case
2113
if (mod3 === 3) {
2114
var pow = this.m.add(new BN(1)).ishrn(2);
2115
var r = this.pow(a, pow);
2116
return r;
2117
}
2118
2119
// Tonelli-Shanks algorithm (Totally unoptimized and slow)
2120
//
2121
// Find Q and S, that Q * 2 ^ S = (P - 1)
2122
var q = this.m.subn(1);
2123
var s = 0;
2124
while (q.cmpn(0) !== 0 && q.andln(1) === 0) {
2125
s++;
2126
q.ishrn(1);
2127
}
2128
assert(q.cmpn(0) !== 0);
2129
2130
var one = new BN(1).toRed(this);
2131
var nOne = one.redNeg();
2132
2133
// Find quadratic non-residue
2134
// NOTE: Max is such because of generalized Riemann hypothesis.
2135
var lpow = this.m.subn(1).ishrn(1);
2136
var z = this.m.bitLength();
2137
z = new BN(2 * z * z).toRed(this);
2138
while (this.pow(z, lpow).cmp(nOne) !== 0)
2139
z.redIAdd(nOne);
2140
2141
var c = this.pow(z, q);
2142
var r = this.pow(a, q.addn(1).ishrn(1));
2143
var t = this.pow(a, q);
2144
var m = s;
2145
while (t.cmp(one) !== 0) {
2146
var tmp = t;
2147
for (var i = 0; tmp.cmp(one) !== 0; i++)
2148
tmp = tmp.redSqr();
2149
assert(i < m);
2150
var b = this.pow(c, new BN(1).ishln(m - i - 1));
2151
2152
r = r.redMul(b);
2153
c = b.redSqr();
2154
t = t.redMul(c);
2155
m = i;
2156
}
2157
2158
return r;
2159
};
2160
2161
Red.prototype.invm = function invm(a) {
2162
var inv = a._invmp(this.m);
2163
if (inv.sign) {
2164
inv.sign = false;
2165
return this.imod(inv).redNeg();
2166
} else {
2167
return this.imod(inv);
2168
}
2169
};
2170
2171
Red.prototype.pow = function pow(a, num) {
2172
var w = [];
2173
2174
if (num.cmpn(0) === 0)
2175
return new BN(1);
2176
2177
var q = num.clone();
2178
2179
while (q.cmpn(0) !== 0) {
2180
w.push(q.andln(1));
2181
q.ishrn(1);
2182
}
2183
2184
// Skip leading zeroes
2185
var res = a;
2186
for (var i = 0; i < w.length; i++, res = this.sqr(res))
2187
if (w[i] !== 0)
2188
break;
2189
2190
if (++i < w.length) {
2191
for (var q = this.sqr(res); i < w.length; i++, q = this.sqr(q)) {
2192
if (w[i] === 0)
2193
continue;
2194
res = this.mul(res, q);
2195
}
2196
}
2197
2198
return res;
2199
};
2200
2201
Red.prototype.convertTo = function convertTo(num) {
2202
var r = num.mod(this.m);
2203
if (r === num)
2204
return r.clone();
2205
else
2206
return r;
2207
};
2208
2209
Red.prototype.convertFrom = function convertFrom(num) {
2210
var res = num.clone();
2211
res.red = null;
2212
return res;
2213
};
2214
2215
//
2216
// Montgomery method engine
2217
//
2218
2219
BN.mont = function mont(num) {
2220
return new Mont(num);
2221
};
2222
2223
function Mont(m) {
2224
Red.call(this, m);
2225
2226
this.shift = this.m.bitLength();
2227
if (this.shift % 26 !== 0)
2228
this.shift += 26 - (this.shift % 26);
2229
this.r = new BN(1).ishln(this.shift);
2230
this.r2 = this.imod(this.r.sqr());
2231
this.rinv = this.r._invmp(this.m);
2232
2233
this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
2234
this.minv.sign = true;
2235
this.minv = this.minv.mod(this.r);
2236
}
2237
inherits(Mont, Red);
2238
2239
Mont.prototype.convertTo = function convertTo(num) {
2240
return this.imod(num.shln(this.shift));
2241
};
2242
2243
Mont.prototype.convertFrom = function convertFrom(num) {
2244
var r = this.imod(num.mul(this.rinv));
2245
r.red = null;
2246
return r;
2247
};
2248
2249
Mont.prototype.imul = function imul(a, b) {
2250
if (a.cmpn(0) === 0 || b.cmpn(0) === 0) {
2251
a.words[0] = 0;
2252
a.length = 1;
2253
return a;
2254
}
2255
2256
var t = a.imul(b);
2257
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
2258
var u = t.isub(c).ishrn(this.shift);
2259
var res = u;
2260
if (u.cmp(this.m) >= 0)
2261
res = u.isub(this.m);
2262
else if (u.cmpn(0) < 0)
2263
res = u.iadd(this.m);
2264
2265
return res._forceRed(this);
2266
};
2267
2268
Mont.prototype.mul = function mul(a, b) {
2269
if (a.cmpn(0) === 0 || b.cmpn(0) === 0)
2270
return new BN(0)._forceRed(this);
2271
2272
var t = a.mul(b);
2273
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
2274
var u = t.isub(c).ishrn(this.shift);
2275
var res = u;
2276
if (u.cmp(this.m) >= 0)
2277
res = u.isub(this.m);
2278
else if (u.cmpn(0) < 0)
2279
res = u.iadd(this.m);
2280
2281
return res._forceRed(this);
2282
};
2283
2284
Mont.prototype.invm = function invm(a) {
2285
// (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
2286
var res = this.imod(a._invmp(this.m).mul(this.r2));
2287
return res._forceRed(this);
2288
};
2289
2290
})(typeof module === 'undefined' || module, this);
2291
2292