Projekt

Obecné

Profil

Stáhnout (85.2 KB) Statistiky
| Větev: | Revize:
1
(function (module, exports) {
2
  'use strict';
3

    
4
  // Utils
5
  function assert (val, msg) {
6
    if (!val) throw new Error(msg || 'Assertion failed');
7
  }
8

    
9
  // Could use `inherits` module, but don't want to move from single file
10
  // architecture yet.
11
  function inherits (ctor, superCtor) {
12
    ctor.super_ = superCtor;
13
    var TempCtor = function () {};
14
    TempCtor.prototype = superCtor.prototype;
15
    ctor.prototype = new TempCtor();
16
    ctor.prototype.constructor = ctor;
17
  }
18

    
19
  // BN
20

    
21
  function BN (number, base, endian) {
22
    if (BN.isBN(number)) {
23
      return number;
24
    }
25

    
26
    this.negative = 0;
27
    this.words = null;
28
    this.length = 0;
29

    
30
    // Reduction context
31
    this.red = null;
32

    
33
    if (number !== null) {
34
      if (base === 'le' || base === 'be') {
35
        endian = base;
36
        base = 10;
37
      }
38

    
39
      this._init(number || 0, base || 10, endian || 'be');
40
    }
41
  }
42
  if (typeof module === 'object') {
43
    module.exports = BN;
44
  } else {
45
    exports.BN = BN;
46
  }
47

    
48
  BN.BN = BN;
49
  BN.wordSize = 26;
50

    
51
  var Buffer;
52
  try {
53
    Buffer = require('buffer').Buffer;
54
  } catch (e) {
55
  }
56

    
57
  BN.isBN = function isBN (num) {
58
    if (num instanceof BN) {
59
      return true;
60
    }
61

    
62
    return num !== null && typeof num === 'object' &&
63
      num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
64
  };
65

    
66
  BN.max = function max (left, right) {
67
    if (left.cmp(right) > 0) return left;
68
    return right;
69
  };
70

    
71
  BN.min = function min (left, right) {
72
    if (left.cmp(right) < 0) return left;
73
    return right;
74
  };
75

    
76
  BN.prototype._init = function init (number, base, endian) {
77
    if (typeof number === 'number') {
78
      return this._initNumber(number, base, endian);
79
    }
80

    
81
    if (typeof number === 'object') {
82
      return this._initArray(number, base, endian);
83
    }
84

    
85
    if (base === 'hex') {
86
      base = 16;
87
    }
88
    assert(base === (base | 0) && base >= 2 && base <= 36);
89

    
90
    number = number.toString().replace(/\s+/g, '');
91
    var start = 0;
92
    if (number[0] === '-') {
93
      start++;
94
    }
95

    
96
    if (base === 16) {
97
      this._parseHex(number, start);
98
    } else {
99
      this._parseBase(number, base, start);
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
  };
112

    
113
  BN.prototype._initNumber = function _initNumber (number, base, endian) {
114
    if (number < 0) {
115
      this.negative = 1;
116
      number = -number;
117
    }
118
    if (number < 0x4000000) {
119
      this.words = [ number & 0x3ffffff ];
120
      this.length = 1;
121
    } else if (number < 0x10000000000000) {
122
      this.words = [
123
        number & 0x3ffffff,
124
        (number / 0x4000000) & 0x3ffffff
125
      ];
126
      this.length = 2;
127
    } else {
128
      assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
129
      this.words = [
130
        number & 0x3ffffff,
131
        (number / 0x4000000) & 0x3ffffff,
132
        1
133
      ];
134
      this.length = 3;
135
    }
136

    
137
    if (endian !== 'le') return;
138

    
139
    // Reverse the bytes
140
    this._initArray(this.toArray(), base, endian);
141
  };
142

    
143
  BN.prototype._initArray = function _initArray (number, base, endian) {
144
    // Perhaps a Uint8Array
145
    assert(typeof number.length === 'number');
146
    if (number.length <= 0) {
147
      this.words = [ 0 ];
148
      this.length = 1;
149
      return this;
150
    }
151

    
152
    this.length = Math.ceil(number.length / 3);
153
    this.words = new Array(this.length);
154
    for (var i = 0; i < this.length; i++) {
155
      this.words[i] = 0;
156
    }
157

    
158
    var j, w;
159
    var off = 0;
160
    if (endian === 'be') {
161
      for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
162
        w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
163
        this.words[j] |= (w << off) & 0x3ffffff;
164
        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
165
        off += 24;
166
        if (off >= 26) {
167
          off -= 26;
168
          j++;
169
        }
170
      }
171
    } else if (endian === 'le') {
172
      for (i = 0, j = 0; i < number.length; i += 3) {
173
        w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
174
        this.words[j] |= (w << off) & 0x3ffffff;
175
        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
176
        off += 24;
177
        if (off >= 26) {
178
          off -= 26;
179
          j++;
180
        }
181
      }
182
    }
183
    return this.strip();
184
  };
185

    
186
  function parseHex (str, start, end) {
187
    var r = 0;
188
    var len = Math.min(str.length, end);
189
    for (var i = start; i < len; i++) {
190
      var c = str.charCodeAt(i) - 48;
191

    
192
      r <<= 4;
193

    
194
      // 'a' - 'f'
195
      if (c >= 49 && c <= 54) {
196
        r |= c - 49 + 0xa;
197

    
198
      // 'A' - 'F'
199
      } else if (c >= 17 && c <= 22) {
200
        r |= c - 17 + 0xa;
201

    
202
      // '0' - '9'
203
      } else {
204
        r |= c & 0xf;
205
      }
206
    }
207
    return r;
208
  }
209

    
210
  BN.prototype._parseHex = function _parseHex (number, start) {
211
    // Create possibly bigger array to ensure that it fits the number
212
    this.length = Math.ceil((number.length - start) / 6);
213
    this.words = new Array(this.length);
214
    for (var i = 0; i < this.length; i++) {
215
      this.words[i] = 0;
216
    }
217

    
218
    var j, w;
219
    // Scan 24-bit chunks and add them to the number
220
    var off = 0;
221
    for (i = number.length - 6, j = 0; i >= start; i -= 6) {
222
      w = parseHex(number, i, i + 6);
223
      this.words[j] |= (w << off) & 0x3ffffff;
224
      // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
225
      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
226
      off += 24;
227
      if (off >= 26) {
228
        off -= 26;
229
        j++;
230
      }
231
    }
232
    if (i + 6 !== start) {
233
      w = parseHex(number, start, i + 6);
234
      this.words[j] |= (w << off) & 0x3ffffff;
235
      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
236
    }
237
    this.strip();
238
  };
239

    
240
  function parseBase (str, start, end, mul) {
241
    var r = 0;
242
    var len = Math.min(str.length, end);
243
    for (var i = start; i < len; i++) {
244
      var c = str.charCodeAt(i) - 48;
245

    
246
      r *= mul;
247

    
248
      // 'a'
249
      if (c >= 49) {
250
        r += c - 49 + 0xa;
251

    
252
      // 'A'
253
      } else if (c >= 17) {
254
        r += c - 17 + 0xa;
255

    
256
      // '0' - '9'
257
      } else {
258
        r += c;
259
      }
260
    }
261
    return r;
262
  }
263

    
264
  BN.prototype._parseBase = function _parseBase (number, base, start) {
265
    // Initialize as zero
266
    this.words = [ 0 ];
267
    this.length = 1;
268

    
269
    // Find length of limb in base
270
    for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
271
      limbLen++;
272
    }
273
    limbLen--;
274
    limbPow = (limbPow / base) | 0;
275

    
276
    var total = number.length - start;
277
    var mod = total % limbLen;
278
    var end = Math.min(total, total - mod) + start;
279

    
280
    var word = 0;
281
    for (var i = start; i < end; i += limbLen) {
282
      word = parseBase(number, i, i + limbLen, base);
283

    
284
      this.imuln(limbPow);
285
      if (this.words[0] + word < 0x4000000) {
286
        this.words[0] += word;
287
      } else {
288
        this._iaddn(word);
289
      }
290
    }
291

    
292
    if (mod !== 0) {
293
      var pow = 1;
294
      word = parseBase(number, i, number.length, base);
295

    
296
      for (i = 0; i < mod; i++) {
297
        pow *= base;
298
      }
299

    
300
      this.imuln(pow);
301
      if (this.words[0] + word < 0x4000000) {
302
        this.words[0] += word;
303
      } else {
304
        this._iaddn(word);
305
      }
306
    }
307
  };
308

    
309
  BN.prototype.copy = function copy (dest) {
310
    dest.words = new Array(this.length);
311
    for (var i = 0; i < this.length; i++) {
312
      dest.words[i] = this.words[i];
313
    }
314
    dest.length = this.length;
315
    dest.negative = this.negative;
316
    dest.red = this.red;
317
  };
318

    
319
  BN.prototype.clone = function clone () {
320
    var r = new BN(null);
321
    this.copy(r);
322
    return r;
323
  };
324

    
325
  BN.prototype._expand = function _expand (size) {
326
    while (this.length < size) {
327
      this.words[this.length++] = 0;
328
    }
329
    return this;
330
  };
331

    
332
  // Remove leading `0` from `this`
333
  BN.prototype.strip = function strip () {
334
    while (this.length > 1 && this.words[this.length - 1] === 0) {
335
      this.length--;
336
    }
337
    return this._normSign();
338
  };
339

    
340
  BN.prototype._normSign = function _normSign () {
341
    // -0 = 0
342
    if (this.length === 1 && this.words[0] === 0) {
343
      this.negative = 0;
344
    }
345
    return this;
346
  };
347

    
348
  BN.prototype.inspect = function inspect () {
349
    return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
350
  };
351

    
352
  /*
353

    
354
  var zeros = [];
355
  var groupSizes = [];
356
  var groupBases = [];
357

    
358
  var s = '';
359
  var i = -1;
360
  while (++i < BN.wordSize) {
361
    zeros[i] = s;
362
    s += '0';
363
  }
364
  groupSizes[0] = 0;
365
  groupSizes[1] = 0;
366
  groupBases[0] = 0;
367
  groupBases[1] = 0;
368
  var base = 2 - 1;
369
  while (++base < 36 + 1) {
370
    var groupSize = 0;
371
    var groupBase = 1;
372
    while (groupBase < (1 << BN.wordSize) / base) {
373
      groupBase *= base;
374
      groupSize += 1;
375
    }
376
    groupSizes[base] = groupSize;
377
    groupBases[base] = groupBase;
378
  }
379

    
380
  */
381

    
382
  var zeros = [
383
    '',
384
    '0',
385
    '00',
386
    '000',
387
    '0000',
388
    '00000',
389
    '000000',
390
    '0000000',
391
    '00000000',
392
    '000000000',
393
    '0000000000',
394
    '00000000000',
395
    '000000000000',
396
    '0000000000000',
397
    '00000000000000',
398
    '000000000000000',
399
    '0000000000000000',
400
    '00000000000000000',
401
    '000000000000000000',
402
    '0000000000000000000',
403
    '00000000000000000000',
404
    '000000000000000000000',
405
    '0000000000000000000000',
406
    '00000000000000000000000',
407
    '000000000000000000000000',
408
    '0000000000000000000000000'
409
  ];
410

    
411
  var groupSizes = [
412
    0, 0,
413
    25, 16, 12, 11, 10, 9, 8,
414
    8, 7, 7, 7, 7, 6, 6,
415
    6, 6, 6, 6, 6, 5, 5,
416
    5, 5, 5, 5, 5, 5, 5,
417
    5, 5, 5, 5, 5, 5, 5
418
  ];
419

    
420
  var groupBases = [
421
    0, 0,
422
    33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
423
    43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
424
    16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
425
    6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
426
    24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
427
  ];
428

    
429
  BN.prototype.toString = function toString (base, padding) {
430
    base = base || 10;
431
    padding = padding | 0 || 1;
432

    
433
    var out;
434
    if (base === 16 || base === 'hex') {
435
      out = '';
436
      var off = 0;
437
      var carry = 0;
438
      for (var i = 0; i < this.length; i++) {
439
        var w = this.words[i];
440
        var word = (((w << off) | carry) & 0xffffff).toString(16);
441
        carry = (w >>> (24 - off)) & 0xffffff;
442
        if (carry !== 0 || i !== this.length - 1) {
443
          out = zeros[6 - word.length] + word + out;
444
        } else {
445
          out = word + out;
446
        }
447
        off += 2;
448
        if (off >= 26) {
449
          off -= 26;
450
          i--;
451
        }
452
      }
453
      if (carry !== 0) {
454
        out = carry.toString(16) + out;
455
      }
456
      while (out.length % padding !== 0) {
457
        out = '0' + out;
458
      }
459
      if (this.negative !== 0) {
460
        out = '-' + out;
461
      }
462
      return out;
463
    }
464

    
465
    if (base === (base | 0) && base >= 2 && base <= 36) {
466
      // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
467
      var groupSize = groupSizes[base];
468
      // var groupBase = Math.pow(base, groupSize);
469
      var groupBase = groupBases[base];
470
      out = '';
471
      var c = this.clone();
472
      c.negative = 0;
473
      while (!c.isZero()) {
474
        var r = c.modn(groupBase).toString(base);
475
        c = c.idivn(groupBase);
476

    
477
        if (!c.isZero()) {
478
          out = zeros[groupSize - r.length] + r + out;
479
        } else {
480
          out = r + out;
481
        }
482
      }
483
      if (this.isZero()) {
484
        out = '0' + out;
485
      }
486
      while (out.length % padding !== 0) {
487
        out = '0' + out;
488
      }
489
      if (this.negative !== 0) {
490
        out = '-' + out;
491
      }
492
      return out;
493
    }
494

    
495
    assert(false, 'Base should be between 2 and 36');
496
  };
497

    
498
  BN.prototype.toNumber = function toNumber () {
499
    var ret = this.words[0];
500
    if (this.length === 2) {
501
      ret += this.words[1] * 0x4000000;
502
    } else if (this.length === 3 && this.words[2] === 0x01) {
503
      // NOTE: at this stage it is known that the top bit is set
504
      ret += 0x10000000000000 + (this.words[1] * 0x4000000);
505
    } else if (this.length > 2) {
506
      assert(false, 'Number can only safely store up to 53 bits');
507
    }
508
    return (this.negative !== 0) ? -ret : ret;
509
  };
510

    
511
  BN.prototype.toJSON = function toJSON () {
512
    return this.toString(16);
513
  };
514

    
515
  BN.prototype.toBuffer = function toBuffer (endian, length) {
516
    assert(typeof Buffer !== 'undefined');
517
    return this.toArrayLike(Buffer, endian, length);
518
  };
519

    
520
  BN.prototype.toArray = function toArray (endian, length) {
521
    return this.toArrayLike(Array, endian, length);
522
  };
523

    
524
  BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
525
    var byteLength = this.byteLength();
526
    var reqLength = length || Math.max(1, byteLength);
527
    assert(byteLength <= reqLength, 'byte array longer than desired length');
528
    assert(reqLength > 0, 'Requested array length <= 0');
529

    
530
    this.strip();
531
    var littleEndian = endian === 'le';
532
    var res = new ArrayType(reqLength);
533

    
534
    var b, i;
535
    var q = this.clone();
536
    if (!littleEndian) {
537
      // Assume big-endian
538
      for (i = 0; i < reqLength - byteLength; i++) {
539
        res[i] = 0;
540
      }
541

    
542
      for (i = 0; !q.isZero(); i++) {
543
        b = q.andln(0xff);
544
        q.iushrn(8);
545

    
546
        res[reqLength - i - 1] = b;
547
      }
548
    } else {
549
      for (i = 0; !q.isZero(); i++) {
550
        b = q.andln(0xff);
551
        q.iushrn(8);
552

    
553
        res[i] = b;
554
      }
555

    
556
      for (; i < reqLength; i++) {
557
        res[i] = 0;
558
      }
559
    }
560

    
561
    return res;
562
  };
563

    
564
  if (Math.clz32) {
565
    BN.prototype._countBits = function _countBits (w) {
566
      return 32 - Math.clz32(w);
567
    };
568
  } else {
569
    BN.prototype._countBits = function _countBits (w) {
570
      var t = w;
571
      var r = 0;
572
      if (t >= 0x1000) {
573
        r += 13;
574
        t >>>= 13;
575
      }
576
      if (t >= 0x40) {
577
        r += 7;
578
        t >>>= 7;
579
      }
580
      if (t >= 0x8) {
581
        r += 4;
582
        t >>>= 4;
583
      }
584
      if (t >= 0x02) {
585
        r += 2;
586
        t >>>= 2;
587
      }
588
      return r + t;
589
    };
590
  }
591

    
592
  BN.prototype._zeroBits = function _zeroBits (w) {
593
    // Short-cut
594
    if (w === 0) return 26;
595

    
596
    var t = w;
597
    var r = 0;
598
    if ((t & 0x1fff) === 0) {
599
      r += 13;
600
      t >>>= 13;
601
    }
602
    if ((t & 0x7f) === 0) {
603
      r += 7;
604
      t >>>= 7;
605
    }
606
    if ((t & 0xf) === 0) {
607
      r += 4;
608
      t >>>= 4;
609
    }
610
    if ((t & 0x3) === 0) {
611
      r += 2;
612
      t >>>= 2;
613
    }
614
    if ((t & 0x1) === 0) {
615
      r++;
616
    }
617
    return r;
618
  };
619

    
620
  // Return number of used bits in a BN
621
  BN.prototype.bitLength = function bitLength () {
622
    var w = this.words[this.length - 1];
623
    var hi = this._countBits(w);
624
    return (this.length - 1) * 26 + hi;
625
  };
626

    
627
  function toBitArray (num) {
628
    var w = new Array(num.bitLength());
629

    
630
    for (var bit = 0; bit < w.length; bit++) {
631
      var off = (bit / 26) | 0;
632
      var wbit = bit % 26;
633

    
634
      w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
635
    }
636

    
637
    return w;
638
  }
639

    
640
  // Number of trailing zero bits
641
  BN.prototype.zeroBits = function zeroBits () {
642
    if (this.isZero()) return 0;
643

    
644
    var r = 0;
645
    for (var i = 0; i < this.length; i++) {
646
      var b = this._zeroBits(this.words[i]);
647
      r += b;
648
      if (b !== 26) break;
649
    }
650
    return r;
651
  };
652

    
653
  BN.prototype.byteLength = function byteLength () {
654
    return Math.ceil(this.bitLength() / 8);
655
  };
656

    
657
  BN.prototype.toTwos = function toTwos (width) {
658
    if (this.negative !== 0) {
659
      return this.abs().inotn(width).iaddn(1);
660
    }
661
    return this.clone();
662
  };
663

    
664
  BN.prototype.fromTwos = function fromTwos (width) {
665
    if (this.testn(width - 1)) {
666
      return this.notn(width).iaddn(1).ineg();
667
    }
668
    return this.clone();
669
  };
670

    
671
  BN.prototype.isNeg = function isNeg () {
672
    return this.negative !== 0;
673
  };
674

    
675
  // Return negative clone of `this`
676
  BN.prototype.neg = function neg () {
677
    return this.clone().ineg();
678
  };
679

    
680
  BN.prototype.ineg = function ineg () {
681
    if (!this.isZero()) {
682
      this.negative ^= 1;
683
    }
684

    
685
    return this;
686
  };
687

    
688
  // Or `num` with `this` in-place
689
  BN.prototype.iuor = function iuor (num) {
690
    while (this.length < num.length) {
691
      this.words[this.length++] = 0;
692
    }
693

    
694
    for (var i = 0; i < num.length; i++) {
695
      this.words[i] = this.words[i] | num.words[i];
696
    }
697

    
698
    return this.strip();
699
  };
700

    
701
  BN.prototype.ior = function ior (num) {
702
    assert((this.negative | num.negative) === 0);
703
    return this.iuor(num);
704
  };
705

    
706
  // Or `num` with `this`
707
  BN.prototype.or = function or (num) {
708
    if (this.length > num.length) return this.clone().ior(num);
709
    return num.clone().ior(this);
710
  };
711

    
712
  BN.prototype.uor = function uor (num) {
713
    if (this.length > num.length) return this.clone().iuor(num);
714
    return num.clone().iuor(this);
715
  };
716

    
717
  // And `num` with `this` in-place
718
  BN.prototype.iuand = function iuand (num) {
719
    // b = min-length(num, this)
720
    var b;
721
    if (this.length > num.length) {
722
      b = num;
723
    } else {
724
      b = this;
725
    }
726

    
727
    for (var i = 0; i < b.length; i++) {
728
      this.words[i] = this.words[i] & num.words[i];
729
    }
730

    
731
    this.length = b.length;
732

    
733
    return this.strip();
734
  };
735

    
736
  BN.prototype.iand = function iand (num) {
737
    assert((this.negative | num.negative) === 0);
738
    return this.iuand(num);
739
  };
740

    
741
  // And `num` with `this`
742
  BN.prototype.and = function and (num) {
743
    if (this.length > num.length) return this.clone().iand(num);
744
    return num.clone().iand(this);
745
  };
746

    
747
  BN.prototype.uand = function uand (num) {
748
    if (this.length > num.length) return this.clone().iuand(num);
749
    return num.clone().iuand(this);
750
  };
751

    
752
  // Xor `num` with `this` in-place
753
  BN.prototype.iuxor = function iuxor (num) {
754
    // a.length > b.length
755
    var a;
756
    var b;
757
    if (this.length > num.length) {
758
      a = this;
759
      b = num;
760
    } else {
761
      a = num;
762
      b = this;
763
    }
764

    
765
    for (var i = 0; i < b.length; i++) {
766
      this.words[i] = a.words[i] ^ b.words[i];
767
    }
768

    
769
    if (this !== a) {
770
      for (; i < a.length; i++) {
771
        this.words[i] = a.words[i];
772
      }
773
    }
774

    
775
    this.length = a.length;
776

    
777
    return this.strip();
778
  };
779

    
780
  BN.prototype.ixor = function ixor (num) {
781
    assert((this.negative | num.negative) === 0);
782
    return this.iuxor(num);
783
  };
784

    
785
  // Xor `num` with `this`
786
  BN.prototype.xor = function xor (num) {
787
    if (this.length > num.length) return this.clone().ixor(num);
788
    return num.clone().ixor(this);
789
  };
790

    
791
  BN.prototype.uxor = function uxor (num) {
792
    if (this.length > num.length) return this.clone().iuxor(num);
793
    return num.clone().iuxor(this);
794
  };
795

    
796
  // Not ``this`` with ``width`` bitwidth
797
  BN.prototype.inotn = function inotn (width) {
798
    assert(typeof width === 'number' && width >= 0);
799

    
800
    var bytesNeeded = Math.ceil(width / 26) | 0;
801
    var bitsLeft = width % 26;
802

    
803
    // Extend the buffer with leading zeroes
804
    this._expand(bytesNeeded);
805

    
806
    if (bitsLeft > 0) {
807
      bytesNeeded--;
808
    }
809

    
810
    // Handle complete words
811
    for (var i = 0; i < bytesNeeded; i++) {
812
      this.words[i] = ~this.words[i] & 0x3ffffff;
813
    }
814

    
815
    // Handle the residue
816
    if (bitsLeft > 0) {
817
      this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
818
    }
819

    
820
    // And remove leading zeroes
821
    return this.strip();
822
  };
823

    
824
  BN.prototype.notn = function notn (width) {
825
    return this.clone().inotn(width);
826
  };
827

    
828
  // Set `bit` of `this`
829
  BN.prototype.setn = function setn (bit, val) {
830
    assert(typeof bit === 'number' && bit >= 0);
831

    
832
    var off = (bit / 26) | 0;
833
    var wbit = bit % 26;
834

    
835
    this._expand(off + 1);
836

    
837
    if (val) {
838
      this.words[off] = this.words[off] | (1 << wbit);
839
    } else {
840
      this.words[off] = this.words[off] & ~(1 << wbit);
841
    }
842

    
843
    return this.strip();
844
  };
845

    
846
  // Add `num` to `this` in-place
847
  BN.prototype.iadd = function iadd (num) {
848
    var r;
849

    
850
    // negative + positive
851
    if (this.negative !== 0 && num.negative === 0) {
852
      this.negative = 0;
853
      r = this.isub(num);
854
      this.negative ^= 1;
855
      return this._normSign();
856

    
857
    // positive + negative
858
    } else if (this.negative === 0 && num.negative !== 0) {
859
      num.negative = 0;
860
      r = this.isub(num);
861
      num.negative = 1;
862
      return r._normSign();
863
    }
864

    
865
    // a.length > b.length
866
    var a, b;
867
    if (this.length > num.length) {
868
      a = this;
869
      b = num;
870
    } else {
871
      a = num;
872
      b = this;
873
    }
874

    
875
    var carry = 0;
876
    for (var i = 0; i < b.length; i++) {
877
      r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
878
      this.words[i] = r & 0x3ffffff;
879
      carry = r >>> 26;
880
    }
881
    for (; carry !== 0 && i < a.length; i++) {
882
      r = (a.words[i] | 0) + carry;
883
      this.words[i] = r & 0x3ffffff;
884
      carry = r >>> 26;
885
    }
886

    
887
    this.length = a.length;
888
    if (carry !== 0) {
889
      this.words[this.length] = carry;
890
      this.length++;
891
    // Copy the rest of the words
892
    } else if (a !== this) {
893
      for (; i < a.length; i++) {
894
        this.words[i] = a.words[i];
895
      }
896
    }
897

    
898
    return this;
899
  };
900

    
901
  // Add `num` to `this`
902
  BN.prototype.add = function add (num) {
903
    var res;
904
    if (num.negative !== 0 && this.negative === 0) {
905
      num.negative = 0;
906
      res = this.sub(num);
907
      num.negative ^= 1;
908
      return res;
909
    } else if (num.negative === 0 && this.negative !== 0) {
910
      this.negative = 0;
911
      res = num.sub(this);
912
      this.negative = 1;
913
      return res;
914
    }
915

    
916
    if (this.length > num.length) return this.clone().iadd(num);
917

    
918
    return num.clone().iadd(this);
919
  };
920

    
921
  // Subtract `num` from `this` in-place
922
  BN.prototype.isub = function isub (num) {
923
    // this - (-num) = this + num
924
    if (num.negative !== 0) {
925
      num.negative = 0;
926
      var r = this.iadd(num);
927
      num.negative = 1;
928
      return r._normSign();
929

    
930
    // -this - num = -(this + num)
931
    } else if (this.negative !== 0) {
932
      this.negative = 0;
933
      this.iadd(num);
934
      this.negative = 1;
935
      return this._normSign();
936
    }
937

    
938
    // At this point both numbers are positive
939
    var cmp = this.cmp(num);
940

    
941
    // Optimization - zeroify
942
    if (cmp === 0) {
943
      this.negative = 0;
944
      this.length = 1;
945
      this.words[0] = 0;
946
      return this;
947
    }
948

    
949
    // a > b
950
    var a, b;
951
    if (cmp > 0) {
952
      a = this;
953
      b = num;
954
    } else {
955
      a = num;
956
      b = this;
957
    }
958

    
959
    var carry = 0;
960
    for (var i = 0; i < b.length; i++) {
961
      r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
962
      carry = r >> 26;
963
      this.words[i] = r & 0x3ffffff;
964
    }
965
    for (; carry !== 0 && i < a.length; i++) {
966
      r = (a.words[i] | 0) + carry;
967
      carry = r >> 26;
968
      this.words[i] = r & 0x3ffffff;
969
    }
970

    
971
    // Copy rest of the words
972
    if (carry === 0 && i < a.length && a !== this) {
973
      for (; i < a.length; i++) {
974
        this.words[i] = a.words[i];
975
      }
976
    }
977

    
978
    this.length = Math.max(this.length, i);
979

    
980
    if (a !== this) {
981
      this.negative = 1;
982
    }
983

    
984
    return this.strip();
985
  };
986

    
987
  // Subtract `num` from `this`
988
  BN.prototype.sub = function sub (num) {
989
    return this.clone().isub(num);
990
  };
991

    
992
  function smallMulTo (self, num, out) {
993
    out.negative = num.negative ^ self.negative;
994
    var len = (self.length + num.length) | 0;
995
    out.length = len;
996
    len = (len - 1) | 0;
997

    
998
    // Peel one iteration (compiler can't do it, because of code complexity)
999
    var a = self.words[0] | 0;
1000
    var b = num.words[0] | 0;
1001
    var r = a * b;
1002

    
1003
    var lo = r & 0x3ffffff;
1004
    var carry = (r / 0x4000000) | 0;
1005
    out.words[0] = lo;
1006

    
1007
    for (var k = 1; k < len; k++) {
1008
      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
1009
      // note that ncarry could be >= 0x3ffffff
1010
      var ncarry = carry >>> 26;
1011
      var rword = carry & 0x3ffffff;
1012
      var maxJ = Math.min(k, num.length - 1);
1013
      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
1014
        var i = (k - j) | 0;
1015
        a = self.words[i] | 0;
1016
        b = num.words[j] | 0;
1017
        r = a * b + rword;
1018
        ncarry += (r / 0x4000000) | 0;
1019
        rword = r & 0x3ffffff;
1020
      }
1021
      out.words[k] = rword | 0;
1022
      carry = ncarry | 0;
1023
    }
1024
    if (carry !== 0) {
1025
      out.words[k] = carry | 0;
1026
    } else {
1027
      out.length--;
1028
    }
1029

    
1030
    return out.strip();
1031
  }
1032

    
1033
  // TODO(indutny): it may be reasonable to omit it for users who don't need
1034
  // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
1035
  // multiplication (like elliptic secp256k1).
1036
  var comb10MulTo = function comb10MulTo (self, num, out) {
1037
    var a = self.words;
1038
    var b = num.words;
1039
    var o = out.words;
1040
    var c = 0;
1041
    var lo;
1042
    var mid;
1043
    var hi;
1044
    var a0 = a[0] | 0;
1045
    var al0 = a0 & 0x1fff;
1046
    var ah0 = a0 >>> 13;
1047
    var a1 = a[1] | 0;
1048
    var al1 = a1 & 0x1fff;
1049
    var ah1 = a1 >>> 13;
1050
    var a2 = a[2] | 0;
1051
    var al2 = a2 & 0x1fff;
1052
    var ah2 = a2 >>> 13;
1053
    var a3 = a[3] | 0;
1054
    var al3 = a3 & 0x1fff;
1055
    var ah3 = a3 >>> 13;
1056
    var a4 = a[4] | 0;
1057
    var al4 = a4 & 0x1fff;
1058
    var ah4 = a4 >>> 13;
1059
    var a5 = a[5] | 0;
1060
    var al5 = a5 & 0x1fff;
1061
    var ah5 = a5 >>> 13;
1062
    var a6 = a[6] | 0;
1063
    var al6 = a6 & 0x1fff;
1064
    var ah6 = a6 >>> 13;
1065
    var a7 = a[7] | 0;
1066
    var al7 = a7 & 0x1fff;
1067
    var ah7 = a7 >>> 13;
1068
    var a8 = a[8] | 0;
1069
    var al8 = a8 & 0x1fff;
1070
    var ah8 = a8 >>> 13;
1071
    var a9 = a[9] | 0;
1072
    var al9 = a9 & 0x1fff;
1073
    var ah9 = a9 >>> 13;
1074
    var b0 = b[0] | 0;
1075
    var bl0 = b0 & 0x1fff;
1076
    var bh0 = b0 >>> 13;
1077
    var b1 = b[1] | 0;
1078
    var bl1 = b1 & 0x1fff;
1079
    var bh1 = b1 >>> 13;
1080
    var b2 = b[2] | 0;
1081
    var bl2 = b2 & 0x1fff;
1082
    var bh2 = b2 >>> 13;
1083
    var b3 = b[3] | 0;
1084
    var bl3 = b3 & 0x1fff;
1085
    var bh3 = b3 >>> 13;
1086
    var b4 = b[4] | 0;
1087
    var bl4 = b4 & 0x1fff;
1088
    var bh4 = b4 >>> 13;
1089
    var b5 = b[5] | 0;
1090
    var bl5 = b5 & 0x1fff;
1091
    var bh5 = b5 >>> 13;
1092
    var b6 = b[6] | 0;
1093
    var bl6 = b6 & 0x1fff;
1094
    var bh6 = b6 >>> 13;
1095
    var b7 = b[7] | 0;
1096
    var bl7 = b7 & 0x1fff;
1097
    var bh7 = b7 >>> 13;
1098
    var b8 = b[8] | 0;
1099
    var bl8 = b8 & 0x1fff;
1100
    var bh8 = b8 >>> 13;
1101
    var b9 = b[9] | 0;
1102
    var bl9 = b9 & 0x1fff;
1103
    var bh9 = b9 >>> 13;
1104

    
1105
    out.negative = self.negative ^ num.negative;
1106
    out.length = 19;
1107
    /* k = 0 */
1108
    lo = Math.imul(al0, bl0);
1109
    mid = Math.imul(al0, bh0);
1110
    mid = (mid + Math.imul(ah0, bl0)) | 0;
1111
    hi = Math.imul(ah0, bh0);
1112
    var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1113
    c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
1114
    w0 &= 0x3ffffff;
1115
    /* k = 1 */
1116
    lo = Math.imul(al1, bl0);
1117
    mid = Math.imul(al1, bh0);
1118
    mid = (mid + Math.imul(ah1, bl0)) | 0;
1119
    hi = Math.imul(ah1, bh0);
1120
    lo = (lo + Math.imul(al0, bl1)) | 0;
1121
    mid = (mid + Math.imul(al0, bh1)) | 0;
1122
    mid = (mid + Math.imul(ah0, bl1)) | 0;
1123
    hi = (hi + Math.imul(ah0, bh1)) | 0;
1124
    var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1125
    c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
1126
    w1 &= 0x3ffffff;
1127
    /* k = 2 */
1128
    lo = Math.imul(al2, bl0);
1129
    mid = Math.imul(al2, bh0);
1130
    mid = (mid + Math.imul(ah2, bl0)) | 0;
1131
    hi = Math.imul(ah2, bh0);
1132
    lo = (lo + Math.imul(al1, bl1)) | 0;
1133
    mid = (mid + Math.imul(al1, bh1)) | 0;
1134
    mid = (mid + Math.imul(ah1, bl1)) | 0;
1135
    hi = (hi + Math.imul(ah1, bh1)) | 0;
1136
    lo = (lo + Math.imul(al0, bl2)) | 0;
1137
    mid = (mid + Math.imul(al0, bh2)) | 0;
1138
    mid = (mid + Math.imul(ah0, bl2)) | 0;
1139
    hi = (hi + Math.imul(ah0, bh2)) | 0;
1140
    var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1141
    c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
1142
    w2 &= 0x3ffffff;
1143
    /* k = 3 */
1144
    lo = Math.imul(al3, bl0);
1145
    mid = Math.imul(al3, bh0);
1146
    mid = (mid + Math.imul(ah3, bl0)) | 0;
1147
    hi = Math.imul(ah3, bh0);
1148
    lo = (lo + Math.imul(al2, bl1)) | 0;
1149
    mid = (mid + Math.imul(al2, bh1)) | 0;
1150
    mid = (mid + Math.imul(ah2, bl1)) | 0;
1151
    hi = (hi + Math.imul(ah2, bh1)) | 0;
1152
    lo = (lo + Math.imul(al1, bl2)) | 0;
1153
    mid = (mid + Math.imul(al1, bh2)) | 0;
1154
    mid = (mid + Math.imul(ah1, bl2)) | 0;
1155
    hi = (hi + Math.imul(ah1, bh2)) | 0;
1156
    lo = (lo + Math.imul(al0, bl3)) | 0;
1157
    mid = (mid + Math.imul(al0, bh3)) | 0;
1158
    mid = (mid + Math.imul(ah0, bl3)) | 0;
1159
    hi = (hi + Math.imul(ah0, bh3)) | 0;
1160
    var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1161
    c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
1162
    w3 &= 0x3ffffff;
1163
    /* k = 4 */
1164
    lo = Math.imul(al4, bl0);
1165
    mid = Math.imul(al4, bh0);
1166
    mid = (mid + Math.imul(ah4, bl0)) | 0;
1167
    hi = Math.imul(ah4, bh0);
1168
    lo = (lo + Math.imul(al3, bl1)) | 0;
1169
    mid = (mid + Math.imul(al3, bh1)) | 0;
1170
    mid = (mid + Math.imul(ah3, bl1)) | 0;
1171
    hi = (hi + Math.imul(ah3, bh1)) | 0;
1172
    lo = (lo + Math.imul(al2, bl2)) | 0;
1173
    mid = (mid + Math.imul(al2, bh2)) | 0;
1174
    mid = (mid + Math.imul(ah2, bl2)) | 0;
1175
    hi = (hi + Math.imul(ah2, bh2)) | 0;
1176
    lo = (lo + Math.imul(al1, bl3)) | 0;
1177
    mid = (mid + Math.imul(al1, bh3)) | 0;
1178
    mid = (mid + Math.imul(ah1, bl3)) | 0;
1179
    hi = (hi + Math.imul(ah1, bh3)) | 0;
1180
    lo = (lo + Math.imul(al0, bl4)) | 0;
1181
    mid = (mid + Math.imul(al0, bh4)) | 0;
1182
    mid = (mid + Math.imul(ah0, bl4)) | 0;
1183
    hi = (hi + Math.imul(ah0, bh4)) | 0;
1184
    var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1185
    c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
1186
    w4 &= 0x3ffffff;
1187
    /* k = 5 */
1188
    lo = Math.imul(al5, bl0);
1189
    mid = Math.imul(al5, bh0);
1190
    mid = (mid + Math.imul(ah5, bl0)) | 0;
1191
    hi = Math.imul(ah5, bh0);
1192
    lo = (lo + Math.imul(al4, bl1)) | 0;
1193
    mid = (mid + Math.imul(al4, bh1)) | 0;
1194
    mid = (mid + Math.imul(ah4, bl1)) | 0;
1195
    hi = (hi + Math.imul(ah4, bh1)) | 0;
1196
    lo = (lo + Math.imul(al3, bl2)) | 0;
1197
    mid = (mid + Math.imul(al3, bh2)) | 0;
1198
    mid = (mid + Math.imul(ah3, bl2)) | 0;
1199
    hi = (hi + Math.imul(ah3, bh2)) | 0;
1200
    lo = (lo + Math.imul(al2, bl3)) | 0;
1201
    mid = (mid + Math.imul(al2, bh3)) | 0;
1202
    mid = (mid + Math.imul(ah2, bl3)) | 0;
1203
    hi = (hi + Math.imul(ah2, bh3)) | 0;
1204
    lo = (lo + Math.imul(al1, bl4)) | 0;
1205
    mid = (mid + Math.imul(al1, bh4)) | 0;
1206
    mid = (mid + Math.imul(ah1, bl4)) | 0;
1207
    hi = (hi + Math.imul(ah1, bh4)) | 0;
1208
    lo = (lo + Math.imul(al0, bl5)) | 0;
1209
    mid = (mid + Math.imul(al0, bh5)) | 0;
1210
    mid = (mid + Math.imul(ah0, bl5)) | 0;
1211
    hi = (hi + Math.imul(ah0, bh5)) | 0;
1212
    var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1213
    c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
1214
    w5 &= 0x3ffffff;
1215
    /* k = 6 */
1216
    lo = Math.imul(al6, bl0);
1217
    mid = Math.imul(al6, bh0);
1218
    mid = (mid + Math.imul(ah6, bl0)) | 0;
1219
    hi = Math.imul(ah6, bh0);
1220
    lo = (lo + Math.imul(al5, bl1)) | 0;
1221
    mid = (mid + Math.imul(al5, bh1)) | 0;
1222
    mid = (mid + Math.imul(ah5, bl1)) | 0;
1223
    hi = (hi + Math.imul(ah5, bh1)) | 0;
1224
    lo = (lo + Math.imul(al4, bl2)) | 0;
1225
    mid = (mid + Math.imul(al4, bh2)) | 0;
1226
    mid = (mid + Math.imul(ah4, bl2)) | 0;
1227
    hi = (hi + Math.imul(ah4, bh2)) | 0;
1228
    lo = (lo + Math.imul(al3, bl3)) | 0;
1229
    mid = (mid + Math.imul(al3, bh3)) | 0;
1230
    mid = (mid + Math.imul(ah3, bl3)) | 0;
1231
    hi = (hi + Math.imul(ah3, bh3)) | 0;
1232
    lo = (lo + Math.imul(al2, bl4)) | 0;
1233
    mid = (mid + Math.imul(al2, bh4)) | 0;
1234
    mid = (mid + Math.imul(ah2, bl4)) | 0;
1235
    hi = (hi + Math.imul(ah2, bh4)) | 0;
1236
    lo = (lo + Math.imul(al1, bl5)) | 0;
1237
    mid = (mid + Math.imul(al1, bh5)) | 0;
1238
    mid = (mid + Math.imul(ah1, bl5)) | 0;
1239
    hi = (hi + Math.imul(ah1, bh5)) | 0;
1240
    lo = (lo + Math.imul(al0, bl6)) | 0;
1241
    mid = (mid + Math.imul(al0, bh6)) | 0;
1242
    mid = (mid + Math.imul(ah0, bl6)) | 0;
1243
    hi = (hi + Math.imul(ah0, bh6)) | 0;
1244
    var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1245
    c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
1246
    w6 &= 0x3ffffff;
1247
    /* k = 7 */
1248
    lo = Math.imul(al7, bl0);
1249
    mid = Math.imul(al7, bh0);
1250
    mid = (mid + Math.imul(ah7, bl0)) | 0;
1251
    hi = Math.imul(ah7, bh0);
1252
    lo = (lo + Math.imul(al6, bl1)) | 0;
1253
    mid = (mid + Math.imul(al6, bh1)) | 0;
1254
    mid = (mid + Math.imul(ah6, bl1)) | 0;
1255
    hi = (hi + Math.imul(ah6, bh1)) | 0;
1256
    lo = (lo + Math.imul(al5, bl2)) | 0;
1257
    mid = (mid + Math.imul(al5, bh2)) | 0;
1258
    mid = (mid + Math.imul(ah5, bl2)) | 0;
1259
    hi = (hi + Math.imul(ah5, bh2)) | 0;
1260
    lo = (lo + Math.imul(al4, bl3)) | 0;
1261
    mid = (mid + Math.imul(al4, bh3)) | 0;
1262
    mid = (mid + Math.imul(ah4, bl3)) | 0;
1263
    hi = (hi + Math.imul(ah4, bh3)) | 0;
1264
    lo = (lo + Math.imul(al3, bl4)) | 0;
1265
    mid = (mid + Math.imul(al3, bh4)) | 0;
1266
    mid = (mid + Math.imul(ah3, bl4)) | 0;
1267
    hi = (hi + Math.imul(ah3, bh4)) | 0;
1268
    lo = (lo + Math.imul(al2, bl5)) | 0;
1269
    mid = (mid + Math.imul(al2, bh5)) | 0;
1270
    mid = (mid + Math.imul(ah2, bl5)) | 0;
1271
    hi = (hi + Math.imul(ah2, bh5)) | 0;
1272
    lo = (lo + Math.imul(al1, bl6)) | 0;
1273
    mid = (mid + Math.imul(al1, bh6)) | 0;
1274
    mid = (mid + Math.imul(ah1, bl6)) | 0;
1275
    hi = (hi + Math.imul(ah1, bh6)) | 0;
1276
    lo = (lo + Math.imul(al0, bl7)) | 0;
1277
    mid = (mid + Math.imul(al0, bh7)) | 0;
1278
    mid = (mid + Math.imul(ah0, bl7)) | 0;
1279
    hi = (hi + Math.imul(ah0, bh7)) | 0;
1280
    var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1281
    c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
1282
    w7 &= 0x3ffffff;
1283
    /* k = 8 */
1284
    lo = Math.imul(al8, bl0);
1285
    mid = Math.imul(al8, bh0);
1286
    mid = (mid + Math.imul(ah8, bl0)) | 0;
1287
    hi = Math.imul(ah8, bh0);
1288
    lo = (lo + Math.imul(al7, bl1)) | 0;
1289
    mid = (mid + Math.imul(al7, bh1)) | 0;
1290
    mid = (mid + Math.imul(ah7, bl1)) | 0;
1291
    hi = (hi + Math.imul(ah7, bh1)) | 0;
1292
    lo = (lo + Math.imul(al6, bl2)) | 0;
1293
    mid = (mid + Math.imul(al6, bh2)) | 0;
1294
    mid = (mid + Math.imul(ah6, bl2)) | 0;
1295
    hi = (hi + Math.imul(ah6, bh2)) | 0;
1296
    lo = (lo + Math.imul(al5, bl3)) | 0;
1297
    mid = (mid + Math.imul(al5, bh3)) | 0;
1298
    mid = (mid + Math.imul(ah5, bl3)) | 0;
1299
    hi = (hi + Math.imul(ah5, bh3)) | 0;
1300
    lo = (lo + Math.imul(al4, bl4)) | 0;
1301
    mid = (mid + Math.imul(al4, bh4)) | 0;
1302
    mid = (mid + Math.imul(ah4, bl4)) | 0;
1303
    hi = (hi + Math.imul(ah4, bh4)) | 0;
1304
    lo = (lo + Math.imul(al3, bl5)) | 0;
1305
    mid = (mid + Math.imul(al3, bh5)) | 0;
1306
    mid = (mid + Math.imul(ah3, bl5)) | 0;
1307
    hi = (hi + Math.imul(ah3, bh5)) | 0;
1308
    lo = (lo + Math.imul(al2, bl6)) | 0;
1309
    mid = (mid + Math.imul(al2, bh6)) | 0;
1310
    mid = (mid + Math.imul(ah2, bl6)) | 0;
1311
    hi = (hi + Math.imul(ah2, bh6)) | 0;
1312
    lo = (lo + Math.imul(al1, bl7)) | 0;
1313
    mid = (mid + Math.imul(al1, bh7)) | 0;
1314
    mid = (mid + Math.imul(ah1, bl7)) | 0;
1315
    hi = (hi + Math.imul(ah1, bh7)) | 0;
1316
    lo = (lo + Math.imul(al0, bl8)) | 0;
1317
    mid = (mid + Math.imul(al0, bh8)) | 0;
1318
    mid = (mid + Math.imul(ah0, bl8)) | 0;
1319
    hi = (hi + Math.imul(ah0, bh8)) | 0;
1320
    var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1321
    c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
1322
    w8 &= 0x3ffffff;
1323
    /* k = 9 */
1324
    lo = Math.imul(al9, bl0);
1325
    mid = Math.imul(al9, bh0);
1326
    mid = (mid + Math.imul(ah9, bl0)) | 0;
1327
    hi = Math.imul(ah9, bh0);
1328
    lo = (lo + Math.imul(al8, bl1)) | 0;
1329
    mid = (mid + Math.imul(al8, bh1)) | 0;
1330
    mid = (mid + Math.imul(ah8, bl1)) | 0;
1331
    hi = (hi + Math.imul(ah8, bh1)) | 0;
1332
    lo = (lo + Math.imul(al7, bl2)) | 0;
1333
    mid = (mid + Math.imul(al7, bh2)) | 0;
1334
    mid = (mid + Math.imul(ah7, bl2)) | 0;
1335
    hi = (hi + Math.imul(ah7, bh2)) | 0;
1336
    lo = (lo + Math.imul(al6, bl3)) | 0;
1337
    mid = (mid + Math.imul(al6, bh3)) | 0;
1338
    mid = (mid + Math.imul(ah6, bl3)) | 0;
1339
    hi = (hi + Math.imul(ah6, bh3)) | 0;
1340
    lo = (lo + Math.imul(al5, bl4)) | 0;
1341
    mid = (mid + Math.imul(al5, bh4)) | 0;
1342
    mid = (mid + Math.imul(ah5, bl4)) | 0;
1343
    hi = (hi + Math.imul(ah5, bh4)) | 0;
1344
    lo = (lo + Math.imul(al4, bl5)) | 0;
1345
    mid = (mid + Math.imul(al4, bh5)) | 0;
1346
    mid = (mid + Math.imul(ah4, bl5)) | 0;
1347
    hi = (hi + Math.imul(ah4, bh5)) | 0;
1348
    lo = (lo + Math.imul(al3, bl6)) | 0;
1349
    mid = (mid + Math.imul(al3, bh6)) | 0;
1350
    mid = (mid + Math.imul(ah3, bl6)) | 0;
1351
    hi = (hi + Math.imul(ah3, bh6)) | 0;
1352
    lo = (lo + Math.imul(al2, bl7)) | 0;
1353
    mid = (mid + Math.imul(al2, bh7)) | 0;
1354
    mid = (mid + Math.imul(ah2, bl7)) | 0;
1355
    hi = (hi + Math.imul(ah2, bh7)) | 0;
1356
    lo = (lo + Math.imul(al1, bl8)) | 0;
1357
    mid = (mid + Math.imul(al1, bh8)) | 0;
1358
    mid = (mid + Math.imul(ah1, bl8)) | 0;
1359
    hi = (hi + Math.imul(ah1, bh8)) | 0;
1360
    lo = (lo + Math.imul(al0, bl9)) | 0;
1361
    mid = (mid + Math.imul(al0, bh9)) | 0;
1362
    mid = (mid + Math.imul(ah0, bl9)) | 0;
1363
    hi = (hi + Math.imul(ah0, bh9)) | 0;
1364
    var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1365
    c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
1366
    w9 &= 0x3ffffff;
1367
    /* k = 10 */
1368
    lo = Math.imul(al9, bl1);
1369
    mid = Math.imul(al9, bh1);
1370
    mid = (mid + Math.imul(ah9, bl1)) | 0;
1371
    hi = Math.imul(ah9, bh1);
1372
    lo = (lo + Math.imul(al8, bl2)) | 0;
1373
    mid = (mid + Math.imul(al8, bh2)) | 0;
1374
    mid = (mid + Math.imul(ah8, bl2)) | 0;
1375
    hi = (hi + Math.imul(ah8, bh2)) | 0;
1376
    lo = (lo + Math.imul(al7, bl3)) | 0;
1377
    mid = (mid + Math.imul(al7, bh3)) | 0;
1378
    mid = (mid + Math.imul(ah7, bl3)) | 0;
1379
    hi = (hi + Math.imul(ah7, bh3)) | 0;
1380
    lo = (lo + Math.imul(al6, bl4)) | 0;
1381
    mid = (mid + Math.imul(al6, bh4)) | 0;
1382
    mid = (mid + Math.imul(ah6, bl4)) | 0;
1383
    hi = (hi + Math.imul(ah6, bh4)) | 0;
1384
    lo = (lo + Math.imul(al5, bl5)) | 0;
1385
    mid = (mid + Math.imul(al5, bh5)) | 0;
1386
    mid = (mid + Math.imul(ah5, bl5)) | 0;
1387
    hi = (hi + Math.imul(ah5, bh5)) | 0;
1388
    lo = (lo + Math.imul(al4, bl6)) | 0;
1389
    mid = (mid + Math.imul(al4, bh6)) | 0;
1390
    mid = (mid + Math.imul(ah4, bl6)) | 0;
1391
    hi = (hi + Math.imul(ah4, bh6)) | 0;
1392
    lo = (lo + Math.imul(al3, bl7)) | 0;
1393
    mid = (mid + Math.imul(al3, bh7)) | 0;
1394
    mid = (mid + Math.imul(ah3, bl7)) | 0;
1395
    hi = (hi + Math.imul(ah3, bh7)) | 0;
1396
    lo = (lo + Math.imul(al2, bl8)) | 0;
1397
    mid = (mid + Math.imul(al2, bh8)) | 0;
1398
    mid = (mid + Math.imul(ah2, bl8)) | 0;
1399
    hi = (hi + Math.imul(ah2, bh8)) | 0;
1400
    lo = (lo + Math.imul(al1, bl9)) | 0;
1401
    mid = (mid + Math.imul(al1, bh9)) | 0;
1402
    mid = (mid + Math.imul(ah1, bl9)) | 0;
1403
    hi = (hi + Math.imul(ah1, bh9)) | 0;
1404
    var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1405
    c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
1406
    w10 &= 0x3ffffff;
1407
    /* k = 11 */
1408
    lo = Math.imul(al9, bl2);
1409
    mid = Math.imul(al9, bh2);
1410
    mid = (mid + Math.imul(ah9, bl2)) | 0;
1411
    hi = Math.imul(ah9, bh2);
1412
    lo = (lo + Math.imul(al8, bl3)) | 0;
1413
    mid = (mid + Math.imul(al8, bh3)) | 0;
1414
    mid = (mid + Math.imul(ah8, bl3)) | 0;
1415
    hi = (hi + Math.imul(ah8, bh3)) | 0;
1416
    lo = (lo + Math.imul(al7, bl4)) | 0;
1417
    mid = (mid + Math.imul(al7, bh4)) | 0;
1418
    mid = (mid + Math.imul(ah7, bl4)) | 0;
1419
    hi = (hi + Math.imul(ah7, bh4)) | 0;
1420
    lo = (lo + Math.imul(al6, bl5)) | 0;
1421
    mid = (mid + Math.imul(al6, bh5)) | 0;
1422
    mid = (mid + Math.imul(ah6, bl5)) | 0;
1423
    hi = (hi + Math.imul(ah6, bh5)) | 0;
1424
    lo = (lo + Math.imul(al5, bl6)) | 0;
1425
    mid = (mid + Math.imul(al5, bh6)) | 0;
1426
    mid = (mid + Math.imul(ah5, bl6)) | 0;
1427
    hi = (hi + Math.imul(ah5, bh6)) | 0;
1428
    lo = (lo + Math.imul(al4, bl7)) | 0;
1429
    mid = (mid + Math.imul(al4, bh7)) | 0;
1430
    mid = (mid + Math.imul(ah4, bl7)) | 0;
1431
    hi = (hi + Math.imul(ah4, bh7)) | 0;
1432
    lo = (lo + Math.imul(al3, bl8)) | 0;
1433
    mid = (mid + Math.imul(al3, bh8)) | 0;
1434
    mid = (mid + Math.imul(ah3, bl8)) | 0;
1435
    hi = (hi + Math.imul(ah3, bh8)) | 0;
1436
    lo = (lo + Math.imul(al2, bl9)) | 0;
1437
    mid = (mid + Math.imul(al2, bh9)) | 0;
1438
    mid = (mid + Math.imul(ah2, bl9)) | 0;
1439
    hi = (hi + Math.imul(ah2, bh9)) | 0;
1440
    var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1441
    c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
1442
    w11 &= 0x3ffffff;
1443
    /* k = 12 */
1444
    lo = Math.imul(al9, bl3);
1445
    mid = Math.imul(al9, bh3);
1446
    mid = (mid + Math.imul(ah9, bl3)) | 0;
1447
    hi = Math.imul(ah9, bh3);
1448
    lo = (lo + Math.imul(al8, bl4)) | 0;
1449
    mid = (mid + Math.imul(al8, bh4)) | 0;
1450
    mid = (mid + Math.imul(ah8, bl4)) | 0;
1451
    hi = (hi + Math.imul(ah8, bh4)) | 0;
1452
    lo = (lo + Math.imul(al7, bl5)) | 0;
1453
    mid = (mid + Math.imul(al7, bh5)) | 0;
1454
    mid = (mid + Math.imul(ah7, bl5)) | 0;
1455
    hi = (hi + Math.imul(ah7, bh5)) | 0;
1456
    lo = (lo + Math.imul(al6, bl6)) | 0;
1457
    mid = (mid + Math.imul(al6, bh6)) | 0;
1458
    mid = (mid + Math.imul(ah6, bl6)) | 0;
1459
    hi = (hi + Math.imul(ah6, bh6)) | 0;
1460
    lo = (lo + Math.imul(al5, bl7)) | 0;
1461
    mid = (mid + Math.imul(al5, bh7)) | 0;
1462
    mid = (mid + Math.imul(ah5, bl7)) | 0;
1463
    hi = (hi + Math.imul(ah5, bh7)) | 0;
1464
    lo = (lo + Math.imul(al4, bl8)) | 0;
1465
    mid = (mid + Math.imul(al4, bh8)) | 0;
1466
    mid = (mid + Math.imul(ah4, bl8)) | 0;
1467
    hi = (hi + Math.imul(ah4, bh8)) | 0;
1468
    lo = (lo + Math.imul(al3, bl9)) | 0;
1469
    mid = (mid + Math.imul(al3, bh9)) | 0;
1470
    mid = (mid + Math.imul(ah3, bl9)) | 0;
1471
    hi = (hi + Math.imul(ah3, bh9)) | 0;
1472
    var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1473
    c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
1474
    w12 &= 0x3ffffff;
1475
    /* k = 13 */
1476
    lo = Math.imul(al9, bl4);
1477
    mid = Math.imul(al9, bh4);
1478
    mid = (mid + Math.imul(ah9, bl4)) | 0;
1479
    hi = Math.imul(ah9, bh4);
1480
    lo = (lo + Math.imul(al8, bl5)) | 0;
1481
    mid = (mid + Math.imul(al8, bh5)) | 0;
1482
    mid = (mid + Math.imul(ah8, bl5)) | 0;
1483
    hi = (hi + Math.imul(ah8, bh5)) | 0;
1484
    lo = (lo + Math.imul(al7, bl6)) | 0;
1485
    mid = (mid + Math.imul(al7, bh6)) | 0;
1486
    mid = (mid + Math.imul(ah7, bl6)) | 0;
1487
    hi = (hi + Math.imul(ah7, bh6)) | 0;
1488
    lo = (lo + Math.imul(al6, bl7)) | 0;
1489
    mid = (mid + Math.imul(al6, bh7)) | 0;
1490
    mid = (mid + Math.imul(ah6, bl7)) | 0;
1491
    hi = (hi + Math.imul(ah6, bh7)) | 0;
1492
    lo = (lo + Math.imul(al5, bl8)) | 0;
1493
    mid = (mid + Math.imul(al5, bh8)) | 0;
1494
    mid = (mid + Math.imul(ah5, bl8)) | 0;
1495
    hi = (hi + Math.imul(ah5, bh8)) | 0;
1496
    lo = (lo + Math.imul(al4, bl9)) | 0;
1497
    mid = (mid + Math.imul(al4, bh9)) | 0;
1498
    mid = (mid + Math.imul(ah4, bl9)) | 0;
1499
    hi = (hi + Math.imul(ah4, bh9)) | 0;
1500
    var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1501
    c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
1502
    w13 &= 0x3ffffff;
1503
    /* k = 14 */
1504
    lo = Math.imul(al9, bl5);
1505
    mid = Math.imul(al9, bh5);
1506
    mid = (mid + Math.imul(ah9, bl5)) | 0;
1507
    hi = Math.imul(ah9, bh5);
1508
    lo = (lo + Math.imul(al8, bl6)) | 0;
1509
    mid = (mid + Math.imul(al8, bh6)) | 0;
1510
    mid = (mid + Math.imul(ah8, bl6)) | 0;
1511
    hi = (hi + Math.imul(ah8, bh6)) | 0;
1512
    lo = (lo + Math.imul(al7, bl7)) | 0;
1513
    mid = (mid + Math.imul(al7, bh7)) | 0;
1514
    mid = (mid + Math.imul(ah7, bl7)) | 0;
1515
    hi = (hi + Math.imul(ah7, bh7)) | 0;
1516
    lo = (lo + Math.imul(al6, bl8)) | 0;
1517
    mid = (mid + Math.imul(al6, bh8)) | 0;
1518
    mid = (mid + Math.imul(ah6, bl8)) | 0;
1519
    hi = (hi + Math.imul(ah6, bh8)) | 0;
1520
    lo = (lo + Math.imul(al5, bl9)) | 0;
1521
    mid = (mid + Math.imul(al5, bh9)) | 0;
1522
    mid = (mid + Math.imul(ah5, bl9)) | 0;
1523
    hi = (hi + Math.imul(ah5, bh9)) | 0;
1524
    var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1525
    c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
1526
    w14 &= 0x3ffffff;
1527
    /* k = 15 */
1528
    lo = Math.imul(al9, bl6);
1529
    mid = Math.imul(al9, bh6);
1530
    mid = (mid + Math.imul(ah9, bl6)) | 0;
1531
    hi = Math.imul(ah9, bh6);
1532
    lo = (lo + Math.imul(al8, bl7)) | 0;
1533
    mid = (mid + Math.imul(al8, bh7)) | 0;
1534
    mid = (mid + Math.imul(ah8, bl7)) | 0;
1535
    hi = (hi + Math.imul(ah8, bh7)) | 0;
1536
    lo = (lo + Math.imul(al7, bl8)) | 0;
1537
    mid = (mid + Math.imul(al7, bh8)) | 0;
1538
    mid = (mid + Math.imul(ah7, bl8)) | 0;
1539
    hi = (hi + Math.imul(ah7, bh8)) | 0;
1540
    lo = (lo + Math.imul(al6, bl9)) | 0;
1541
    mid = (mid + Math.imul(al6, bh9)) | 0;
1542
    mid = (mid + Math.imul(ah6, bl9)) | 0;
1543
    hi = (hi + Math.imul(ah6, bh9)) | 0;
1544
    var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1545
    c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
1546
    w15 &= 0x3ffffff;
1547
    /* k = 16 */
1548
    lo = Math.imul(al9, bl7);
1549
    mid = Math.imul(al9, bh7);
1550
    mid = (mid + Math.imul(ah9, bl7)) | 0;
1551
    hi = Math.imul(ah9, bh7);
1552
    lo = (lo + Math.imul(al8, bl8)) | 0;
1553
    mid = (mid + Math.imul(al8, bh8)) | 0;
1554
    mid = (mid + Math.imul(ah8, bl8)) | 0;
1555
    hi = (hi + Math.imul(ah8, bh8)) | 0;
1556
    lo = (lo + Math.imul(al7, bl9)) | 0;
1557
    mid = (mid + Math.imul(al7, bh9)) | 0;
1558
    mid = (mid + Math.imul(ah7, bl9)) | 0;
1559
    hi = (hi + Math.imul(ah7, bh9)) | 0;
1560
    var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1561
    c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
1562
    w16 &= 0x3ffffff;
1563
    /* k = 17 */
1564
    lo = Math.imul(al9, bl8);
1565
    mid = Math.imul(al9, bh8);
1566
    mid = (mid + Math.imul(ah9, bl8)) | 0;
1567
    hi = Math.imul(ah9, bh8);
1568
    lo = (lo + Math.imul(al8, bl9)) | 0;
1569
    mid = (mid + Math.imul(al8, bh9)) | 0;
1570
    mid = (mid + Math.imul(ah8, bl9)) | 0;
1571
    hi = (hi + Math.imul(ah8, bh9)) | 0;
1572
    var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1573
    c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
1574
    w17 &= 0x3ffffff;
1575
    /* k = 18 */
1576
    lo = Math.imul(al9, bl9);
1577
    mid = Math.imul(al9, bh9);
1578
    mid = (mid + Math.imul(ah9, bl9)) | 0;
1579
    hi = Math.imul(ah9, bh9);
1580
    var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
1581
    c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
1582
    w18 &= 0x3ffffff;
1583
    o[0] = w0;
1584
    o[1] = w1;
1585
    o[2] = w2;
1586
    o[3] = w3;
1587
    o[4] = w4;
1588
    o[5] = w5;
1589
    o[6] = w6;
1590
    o[7] = w7;
1591
    o[8] = w8;
1592
    o[9] = w9;
1593
    o[10] = w10;
1594
    o[11] = w11;
1595
    o[12] = w12;
1596
    o[13] = w13;
1597
    o[14] = w14;
1598
    o[15] = w15;
1599
    o[16] = w16;
1600
    o[17] = w17;
1601
    o[18] = w18;
1602
    if (c !== 0) {
1603
      o[19] = c;
1604
      out.length++;
1605
    }
1606
    return out;
1607
  };
1608

    
1609
  // Polyfill comb
1610
  if (!Math.imul) {
1611
    comb10MulTo = smallMulTo;
1612
  }
1613

    
1614
  function bigMulTo (self, num, out) {
1615
    out.negative = num.negative ^ self.negative;
1616
    out.length = self.length + num.length;
1617

    
1618
    var carry = 0;
1619
    var hncarry = 0;
1620
    for (var k = 0; k < out.length - 1; k++) {
1621
      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
1622
      // note that ncarry could be >= 0x3ffffff
1623
      var ncarry = hncarry;
1624
      hncarry = 0;
1625
      var rword = carry & 0x3ffffff;
1626
      var maxJ = Math.min(k, num.length - 1);
1627
      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
1628
        var i = k - j;
1629
        var a = self.words[i] | 0;
1630
        var b = num.words[j] | 0;
1631
        var r = a * b;
1632

    
1633
        var lo = r & 0x3ffffff;
1634
        ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
1635
        lo = (lo + rword) | 0;
1636
        rword = lo & 0x3ffffff;
1637
        ncarry = (ncarry + (lo >>> 26)) | 0;
1638

    
1639
        hncarry += ncarry >>> 26;
1640
        ncarry &= 0x3ffffff;
1641
      }
1642
      out.words[k] = rword;
1643
      carry = ncarry;
1644
      ncarry = hncarry;
1645
    }
1646
    if (carry !== 0) {
1647
      out.words[k] = carry;
1648
    } else {
1649
      out.length--;
1650
    }
1651

    
1652
    return out.strip();
1653
  }
1654

    
1655
  function jumboMulTo (self, num, out) {
1656
    var fftm = new FFTM();
1657
    return fftm.mulp(self, num, out);
1658
  }
1659

    
1660
  BN.prototype.mulTo = function mulTo (num, out) {
1661
    var res;
1662
    var len = this.length + num.length;
1663
    if (this.length === 10 && num.length === 10) {
1664
      res = comb10MulTo(this, num, out);
1665
    } else if (len < 63) {
1666
      res = smallMulTo(this, num, out);
1667
    } else if (len < 1024) {
1668
      res = bigMulTo(this, num, out);
1669
    } else {
1670
      res = jumboMulTo(this, num, out);
1671
    }
1672

    
1673
    return res;
1674
  };
1675

    
1676
  // Cooley-Tukey algorithm for FFT
1677
  // slightly revisited to rely on looping instead of recursion
1678

    
1679
  function FFTM (x, y) {
1680
    this.x = x;
1681
    this.y = y;
1682
  }
1683

    
1684
  FFTM.prototype.makeRBT = function makeRBT (N) {
1685
    var t = new Array(N);
1686
    var l = BN.prototype._countBits(N) - 1;
1687
    for (var i = 0; i < N; i++) {
1688
      t[i] = this.revBin(i, l, N);
1689
    }
1690

    
1691
    return t;
1692
  };
1693

    
1694
  // Returns binary-reversed representation of `x`
1695
  FFTM.prototype.revBin = function revBin (x, l, N) {
1696
    if (x === 0 || x === N - 1) return x;
1697

    
1698
    var rb = 0;
1699
    for (var i = 0; i < l; i++) {
1700
      rb |= (x & 1) << (l - i - 1);
1701
      x >>= 1;
1702
    }
1703

    
1704
    return rb;
1705
  };
1706

    
1707
  // Performs "tweedling" phase, therefore 'emulating'
1708
  // behaviour of the recursive algorithm
1709
  FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
1710
    for (var i = 0; i < N; i++) {
1711
      rtws[i] = rws[rbt[i]];
1712
      itws[i] = iws[rbt[i]];
1713
    }
1714
  };
1715

    
1716
  FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
1717
    this.permute(rbt, rws, iws, rtws, itws, N);
1718

    
1719
    for (var s = 1; s < N; s <<= 1) {
1720
      var l = s << 1;
1721

    
1722
      var rtwdf = Math.cos(2 * Math.PI / l);
1723
      var itwdf = Math.sin(2 * Math.PI / l);
1724

    
1725
      for (var p = 0; p < N; p += l) {
1726
        var rtwdf_ = rtwdf;
1727
        var itwdf_ = itwdf;
1728

    
1729
        for (var j = 0; j < s; j++) {
1730
          var re = rtws[p + j];
1731
          var ie = itws[p + j];
1732

    
1733
          var ro = rtws[p + j + s];
1734
          var io = itws[p + j + s];
1735

    
1736
          var rx = rtwdf_ * ro - itwdf_ * io;
1737

    
1738
          io = rtwdf_ * io + itwdf_ * ro;
1739
          ro = rx;
1740

    
1741
          rtws[p + j] = re + ro;
1742
          itws[p + j] = ie + io;
1743

    
1744
          rtws[p + j + s] = re - ro;
1745
          itws[p + j + s] = ie - io;
1746

    
1747
          /* jshint maxdepth : false */
1748
          if (j !== l) {
1749
            rx = rtwdf * rtwdf_ - itwdf * itwdf_;
1750

    
1751
            itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
1752
            rtwdf_ = rx;
1753
          }
1754
        }
1755
      }
1756
    }
1757
  };
1758

    
1759
  FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
1760
    var N = Math.max(m, n) | 1;
1761
    var odd = N & 1;
1762
    var i = 0;
1763
    for (N = N / 2 | 0; N; N = N >>> 1) {
1764
      i++;
1765
    }
1766

    
1767
    return 1 << i + 1 + odd;
1768
  };
1769

    
1770
  FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
1771
    if (N <= 1) return;
1772

    
1773
    for (var i = 0; i < N / 2; i++) {
1774
      var t = rws[i];
1775

    
1776
      rws[i] = rws[N - i - 1];
1777
      rws[N - i - 1] = t;
1778

    
1779
      t = iws[i];
1780

    
1781
      iws[i] = -iws[N - i - 1];
1782
      iws[N - i - 1] = -t;
1783
    }
1784
  };
1785

    
1786
  FFTM.prototype.normalize13b = function normalize13b (ws, N) {
1787
    var carry = 0;
1788
    for (var i = 0; i < N / 2; i++) {
1789
      var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
1790
        Math.round(ws[2 * i] / N) +
1791
        carry;
1792

    
1793
      ws[i] = w & 0x3ffffff;
1794

    
1795
      if (w < 0x4000000) {
1796
        carry = 0;
1797
      } else {
1798
        carry = w / 0x4000000 | 0;
1799
      }
1800
    }
1801

    
1802
    return ws;
1803
  };
1804

    
1805
  FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
1806
    var carry = 0;
1807
    for (var i = 0; i < len; i++) {
1808
      carry = carry + (ws[i] | 0);
1809

    
1810
      rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
1811
      rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
1812
    }
1813

    
1814
    // Pad with zeroes
1815
    for (i = 2 * len; i < N; ++i) {
1816
      rws[i] = 0;
1817
    }
1818

    
1819
    assert(carry === 0);
1820
    assert((carry & ~0x1fff) === 0);
1821
  };
1822

    
1823
  FFTM.prototype.stub = function stub (N) {
1824
    var ph = new Array(N);
1825
    for (var i = 0; i < N; i++) {
1826
      ph[i] = 0;
1827
    }
1828

    
1829
    return ph;
1830
  };
1831

    
1832
  FFTM.prototype.mulp = function mulp (x, y, out) {
1833
    var N = 2 * this.guessLen13b(x.length, y.length);
1834

    
1835
    var rbt = this.makeRBT(N);
1836

    
1837
    var _ = this.stub(N);
1838

    
1839
    var rws = new Array(N);
1840
    var rwst = new Array(N);
1841
    var iwst = new Array(N);
1842

    
1843
    var nrws = new Array(N);
1844
    var nrwst = new Array(N);
1845
    var niwst = new Array(N);
1846

    
1847
    var rmws = out.words;
1848
    rmws.length = N;
1849

    
1850
    this.convert13b(x.words, x.length, rws, N);
1851
    this.convert13b(y.words, y.length, nrws, N);
1852

    
1853
    this.transform(rws, _, rwst, iwst, N, rbt);
1854
    this.transform(nrws, _, nrwst, niwst, N, rbt);
1855

    
1856
    for (var i = 0; i < N; i++) {
1857
      var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
1858
      iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
1859
      rwst[i] = rx;
1860
    }
1861

    
1862
    this.conjugate(rwst, iwst, N);
1863
    this.transform(rwst, iwst, rmws, _, N, rbt);
1864
    this.conjugate(rmws, _, N);
1865
    this.normalize13b(rmws, N);
1866

    
1867
    out.negative = x.negative ^ y.negative;
1868
    out.length = x.length + y.length;
1869
    return out.strip();
1870
  };
1871

    
1872
  // Multiply `this` by `num`
1873
  BN.prototype.mul = function mul (num) {
1874
    var out = new BN(null);
1875
    out.words = new Array(this.length + num.length);
1876
    return this.mulTo(num, out);
1877
  };
1878

    
1879
  // Multiply employing FFT
1880
  BN.prototype.mulf = function mulf (num) {
1881
    var out = new BN(null);
1882
    out.words = new Array(this.length + num.length);
1883
    return jumboMulTo(this, num, out);
1884
  };
1885

    
1886
  // In-place Multiplication
1887
  BN.prototype.imul = function imul (num) {
1888
    return this.clone().mulTo(num, this);
1889
  };
1890

    
1891
  BN.prototype.imuln = function imuln (num) {
1892
    assert(typeof num === 'number');
1893
    assert(num < 0x4000000);
1894

    
1895
    // Carry
1896
    var carry = 0;
1897
    for (var i = 0; i < this.length; i++) {
1898
      var w = (this.words[i] | 0) * num;
1899
      var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
1900
      carry >>= 26;
1901
      carry += (w / 0x4000000) | 0;
1902
      // NOTE: lo is 27bit maximum
1903
      carry += lo >>> 26;
1904
      this.words[i] = lo & 0x3ffffff;
1905
    }
1906

    
1907
    if (carry !== 0) {
1908
      this.words[i] = carry;
1909
      this.length++;
1910
    }
1911

    
1912
    return this;
1913
  };
1914

    
1915
  BN.prototype.muln = function muln (num) {
1916
    return this.clone().imuln(num);
1917
  };
1918

    
1919
  // `this` * `this`
1920
  BN.prototype.sqr = function sqr () {
1921
    return this.mul(this);
1922
  };
1923

    
1924
  // `this` * `this` in-place
1925
  BN.prototype.isqr = function isqr () {
1926
    return this.imul(this.clone());
1927
  };
1928

    
1929
  // Math.pow(`this`, `num`)
1930
  BN.prototype.pow = function pow (num) {
1931
    var w = toBitArray(num);
1932
    if (w.length === 0) return new BN(1);
1933

    
1934
    // Skip leading zeroes
1935
    var res = this;
1936
    for (var i = 0; i < w.length; i++, res = res.sqr()) {
1937
      if (w[i] !== 0) break;
1938
    }
1939

    
1940
    if (++i < w.length) {
1941
      for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
1942
        if (w[i] === 0) continue;
1943

    
1944
        res = res.mul(q);
1945
      }
1946
    }
1947

    
1948
    return res;
1949
  };
1950

    
1951
  // Shift-left in-place
1952
  BN.prototype.iushln = function iushln (bits) {
1953
    assert(typeof bits === 'number' && bits >= 0);
1954
    var r = bits % 26;
1955
    var s = (bits - r) / 26;
1956
    var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
1957
    var i;
1958

    
1959
    if (r !== 0) {
1960
      var carry = 0;
1961

    
1962
      for (i = 0; i < this.length; i++) {
1963
        var newCarry = this.words[i] & carryMask;
1964
        var c = ((this.words[i] | 0) - newCarry) << r;
1965
        this.words[i] = c | carry;
1966
        carry = newCarry >>> (26 - r);
1967
      }
1968

    
1969
      if (carry) {
1970
        this.words[i] = carry;
1971
        this.length++;
1972
      }
1973
    }
1974

    
1975
    if (s !== 0) {
1976
      for (i = this.length - 1; i >= 0; i--) {
1977
        this.words[i + s] = this.words[i];
1978
      }
1979

    
1980
      for (i = 0; i < s; i++) {
1981
        this.words[i] = 0;
1982
      }
1983

    
1984
      this.length += s;
1985
    }
1986

    
1987
    return this.strip();
1988
  };
1989

    
1990
  BN.prototype.ishln = function ishln (bits) {
1991
    // TODO(indutny): implement me
1992
    assert(this.negative === 0);
1993
    return this.iushln(bits);
1994
  };
1995

    
1996
  // Shift-right in-place
1997
  // NOTE: `hint` is a lowest bit before trailing zeroes
1998
  // NOTE: if `extended` is present - it will be filled with destroyed bits
1999
  BN.prototype.iushrn = function iushrn (bits, hint, extended) {
2000
    assert(typeof bits === 'number' && bits >= 0);
2001
    var h;
2002
    if (hint) {
2003
      h = (hint - (hint % 26)) / 26;
2004
    } else {
2005
      h = 0;
2006
    }
2007

    
2008
    var r = bits % 26;
2009
    var s = Math.min((bits - r) / 26, this.length);
2010
    var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
2011
    var maskedWords = extended;
2012

    
2013
    h -= s;
2014
    h = Math.max(0, h);
2015

    
2016
    // Extended mode, copy masked part
2017
    if (maskedWords) {
2018
      for (var i = 0; i < s; i++) {
2019
        maskedWords.words[i] = this.words[i];
2020
      }
2021
      maskedWords.length = s;
2022
    }
2023

    
2024
    if (s === 0) {
2025
      // No-op, we should not move anything at all
2026
    } else if (this.length > s) {
2027
      this.length -= s;
2028
      for (i = 0; i < this.length; i++) {
2029
        this.words[i] = this.words[i + s];
2030
      }
2031
    } else {
2032
      this.words[0] = 0;
2033
      this.length = 1;
2034
    }
2035

    
2036
    var carry = 0;
2037
    for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
2038
      var word = this.words[i] | 0;
2039
      this.words[i] = (carry << (26 - r)) | (word >>> r);
2040
      carry = word & mask;
2041
    }
2042

    
2043
    // Push carried bits as a mask
2044
    if (maskedWords && carry !== 0) {
2045
      maskedWords.words[maskedWords.length++] = carry;
2046
    }
2047

    
2048
    if (this.length === 0) {
2049
      this.words[0] = 0;
2050
      this.length = 1;
2051
    }
2052

    
2053
    return this.strip();
2054
  };
2055

    
2056
  BN.prototype.ishrn = function ishrn (bits, hint, extended) {
2057
    // TODO(indutny): implement me
2058
    assert(this.negative === 0);
2059
    return this.iushrn(bits, hint, extended);
2060
  };
2061

    
2062
  // Shift-left
2063
  BN.prototype.shln = function shln (bits) {
2064
    return this.clone().ishln(bits);
2065
  };
2066

    
2067
  BN.prototype.ushln = function ushln (bits) {
2068
    return this.clone().iushln(bits);
2069
  };
2070

    
2071
  // Shift-right
2072
  BN.prototype.shrn = function shrn (bits) {
2073
    return this.clone().ishrn(bits);
2074
  };
2075

    
2076
  BN.prototype.ushrn = function ushrn (bits) {
2077
    return this.clone().iushrn(bits);
2078
  };
2079

    
2080
  // Test if n bit is set
2081
  BN.prototype.testn = function testn (bit) {
2082
    assert(typeof bit === 'number' && bit >= 0);
2083
    var r = bit % 26;
2084
    var s = (bit - r) / 26;
2085
    var q = 1 << r;
2086

    
2087
    // Fast case: bit is much higher than all existing words
2088
    if (this.length <= s) return false;
2089

    
2090
    // Check bit and return
2091
    var w = this.words[s];
2092

    
2093
    return !!(w & q);
2094
  };
2095

    
2096
  // Return only lowers bits of number (in-place)
2097
  BN.prototype.imaskn = function imaskn (bits) {
2098
    assert(typeof bits === 'number' && bits >= 0);
2099
    var r = bits % 26;
2100
    var s = (bits - r) / 26;
2101

    
2102
    assert(this.negative === 0, 'imaskn works only with positive numbers');
2103

    
2104
    if (this.length <= s) {
2105
      return this;
2106
    }
2107

    
2108
    if (r !== 0) {
2109
      s++;
2110
    }
2111
    this.length = Math.min(s, this.length);
2112

    
2113
    if (r !== 0) {
2114
      var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
2115
      this.words[this.length - 1] &= mask;
2116
    }
2117

    
2118
    return this.strip();
2119
  };
2120

    
2121
  // Return only lowers bits of number
2122
  BN.prototype.maskn = function maskn (bits) {
2123
    return this.clone().imaskn(bits);
2124
  };
2125

    
2126
  // Add plain number `num` to `this`
2127
  BN.prototype.iaddn = function iaddn (num) {
2128
    assert(typeof num === 'number');
2129
    assert(num < 0x4000000);
2130
    if (num < 0) return this.isubn(-num);
2131

    
2132
    // Possible sign change
2133
    if (this.negative !== 0) {
2134
      if (this.length === 1 && (this.words[0] | 0) < num) {
2135
        this.words[0] = num - (this.words[0] | 0);
2136
        this.negative = 0;
2137
        return this;
2138
      }
2139

    
2140
      this.negative = 0;
2141
      this.isubn(num);
2142
      this.negative = 1;
2143
      return this;
2144
    }
2145

    
2146
    // Add without checks
2147
    return this._iaddn(num);
2148
  };
2149

    
2150
  BN.prototype._iaddn = function _iaddn (num) {
2151
    this.words[0] += num;
2152

    
2153
    // Carry
2154
    for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
2155
      this.words[i] -= 0x4000000;
2156
      if (i === this.length - 1) {
2157
        this.words[i + 1] = 1;
2158
      } else {
2159
        this.words[i + 1]++;
2160
      }
2161
    }
2162
    this.length = Math.max(this.length, i + 1);
2163

    
2164
    return this;
2165
  };
2166

    
2167
  // Subtract plain number `num` from `this`
2168
  BN.prototype.isubn = function isubn (num) {
2169
    assert(typeof num === 'number');
2170
    assert(num < 0x4000000);
2171
    if (num < 0) return this.iaddn(-num);
2172

    
2173
    if (this.negative !== 0) {
2174
      this.negative = 0;
2175
      this.iaddn(num);
2176
      this.negative = 1;
2177
      return this;
2178
    }
2179

    
2180
    this.words[0] -= num;
2181

    
2182
    if (this.length === 1 && this.words[0] < 0) {
2183
      this.words[0] = -this.words[0];
2184
      this.negative = 1;
2185
    } else {
2186
      // Carry
2187
      for (var i = 0; i < this.length && this.words[i] < 0; i++) {
2188
        this.words[i] += 0x4000000;
2189
        this.words[i + 1] -= 1;
2190
      }
2191
    }
2192

    
2193
    return this.strip();
2194
  };
2195

    
2196
  BN.prototype.addn = function addn (num) {
2197
    return this.clone().iaddn(num);
2198
  };
2199

    
2200
  BN.prototype.subn = function subn (num) {
2201
    return this.clone().isubn(num);
2202
  };
2203

    
2204
  BN.prototype.iabs = function iabs () {
2205
    this.negative = 0;
2206

    
2207
    return this;
2208
  };
2209

    
2210
  BN.prototype.abs = function abs () {
2211
    return this.clone().iabs();
2212
  };
2213

    
2214
  BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
2215
    var len = num.length + shift;
2216
    var i;
2217

    
2218
    this._expand(len);
2219

    
2220
    var w;
2221
    var carry = 0;
2222
    for (i = 0; i < num.length; i++) {
2223
      w = (this.words[i + shift] | 0) + carry;
2224
      var right = (num.words[i] | 0) * mul;
2225
      w -= right & 0x3ffffff;
2226
      carry = (w >> 26) - ((right / 0x4000000) | 0);
2227
      this.words[i + shift] = w & 0x3ffffff;
2228
    }
2229
    for (; i < this.length - shift; i++) {
2230
      w = (this.words[i + shift] | 0) + carry;
2231
      carry = w >> 26;
2232
      this.words[i + shift] = w & 0x3ffffff;
2233
    }
2234

    
2235
    if (carry === 0) return this.strip();
2236

    
2237
    // Subtraction overflow
2238
    assert(carry === -1);
2239
    carry = 0;
2240
    for (i = 0; i < this.length; i++) {
2241
      w = -(this.words[i] | 0) + carry;
2242
      carry = w >> 26;
2243
      this.words[i] = w & 0x3ffffff;
2244
    }
2245
    this.negative = 1;
2246

    
2247
    return this.strip();
2248
  };
2249

    
2250
  BN.prototype._wordDiv = function _wordDiv (num, mode) {
2251
    var shift = this.length - num.length;
2252

    
2253
    var a = this.clone();
2254
    var b = num;
2255

    
2256
    // Normalize
2257
    var bhi = b.words[b.length - 1] | 0;
2258
    var bhiBits = this._countBits(bhi);
2259
    shift = 26 - bhiBits;
2260
    if (shift !== 0) {
2261
      b = b.ushln(shift);
2262
      a.iushln(shift);
2263
      bhi = b.words[b.length - 1] | 0;
2264
    }
2265

    
2266
    // Initialize quotient
2267
    var m = a.length - b.length;
2268
    var q;
2269

    
2270
    if (mode !== 'mod') {
2271
      q = new BN(null);
2272
      q.length = m + 1;
2273
      q.words = new Array(q.length);
2274
      for (var i = 0; i < q.length; i++) {
2275
        q.words[i] = 0;
2276
      }
2277
    }
2278

    
2279
    var diff = a.clone()._ishlnsubmul(b, 1, m);
2280
    if (diff.negative === 0) {
2281
      a = diff;
2282
      if (q) {
2283
        q.words[m] = 1;
2284
      }
2285
    }
2286

    
2287
    for (var j = m - 1; j >= 0; j--) {
2288
      var qj = (a.words[b.length + j] | 0) * 0x4000000 +
2289
        (a.words[b.length + j - 1] | 0);
2290

    
2291
      // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
2292
      // (0x7ffffff)
2293
      qj = Math.min((qj / bhi) | 0, 0x3ffffff);
2294

    
2295
      a._ishlnsubmul(b, qj, j);
2296
      while (a.negative !== 0) {
2297
        qj--;
2298
        a.negative = 0;
2299
        a._ishlnsubmul(b, 1, j);
2300
        if (!a.isZero()) {
2301
          a.negative ^= 1;
2302
        }
2303
      }
2304
      if (q) {
2305
        q.words[j] = qj;
2306
      }
2307
    }
2308
    if (q) {
2309
      q.strip();
2310
    }
2311
    a.strip();
2312

    
2313
    // Denormalize
2314
    if (mode !== 'div' && shift !== 0) {
2315
      a.iushrn(shift);
2316
    }
2317

    
2318
    return {
2319
      div: q || null,
2320
      mod: a
2321
    };
2322
  };
2323

    
2324
  // NOTE: 1) `mode` can be set to `mod` to request mod only,
2325
  //       to `div` to request div only, or be absent to
2326
  //       request both div & mod
2327
  //       2) `positive` is true if unsigned mod is requested
2328
  BN.prototype.divmod = function divmod (num, mode, positive) {
2329
    assert(!num.isZero());
2330

    
2331
    if (this.isZero()) {
2332
      return {
2333
        div: new BN(0),
2334
        mod: new BN(0)
2335
      };
2336
    }
2337

    
2338
    var div, mod, res;
2339
    if (this.negative !== 0 && num.negative === 0) {
2340
      res = this.neg().divmod(num, mode);
2341

    
2342
      if (mode !== 'mod') {
2343
        div = res.div.neg();
2344
      }
2345

    
2346
      if (mode !== 'div') {
2347
        mod = res.mod.neg();
2348
        if (positive && mod.negative !== 0) {
2349
          mod.iadd(num);
2350
        }
2351
      }
2352

    
2353
      return {
2354
        div: div,
2355
        mod: mod
2356
      };
2357
    }
2358

    
2359
    if (this.negative === 0 && num.negative !== 0) {
2360
      res = this.divmod(num.neg(), mode);
2361

    
2362
      if (mode !== 'mod') {
2363
        div = res.div.neg();
2364
      }
2365

    
2366
      return {
2367
        div: div,
2368
        mod: res.mod
2369
      };
2370
    }
2371

    
2372
    if ((this.negative & num.negative) !== 0) {
2373
      res = this.neg().divmod(num.neg(), mode);
2374

    
2375
      if (mode !== 'div') {
2376
        mod = res.mod.neg();
2377
        if (positive && mod.negative !== 0) {
2378
          mod.isub(num);
2379
        }
2380
      }
2381

    
2382
      return {
2383
        div: res.div,
2384
        mod: mod
2385
      };
2386
    }
2387

    
2388
    // Both numbers are positive at this point
2389

    
2390
    // Strip both numbers to approximate shift value
2391
    if (num.length > this.length || this.cmp(num) < 0) {
2392
      return {
2393
        div: new BN(0),
2394
        mod: this
2395
      };
2396
    }
2397

    
2398
    // Very short reduction
2399
    if (num.length === 1) {
2400
      if (mode === 'div') {
2401
        return {
2402
          div: this.divn(num.words[0]),
2403
          mod: null
2404
        };
2405
      }
2406

    
2407
      if (mode === 'mod') {
2408
        return {
2409
          div: null,
2410
          mod: new BN(this.modn(num.words[0]))
2411
        };
2412
      }
2413

    
2414
      return {
2415
        div: this.divn(num.words[0]),
2416
        mod: new BN(this.modn(num.words[0]))
2417
      };
2418
    }
2419

    
2420
    return this._wordDiv(num, mode);
2421
  };
2422

    
2423
  // Find `this` / `num`
2424
  BN.prototype.div = function div (num) {
2425
    return this.divmod(num, 'div', false).div;
2426
  };
2427

    
2428
  // Find `this` % `num`
2429
  BN.prototype.mod = function mod (num) {
2430
    return this.divmod(num, 'mod', false).mod;
2431
  };
2432

    
2433
  BN.prototype.umod = function umod (num) {
2434
    return this.divmod(num, 'mod', true).mod;
2435
  };
2436

    
2437
  // Find Round(`this` / `num`)
2438
  BN.prototype.divRound = function divRound (num) {
2439
    var dm = this.divmod(num);
2440

    
2441
    // Fast case - exact division
2442
    if (dm.mod.isZero()) return dm.div;
2443

    
2444
    var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
2445

    
2446
    var half = num.ushrn(1);
2447
    var r2 = num.andln(1);
2448
    var cmp = mod.cmp(half);
2449

    
2450
    // Round down
2451
    if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
2452

    
2453
    // Round up
2454
    return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
2455
  };
2456

    
2457
  BN.prototype.modn = function modn (num) {
2458
    assert(num <= 0x3ffffff);
2459
    var p = (1 << 26) % num;
2460

    
2461
    var acc = 0;
2462
    for (var i = this.length - 1; i >= 0; i--) {
2463
      acc = (p * acc + (this.words[i] | 0)) % num;
2464
    }
2465

    
2466
    return acc;
2467
  };
2468

    
2469
  // In-place division by number
2470
  BN.prototype.idivn = function idivn (num) {
2471
    assert(num <= 0x3ffffff);
2472

    
2473
    var carry = 0;
2474
    for (var i = this.length - 1; i >= 0; i--) {
2475
      var w = (this.words[i] | 0) + carry * 0x4000000;
2476
      this.words[i] = (w / num) | 0;
2477
      carry = w % num;
2478
    }
2479

    
2480
    return this.strip();
2481
  };
2482

    
2483
  BN.prototype.divn = function divn (num) {
2484
    return this.clone().idivn(num);
2485
  };
2486

    
2487
  BN.prototype.egcd = function egcd (p) {
2488
    assert(p.negative === 0);
2489
    assert(!p.isZero());
2490

    
2491
    var x = this;
2492
    var y = p.clone();
2493

    
2494
    if (x.negative !== 0) {
2495
      x = x.umod(p);
2496
    } else {
2497
      x = x.clone();
2498
    }
2499

    
2500
    // A * x + B * y = x
2501
    var A = new BN(1);
2502
    var B = new BN(0);
2503

    
2504
    // C * x + D * y = y
2505
    var C = new BN(0);
2506
    var D = new BN(1);
2507

    
2508
    var g = 0;
2509

    
2510
    while (x.isEven() && y.isEven()) {
2511
      x.iushrn(1);
2512
      y.iushrn(1);
2513
      ++g;
2514
    }
2515

    
2516
    var yp = y.clone();
2517
    var xp = x.clone();
2518

    
2519
    while (!x.isZero()) {
2520
      for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
2521
      if (i > 0) {
2522
        x.iushrn(i);
2523
        while (i-- > 0) {
2524
          if (A.isOdd() || B.isOdd()) {
2525
            A.iadd(yp);
2526
            B.isub(xp);
2527
          }
2528

    
2529
          A.iushrn(1);
2530
          B.iushrn(1);
2531
        }
2532
      }
2533

    
2534
      for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
2535
      if (j > 0) {
2536
        y.iushrn(j);
2537
        while (j-- > 0) {
2538
          if (C.isOdd() || D.isOdd()) {
2539
            C.iadd(yp);
2540
            D.isub(xp);
2541
          }
2542

    
2543
          C.iushrn(1);
2544
          D.iushrn(1);
2545
        }
2546
      }
2547

    
2548
      if (x.cmp(y) >= 0) {
2549
        x.isub(y);
2550
        A.isub(C);
2551
        B.isub(D);
2552
      } else {
2553
        y.isub(x);
2554
        C.isub(A);
2555
        D.isub(B);
2556
      }
2557
    }
2558

    
2559
    return {
2560
      a: C,
2561
      b: D,
2562
      gcd: y.iushln(g)
2563
    };
2564
  };
2565

    
2566
  // This is reduced incarnation of the binary EEA
2567
  // above, designated to invert members of the
2568
  // _prime_ fields F(p) at a maximal speed
2569
  BN.prototype._invmp = function _invmp (p) {
2570
    assert(p.negative === 0);
2571
    assert(!p.isZero());
2572

    
2573
    var a = this;
2574
    var b = p.clone();
2575

    
2576
    if (a.negative !== 0) {
2577
      a = a.umod(p);
2578
    } else {
2579
      a = a.clone();
2580
    }
2581

    
2582
    var x1 = new BN(1);
2583
    var x2 = new BN(0);
2584

    
2585
    var delta = b.clone();
2586

    
2587
    while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
2588
      for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
2589
      if (i > 0) {
2590
        a.iushrn(i);
2591
        while (i-- > 0) {
2592
          if (x1.isOdd()) {
2593
            x1.iadd(delta);
2594
          }
2595

    
2596
          x1.iushrn(1);
2597
        }
2598
      }
2599

    
2600
      for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
2601
      if (j > 0) {
2602
        b.iushrn(j);
2603
        while (j-- > 0) {
2604
          if (x2.isOdd()) {
2605
            x2.iadd(delta);
2606
          }
2607

    
2608
          x2.iushrn(1);
2609
        }
2610
      }
2611

    
2612
      if (a.cmp(b) >= 0) {
2613
        a.isub(b);
2614
        x1.isub(x2);
2615
      } else {
2616
        b.isub(a);
2617
        x2.isub(x1);
2618
      }
2619
    }
2620

    
2621
    var res;
2622
    if (a.cmpn(1) === 0) {
2623
      res = x1;
2624
    } else {
2625
      res = x2;
2626
    }
2627

    
2628
    if (res.cmpn(0) < 0) {
2629
      res.iadd(p);
2630
    }
2631

    
2632
    return res;
2633
  };
2634

    
2635
  BN.prototype.gcd = function gcd (num) {
2636
    if (this.isZero()) return num.abs();
2637
    if (num.isZero()) return this.abs();
2638

    
2639
    var a = this.clone();
2640
    var b = num.clone();
2641
    a.negative = 0;
2642
    b.negative = 0;
2643

    
2644
    // Remove common factor of two
2645
    for (var shift = 0; a.isEven() && b.isEven(); shift++) {
2646
      a.iushrn(1);
2647
      b.iushrn(1);
2648
    }
2649

    
2650
    do {
2651
      while (a.isEven()) {
2652
        a.iushrn(1);
2653
      }
2654
      while (b.isEven()) {
2655
        b.iushrn(1);
2656
      }
2657

    
2658
      var r = a.cmp(b);
2659
      if (r < 0) {
2660
        // Swap `a` and `b` to make `a` always bigger than `b`
2661
        var t = a;
2662
        a = b;
2663
        b = t;
2664
      } else if (r === 0 || b.cmpn(1) === 0) {
2665
        break;
2666
      }
2667

    
2668
      a.isub(b);
2669
    } while (true);
2670

    
2671
    return b.iushln(shift);
2672
  };
2673

    
2674
  // Invert number in the field F(num)
2675
  BN.prototype.invm = function invm (num) {
2676
    return this.egcd(num).a.umod(num);
2677
  };
2678

    
2679
  BN.prototype.isEven = function isEven () {
2680
    return (this.words[0] & 1) === 0;
2681
  };
2682

    
2683
  BN.prototype.isOdd = function isOdd () {
2684
    return (this.words[0] & 1) === 1;
2685
  };
2686

    
2687
  // And first word and num
2688
  BN.prototype.andln = function andln (num) {
2689
    return this.words[0] & num;
2690
  };
2691

    
2692
  // Increment at the bit position in-line
2693
  BN.prototype.bincn = function bincn (bit) {
2694
    assert(typeof bit === 'number');
2695
    var r = bit % 26;
2696
    var s = (bit - r) / 26;
2697
    var q = 1 << r;
2698

    
2699
    // Fast case: bit is much higher than all existing words
2700
    if (this.length <= s) {
2701
      this._expand(s + 1);
2702
      this.words[s] |= q;
2703
      return this;
2704
    }
2705

    
2706
    // Add bit and propagate, if needed
2707
    var carry = q;
2708
    for (var i = s; carry !== 0 && i < this.length; i++) {
2709
      var w = this.words[i] | 0;
2710
      w += carry;
2711
      carry = w >>> 26;
2712
      w &= 0x3ffffff;
2713
      this.words[i] = w;
2714
    }
2715
    if (carry !== 0) {
2716
      this.words[i] = carry;
2717
      this.length++;
2718
    }
2719
    return this;
2720
  };
2721

    
2722
  BN.prototype.isZero = function isZero () {
2723
    return this.length === 1 && this.words[0] === 0;
2724
  };
2725

    
2726
  BN.prototype.cmpn = function cmpn (num) {
2727
    var negative = num < 0;
2728

    
2729
    if (this.negative !== 0 && !negative) return -1;
2730
    if (this.negative === 0 && negative) return 1;
2731

    
2732
    this.strip();
2733

    
2734
    var res;
2735
    if (this.length > 1) {
2736
      res = 1;
2737
    } else {
2738
      if (negative) {
2739
        num = -num;
2740
      }
2741

    
2742
      assert(num <= 0x3ffffff, 'Number is too big');
2743

    
2744
      var w = this.words[0] | 0;
2745
      res = w === num ? 0 : w < num ? -1 : 1;
2746
    }
2747
    if (this.negative !== 0) return -res | 0;
2748
    return res;
2749
  };
2750

    
2751
  // Compare two numbers and return:
2752
  // 1 - if `this` > `num`
2753
  // 0 - if `this` == `num`
2754
  // -1 - if `this` < `num`
2755
  BN.prototype.cmp = function cmp (num) {
2756
    if (this.negative !== 0 && num.negative === 0) return -1;
2757
    if (this.negative === 0 && num.negative !== 0) return 1;
2758

    
2759
    var res = this.ucmp(num);
2760
    if (this.negative !== 0) return -res | 0;
2761
    return res;
2762
  };
2763

    
2764
  // Unsigned comparison
2765
  BN.prototype.ucmp = function ucmp (num) {
2766
    // At this point both numbers have the same sign
2767
    if (this.length > num.length) return 1;
2768
    if (this.length < num.length) return -1;
2769

    
2770
    var res = 0;
2771
    for (var i = this.length - 1; i >= 0; i--) {
2772
      var a = this.words[i] | 0;
2773
      var b = num.words[i] | 0;
2774

    
2775
      if (a === b) continue;
2776
      if (a < b) {
2777
        res = -1;
2778
      } else if (a > b) {
2779
        res = 1;
2780
      }
2781
      break;
2782
    }
2783
    return res;
2784
  };
2785

    
2786
  BN.prototype.gtn = function gtn (num) {
2787
    return this.cmpn(num) === 1;
2788
  };
2789

    
2790
  BN.prototype.gt = function gt (num) {
2791
    return this.cmp(num) === 1;
2792
  };
2793

    
2794
  BN.prototype.gten = function gten (num) {
2795
    return this.cmpn(num) >= 0;
2796
  };
2797

    
2798
  BN.prototype.gte = function gte (num) {
2799
    return this.cmp(num) >= 0;
2800
  };
2801

    
2802
  BN.prototype.ltn = function ltn (num) {
2803
    return this.cmpn(num) === -1;
2804
  };
2805

    
2806
  BN.prototype.lt = function lt (num) {
2807
    return this.cmp(num) === -1;
2808
  };
2809

    
2810
  BN.prototype.lten = function lten (num) {
2811
    return this.cmpn(num) <= 0;
2812
  };
2813

    
2814
  BN.prototype.lte = function lte (num) {
2815
    return this.cmp(num) <= 0;
2816
  };
2817

    
2818
  BN.prototype.eqn = function eqn (num) {
2819
    return this.cmpn(num) === 0;
2820
  };
2821

    
2822
  BN.prototype.eq = function eq (num) {
2823
    return this.cmp(num) === 0;
2824
  };
2825

    
2826
  //
2827
  // A reduce context, could be using montgomery or something better, depending
2828
  // on the `m` itself.
2829
  //
2830
  BN.red = function red (num) {
2831
    return new Red(num);
2832
  };
2833

    
2834
  BN.prototype.toRed = function toRed (ctx) {
2835
    assert(!this.red, 'Already a number in reduction context');
2836
    assert(this.negative === 0, 'red works only with positives');
2837
    return ctx.convertTo(this)._forceRed(ctx);
2838
  };
2839

    
2840
  BN.prototype.fromRed = function fromRed () {
2841
    assert(this.red, 'fromRed works only with numbers in reduction context');
2842
    return this.red.convertFrom(this);
2843
  };
2844

    
2845
  BN.prototype._forceRed = function _forceRed (ctx) {
2846
    this.red = ctx;
2847
    return this;
2848
  };
2849

    
2850
  BN.prototype.forceRed = function forceRed (ctx) {
2851
    assert(!this.red, 'Already a number in reduction context');
2852
    return this._forceRed(ctx);
2853
  };
2854

    
2855
  BN.prototype.redAdd = function redAdd (num) {
2856
    assert(this.red, 'redAdd works only with red numbers');
2857
    return this.red.add(this, num);
2858
  };
2859

    
2860
  BN.prototype.redIAdd = function redIAdd (num) {
2861
    assert(this.red, 'redIAdd works only with red numbers');
2862
    return this.red.iadd(this, num);
2863
  };
2864

    
2865
  BN.prototype.redSub = function redSub (num) {
2866
    assert(this.red, 'redSub works only with red numbers');
2867
    return this.red.sub(this, num);
2868
  };
2869

    
2870
  BN.prototype.redISub = function redISub (num) {
2871
    assert(this.red, 'redISub works only with red numbers');
2872
    return this.red.isub(this, num);
2873
  };
2874

    
2875
  BN.prototype.redShl = function redShl (num) {
2876
    assert(this.red, 'redShl works only with red numbers');
2877
    return this.red.shl(this, num);
2878
  };
2879

    
2880
  BN.prototype.redMul = function redMul (num) {
2881
    assert(this.red, 'redMul works only with red numbers');
2882
    this.red._verify2(this, num);
2883
    return this.red.mul(this, num);
2884
  };
2885

    
2886
  BN.prototype.redIMul = function redIMul (num) {
2887
    assert(this.red, 'redMul works only with red numbers');
2888
    this.red._verify2(this, num);
2889
    return this.red.imul(this, num);
2890
  };
2891

    
2892
  BN.prototype.redSqr = function redSqr () {
2893
    assert(this.red, 'redSqr works only with red numbers');
2894
    this.red._verify1(this);
2895
    return this.red.sqr(this);
2896
  };
2897

    
2898
  BN.prototype.redISqr = function redISqr () {
2899
    assert(this.red, 'redISqr works only with red numbers');
2900
    this.red._verify1(this);
2901
    return this.red.isqr(this);
2902
  };
2903

    
2904
  // Square root over p
2905
  BN.prototype.redSqrt = function redSqrt () {
2906
    assert(this.red, 'redSqrt works only with red numbers');
2907
    this.red._verify1(this);
2908
    return this.red.sqrt(this);
2909
  };
2910

    
2911
  BN.prototype.redInvm = function redInvm () {
2912
    assert(this.red, 'redInvm works only with red numbers');
2913
    this.red._verify1(this);
2914
    return this.red.invm(this);
2915
  };
2916

    
2917
  // Return negative clone of `this` % `red modulo`
2918
  BN.prototype.redNeg = function redNeg () {
2919
    assert(this.red, 'redNeg works only with red numbers');
2920
    this.red._verify1(this);
2921
    return this.red.neg(this);
2922
  };
2923

    
2924
  BN.prototype.redPow = function redPow (num) {
2925
    assert(this.red && !num.red, 'redPow(normalNum)');
2926
    this.red._verify1(this);
2927
    return this.red.pow(this, num);
2928
  };
2929

    
2930
  // Prime numbers with efficient reduction
2931
  var primes = {
2932
    k256: null,
2933
    p224: null,
2934
    p192: null,
2935
    p25519: null
2936
  };
2937

    
2938
  // Pseudo-Mersenne prime
2939
  function MPrime (name, p) {
2940
    // P = 2 ^ N - K
2941
    this.name = name;
2942
    this.p = new BN(p, 16);
2943
    this.n = this.p.bitLength();
2944
    this.k = new BN(1).iushln(this.n).isub(this.p);
2945

    
2946
    this.tmp = this._tmp();
2947
  }
2948

    
2949
  MPrime.prototype._tmp = function _tmp () {
2950
    var tmp = new BN(null);
2951
    tmp.words = new Array(Math.ceil(this.n / 13));
2952
    return tmp;
2953
  };
2954

    
2955
  MPrime.prototype.ireduce = function ireduce (num) {
2956
    // Assumes that `num` is less than `P^2`
2957
    // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
2958
    var r = num;
2959
    var rlen;
2960

    
2961
    do {
2962
      this.split(r, this.tmp);
2963
      r = this.imulK(r);
2964
      r = r.iadd(this.tmp);
2965
      rlen = r.bitLength();
2966
    } while (rlen > this.n);
2967

    
2968
    var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
2969
    if (cmp === 0) {
2970
      r.words[0] = 0;
2971
      r.length = 1;
2972
    } else if (cmp > 0) {
2973
      r.isub(this.p);
2974
    } else {
2975
      r.strip();
2976
    }
2977

    
2978
    return r;
2979
  };
2980

    
2981
  MPrime.prototype.split = function split (input, out) {
2982
    input.iushrn(this.n, 0, out);
2983
  };
2984

    
2985
  MPrime.prototype.imulK = function imulK (num) {
2986
    return num.imul(this.k);
2987
  };
2988

    
2989
  function K256 () {
2990
    MPrime.call(
2991
      this,
2992
      'k256',
2993
      'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
2994
  }
2995
  inherits(K256, MPrime);
2996

    
2997
  K256.prototype.split = function split (input, output) {
2998
    // 256 = 9 * 26 + 22
2999
    var mask = 0x3fffff;
3000

    
3001
    var outLen = Math.min(input.length, 9);
3002
    for (var i = 0; i < outLen; i++) {
3003
      output.words[i] = input.words[i];
3004
    }
3005
    output.length = outLen;
3006

    
3007
    if (input.length <= 9) {
3008
      input.words[0] = 0;
3009
      input.length = 1;
3010
      return;
3011
    }
3012

    
3013
    // Shift by 9 limbs
3014
    var prev = input.words[9];
3015
    output.words[output.length++] = prev & mask;
3016

    
3017
    for (i = 10; i < input.length; i++) {
3018
      var next = input.words[i] | 0;
3019
      input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
3020
      prev = next;
3021
    }
3022
    prev >>>= 22;
3023
    input.words[i - 10] = prev;
3024
    if (prev === 0 && input.length > 10) {
3025
      input.length -= 10;
3026
    } else {
3027
      input.length -= 9;
3028
    }
3029
  };
3030

    
3031
  K256.prototype.imulK = function imulK (num) {
3032
    // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
3033
    num.words[num.length] = 0;
3034
    num.words[num.length + 1] = 0;
3035
    num.length += 2;
3036

    
3037
    // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
3038
    var lo = 0;
3039
    for (var i = 0; i < num.length; i++) {
3040
      var w = num.words[i] | 0;
3041
      lo += w * 0x3d1;
3042
      num.words[i] = lo & 0x3ffffff;
3043
      lo = w * 0x40 + ((lo / 0x4000000) | 0);
3044
    }
3045

    
3046
    // Fast length reduction
3047
    if (num.words[num.length - 1] === 0) {
3048
      num.length--;
3049
      if (num.words[num.length - 1] === 0) {
3050
        num.length--;
3051
      }
3052
    }
3053
    return num;
3054
  };
3055

    
3056
  function P224 () {
3057
    MPrime.call(
3058
      this,
3059
      'p224',
3060
      'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
3061
  }
3062
  inherits(P224, MPrime);
3063

    
3064
  function P192 () {
3065
    MPrime.call(
3066
      this,
3067
      'p192',
3068
      'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
3069
  }
3070
  inherits(P192, MPrime);
3071

    
3072
  function P25519 () {
3073
    // 2 ^ 255 - 19
3074
    MPrime.call(
3075
      this,
3076
      '25519',
3077
      '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
3078
  }
3079
  inherits(P25519, MPrime);
3080

    
3081
  P25519.prototype.imulK = function imulK (num) {
3082
    // K = 0x13
3083
    var carry = 0;
3084
    for (var i = 0; i < num.length; i++) {
3085
      var hi = (num.words[i] | 0) * 0x13 + carry;
3086
      var lo = hi & 0x3ffffff;
3087
      hi >>>= 26;
3088

    
3089
      num.words[i] = lo;
3090
      carry = hi;
3091
    }
3092
    if (carry !== 0) {
3093
      num.words[num.length++] = carry;
3094
    }
3095
    return num;
3096
  };
3097

    
3098
  // Exported mostly for testing purposes, use plain name instead
3099
  BN._prime = function prime (name) {
3100
    // Cached version of prime
3101
    if (primes[name]) return primes[name];
3102

    
3103
    var prime;
3104
    if (name === 'k256') {
3105
      prime = new K256();
3106
    } else if (name === 'p224') {
3107
      prime = new P224();
3108
    } else if (name === 'p192') {
3109
      prime = new P192();
3110
    } else if (name === 'p25519') {
3111
      prime = new P25519();
3112
    } else {
3113
      throw new Error('Unknown prime ' + name);
3114
    }
3115
    primes[name] = prime;
3116

    
3117
    return prime;
3118
  };
3119

    
3120
  //
3121
  // Base reduction engine
3122
  //
3123
  function Red (m) {
3124
    if (typeof m === 'string') {
3125
      var prime = BN._prime(m);
3126
      this.m = prime.p;
3127
      this.prime = prime;
3128
    } else {
3129
      assert(m.gtn(1), 'modulus must be greater than 1');
3130
      this.m = m;
3131
      this.prime = null;
3132
    }
3133
  }
3134

    
3135
  Red.prototype._verify1 = function _verify1 (a) {
3136
    assert(a.negative === 0, 'red works only with positives');
3137
    assert(a.red, 'red works only with red numbers');
3138
  };
3139

    
3140
  Red.prototype._verify2 = function _verify2 (a, b) {
3141
    assert((a.negative | b.negative) === 0, 'red works only with positives');
3142
    assert(a.red && a.red === b.red,
3143
      'red works only with red numbers');
3144
  };
3145

    
3146
  Red.prototype.imod = function imod (a) {
3147
    if (this.prime) return this.prime.ireduce(a)._forceRed(this);
3148
    return a.umod(this.m)._forceRed(this);
3149
  };
3150

    
3151
  Red.prototype.neg = function neg (a) {
3152
    if (a.isZero()) {
3153
      return a.clone();
3154
    }
3155

    
3156
    return this.m.sub(a)._forceRed(this);
3157
  };
3158

    
3159
  Red.prototype.add = function add (a, b) {
3160
    this._verify2(a, b);
3161

    
3162
    var res = a.add(b);
3163
    if (res.cmp(this.m) >= 0) {
3164
      res.isub(this.m);
3165
    }
3166
    return res._forceRed(this);
3167
  };
3168

    
3169
  Red.prototype.iadd = function iadd (a, b) {
3170
    this._verify2(a, b);
3171

    
3172
    var res = a.iadd(b);
3173
    if (res.cmp(this.m) >= 0) {
3174
      res.isub(this.m);
3175
    }
3176
    return res;
3177
  };
3178

    
3179
  Red.prototype.sub = function sub (a, b) {
3180
    this._verify2(a, b);
3181

    
3182
    var res = a.sub(b);
3183
    if (res.cmpn(0) < 0) {
3184
      res.iadd(this.m);
3185
    }
3186
    return res._forceRed(this);
3187
  };
3188

    
3189
  Red.prototype.isub = function isub (a, b) {
3190
    this._verify2(a, b);
3191

    
3192
    var res = a.isub(b);
3193
    if (res.cmpn(0) < 0) {
3194
      res.iadd(this.m);
3195
    }
3196
    return res;
3197
  };
3198

    
3199
  Red.prototype.shl = function shl (a, num) {
3200
    this._verify1(a);
3201
    return this.imod(a.ushln(num));
3202
  };
3203

    
3204
  Red.prototype.imul = function imul (a, b) {
3205
    this._verify2(a, b);
3206
    return this.imod(a.imul(b));
3207
  };
3208

    
3209
  Red.prototype.mul = function mul (a, b) {
3210
    this._verify2(a, b);
3211
    return this.imod(a.mul(b));
3212
  };
3213

    
3214
  Red.prototype.isqr = function isqr (a) {
3215
    return this.imul(a, a.clone());
3216
  };
3217

    
3218
  Red.prototype.sqr = function sqr (a) {
3219
    return this.mul(a, a);
3220
  };
3221

    
3222
  Red.prototype.sqrt = function sqrt (a) {
3223
    if (a.isZero()) return a.clone();
3224

    
3225
    var mod3 = this.m.andln(3);
3226
    assert(mod3 % 2 === 1);
3227

    
3228
    // Fast case
3229
    if (mod3 === 3) {
3230
      var pow = this.m.add(new BN(1)).iushrn(2);
3231
      return this.pow(a, pow);
3232
    }
3233

    
3234
    // Tonelli-Shanks algorithm (Totally unoptimized and slow)
3235
    //
3236
    // Find Q and S, that Q * 2 ^ S = (P - 1)
3237
    var q = this.m.subn(1);
3238
    var s = 0;
3239
    while (!q.isZero() && q.andln(1) === 0) {
3240
      s++;
3241
      q.iushrn(1);
3242
    }
3243
    assert(!q.isZero());
3244

    
3245
    var one = new BN(1).toRed(this);
3246
    var nOne = one.redNeg();
3247

    
3248
    // Find quadratic non-residue
3249
    // NOTE: Max is such because of generalized Riemann hypothesis.
3250
    var lpow = this.m.subn(1).iushrn(1);
3251
    var z = this.m.bitLength();
3252
    z = new BN(2 * z * z).toRed(this);
3253

    
3254
    while (this.pow(z, lpow).cmp(nOne) !== 0) {
3255
      z.redIAdd(nOne);
3256
    }
3257

    
3258
    var c = this.pow(z, q);
3259
    var r = this.pow(a, q.addn(1).iushrn(1));
3260
    var t = this.pow(a, q);
3261
    var m = s;
3262
    while (t.cmp(one) !== 0) {
3263
      var tmp = t;
3264
      for (var i = 0; tmp.cmp(one) !== 0; i++) {
3265
        tmp = tmp.redSqr();
3266
      }
3267
      assert(i < m);
3268
      var b = this.pow(c, new BN(1).iushln(m - i - 1));
3269

    
3270
      r = r.redMul(b);
3271
      c = b.redSqr();
3272
      t = t.redMul(c);
3273
      m = i;
3274
    }
3275

    
3276
    return r;
3277
  };
3278

    
3279
  Red.prototype.invm = function invm (a) {
3280
    var inv = a._invmp(this.m);
3281
    if (inv.negative !== 0) {
3282
      inv.negative = 0;
3283
      return this.imod(inv).redNeg();
3284
    } else {
3285
      return this.imod(inv);
3286
    }
3287
  };
3288

    
3289
  Red.prototype.pow = function pow (a, num) {
3290
    if (num.isZero()) return new BN(1).toRed(this);
3291
    if (num.cmpn(1) === 0) return a.clone();
3292

    
3293
    var windowSize = 4;
3294
    var wnd = new Array(1 << windowSize);
3295
    wnd[0] = new BN(1).toRed(this);
3296
    wnd[1] = a;
3297
    for (var i = 2; i < wnd.length; i++) {
3298
      wnd[i] = this.mul(wnd[i - 1], a);
3299
    }
3300

    
3301
    var res = wnd[0];
3302
    var current = 0;
3303
    var currentLen = 0;
3304
    var start = num.bitLength() % 26;
3305
    if (start === 0) {
3306
      start = 26;
3307
    }
3308

    
3309
    for (i = num.length - 1; i >= 0; i--) {
3310
      var word = num.words[i];
3311
      for (var j = start - 1; j >= 0; j--) {
3312
        var bit = (word >> j) & 1;
3313
        if (res !== wnd[0]) {
3314
          res = this.sqr(res);
3315
        }
3316

    
3317
        if (bit === 0 && current === 0) {
3318
          currentLen = 0;
3319
          continue;
3320
        }
3321

    
3322
        current <<= 1;
3323
        current |= bit;
3324
        currentLen++;
3325
        if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
3326

    
3327
        res = this.mul(res, wnd[current]);
3328
        currentLen = 0;
3329
        current = 0;
3330
      }
3331
      start = 26;
3332
    }
3333

    
3334
    return res;
3335
  };
3336

    
3337
  Red.prototype.convertTo = function convertTo (num) {
3338
    var r = num.umod(this.m);
3339

    
3340
    return r === num ? r.clone() : r;
3341
  };
3342

    
3343
  Red.prototype.convertFrom = function convertFrom (num) {
3344
    var res = num.clone();
3345
    res.red = null;
3346
    return res;
3347
  };
3348

    
3349
  //
3350
  // Montgomery method engine
3351
  //
3352

    
3353
  BN.mont = function mont (num) {
3354
    return new Mont(num);
3355
  };
3356

    
3357
  function Mont (m) {
3358
    Red.call(this, m);
3359

    
3360
    this.shift = this.m.bitLength();
3361
    if (this.shift % 26 !== 0) {
3362
      this.shift += 26 - (this.shift % 26);
3363
    }
3364

    
3365
    this.r = new BN(1).iushln(this.shift);
3366
    this.r2 = this.imod(this.r.sqr());
3367
    this.rinv = this.r._invmp(this.m);
3368

    
3369
    this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
3370
    this.minv = this.minv.umod(this.r);
3371
    this.minv = this.r.sub(this.minv);
3372
  }
3373
  inherits(Mont, Red);
3374

    
3375
  Mont.prototype.convertTo = function convertTo (num) {
3376
    return this.imod(num.ushln(this.shift));
3377
  };
3378

    
3379
  Mont.prototype.convertFrom = function convertFrom (num) {
3380
    var r = this.imod(num.mul(this.rinv));
3381
    r.red = null;
3382
    return r;
3383
  };
3384

    
3385
  Mont.prototype.imul = function imul (a, b) {
3386
    if (a.isZero() || b.isZero()) {
3387
      a.words[0] = 0;
3388
      a.length = 1;
3389
      return a;
3390
    }
3391

    
3392
    var t = a.imul(b);
3393
    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
3394
    var u = t.isub(c).iushrn(this.shift);
3395
    var res = u;
3396

    
3397
    if (u.cmp(this.m) >= 0) {
3398
      res = u.isub(this.m);
3399
    } else if (u.cmpn(0) < 0) {
3400
      res = u.iadd(this.m);
3401
    }
3402

    
3403
    return res._forceRed(this);
3404
  };
3405

    
3406
  Mont.prototype.mul = function mul (a, b) {
3407
    if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
3408

    
3409
    var t = a.mul(b);
3410
    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
3411
    var u = t.isub(c).iushrn(this.shift);
3412
    var res = u;
3413
    if (u.cmp(this.m) >= 0) {
3414
      res = u.isub(this.m);
3415
    } else if (u.cmpn(0) < 0) {
3416
      res = u.iadd(this.m);
3417
    }
3418

    
3419
    return res._forceRed(this);
3420
  };
3421

    
3422
  Mont.prototype.invm = function invm (a) {
3423
    // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
3424
    var res = this.imod(a._invmp(this.m).mul(this.r2));
3425
    return res._forceRed(this);
3426
  };
3427
})(typeof module === 'undefined' || module, this);
    (1-1/1)