UNPKG

19.4 kBJavaScriptView Raw
1// A small implementation of BigInteger based on http://www-cs-students.stanford.edu/~tjw/jsbn/
2//
3// All public methods have been removed except the following:
4// new BigInteger(a, b) (only radix 2, 4, 8, 16 and 32 supported)
5// toString (only radix 2, 4, 8, 16 and 32 supported)
6// negate
7// abs
8// compareTo
9// bitLength
10// mod
11// equals
12// add
13// subtract
14// multiply
15// divide
16// modPow
17export default BigInteger;
18/*
19 * Copyright (c) 2003-2005 Tom Wu
20 * All Rights Reserved.
21 *
22 * Permission is hereby granted, free of charge, to any person obtaining
23 * a copy of this software and associated documentation files (the
24 * "Software"), to deal in the Software without restriction, including
25 * without limitation the rights to use, copy, modify, merge, publish,
26 * distribute, sublicense, and/or sell copies of the Software, and to
27 * permit persons to whom the Software is furnished to do so, subject to
28 * the following conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
35 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
36 *
37 * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
38 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
39 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
40 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
41 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 *
43 * In addition, the following condition applies:
44 *
45 * All redistributions must retain an intact copy of this copyright notice
46 * and disclaimer.
47 */
48// (public) Constructor
49
50function BigInteger(a, b) {
51 if (a != null) this.fromString(a, b);
52} // return new, unset BigInteger
53
54
55function nbi() {
56 return new BigInteger(null);
57} // Bits per digit
58
59
60var dbits; // JavaScript engine analysis
61
62var canary = 0xdeadbeefcafe;
63var j_lm = (canary & 0xffffff) == 0xefcafe; // am: Compute w_j += (x*this_i), propagate carries,
64// c is initial carry, returns final carry.
65// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
66// We need to select the fastest one that works in this environment.
67// am1: use a single mult and divide to get the high bits,
68// max digit bits should be 26 because
69// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
70
71function am1(i, x, w, j, c, n) {
72 while (--n >= 0) {
73 var v = x * this[i++] + w[j] + c;
74 c = Math.floor(v / 0x4000000);
75 w[j++] = v & 0x3ffffff;
76 }
77
78 return c;
79} // am2 avoids a big mult-and-extract completely.
80// Max digit bits should be <= 30 because we do bitwise ops
81// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
82
83
84function am2(i, x, w, j, c, n) {
85 var xl = x & 0x7fff,
86 xh = x >> 15;
87
88 while (--n >= 0) {
89 var l = this[i] & 0x7fff;
90 var h = this[i++] >> 15;
91 var m = xh * l + h * xl;
92 l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
93 c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
94 w[j++] = l & 0x3fffffff;
95 }
96
97 return c;
98} // Alternately, set max digit bits to 28 since some
99// browsers slow down when dealing with 32-bit numbers.
100
101
102function am3(i, x, w, j, c, n) {
103 var xl = x & 0x3fff,
104 xh = x >> 14;
105
106 while (--n >= 0) {
107 var l = this[i] & 0x3fff;
108 var h = this[i++] >> 14;
109 var m = xh * l + h * xl;
110 l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
111 c = (l >> 28) + (m >> 14) + xh * h;
112 w[j++] = l & 0xfffffff;
113 }
114
115 return c;
116}
117
118var inBrowser = typeof navigator !== 'undefined';
119
120if (inBrowser && j_lm && navigator.appName == 'Microsoft Internet Explorer') {
121 BigInteger.prototype.am = am2;
122 dbits = 30;
123} else if (inBrowser && j_lm && navigator.appName != 'Netscape') {
124 BigInteger.prototype.am = am1;
125 dbits = 26;
126} else {
127 // Mozilla/Netscape seems to prefer am3
128 BigInteger.prototype.am = am3;
129 dbits = 28;
130}
131
132BigInteger.prototype.DB = dbits;
133BigInteger.prototype.DM = (1 << dbits) - 1;
134BigInteger.prototype.DV = 1 << dbits;
135var BI_FP = 52;
136BigInteger.prototype.FV = Math.pow(2, BI_FP);
137BigInteger.prototype.F1 = BI_FP - dbits;
138BigInteger.prototype.F2 = 2 * dbits - BI_FP; // Digit conversions
139
140var BI_RM = '0123456789abcdefghijklmnopqrstuvwxyz';
141var BI_RC = new Array();
142var rr, vv;
143rr = '0'.charCodeAt(0);
144
145for (vv = 0; vv <= 9; ++vv) {
146 BI_RC[rr++] = vv;
147}
148
149rr = 'a'.charCodeAt(0);
150
151for (vv = 10; vv < 36; ++vv) {
152 BI_RC[rr++] = vv;
153}
154
155rr = 'A'.charCodeAt(0);
156
157for (vv = 10; vv < 36; ++vv) {
158 BI_RC[rr++] = vv;
159}
160
161function int2char(n) {
162 return BI_RM.charAt(n);
163}
164
165function intAt(s, i) {
166 var c = BI_RC[s.charCodeAt(i)];
167 return c == null ? -1 : c;
168} // (protected) copy this to r
169
170
171function bnpCopyTo(r) {
172 for (var i = this.t - 1; i >= 0; --i) {
173 r[i] = this[i];
174 }
175
176 r.t = this.t;
177 r.s = this.s;
178} // (protected) set from integer value x, -DV <= x < DV
179
180
181function bnpFromInt(x) {
182 this.t = 1;
183 this.s = x < 0 ? -1 : 0;
184 if (x > 0) this[0] = x;else if (x < -1) this[0] = x + this.DV;else this.t = 0;
185} // return bigint initialized to value
186
187
188function nbv(i) {
189 var r = nbi();
190 r.fromInt(i);
191 return r;
192} // (protected) set from string and radix
193
194
195function bnpFromString(s, b) {
196 var k;
197 if (b == 16) k = 4;else if (b == 8) k = 3;else if (b == 2) k = 1;else if (b == 32) k = 5;else if (b == 4) k = 2;else throw new Error('Only radix 2, 4, 8, 16, 32 are supported');
198 this.t = 0;
199 this.s = 0;
200 var i = s.length,
201 mi = false,
202 sh = 0;
203
204 while (--i >= 0) {
205 var x = intAt(s, i);
206
207 if (x < 0) {
208 if (s.charAt(i) == '-') mi = true;
209 continue;
210 }
211
212 mi = false;
213 if (sh == 0) this[this.t++] = x;else if (sh + k > this.DB) {
214 this[this.t - 1] |= (x & (1 << this.DB - sh) - 1) << sh;
215 this[this.t++] = x >> this.DB - sh;
216 } else this[this.t - 1] |= x << sh;
217 sh += k;
218 if (sh >= this.DB) sh -= this.DB;
219 }
220
221 this.clamp();
222 if (mi) BigInteger.ZERO.subTo(this, this);
223} // (protected) clamp off excess high words
224
225
226function bnpClamp() {
227 var c = this.s & this.DM;
228
229 while (this.t > 0 && this[this.t - 1] == c) {
230 --this.t;
231 }
232} // (public) return string representation in given radix
233
234
235function bnToString(b) {
236 if (this.s < 0) return '-' + this.negate().toString(b);
237 var k;
238 if (b == 16) k = 4;else if (b == 8) k = 3;else if (b == 2) k = 1;else if (b == 32) k = 5;else if (b == 4) k = 2;else throw new Error('Only radix 2, 4, 8, 16, 32 are supported');
239 var km = (1 << k) - 1,
240 d,
241 m = false,
242 r = '',
243 i = this.t;
244 var p = this.DB - i * this.DB % k;
245
246 if (i-- > 0) {
247 if (p < this.DB && (d = this[i] >> p) > 0) {
248 m = true;
249 r = int2char(d);
250 }
251
252 while (i >= 0) {
253 if (p < k) {
254 d = (this[i] & (1 << p) - 1) << k - p;
255 d |= this[--i] >> (p += this.DB - k);
256 } else {
257 d = this[i] >> (p -= k) & km;
258
259 if (p <= 0) {
260 p += this.DB;
261 --i;
262 }
263 }
264
265 if (d > 0) m = true;
266 if (m) r += int2char(d);
267 }
268 }
269
270 return m ? r : '0';
271} // (public) -this
272
273
274function bnNegate() {
275 var r = nbi();
276 BigInteger.ZERO.subTo(this, r);
277 return r;
278} // (public) |this|
279
280
281function bnAbs() {
282 return this.s < 0 ? this.negate() : this;
283} // (public) return + if this > a, - if this < a, 0 if equal
284
285
286function bnCompareTo(a) {
287 var r = this.s - a.s;
288 if (r != 0) return r;
289 var i = this.t;
290 r = i - a.t;
291 if (r != 0) return this.s < 0 ? -r : r;
292
293 while (--i >= 0) {
294 if ((r = this[i] - a[i]) != 0) return r;
295 }
296
297 return 0;
298} // returns bit length of the integer x
299
300
301function nbits(x) {
302 var r = 1,
303 t;
304
305 if ((t = x >>> 16) != 0) {
306 x = t;
307 r += 16;
308 }
309
310 if ((t = x >> 8) != 0) {
311 x = t;
312 r += 8;
313 }
314
315 if ((t = x >> 4) != 0) {
316 x = t;
317 r += 4;
318 }
319
320 if ((t = x >> 2) != 0) {
321 x = t;
322 r += 2;
323 }
324
325 if ((t = x >> 1) != 0) {
326 x = t;
327 r += 1;
328 }
329
330 return r;
331} // (public) return the number of bits in "this"
332
333
334function bnBitLength() {
335 if (this.t <= 0) return 0;
336 return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ this.s & this.DM);
337} // (protected) r = this << n*DB
338
339
340function bnpDLShiftTo(n, r) {
341 var i;
342
343 for (i = this.t - 1; i >= 0; --i) {
344 r[i + n] = this[i];
345 }
346
347 for (i = n - 1; i >= 0; --i) {
348 r[i] = 0;
349 }
350
351 r.t = this.t + n;
352 r.s = this.s;
353} // (protected) r = this >> n*DB
354
355
356function bnpDRShiftTo(n, r) {
357 for (var i = n; i < this.t; ++i) {
358 r[i - n] = this[i];
359 }
360
361 r.t = Math.max(this.t - n, 0);
362 r.s = this.s;
363} // (protected) r = this << n
364
365
366function bnpLShiftTo(n, r) {
367 var bs = n % this.DB;
368 var cbs = this.DB - bs;
369 var bm = (1 << cbs) - 1;
370 var ds = Math.floor(n / this.DB),
371 c = this.s << bs & this.DM,
372 i;
373
374 for (i = this.t - 1; i >= 0; --i) {
375 r[i + ds + 1] = this[i] >> cbs | c;
376 c = (this[i] & bm) << bs;
377 }
378
379 for (i = ds - 1; i >= 0; --i) {
380 r[i] = 0;
381 }
382
383 r[ds] = c;
384 r.t = this.t + ds + 1;
385 r.s = this.s;
386 r.clamp();
387} // (protected) r = this >> n
388
389
390function bnpRShiftTo(n, r) {
391 r.s = this.s;
392 var ds = Math.floor(n / this.DB);
393
394 if (ds >= this.t) {
395 r.t = 0;
396 return;
397 }
398
399 var bs = n % this.DB;
400 var cbs = this.DB - bs;
401 var bm = (1 << bs) - 1;
402 r[0] = this[ds] >> bs;
403
404 for (var i = ds + 1; i < this.t; ++i) {
405 r[i - ds - 1] |= (this[i] & bm) << cbs;
406 r[i - ds] = this[i] >> bs;
407 }
408
409 if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs;
410 r.t = this.t - ds;
411 r.clamp();
412} // (protected) r = this - a
413
414
415function bnpSubTo(a, r) {
416 var i = 0,
417 c = 0,
418 m = Math.min(a.t, this.t);
419
420 while (i < m) {
421 c += this[i] - a[i];
422 r[i++] = c & this.DM;
423 c >>= this.DB;
424 }
425
426 if (a.t < this.t) {
427 c -= a.s;
428
429 while (i < this.t) {
430 c += this[i];
431 r[i++] = c & this.DM;
432 c >>= this.DB;
433 }
434
435 c += this.s;
436 } else {
437 c += this.s;
438
439 while (i < a.t) {
440 c -= a[i];
441 r[i++] = c & this.DM;
442 c >>= this.DB;
443 }
444
445 c -= a.s;
446 }
447
448 r.s = c < 0 ? -1 : 0;
449 if (c < -1) r[i++] = this.DV + c;else if (c > 0) r[i++] = c;
450 r.t = i;
451 r.clamp();
452} // (protected) r = this * a, r != this,a (HAC 14.12)
453// "this" should be the larger one if appropriate.
454
455
456function bnpMultiplyTo(a, r) {
457 var x = this.abs(),
458 y = a.abs();
459 var i = x.t;
460 r.t = i + y.t;
461
462 while (--i >= 0) {
463 r[i] = 0;
464 }
465
466 for (i = 0; i < y.t; ++i) {
467 r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
468 }
469
470 r.s = 0;
471 r.clamp();
472 if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
473} // (protected) r = this^2, r != this (HAC 14.16)
474
475
476function bnpSquareTo(r) {
477 var x = this.abs();
478 var i = r.t = 2 * x.t;
479
480 while (--i >= 0) {
481 r[i] = 0;
482 }
483
484 for (i = 0; i < x.t - 1; ++i) {
485 var c = x.am(i, x[i], r, 2 * i, 0, 1);
486
487 if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
488 r[i + x.t] -= x.DV;
489 r[i + x.t + 1] = 1;
490 }
491 }
492
493 if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
494 r.s = 0;
495 r.clamp();
496} // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
497// r != q, this != m. q or r may be null.
498
499
500function bnpDivRemTo(m, q, r) {
501 var pm = m.abs();
502 if (pm.t <= 0) return;
503 var pt = this.abs();
504
505 if (pt.t < pm.t) {
506 if (q != null) q.fromInt(0);
507 if (r != null) this.copyTo(r);
508 return;
509 }
510
511 if (r == null) r = nbi();
512 var y = nbi(),
513 ts = this.s,
514 ms = m.s;
515 var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
516
517 if (nsh > 0) {
518 pm.lShiftTo(nsh, y);
519 pt.lShiftTo(nsh, r);
520 } else {
521 pm.copyTo(y);
522 pt.copyTo(r);
523 }
524
525 var ys = y.t;
526 var y0 = y[ys - 1];
527 if (y0 == 0) return;
528 var yt = y0 * (1 << this.F1) + (ys > 1 ? y[ys - 2] >> this.F2 : 0);
529 var d1 = this.FV / yt,
530 d2 = (1 << this.F1) / yt,
531 e = 1 << this.F2;
532 var i = r.t,
533 j = i - ys,
534 t = q == null ? nbi() : q;
535 y.dlShiftTo(j, t);
536
537 if (r.compareTo(t) >= 0) {
538 r[r.t++] = 1;
539 r.subTo(t, r);
540 }
541
542 BigInteger.ONE.dlShiftTo(ys, t);
543 t.subTo(y, y); // "negative" y so we can replace sub with am later
544
545 while (y.t < ys) {
546 y[y.t++] = 0;
547 }
548
549 while (--j >= 0) {
550 // Estimate quotient digit
551 var qd = r[--i] == y0 ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
552
553 if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) {
554 // Try it out
555 y.dlShiftTo(j, t);
556 r.subTo(t, r);
557
558 while (r[i] < --qd) {
559 r.subTo(t, r);
560 }
561 }
562 }
563
564 if (q != null) {
565 r.drShiftTo(ys, q);
566 if (ts != ms) BigInteger.ZERO.subTo(q, q);
567 }
568
569 r.t = ys;
570 r.clamp();
571 if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder
572
573 if (ts < 0) BigInteger.ZERO.subTo(r, r);
574} // (public) this mod a
575
576
577function bnMod(a) {
578 var r = nbi();
579 this.abs().divRemTo(a, null, r);
580 if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
581 return r;
582} // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
583// justification:
584// xy == 1 (mod m)
585// xy = 1+km
586// xy(2-xy) = (1+km)(1-km)
587// x[y(2-xy)] = 1-k^2m^2
588// x[y(2-xy)] == 1 (mod m^2)
589// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
590// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
591// JS multiply "overflows" differently from C/C++, so care is needed here.
592
593
594function bnpInvDigit() {
595 if (this.t < 1) return 0;
596 var x = this[0];
597 if ((x & 1) == 0) return 0;
598 var y = x & 3; // y == 1/x mod 2^2
599
600 y = y * (2 - (x & 0xf) * y) & 0xf; // y == 1/x mod 2^4
601
602 y = y * (2 - (x & 0xff) * y) & 0xff; // y == 1/x mod 2^8
603
604 y = y * (2 - ((x & 0xffff) * y & 0xffff)) & 0xffff; // y == 1/x mod 2^16
605 // last step - calculate inverse mod DV directly;
606 // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
607
608 y = y * (2 - x * y % this.DV) % this.DV; // y == 1/x mod 2^dbits
609 // we really want the negative inverse, and -DV < y < DV
610
611 return y > 0 ? this.DV - y : -y;
612}
613
614function bnEquals(a) {
615 return this.compareTo(a) == 0;
616} // (protected) r = this + a
617
618
619function bnpAddTo(a, r) {
620 var i = 0,
621 c = 0,
622 m = Math.min(a.t, this.t);
623
624 while (i < m) {
625 c += this[i] + a[i];
626 r[i++] = c & this.DM;
627 c >>= this.DB;
628 }
629
630 if (a.t < this.t) {
631 c += a.s;
632
633 while (i < this.t) {
634 c += this[i];
635 r[i++] = c & this.DM;
636 c >>= this.DB;
637 }
638
639 c += this.s;
640 } else {
641 c += this.s;
642
643 while (i < a.t) {
644 c += a[i];
645 r[i++] = c & this.DM;
646 c >>= this.DB;
647 }
648
649 c += a.s;
650 }
651
652 r.s = c < 0 ? -1 : 0;
653 if (c > 0) r[i++] = c;else if (c < -1) r[i++] = this.DV + c;
654 r.t = i;
655 r.clamp();
656} // (public) this + a
657
658
659function bnAdd(a) {
660 var r = nbi();
661 this.addTo(a, r);
662 return r;
663} // (public) this - a
664
665
666function bnSubtract(a) {
667 var r = nbi();
668 this.subTo(a, r);
669 return r;
670} // (public) this * a
671
672
673function bnMultiply(a) {
674 var r = nbi();
675 this.multiplyTo(a, r);
676 return r;
677} // (public) this / a
678
679
680function bnDivide(a) {
681 var r = nbi();
682 this.divRemTo(a, r, null);
683 return r;
684} // Montgomery reduction
685
686
687function Montgomery(m) {
688 this.m = m;
689 this.mp = m.invDigit();
690 this.mpl = this.mp & 0x7fff;
691 this.mph = this.mp >> 15;
692 this.um = (1 << m.DB - 15) - 1;
693 this.mt2 = 2 * m.t;
694} // xR mod m
695
696
697function montConvert(x) {
698 var r = nbi();
699 x.abs().dlShiftTo(this.m.t, r);
700 r.divRemTo(this.m, null, r);
701 if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
702 return r;
703} // x/R mod m
704
705
706function montRevert(x) {
707 var r = nbi();
708 x.copyTo(r);
709 this.reduce(r);
710 return r;
711} // x = x/R mod m (HAC 14.32)
712
713
714function montReduce(x) {
715 while (x.t <= this.mt2) {
716 // pad x so am has enough room later
717 x[x.t++] = 0;
718 }
719
720 for (var i = 0; i < this.m.t; ++i) {
721 // faster way of calculating u0 = x[i]*mp mod DV
722 var j = x[i] & 0x7fff;
723 var u0 = j * this.mpl + ((j * this.mph + (x[i] >> 15) * this.mpl & this.um) << 15) & x.DM; // use am to combine the multiply-shift-add into one call
724
725 j = i + this.m.t;
726 x[j] += this.m.am(0, u0, x, i, 0, this.m.t); // propagate carry
727
728 while (x[j] >= x.DV) {
729 x[j] -= x.DV;
730 x[++j]++;
731 }
732 }
733
734 x.clamp();
735 x.drShiftTo(this.m.t, x);
736 if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
737} // r = "x^2/R mod m"; x != r
738
739
740function montSqrTo(x, r) {
741 x.squareTo(r);
742 this.reduce(r);
743} // r = "xy/R mod m"; x,y != r
744
745
746function montMulTo(x, y, r) {
747 x.multiplyTo(y, r);
748 this.reduce(r);
749}
750
751Montgomery.prototype.convert = montConvert;
752Montgomery.prototype.revert = montRevert;
753Montgomery.prototype.reduce = montReduce;
754Montgomery.prototype.mulTo = montMulTo;
755Montgomery.prototype.sqrTo = montSqrTo; // (public) this^e % m (HAC 14.85)
756
757function bnModPow(e, m, callback) {
758 var i = e.bitLength(),
759 k,
760 r = nbv(1),
761 z = new Montgomery(m);
762 if (i <= 0) return r;else if (i < 18) k = 1;else if (i < 48) k = 3;else if (i < 144) k = 4;else if (i < 768) k = 5;else k = 6; // precomputation
763
764 var g = new Array(),
765 n = 3,
766 k1 = k - 1,
767 km = (1 << k) - 1;
768 g[1] = z.convert(this);
769
770 if (k > 1) {
771 var g2 = nbi();
772 z.sqrTo(g[1], g2);
773
774 while (n <= km) {
775 g[n] = nbi();
776 z.mulTo(g2, g[n - 2], g[n]);
777 n += 2;
778 }
779 }
780
781 var j = e.t - 1,
782 w,
783 is1 = true,
784 r2 = nbi(),
785 t;
786 i = nbits(e[j]) - 1;
787
788 while (j >= 0) {
789 if (i >= k1) w = e[j] >> i - k1 & km;else {
790 w = (e[j] & (1 << i + 1) - 1) << k1 - i;
791 if (j > 0) w |= e[j - 1] >> this.DB + i - k1;
792 }
793 n = k;
794
795 while ((w & 1) == 0) {
796 w >>= 1;
797 --n;
798 }
799
800 if ((i -= n) < 0) {
801 i += this.DB;
802 --j;
803 }
804
805 if (is1) {
806 // ret == 1, don't bother squaring or multiplying it
807 g[w].copyTo(r);
808 is1 = false;
809 } else {
810 while (n > 1) {
811 z.sqrTo(r, r2);
812 z.sqrTo(r2, r);
813 n -= 2;
814 }
815
816 if (n > 0) z.sqrTo(r, r2);else {
817 t = r;
818 r = r2;
819 r2 = t;
820 }
821 z.mulTo(r2, g[w], r);
822 }
823
824 while (j >= 0 && (e[j] & 1 << i) == 0) {
825 z.sqrTo(r, r2);
826 t = r;
827 r = r2;
828 r2 = t;
829
830 if (--i < 0) {
831 i = this.DB - 1;
832 --j;
833 }
834 }
835 }
836
837 var result = z.revert(r);
838 callback(null, result);
839 return result;
840} // protected
841
842
843BigInteger.prototype.copyTo = bnpCopyTo;
844BigInteger.prototype.fromInt = bnpFromInt;
845BigInteger.prototype.fromString = bnpFromString;
846BigInteger.prototype.clamp = bnpClamp;
847BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
848BigInteger.prototype.drShiftTo = bnpDRShiftTo;
849BigInteger.prototype.lShiftTo = bnpLShiftTo;
850BigInteger.prototype.rShiftTo = bnpRShiftTo;
851BigInteger.prototype.subTo = bnpSubTo;
852BigInteger.prototype.multiplyTo = bnpMultiplyTo;
853BigInteger.prototype.squareTo = bnpSquareTo;
854BigInteger.prototype.divRemTo = bnpDivRemTo;
855BigInteger.prototype.invDigit = bnpInvDigit;
856BigInteger.prototype.addTo = bnpAddTo; // public
857
858BigInteger.prototype.toString = bnToString;
859BigInteger.prototype.negate = bnNegate;
860BigInteger.prototype.abs = bnAbs;
861BigInteger.prototype.compareTo = bnCompareTo;
862BigInteger.prototype.bitLength = bnBitLength;
863BigInteger.prototype.mod = bnMod;
864BigInteger.prototype.equals = bnEquals;
865BigInteger.prototype.add = bnAdd;
866BigInteger.prototype.subtract = bnSubtract;
867BigInteger.prototype.multiply = bnMultiply;
868BigInteger.prototype.divide = bnDivide;
869BigInteger.prototype.modPow = bnModPow; // "constants"
870
871BigInteger.ZERO = nbv(0);
872BigInteger.ONE = nbv(1);
\No newline at end of file