blob: e53e00b49808a4afe2285369c2644dab30c269e4 [file] [log] [blame]
Alexander Afanasyev181a8b92013-02-28 13:28:53 -08001// Copyright (c) 2005-2009 Tom Wu
2// All Rights Reserved.
3// See "LICENSE" for details.
4
5// Extended JavaScript BN functions, required for RSA private ops.
6
7// Version 1.1: new BigInteger("0", 10) returns "proper" zero
8
9// (public)
10function bnClone() { var r = nbi(); this.copyTo(r); return r; }
11
12// (public) return value as integer
13function bnIntValue() {
14 if(this.s < 0) {
15 if(this.t == 1) return this[0]-this.DV;
16 else if(this.t == 0) return -1;
17 }
18 else if(this.t == 1) return this[0];
19 else if(this.t == 0) return 0;
20 // assumes 16 < DB < 32
21 return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
22}
23
24// (public) return value as byte
25function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
26
27// (public) return value as short (assumes DB>=16)
28function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
29
30// (protected) return x s.t. r^x < DV
31function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
32
33// (public) 0 if this == 0, 1 if this > 0
34function bnSigNum() {
35 if(this.s < 0) return -1;
36 else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
37 else return 1;
38}
39
40// (protected) convert to radix string
41function bnpToRadix(b) {
42 if(b == null) b = 10;
43 if(this.signum() == 0 || b < 2 || b > 36) return "0";
44 var cs = this.chunkSize(b);
45 var a = Math.pow(b,cs);
46 var d = nbv(a), y = nbi(), z = nbi(), r = "";
47 this.divRemTo(d,y,z);
48 while(y.signum() > 0) {
49 r = (a+z.intValue()).toString(b).substr(1) + r;
50 y.divRemTo(d,y,z);
51 }
52 return z.intValue().toString(b) + r;
53}
54
55// (protected) convert from radix string
56function bnpFromRadix(s,b) {
57 this.fromInt(0);
58 if(b == null) b = 10;
59 var cs = this.chunkSize(b);
60 var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
61 for(var i = 0; i < s.length; ++i) {
62 var x = intAt(s,i);
63 if(x < 0) {
64 if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
65 continue;
66 }
67 w = b*w+x;
68 if(++j >= cs) {
69 this.dMultiply(d);
70 this.dAddOffset(w,0);
71 j = 0;
72 w = 0;
73 }
74 }
75 if(j > 0) {
76 this.dMultiply(Math.pow(b,j));
77 this.dAddOffset(w,0);
78 }
79 if(mi) BigInteger.ZERO.subTo(this,this);
80}
81
82// (protected) alternate constructor
83function bnpFromNumber(a,b,c) {
84 if("number" == typeof b) {
85 // new BigInteger(int,int,RNG)
86 if(a < 2) this.fromInt(1);
87 else {
88 this.fromNumber(a,c);
89 if(!this.testBit(a-1)) // force MSB set
90 this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
91 if(this.isEven()) this.dAddOffset(1,0); // force odd
92 while(!this.isProbablePrime(b)) {
93 this.dAddOffset(2,0);
94 if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
95 }
96 }
97 }
98 else {
99 // new BigInteger(int,RNG)
100 var x = new Array(), t = a&7;
101 x.length = (a>>3)+1;
102 b.nextBytes(x);
103 if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
104 this.fromString(x,256);
105 }
106}
107
108// (public) convert to bigendian byte array
109function bnToByteArray() {
110 var i = this.t, r = new Array();
111 r[0] = this.s;
112 var p = this.DB-(i*this.DB)%8, d, k = 0;
113 if(i-- > 0) {
114 if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
115 r[k++] = d|(this.s<<(this.DB-p));
116 while(i >= 0) {
117 if(p < 8) {
118 d = (this[i]&((1<<p)-1))<<(8-p);
119 d |= this[--i]>>(p+=this.DB-8);
120 }
121 else {
122 d = (this[i]>>(p-=8))&0xff;
123 if(p <= 0) { p += this.DB; --i; }
124 }
125 if((d&0x80) != 0) d |= -256;
126 if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
127 if(k > 0 || d != this.s) r[k++] = d;
128 }
129 }
130 return r;
131}
132
133function bnEquals(a) { return(this.compareTo(a)==0); }
134function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
135function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
136
137// (protected) r = this op a (bitwise)
138function bnpBitwiseTo(a,op,r) {
139 var i, f, m = Math.min(a.t,this.t);
140 for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
141 if(a.t < this.t) {
142 f = a.s&this.DM;
143 for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
144 r.t = this.t;
145 }
146 else {
147 f = this.s&this.DM;
148 for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
149 r.t = a.t;
150 }
151 r.s = op(this.s,a.s);
152 r.clamp();
153}
154
155// (public) this & a
156function op_and(x,y) { return x&y; }
157function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
158
159// (public) this | a
160function op_or(x,y) { return x|y; }
161function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
162
163// (public) this ^ a
164function op_xor(x,y) { return x^y; }
165function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
166
167// (public) this & ~a
168function op_andnot(x,y) { return x&~y; }
169function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
170
171// (public) ~this
172function bnNot() {
173 var r = nbi();
174 for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
175 r.t = this.t;
176 r.s = ~this.s;
177 return r;
178}
179
180// (public) this << n
181function bnShiftLeft(n) {
182 var r = nbi();
183 if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
184 return r;
185}
186
187// (public) this >> n
188function bnShiftRight(n) {
189 var r = nbi();
190 if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
191 return r;
192}
193
194// return index of lowest 1-bit in x, x < 2^31
195function lbit(x) {
196 if(x == 0) return -1;
197 var r = 0;
198 if((x&0xffff) == 0) { x >>= 16; r += 16; }
199 if((x&0xff) == 0) { x >>= 8; r += 8; }
200 if((x&0xf) == 0) { x >>= 4; r += 4; }
201 if((x&3) == 0) { x >>= 2; r += 2; }
202 if((x&1) == 0) ++r;
203 return r;
204}
205
206// (public) returns index of lowest 1-bit (or -1 if none)
207function bnGetLowestSetBit() {
208 for(var i = 0; i < this.t; ++i)
209 if(this[i] != 0) return i*this.DB+lbit(this[i]);
210 if(this.s < 0) return this.t*this.DB;
211 return -1;
212}
213
214// return number of 1 bits in x
215function cbit(x) {
216 var r = 0;
217 while(x != 0) { x &= x-1; ++r; }
218 return r;
219}
220
221// (public) return number of set bits
222function bnBitCount() {
223 var r = 0, x = this.s&this.DM;
224 for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
225 return r;
226}
227
228// (public) true iff nth bit is set
229function bnTestBit(n) {
230 var j = Math.floor(n/this.DB);
231 if(j >= this.t) return(this.s!=0);
232 return((this[j]&(1<<(n%this.DB)))!=0);
233}
234
235// (protected) this op (1<<n)
236function bnpChangeBit(n,op) {
237 var r = BigInteger.ONE.shiftLeft(n);
238 this.bitwiseTo(r,op,r);
239 return r;
240}
241
242// (public) this | (1<<n)
243function bnSetBit(n) { return this.changeBit(n,op_or); }
244
245// (public) this & ~(1<<n)
246function bnClearBit(n) { return this.changeBit(n,op_andnot); }
247
248// (public) this ^ (1<<n)
249function bnFlipBit(n) { return this.changeBit(n,op_xor); }
250
251// (protected) r = this + a
252function bnpAddTo(a,r) {
253 var i = 0, c = 0, m = Math.min(a.t,this.t);
254 while(i < m) {
255 c += this[i]+a[i];
256 r[i++] = c&this.DM;
257 c >>= this.DB;
258 }
259 if(a.t < this.t) {
260 c += a.s;
261 while(i < this.t) {
262 c += this[i];
263 r[i++] = c&this.DM;
264 c >>= this.DB;
265 }
266 c += this.s;
267 }
268 else {
269 c += this.s;
270 while(i < a.t) {
271 c += a[i];
272 r[i++] = c&this.DM;
273 c >>= this.DB;
274 }
275 c += a.s;
276 }
277 r.s = (c<0)?-1:0;
278 if(c > 0) r[i++] = c;
279 else if(c < -1) r[i++] = this.DV+c;
280 r.t = i;
281 r.clamp();
282}
283
284// (public) this + a
285function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
286
287// (public) this - a
288function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
289
290// (public) this * a
291function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
292
293// (public) this / a
294function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
295
296// (public) this % a
297function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
298
299// (public) [this/a,this%a]
300function bnDivideAndRemainder(a) {
301 var q = nbi(), r = nbi();
302 this.divRemTo(a,q,r);
303 return new Array(q,r);
304}
305
306// (protected) this *= n, this >= 0, 1 < n < DV
307function bnpDMultiply(n) {
308 this[this.t] = this.am(0,n-1,this,0,0,this.t);
309 ++this.t;
310 this.clamp();
311}
312
313// (protected) this += n << w words, this >= 0
314function bnpDAddOffset(n,w) {
315 if(n == 0) return;
316 while(this.t <= w) this[this.t++] = 0;
317 this[w] += n;
318 while(this[w] >= this.DV) {
319 this[w] -= this.DV;
320 if(++w >= this.t) this[this.t++] = 0;
321 ++this[w];
322 }
323}
324
325// A "null" reducer
326function NullExp() {}
327function nNop(x) { return x; }
328function nMulTo(x,y,r) { x.multiplyTo(y,r); }
329function nSqrTo(x,r) { x.squareTo(r); }
330
331NullExp.prototype.convert = nNop;
332NullExp.prototype.revert = nNop;
333NullExp.prototype.mulTo = nMulTo;
334NullExp.prototype.sqrTo = nSqrTo;
335
336// (public) this^e
337function bnPow(e) { return this.exp(e,new NullExp()); }
338
339// (protected) r = lower n words of "this * a", a.t <= n
340// "this" should be the larger one if appropriate.
341function bnpMultiplyLowerTo(a,n,r) {
342 var i = Math.min(this.t+a.t,n);
343 r.s = 0; // assumes a,this >= 0
344 r.t = i;
345 while(i > 0) r[--i] = 0;
346 var j;
347 for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
348 for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
349 r.clamp();
350}
351
352// (protected) r = "this * a" without lower n words, n > 0
353// "this" should be the larger one if appropriate.
354function bnpMultiplyUpperTo(a,n,r) {
355 --n;
356 var i = r.t = this.t+a.t-n;
357 r.s = 0; // assumes a,this >= 0
358 while(--i >= 0) r[i] = 0;
359 for(i = Math.max(n-this.t,0); i < a.t; ++i)
360 r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
361 r.clamp();
362 r.drShiftTo(1,r);
363}
364
365// Barrett modular reduction
366function Barrett(m) {
367 // setup Barrett
368 this.r2 = nbi();
369 this.q3 = nbi();
370 BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
371 this.mu = this.r2.divide(m);
372 this.m = m;
373}
374
375function barrettConvert(x) {
376 if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
377 else if(x.compareTo(this.m) < 0) return x;
378 else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
379}
380
381function barrettRevert(x) { return x; }
382
383// x = x mod m (HAC 14.42)
384function barrettReduce(x) {
385 x.drShiftTo(this.m.t-1,this.r2);
386 if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
387 this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
388 this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
389 while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
390 x.subTo(this.r2,x);
391 while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
392}
393
394// r = x^2 mod m; x != r
395function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
396
397// r = x*y mod m; x,y != r
398function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
399
400Barrett.prototype.convert = barrettConvert;
401Barrett.prototype.revert = barrettRevert;
402Barrett.prototype.reduce = barrettReduce;
403Barrett.prototype.mulTo = barrettMulTo;
404Barrett.prototype.sqrTo = barrettSqrTo;
405
406// (public) this^e % m (HAC 14.85)
407function bnModPow(e,m) {
408 var i = e.bitLength(), k, r = nbv(1), z;
409 if(i <= 0) return r;
410 else if(i < 18) k = 1;
411 else if(i < 48) k = 3;
412 else if(i < 144) k = 4;
413 else if(i < 768) k = 5;
414 else k = 6;
415 if(i < 8)
416 z = new Classic(m);
417 else if(m.isEven())
418 z = new Barrett(m);
419 else
420 z = new Montgomery(m);
421
422 // precomputation
423 var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
424 g[1] = z.convert(this);
425 if(k > 1) {
426 var g2 = nbi();
427 z.sqrTo(g[1],g2);
428 while(n <= km) {
429 g[n] = nbi();
430 z.mulTo(g2,g[n-2],g[n]);
431 n += 2;
432 }
433 }
434
435 var j = e.t-1, w, is1 = true, r2 = nbi(), t;
436 i = nbits(e[j])-1;
437 while(j >= 0) {
438 if(i >= k1) w = (e[j]>>(i-k1))&km;
439 else {
440 w = (e[j]&((1<<(i+1))-1))<<(k1-i);
441 if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
442 }
443
444 n = k;
445 while((w&1) == 0) { w >>= 1; --n; }
446 if((i -= n) < 0) { i += this.DB; --j; }
447 if(is1) { // ret == 1, don't bother squaring or multiplying it
448 g[w].copyTo(r);
449 is1 = false;
450 }
451 else {
452 while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
453 if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
454 z.mulTo(r2,g[w],r);
455 }
456
457 while(j >= 0 && (e[j]&(1<<i)) == 0) {
458 z.sqrTo(r,r2); t = r; r = r2; r2 = t;
459 if(--i < 0) { i = this.DB-1; --j; }
460 }
461 }
462 return z.revert(r);
463}
464
465// (public) gcd(this,a) (HAC 14.54)
466function bnGCD(a) {
467 var x = (this.s<0)?this.negate():this.clone();
468 var y = (a.s<0)?a.negate():a.clone();
469 if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
470 var i = x.getLowestSetBit(), g = y.getLowestSetBit();
471 if(g < 0) return x;
472 if(i < g) g = i;
473 if(g > 0) {
474 x.rShiftTo(g,x);
475 y.rShiftTo(g,y);
476 }
477 while(x.signum() > 0) {
478 if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
479 if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
480 if(x.compareTo(y) >= 0) {
481 x.subTo(y,x);
482 x.rShiftTo(1,x);
483 }
484 else {
485 y.subTo(x,y);
486 y.rShiftTo(1,y);
487 }
488 }
489 if(g > 0) y.lShiftTo(g,y);
490 return y;
491}
492
493// (protected) this % n, n < 2^26
494function bnpModInt(n) {
495 if(n <= 0) return 0;
496 var d = this.DV%n, r = (this.s<0)?n-1:0;
497 if(this.t > 0)
498 if(d == 0) r = this[0]%n;
499 else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
500 return r;
501}
502
503// (public) 1/this % m (HAC 14.61)
504function bnModInverse(m) {
505 var ac = m.isEven();
506 if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
507 var u = m.clone(), v = this.clone();
508 var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
509 while(u.signum() != 0) {
510 while(u.isEven()) {
511 u.rShiftTo(1,u);
512 if(ac) {
513 if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
514 a.rShiftTo(1,a);
515 }
516 else if(!b.isEven()) b.subTo(m,b);
517 b.rShiftTo(1,b);
518 }
519 while(v.isEven()) {
520 v.rShiftTo(1,v);
521 if(ac) {
522 if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
523 c.rShiftTo(1,c);
524 }
525 else if(!d.isEven()) d.subTo(m,d);
526 d.rShiftTo(1,d);
527 }
528 if(u.compareTo(v) >= 0) {
529 u.subTo(v,u);
530 if(ac) a.subTo(c,a);
531 b.subTo(d,b);
532 }
533 else {
534 v.subTo(u,v);
535 if(ac) c.subTo(a,c);
536 d.subTo(b,d);
537 }
538 }
539 if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
540 if(d.compareTo(m) >= 0) return d.subtract(m);
541 if(d.signum() < 0) d.addTo(m,d); else return d;
542 if(d.signum() < 0) return d.add(m); else return d;
543}
544
545var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];
546var lplim = (1<<26)/lowprimes[lowprimes.length-1];
547
548// (public) test primality with certainty >= 1-.5^t
549function bnIsProbablePrime(t) {
550 var i, x = this.abs();
551 if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
552 for(i = 0; i < lowprimes.length; ++i)
553 if(x[0] == lowprimes[i]) return true;
554 return false;
555 }
556 if(x.isEven()) return false;
557 i = 1;
558 while(i < lowprimes.length) {
559 var m = lowprimes[i], j = i+1;
560 while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
561 m = x.modInt(m);
562 while(i < j) if(m%lowprimes[i++] == 0) return false;
563 }
564 return x.millerRabin(t);
565}
566
567// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
568function bnpMillerRabin(t) {
569 var n1 = this.subtract(BigInteger.ONE);
570 var k = n1.getLowestSetBit();
571 if(k <= 0) return false;
572 var r = n1.shiftRight(k);
573 t = (t+1)>>1;
574 if(t > lowprimes.length) t = lowprimes.length;
575 var a = nbi();
576 for(var i = 0; i < t; ++i) {
577 a.fromInt(lowprimes[i]);
578 var y = a.modPow(r,this);
579 if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
580 var j = 1;
581 while(j++ < k && y.compareTo(n1) != 0) {
582 y = y.modPowInt(2,this);
583 if(y.compareTo(BigInteger.ONE) == 0) return false;
584 }
585 if(y.compareTo(n1) != 0) return false;
586 }
587 }
588 return true;
589}
590
591// protected
592BigInteger.prototype.chunkSize = bnpChunkSize;
593BigInteger.prototype.toRadix = bnpToRadix;
594BigInteger.prototype.fromRadix = bnpFromRadix;
595BigInteger.prototype.fromNumber = bnpFromNumber;
596BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
597BigInteger.prototype.changeBit = bnpChangeBit;
598BigInteger.prototype.addTo = bnpAddTo;
599BigInteger.prototype.dMultiply = bnpDMultiply;
600BigInteger.prototype.dAddOffset = bnpDAddOffset;
601BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
602BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
603BigInteger.prototype.modInt = bnpModInt;
604BigInteger.prototype.millerRabin = bnpMillerRabin;
605
606// public
607BigInteger.prototype.clone = bnClone;
608BigInteger.prototype.intValue = bnIntValue;
609BigInteger.prototype.byteValue = bnByteValue;
610BigInteger.prototype.shortValue = bnShortValue;
611BigInteger.prototype.signum = bnSigNum;
612BigInteger.prototype.toByteArray = bnToByteArray;
613BigInteger.prototype.equals = bnEquals;
614BigInteger.prototype.min = bnMin;
615BigInteger.prototype.max = bnMax;
616BigInteger.prototype.and = bnAnd;
617BigInteger.prototype.or = bnOr;
618BigInteger.prototype.xor = bnXor;
619BigInteger.prototype.andNot = bnAndNot;
620BigInteger.prototype.not = bnNot;
621BigInteger.prototype.shiftLeft = bnShiftLeft;
622BigInteger.prototype.shiftRight = bnShiftRight;
623BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
624BigInteger.prototype.bitCount = bnBitCount;
625BigInteger.prototype.testBit = bnTestBit;
626BigInteger.prototype.setBit = bnSetBit;
627BigInteger.prototype.clearBit = bnClearBit;
628BigInteger.prototype.flipBit = bnFlipBit;
629BigInteger.prototype.add = bnAdd;
630BigInteger.prototype.subtract = bnSubtract;
631BigInteger.prototype.multiply = bnMultiply;
632BigInteger.prototype.divide = bnDivide;
633BigInteger.prototype.remainder = bnRemainder;
634BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
635BigInteger.prototype.modPow = bnModPow;
636BigInteger.prototype.modInverse = bnModInverse;
637BigInteger.prototype.pow = bnPow;
638BigInteger.prototype.gcd = bnGCD;
639BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
640
641// BigInteger interfaces not implemented in jsbn:
642
643// BigInteger(int signum, byte[] magnitude)
644// double doubleValue()
645// float floatValue()
646// int hashCode()
647// long longValue()
648// static BigInteger valueOf(long val)