blob: c33d7736b437960affbde9059277f67c5fccbf9d [file] [log] [blame]
basile_clement@apple.com6e4beb92015-09-04 02:43:41 +00001"use strict";
2
3/*
4 * Copyright (c) 2003-2005 Tom Wu
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
20 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
21 *
22 * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
23 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
24 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
25 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
26 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 *
28 * In addition, the following condition applies:
29 *
30 * All redistributions must retain an intact copy of this copyright notice
31 * and disclaimer.
32 */
33
34// Basic JavaScript BN library - subset useful for RSA encryption.
35
36// Bits per digit
37var dbits;
38var BI_DB;
39var BI_DM;
40var BI_DV;
41
42var BI_FP;
43var BI_FV;
44var BI_F1;
45var BI_F2;
46
47// JavaScript engine analysis
48var canary = 0xdeadbeefcafe;
49var j_lm = ((canary&0xffffff)==0xefcafe);
50
51// (public) Constructor
52function BigInteger(a,b,c) {
53 this.array = new Array();
54 if(a != null)
55 if("number" == typeof a) this.fromNumber(a,b,c);
56 else if(b == null && "string" != typeof a) this.fromString(a,256);
57 else this.fromString(a,b);
58}
59
60// return new, unset BigInteger
61function nbi() { return new BigInteger(null); }
62
63// 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
68// am1: use a single mult and divide to get the high bits,
69// max digit bits should be 26 because
70// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
71function am1(i,x,w,j,c,n) {
72 var this_array = this.array;
73 var w_array = w.array;
74 while(--n >= 0) {
75 var v = x*this_array[i++]+w_array[j]+c;
76 c = Math.floor(v/0x4000000);
77 w_array[j++] = v&0x3ffffff;
78 }
79 return c;
80}
81
82// am2 avoids a big mult-and-extract completely.
83// Max digit bits should be <= 30 because we do bitwise ops
84// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
85function am2(i,x,w,j,c,n) {
86 var this_array = this.array;
87 var w_array = w.array;
88 var xl = x&0x7fff, xh = x>>15;
89 while(--n >= 0) {
90 var l = this_array[i]&0x7fff;
91 var h = this_array[i++]>>15;
92 var m = xh*l+h*xl;
93 l = xl*l+((m&0x7fff)<<15)+w_array[j]+(c&0x3fffffff);
94 c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
95 w_array[j++] = l&0x3fffffff;
96 }
97 return c;
98}
99
100// Alternately, set max digit bits to 28 since some
101// browsers slow down when dealing with 32-bit numbers.
102function am3(i,x,w,j,c,n) {
103 var this_array = this.array;
104 var w_array = w.array;
105
106 var xl = x&0x3fff, xh = x>>14;
107 while(--n >= 0) {
108 var l = this_array[i]&0x3fff;
109 var h = this_array[i++]>>14;
110 var m = xh*l+h*xl;
111 l = xl*l+((m&0x3fff)<<14)+w_array[j]+c;
112 c = (l>>28)+(m>>14)+xh*h;
113 w_array[j++] = l&0xfffffff;
114 }
115 return c;
116}
117
118// This is tailored to VMs with 2-bit tagging. It makes sure
119// that all the computations stay within the 29 bits available.
120function am4(i,x,w,j,c,n) {
121 var this_array = this.array;
122 var w_array = w.array;
123
124 var xl = x&0x1fff, xh = x>>13;
125 while(--n >= 0) {
126 var l = this_array[i]&0x1fff;
127 var h = this_array[i++]>>13;
128 var m = xh*l+h*xl;
129 l = xl*l+((m&0x1fff)<<13)+w_array[j]+c;
130 c = (l>>26)+(m>>13)+xh*h;
131 w_array[j++] = l&0x3ffffff;
132 }
133 return c;
134}
135
136// am3/28 is best for SM, Rhino, but am4/26 is best for v8.
137// Kestrel (Opera 9.5) gets its best result with am4/26.
138// IE7 does 9% better with am3/28 than with am4/26.
139// Firefox (SM) gets 10% faster with am3/28 than with am4/26.
140
141var setupEngine = function(fn, bits) {
142 BigInteger.prototype.am = fn;
143 dbits = bits;
144
145 BI_DB = dbits;
146 BI_DM = ((1<<dbits)-1);
147 BI_DV = (1<<dbits);
148
149 BI_FP = 52;
150 BI_FV = Math.pow(2,BI_FP);
151 BI_F1 = BI_FP-dbits;
152 BI_F2 = 2*dbits-BI_FP;
153}
154
155
156// Digit conversions
157var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
158var BI_RC = new Array();
159var rr,vv;
160rr = "0".charCodeAt(0);
161for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
162rr = "a".charCodeAt(0);
163for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
164rr = "A".charCodeAt(0);
165for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
166
167function int2char(n) { return BI_RM.charAt(n); }
168function intAt(s,i) {
169 var c = BI_RC[s.charCodeAt(i)];
170 return (c==null)?-1:c;
171}
172
173// (protected) copy this to r
174function bnpCopyTo(r) {
175 var this_array = this.array;
176 var r_array = r.array;
177
178 for(var i = this.t-1; i >= 0; --i) r_array[i] = this_array[i];
179 r.t = this.t;
180 r.s = this.s;
181}
182
183// (protected) set from integer value x, -DV <= x < DV
184function bnpFromInt(x) {
185 var this_array = this.array;
186 this.t = 1;
187 this.s = (x<0)?-1:0;
188 if(x > 0) this_array[0] = x;
189 else if(x < -1) this_array[0] = x+DV;
190 else this.t = 0;
191}
192
193// return bigint initialized to value
194function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
195
196// (protected) set from string and radix
197function bnpFromString(s,b) {
198 var this_array = this.array;
199 var k;
200 if(b == 16) k = 4;
201 else if(b == 8) k = 3;
202 else if(b == 256) k = 8; // byte array
203 else if(b == 2) k = 1;
204 else if(b == 32) k = 5;
205 else if(b == 4) k = 2;
206 else { this.fromRadix(s,b); return; }
207 this.t = 0;
208 this.s = 0;
209 var i = s.length, mi = false, sh = 0;
210 while(--i >= 0) {
211 var x = (k==8)?s[i]&0xff:intAt(s,i);
212 if(x < 0) {
213 if(s.charAt(i) == "-") mi = true;
214 continue;
215 }
216 mi = false;
217 if(sh == 0)
218 this_array[this.t++] = x;
219 else if(sh+k > BI_DB) {
220 this_array[this.t-1] |= (x&((1<<(BI_DB-sh))-1))<<sh;
221 this_array[this.t++] = (x>>(BI_DB-sh));
222 }
223 else
224 this_array[this.t-1] |= x<<sh;
225 sh += k;
226 if(sh >= BI_DB) sh -= BI_DB;
227 }
228 if(k == 8 && (s[0]&0x80) != 0) {
229 this.s = -1;
230 if(sh > 0) this_array[this.t-1] |= ((1<<(BI_DB-sh))-1)<<sh;
231 }
232 this.clamp();
233 if(mi) BigInteger.ZERO.subTo(this,this);
234}
235
236// (protected) clamp off excess high words
237function bnpClamp() {
238 var this_array = this.array;
239 var c = this.s&BI_DM;
240 while(this.t > 0 && this_array[this.t-1] == c) --this.t;
241}
242
243// (public) return string representation in given radix
244function bnToString(b) {
245 var this_array = this.array;
246 if(this.s < 0) return "-"+this.negate().toString(b);
247 var k;
248 if(b == 16) k = 4;
249 else if(b == 8) k = 3;
250 else if(b == 2) k = 1;
251 else if(b == 32) k = 5;
252 else if(b == 4) k = 2;
253 else return this.toRadix(b);
254 var km = (1<<k)-1, d, m = false, r = "", i = this.t;
255 var p = BI_DB-(i*BI_DB)%k;
256 if(i-- > 0) {
257 if(p < BI_DB && (d = this_array[i]>>p) > 0) { m = true; r = int2char(d); }
258 while(i >= 0) {
259 if(p < k) {
260 d = (this_array[i]&((1<<p)-1))<<(k-p);
261 d |= this_array[--i]>>(p+=BI_DB-k);
262 }
263 else {
264 d = (this_array[i]>>(p-=k))&km;
265 if(p <= 0) { p += BI_DB; --i; }
266 }
267 if(d > 0) m = true;
268 if(m) r += int2char(d);
269 }
270 }
271 return m?r:"0";
272}
273
274// (public) -this
275function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
276
277// (public) |this|
278function bnAbs() { return (this.s<0)?this.negate():this; }
279
280// (public) return + if this > a, - if this < a, 0 if equal
281function bnCompareTo(a) {
282 var this_array = this.array;
283 var a_array = a.array;
284
285 var r = this.s-a.s;
286 if(r != 0) return r;
287 var i = this.t;
288 r = i-a.t;
289 if(r != 0) return r;
290 while(--i >= 0) if((r=this_array[i]-a_array[i]) != 0) return r;
291 return 0;
292}
293
294// returns bit length of the integer x
295function nbits(x) {
296 var r = 1, t;
297 if((t=x>>>16) != 0) { x = t; r += 16; }
298 if((t=x>>8) != 0) { x = t; r += 8; }
299 if((t=x>>4) != 0) { x = t; r += 4; }
300 if((t=x>>2) != 0) { x = t; r += 2; }
301 if((t=x>>1) != 0) { x = t; r += 1; }
302 return r;
303}
304
305// (public) return the number of bits in "this"
306function bnBitLength() {
307 var this_array = this.array;
308 if(this.t <= 0) return 0;
309 return BI_DB*(this.t-1)+nbits(this_array[this.t-1]^(this.s&BI_DM));
310}
311
312// (protected) r = this << n*DB
313function bnpDLShiftTo(n,r) {
314 var this_array = this.array;
315 var r_array = r.array;
316 var i;
317 for(i = this.t-1; i >= 0; --i) r_array[i+n] = this_array[i];
318 for(i = n-1; i >= 0; --i) r_array[i] = 0;
319 r.t = this.t+n;
320 r.s = this.s;
321}
322
323// (protected) r = this >> n*DB
324function bnpDRShiftTo(n,r) {
325 var this_array = this.array;
326 var r_array = r.array;
327 for(var i = n; i < this.t; ++i) r_array[i-n] = this_array[i];
328 r.t = Math.max(this.t-n,0);
329 r.s = this.s;
330}
331
332// (protected) r = this << n
333function bnpLShiftTo(n,r) {
334 var this_array = this.array;
335 var r_array = r.array;
336 var bs = n%BI_DB;
337 var cbs = BI_DB-bs;
338 var bm = (1<<cbs)-1;
339 var ds = Math.floor(n/BI_DB), c = (this.s<<bs)&BI_DM, i;
340 for(i = this.t-1; i >= 0; --i) {
341 r_array[i+ds+1] = (this_array[i]>>cbs)|c;
342 c = (this_array[i]&bm)<<bs;
343 }
344 for(i = ds-1; i >= 0; --i) r_array[i] = 0;
345 r_array[ds] = c;
346 r.t = this.t+ds+1;
347 r.s = this.s;
348 r.clamp();
349}
350
351// (protected) r = this >> n
352function bnpRShiftTo(n,r) {
353 var this_array = this.array;
354 var r_array = r.array;
355 r.s = this.s;
356 var ds = Math.floor(n/BI_DB);
357 if(ds >= this.t) { r.t = 0; return; }
358 var bs = n%BI_DB;
359 var cbs = BI_DB-bs;
360 var bm = (1<<bs)-1;
361 r_array[0] = this_array[ds]>>bs;
362 for(var i = ds+1; i < this.t; ++i) {
363 r_array[i-ds-1] |= (this_array[i]&bm)<<cbs;
364 r_array[i-ds] = this_array[i]>>bs;
365 }
366 if(bs > 0) r_array[this.t-ds-1] |= (this.s&bm)<<cbs;
367 r.t = this.t-ds;
368 r.clamp();
369}
370
371// (protected) r = this - a
372function bnpSubTo(a,r) {
373 var this_array = this.array;
374 var r_array = r.array;
375 var a_array = a.array;
376 var i = 0, c = 0, m = Math.min(a.t,this.t);
377 while(i < m) {
378 c += this_array[i]-a_array[i];
379 r_array[i++] = c&BI_DM;
380 c >>= BI_DB;
381 }
382 if(a.t < this.t) {
383 c -= a.s;
384 while(i < this.t) {
385 c += this_array[i];
386 r_array[i++] = c&BI_DM;
387 c >>= BI_DB;
388 }
389 c += this.s;
390 }
391 else {
392 c += this.s;
393 while(i < a.t) {
394 c -= a_array[i];
395 r_array[i++] = c&BI_DM;
396 c >>= BI_DB;
397 }
398 c -= a.s;
399 }
400 r.s = (c<0)?-1:0;
401 if(c < -1) r_array[i++] = BI_DV+c;
402 else if(c > 0) r_array[i++] = c;
403 r.t = i;
404 r.clamp();
405}
406
407// (protected) r = this * a, r != this,a (HAC 14.12)
408// "this" should be the larger one if appropriate.
409function bnpMultiplyTo(a,r) {
410 var this_array = this.array;
411 var r_array = r.array;
412 var x = this.abs(), y = a.abs();
413 var y_array = y.array;
414
415 var i = x.t;
416 r.t = i+y.t;
417 while(--i >= 0) r_array[i] = 0;
418 for(i = 0; i < y.t; ++i) r_array[i+x.t] = x.am(0,y_array[i],r,i,0,x.t);
419 r.s = 0;
420 r.clamp();
421 if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
422}
423
424// (protected) r = this^2, r != this (HAC 14.16)
425function bnpSquareTo(r) {
426 var x = this.abs();
427 var x_array = x.array;
428 var r_array = r.array;
429
430 var i = r.t = 2*x.t;
431 while(--i >= 0) r_array[i] = 0;
432 for(i = 0; i < x.t-1; ++i) {
433 var c = x.am(i,x_array[i],r,2*i,0,1);
434 if((r_array[i+x.t]+=x.am(i+1,2*x_array[i],r,2*i+1,c,x.t-i-1)) >= BI_DV) {
435 r_array[i+x.t] -= BI_DV;
436 r_array[i+x.t+1] = 1;
437 }
438 }
439 if(r.t > 0) r_array[r.t-1] += x.am(i,x_array[i],r,2*i,0,1);
440 r.s = 0;
441 r.clamp();
442}
443
444// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
445// r != q, this != m. q or r may be null.
446function bnpDivRemTo(m,q,r) {
447 var pm = m.abs();
448 if(pm.t <= 0) return;
449 var pt = this.abs();
450 if(pt.t < pm.t) {
451 if(q != null) q.fromInt(0);
452 if(r != null) this.copyTo(r);
453 return;
454 }
455 if(r == null) r = nbi();
456 var y = nbi(), ts = this.s, ms = m.s;
457 var pm_array = pm.array;
458 var nsh = BI_DB-nbits(pm_array[pm.t-1]); // normalize modulus
459 if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
460 else { pm.copyTo(y); pt.copyTo(r); }
461 var ys = y.t;
462
463 var y_array = y.array;
464 var y0 = y_array[ys-1];
465 if(y0 == 0) return;
466 var yt = y0*(1<<BI_F1)+((ys>1)?y_array[ys-2]>>BI_F2:0);
467 var d1 = BI_FV/yt, d2 = (1<<BI_F1)/yt, e = 1<<BI_F2;
468 var i = r.t, j = i-ys, t = (q==null)?nbi():q;
469 y.dlShiftTo(j,t);
470
471 var r_array = r.array;
472 if(r.compareTo(t) >= 0) {
473 r_array[r.t++] = 1;
474 r.subTo(t,r);
475 }
476 BigInteger.ONE.dlShiftTo(ys,t);
477 t.subTo(y,y); // "negative" y so we can replace sub with am later
478 while(y.t < ys) y_array[y.t++] = 0;
479 while(--j >= 0) {
480 // Estimate quotient digit
481 var qd = (r_array[--i]==y0)?BI_DM:Math.floor(r_array[i]*d1+(r_array[i-1]+e)*d2);
482 if((r_array[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
483 y.dlShiftTo(j,t);
484 r.subTo(t,r);
485 while(r_array[i] < --qd) r.subTo(t,r);
486 }
487 }
488 if(q != null) {
489 r.drShiftTo(ys,q);
490 if(ts != ms) BigInteger.ZERO.subTo(q,q);
491 }
492 r.t = ys;
493 r.clamp();
494 if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
495 if(ts < 0) BigInteger.ZERO.subTo(r,r);
496}
497
498// (public) this mod a
499function bnMod(a) {
500 var r = nbi();
501 this.abs().divRemTo(a,null,r);
502 if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
503 return r;
504}
505
506// Modular reduction using "classic" algorithm
507function Classic(m) { this.m = m; }
508function cConvert(x) {
509 if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
510 else return x;
511}
512function cRevert(x) { return x; }
513function cReduce(x) { x.divRemTo(this.m,null,x); }
514function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
515function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
516
517Classic.prototype.convert = cConvert;
518Classic.prototype.revert = cRevert;
519Classic.prototype.reduce = cReduce;
520Classic.prototype.mulTo = cMulTo;
521Classic.prototype.sqrTo = cSqrTo;
522
523// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
524// justification:
525// xy == 1 (mod m)
526// xy = 1+km
527// xy(2-xy) = (1+km)(1-km)
528// x[y(2-xy)] = 1-k^2m^2
529// x[y(2-xy)] == 1 (mod m^2)
530// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
531// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
532// JS multiply "overflows" differently from C/C++, so care is needed here.
533function bnpInvDigit() {
534 var this_array = this.array;
535 if(this.t < 1) return 0;
536 var x = this_array[0];
537 if((x&1) == 0) return 0;
538 var y = x&3; // y == 1/x mod 2^2
539 y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
540 y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
541 y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
542 // last step - calculate inverse mod DV directly;
543 // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
544 y = (y*(2-x*y%BI_DV))%BI_DV; // y == 1/x mod 2^dbits
545 // we really want the negative inverse, and -DV < y < DV
546 return (y>0)?BI_DV-y:-y;
547}
548
549// Montgomery reduction
550function Montgomery(m) {
551 this.m = m;
552 this.mp = m.invDigit();
553 this.mpl = this.mp&0x7fff;
554 this.mph = this.mp>>15;
555 this.um = (1<<(BI_DB-15))-1;
556 this.mt2 = 2*m.t;
557}
558
559// xR mod m
560function montConvert(x) {
561 var r = nbi();
562 x.abs().dlShiftTo(this.m.t,r);
563 r.divRemTo(this.m,null,r);
564 if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
565 return r;
566}
567
568// x/R mod m
569function montRevert(x) {
570 var r = nbi();
571 x.copyTo(r);
572 this.reduce(r);
573 return r;
574}
575
576// x = x/R mod m (HAC 14.32)
577function montReduce(x) {
578 var x_array = x.array;
579 while(x.t <= this.mt2) // pad x so am has enough room later
580 x_array[x.t++] = 0;
581 for(var i = 0; i < this.m.t; ++i) {
582 // faster way of calculating u0 = x[i]*mp mod DV
583 var j = x_array[i]&0x7fff;
584 var u0 = (j*this.mpl+(((j*this.mph+(x_array[i]>>15)*this.mpl)&this.um)<<15))&BI_DM;
585 // use am to combine the multiply-shift-add into one call
586 j = i+this.m.t;
587 x_array[j] += this.m.am(0,u0,x,i,0,this.m.t);
588 // propagate carry
589 while(x_array[j] >= BI_DV) { x_array[j] -= BI_DV; x_array[++j]++; }
590 }
591 x.clamp();
592 x.drShiftTo(this.m.t,x);
593 if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
594}
595
596// r = "x^2/R mod m"; x != r
597function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
598
599// r = "xy/R mod m"; x,y != r
600function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
601
602Montgomery.prototype.convert = montConvert;
603Montgomery.prototype.revert = montRevert;
604Montgomery.prototype.reduce = montReduce;
605Montgomery.prototype.mulTo = montMulTo;
606Montgomery.prototype.sqrTo = montSqrTo;
607
608// (protected) true iff this is even
609function bnpIsEven() {
610 var this_array = this.array;
611 return ((this.t>0)?(this_array[0]&1):this.s) == 0;
612}
613
614// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
615function bnpExp(e,z) {
616 if(e > 0xffffffff || e < 1) return BigInteger.ONE;
617 var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
618 g.copyTo(r);
619 while(--i >= 0) {
620 z.sqrTo(r,r2);
621 if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
622 else { var t = r; r = r2; r2 = t; }
623 }
624 return z.revert(r);
625}
626
627// (public) this^e % m, 0 <= e < 2^32
628function bnModPowInt(e,m) {
629 var z;
630 if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
631 return this.exp(e,z);
632}
633
634// protected
635BigInteger.prototype.copyTo = bnpCopyTo;
636BigInteger.prototype.fromInt = bnpFromInt;
637BigInteger.prototype.fromString = bnpFromString;
638BigInteger.prototype.clamp = bnpClamp;
639BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
640BigInteger.prototype.drShiftTo = bnpDRShiftTo;
641BigInteger.prototype.lShiftTo = bnpLShiftTo;
642BigInteger.prototype.rShiftTo = bnpRShiftTo;
643BigInteger.prototype.subTo = bnpSubTo;
644BigInteger.prototype.multiplyTo = bnpMultiplyTo;
645BigInteger.prototype.squareTo = bnpSquareTo;
646BigInteger.prototype.divRemTo = bnpDivRemTo;
647BigInteger.prototype.invDigit = bnpInvDigit;
648BigInteger.prototype.isEven = bnpIsEven;
649BigInteger.prototype.exp = bnpExp;
650
651// public
652BigInteger.prototype.toString = bnToString;
653BigInteger.prototype.negate = bnNegate;
654BigInteger.prototype.abs = bnAbs;
655BigInteger.prototype.compareTo = bnCompareTo;
656BigInteger.prototype.bitLength = bnBitLength;
657BigInteger.prototype.mod = bnMod;
658BigInteger.prototype.modPowInt = bnModPowInt;
659
660// "constants"
661BigInteger.ZERO = nbv(0);
662BigInteger.ONE = nbv(1);
663// Copyright (c) 2005 Tom Wu
664// All Rights Reserved.
665// See "LICENSE" for details.
666
667// Extended JavaScript BN functions, required for RSA private ops.
668
669// (public)
670function bnClone() { var r = nbi(); this.copyTo(r); return r; }
671
672// (public) return value as integer
673function bnIntValue() {
674 var this_array = this.array;
675 if(this.s < 0) {
676 if(this.t == 1) return this_array[0]-BI_DV;
677 else if(this.t == 0) return -1;
678 }
679 else if(this.t == 1) return this_array[0];
680 else if(this.t == 0) return 0;
681 // assumes 16 < DB < 32
682 return ((this_array[1]&((1<<(32-BI_DB))-1))<<BI_DB)|this_array[0];
683}
684
685// (public) return value as byte
686function bnByteValue() {
687 var this_array = this.array;
688 return (this.t==0)?this.s:(this_array[0]<<24)>>24;
689}
690
691// (public) return value as short (assumes DB>=16)
692function bnShortValue() {
693 var this_array = this.array;
694 return (this.t==0)?this.s:(this_array[0]<<16)>>16;
695}
696
697// (protected) return x s.t. r^x < DV
698function bnpChunkSize(r) { return Math.floor(Math.LN2*BI_DB/Math.log(r)); }
699
700// (public) 0 if this == 0, 1 if this > 0
701function bnSigNum() {
702 var this_array = this.array;
703 if(this.s < 0) return -1;
704 else if(this.t <= 0 || (this.t == 1 && this_array[0] <= 0)) return 0;
705 else return 1;
706}
707
708// (protected) convert to radix string
709function bnpToRadix(b) {
710 if(b == null) b = 10;
711 if(this.signum() == 0 || b < 2 || b > 36) return "0";
712 var cs = this.chunkSize(b);
713 var a = Math.pow(b,cs);
714 var d = nbv(a), y = nbi(), z = nbi(), r = "";
715 this.divRemTo(d,y,z);
716 while(y.signum() > 0) {
717 r = (a+z.intValue()).toString(b).substr(1) + r;
718 y.divRemTo(d,y,z);
719 }
720 return z.intValue().toString(b) + r;
721}
722
723// (protected) convert from radix string
724function bnpFromRadix(s,b) {
725 this.fromInt(0);
726 if(b == null) b = 10;
727 var cs = this.chunkSize(b);
728 var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
729 for(var i = 0; i < s.length; ++i) {
730 var x = intAt(s,i);
731 if(x < 0) {
732 if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
733 continue;
734 }
735 w = b*w+x;
736 if(++j >= cs) {
737 this.dMultiply(d);
738 this.dAddOffset(w,0);
739 j = 0;
740 w = 0;
741 }
742 }
743 if(j > 0) {
744 this.dMultiply(Math.pow(b,j));
745 this.dAddOffset(w,0);
746 }
747 if(mi) BigInteger.ZERO.subTo(this,this);
748}
749
750// (protected) alternate constructor
751function bnpFromNumber(a,b,c) {
752 if("number" == typeof b) {
753 // new BigInteger(int,int,RNG)
754 if(a < 2) this.fromInt(1);
755 else {
756 this.fromNumber(a,c);
757 if(!this.testBit(a-1)) // force MSB set
758 this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
759 if(this.isEven()) this.dAddOffset(1,0); // force odd
760 while(!this.isProbablePrime(b)) {
761 this.dAddOffset(2,0);
762 if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
763 }
764 }
765 }
766 else {
767 // new BigInteger(int,RNG)
768 var x = new Array(), t = a&7;
769 x.length = (a>>3)+1;
770 b.nextBytes(x);
771 if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
772 this.fromString(x,256);
773 }
774}
775
776// (public) convert to bigendian byte array
777function bnToByteArray() {
778 var this_array = this.array;
779 var i = this.t, r = new Array();
780 r[0] = this.s;
781 var p = BI_DB-(i*BI_DB)%8, d, k = 0;
782 if(i-- > 0) {
783 if(p < BI_DB && (d = this_array[i]>>p) != (this.s&BI_DM)>>p)
784 r[k++] = d|(this.s<<(BI_DB-p));
785 while(i >= 0) {
786 if(p < 8) {
787 d = (this_array[i]&((1<<p)-1))<<(8-p);
788 d |= this_array[--i]>>(p+=BI_DB-8);
789 }
790 else {
791 d = (this_array[i]>>(p-=8))&0xff;
792 if(p <= 0) { p += BI_DB; --i; }
793 }
794 if((d&0x80) != 0) d |= -256;
795 if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
796 if(k > 0 || d != this.s) r[k++] = d;
797 }
798 }
799 return r;
800}
801
802function bnEquals(a) { return(this.compareTo(a)==0); }
803function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
804function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
805
806// (protected) r = this op a (bitwise)
807function bnpBitwiseTo(a,op,r) {
808 var this_array = this.array;
809 var a_array = a.array;
810 var r_array = r.array;
811 var i, f, m = Math.min(a.t,this.t);
812 for(i = 0; i < m; ++i) r_array[i] = op(this_array[i],a_array[i]);
813 if(a.t < this.t) {
814 f = a.s&BI_DM;
815 for(i = m; i < this.t; ++i) r_array[i] = op(this_array[i],f);
816 r.t = this.t;
817 }
818 else {
819 f = this.s&BI_DM;
820 for(i = m; i < a.t; ++i) r_array[i] = op(f,a_array[i]);
821 r.t = a.t;
822 }
823 r.s = op(this.s,a.s);
824 r.clamp();
825}
826
827// (public) this & a
828function op_and(x,y) { return x&y; }
829function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
830
831// (public) this | a
832function op_or(x,y) { return x|y; }
833function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
834
835// (public) this ^ a
836function op_xor(x,y) { return x^y; }
837function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
838
839// (public) this & ~a
840function op_andnot(x,y) { return x&~y; }
841function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
842
843// (public) ~this
844function bnNot() {
845 var this_array = this.array;
846 var r = nbi();
847 var r_array = r.array;
848
849 for(var i = 0; i < this.t; ++i) r_array[i] = BI_DM&~this_array[i];
850 r.t = this.t;
851 r.s = ~this.s;
852 return r;
853}
854
855// (public) this << n
856function bnShiftLeft(n) {
857 var r = nbi();
858 if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
859 return r;
860}
861
862// (public) this >> n
863function bnShiftRight(n) {
864 var r = nbi();
865 if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
866 return r;
867}
868
869// return index of lowest 1-bit in x, x < 2^31
870function lbit(x) {
871 if(x == 0) return -1;
872 var r = 0;
873 if((x&0xffff) == 0) { x >>= 16; r += 16; }
874 if((x&0xff) == 0) { x >>= 8; r += 8; }
875 if((x&0xf) == 0) { x >>= 4; r += 4; }
876 if((x&3) == 0) { x >>= 2; r += 2; }
877 if((x&1) == 0) ++r;
878 return r;
879}
880
881// (public) returns index of lowest 1-bit (or -1 if none)
882function bnGetLowestSetBit() {
883 var this_array = this.array;
884 for(var i = 0; i < this.t; ++i)
885 if(this_array[i] != 0) return i*BI_DB+lbit(this_array[i]);
886 if(this.s < 0) return this.t*BI_DB;
887 return -1;
888}
889
890// return number of 1 bits in x
891function cbit(x) {
892 var r = 0;
893 while(x != 0) { x &= x-1; ++r; }
894 return r;
895}
896
897// (public) return number of set bits
898function bnBitCount() {
899 var r = 0, x = this.s&BI_DM;
900 for(var i = 0; i < this.t; ++i) r += cbit(this_array[i]^x);
901 return r;
902}
903
904// (public) true iff nth bit is set
905function bnTestBit(n) {
906 var this_array = this.array;
907 var j = Math.floor(n/BI_DB);
908 if(j >= this.t) return(this.s!=0);
909 return((this_array[j]&(1<<(n%BI_DB)))!=0);
910}
911
912// (protected) this op (1<<n)
913function bnpChangeBit(n,op) {
914 var r = BigInteger.ONE.shiftLeft(n);
915 this.bitwiseTo(r,op,r);
916 return r;
917}
918
919// (public) this | (1<<n)
920function bnSetBit(n) { return this.changeBit(n,op_or); }
921
922// (public) this & ~(1<<n)
923function bnClearBit(n) { return this.changeBit(n,op_andnot); }
924
925// (public) this ^ (1<<n)
926function bnFlipBit(n) { return this.changeBit(n,op_xor); }
927
928// (protected) r = this + a
929function bnpAddTo(a,r) {
930 var this_array = this.array;
931 var a_array = a.array;
932 var r_array = r.array;
933 var i = 0, c = 0, m = Math.min(a.t,this.t);
934 while(i < m) {
935 c += this_array[i]+a_array[i];
936 r_array[i++] = c&BI_DM;
937 c >>= BI_DB;
938 }
939 if(a.t < this.t) {
940 c += a.s;
941 while(i < this.t) {
942 c += this_array[i];
943 r_array[i++] = c&BI_DM;
944 c >>= BI_DB;
945 }
946 c += this.s;
947 }
948 else {
949 c += this.s;
950 while(i < a.t) {
951 c += a_array[i];
952 r_array[i++] = c&BI_DM;
953 c >>= BI_DB;
954 }
955 c += a.s;
956 }
957 r.s = (c<0)?-1:0;
958 if(c > 0) r_array[i++] = c;
959 else if(c < -1) r_array[i++] = BI_DV+c;
960 r.t = i;
961 r.clamp();
962}
963
964// (public) this + a
965function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
966
967// (public) this - a
968function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
969
970// (public) this * a
971function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
972
973// (public) this / a
974function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
975
976// (public) this % a
977function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
978
979// (public) [this/a,this%a]
980function bnDivideAndRemainder(a) {
981 var q = nbi(), r = nbi();
982 this.divRemTo(a,q,r);
983 return new Array(q,r);
984}
985
986// (protected) this *= n, this >= 0, 1 < n < DV
987function bnpDMultiply(n) {
988 var this_array = this.array;
989 this_array[this.t] = this.am(0,n-1,this,0,0,this.t);
990 ++this.t;
991 this.clamp();
992}
993
994// (protected) this += n << w words, this >= 0
995function bnpDAddOffset(n,w) {
996 var this_array = this.array;
997 while(this.t <= w) this_array[this.t++] = 0;
998 this_array[w] += n;
999 while(this_array[w] >= BI_DV) {
1000 this_array[w] -= BI_DV;
1001 if(++w >= this.t) this_array[this.t++] = 0;
1002 ++this_array[w];
1003 }
1004}
1005
1006// A "null" reducer
1007function NullExp() {}
1008function nNop(x) { return x; }
1009function nMulTo(x,y,r) { x.multiplyTo(y,r); }
1010function nSqrTo(x,r) { x.squareTo(r); }
1011
1012NullExp.prototype.convert = nNop;
1013NullExp.prototype.revert = nNop;
1014NullExp.prototype.mulTo = nMulTo;
1015NullExp.prototype.sqrTo = nSqrTo;
1016
1017// (public) this^e
1018function bnPow(e) { return this.exp(e,new NullExp()); }
1019
1020// (protected) r = lower n words of "this * a", a.t <= n
1021// "this" should be the larger one if appropriate.
1022function bnpMultiplyLowerTo(a,n,r) {
1023 var r_array = r.array;
1024 var a_array = a.array;
1025 var i = Math.min(this.t+a.t,n);
1026 r.s = 0; // assumes a,this >= 0
1027 r.t = i;
1028 while(i > 0) r_array[--i] = 0;
1029 var j;
1030 for(j = r.t-this.t; i < j; ++i) r_array[i+this.t] = this.am(0,a_array[i],r,i,0,this.t);
1031 for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a_array[i],r,i,0,n-i);
1032 r.clamp();
1033}
1034
1035// (protected) r = "this * a" without lower n words, n > 0
1036// "this" should be the larger one if appropriate.
1037function bnpMultiplyUpperTo(a,n,r) {
1038 var r_array = r.array;
1039 var a_array = a.array;
1040 --n;
1041 var i = r.t = this.t+a.t-n;
1042 r.s = 0; // assumes a,this >= 0
1043 while(--i >= 0) r_array[i] = 0;
1044 for(i = Math.max(n-this.t,0); i < a.t; ++i)
1045 r_array[this.t+i-n] = this.am(n-i,a_array[i],r,0,0,this.t+i-n);
1046 r.clamp();
1047 r.drShiftTo(1,r);
1048}
1049
1050// Barrett modular reduction
1051function Barrett(m) {
1052 // setup Barrett
1053 this.r2 = nbi();
1054 this.q3 = nbi();
1055 BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
1056 this.mu = this.r2.divide(m);
1057 this.m = m;
1058}
1059
1060function barrettConvert(x) {
1061 if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
1062 else if(x.compareTo(this.m) < 0) return x;
1063 else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
1064}
1065
1066function barrettRevert(x) { return x; }
1067
1068// x = x mod m (HAC 14.42)
1069function barrettReduce(x) {
1070 x.drShiftTo(this.m.t-1,this.r2);
1071 if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
1072 this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
1073 this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
1074 while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
1075 x.subTo(this.r2,x);
1076 while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
1077}
1078
1079// r = x^2 mod m; x != r
1080function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
1081
1082// r = x*y mod m; x,y != r
1083function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
1084
1085Barrett.prototype.convert = barrettConvert;
1086Barrett.prototype.revert = barrettRevert;
1087Barrett.prototype.reduce = barrettReduce;
1088Barrett.prototype.mulTo = barrettMulTo;
1089Barrett.prototype.sqrTo = barrettSqrTo;
1090
1091// (public) this^e % m (HAC 14.85)
1092function bnModPow(e,m) {
1093 var e_array = e.array;
1094 var i = e.bitLength(), k, r = nbv(1), z;
1095 if(i <= 0) return r;
1096 else if(i < 18) k = 1;
1097 else if(i < 48) k = 3;
1098 else if(i < 144) k = 4;
1099 else if(i < 768) k = 5;
1100 else k = 6;
1101 if(i < 8)
1102 z = new Classic(m);
1103 else if(m.isEven())
1104 z = new Barrett(m);
1105 else
1106 z = new Montgomery(m);
1107
1108 // precomputation
1109 var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
1110 g[1] = z.convert(this);
1111 if(k > 1) {
1112 var g2 = nbi();
1113 z.sqrTo(g[1],g2);
1114 while(n <= km) {
1115 g[n] = nbi();
1116 z.mulTo(g2,g[n-2],g[n]);
1117 n += 2;
1118 }
1119 }
1120
1121 var j = e.t-1, w, is1 = true, r2 = nbi(), t;
1122 i = nbits(e_array[j])-1;
1123 while(j >= 0) {
1124 if(i >= k1) w = (e_array[j]>>(i-k1))&km;
1125 else {
1126 w = (e_array[j]&((1<<(i+1))-1))<<(k1-i);
1127 if(j > 0) w |= e_array[j-1]>>(BI_DB+i-k1);
1128 }
1129
1130 n = k;
1131 while((w&1) == 0) { w >>= 1; --n; }
1132 if((i -= n) < 0) { i += BI_DB; --j; }
1133 if(is1) { // ret == 1, don't bother squaring or multiplying it
1134 g[w].copyTo(r);
1135 is1 = false;
1136 }
1137 else {
1138 while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
1139 if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
1140 z.mulTo(r2,g[w],r);
1141 }
1142
1143 while(j >= 0 && (e_array[j]&(1<<i)) == 0) {
1144 z.sqrTo(r,r2); t = r; r = r2; r2 = t;
1145 if(--i < 0) { i = BI_DB-1; --j; }
1146 }
1147 }
1148 return z.revert(r);
1149}
1150
1151// (public) gcd(this,a) (HAC 14.54)
1152function bnGCD(a) {
1153 var x = (this.s<0)?this.negate():this.clone();
1154 var y = (a.s<0)?a.negate():a.clone();
1155 if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
1156 var i = x.getLowestSetBit(), g = y.getLowestSetBit();
1157 if(g < 0) return x;
1158 if(i < g) g = i;
1159 if(g > 0) {
1160 x.rShiftTo(g,x);
1161 y.rShiftTo(g,y);
1162 }
1163 while(x.signum() > 0) {
1164 if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
1165 if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
1166 if(x.compareTo(y) >= 0) {
1167 x.subTo(y,x);
1168 x.rShiftTo(1,x);
1169 }
1170 else {
1171 y.subTo(x,y);
1172 y.rShiftTo(1,y);
1173 }
1174 }
1175 if(g > 0) y.lShiftTo(g,y);
1176 return y;
1177}
1178
1179// (protected) this % n, n < 2^26
1180function bnpModInt(n) {
1181 var this_array = this.array;
1182 if(n <= 0) return 0;
1183 var d = BI_DV%n, r = (this.s<0)?n-1:0;
1184 if(this.t > 0)
1185 if(d == 0) r = this_array[0]%n;
1186 else for(var i = this.t-1; i >= 0; --i) r = (d*r+this_array[i])%n;
1187 return r;
1188}
1189
1190// (public) 1/this % m (HAC 14.61)
1191function bnModInverse(m) {
1192 var ac = m.isEven();
1193 if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
1194 var u = m.clone(), v = this.clone();
1195 var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
1196 while(u.signum() != 0) {
1197 while(u.isEven()) {
1198 u.rShiftTo(1,u);
1199 if(ac) {
1200 if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
1201 a.rShiftTo(1,a);
1202 }
1203 else if(!b.isEven()) b.subTo(m,b);
1204 b.rShiftTo(1,b);
1205 }
1206 while(v.isEven()) {
1207 v.rShiftTo(1,v);
1208 if(ac) {
1209 if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
1210 c.rShiftTo(1,c);
1211 }
1212 else if(!d.isEven()) d.subTo(m,d);
1213 d.rShiftTo(1,d);
1214 }
1215 if(u.compareTo(v) >= 0) {
1216 u.subTo(v,u);
1217 if(ac) a.subTo(c,a);
1218 b.subTo(d,b);
1219 }
1220 else {
1221 v.subTo(u,v);
1222 if(ac) c.subTo(a,c);
1223 d.subTo(b,d);
1224 }
1225 }
1226 if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
1227 if(d.compareTo(m) >= 0) return d.subtract(m);
1228 if(d.signum() < 0) d.addTo(m,d); else return d;
1229 if(d.signum() < 0) return d.add(m); else return d;
1230}
1231
1232var 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];
1233var lplim = (1<<26)/lowprimes[lowprimes.length-1];
1234
1235// (public) test primality with certainty >= 1-.5^t
1236function bnIsProbablePrime(t) {
1237 var i, x = this.abs();
1238 var x_array = x.array;
1239 if(x.t == 1 && x_array[0] <= lowprimes[lowprimes.length-1]) {
1240 for(i = 0; i < lowprimes.length; ++i)
1241 if(x_array[0] == lowprimes[i]) return true;
1242 return false;
1243 }
1244 if(x.isEven()) return false;
1245 i = 1;
1246 while(i < lowprimes.length) {
1247 var m = lowprimes[i], j = i+1;
1248 while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
1249 m = x.modInt(m);
1250 while(i < j) if(m%lowprimes[i++] == 0) return false;
1251 }
1252 return x.millerRabin(t);
1253}
1254
1255// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
1256function bnpMillerRabin(t) {
1257 var n1 = this.subtract(BigInteger.ONE);
1258 var k = n1.getLowestSetBit();
1259 if(k <= 0) return false;
1260 var r = n1.shiftRight(k);
1261 t = (t+1)>>1;
1262 if(t > lowprimes.length) t = lowprimes.length;
1263 var a = nbi();
1264 for(var i = 0; i < t; ++i) {
1265 a.fromInt(lowprimes[i]);
1266 var y = a.modPow(r,this);
1267 if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
1268 var j = 1;
1269 while(j++ < k && y.compareTo(n1) != 0) {
1270 y = y.modPowInt(2,this);
1271 if(y.compareTo(BigInteger.ONE) == 0) return false;
1272 }
1273 if(y.compareTo(n1) != 0) return false;
1274 }
1275 }
1276 return true;
1277}
1278
1279// protected
1280BigInteger.prototype.chunkSize = bnpChunkSize;
1281BigInteger.prototype.toRadix = bnpToRadix;
1282BigInteger.prototype.fromRadix = bnpFromRadix;
1283BigInteger.prototype.fromNumber = bnpFromNumber;
1284BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
1285BigInteger.prototype.changeBit = bnpChangeBit;
1286BigInteger.prototype.addTo = bnpAddTo;
1287BigInteger.prototype.dMultiply = bnpDMultiply;
1288BigInteger.prototype.dAddOffset = bnpDAddOffset;
1289BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
1290BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
1291BigInteger.prototype.modInt = bnpModInt;
1292BigInteger.prototype.millerRabin = bnpMillerRabin;
1293
1294// public
1295BigInteger.prototype.clone = bnClone;
1296BigInteger.prototype.intValue = bnIntValue;
1297BigInteger.prototype.byteValue = bnByteValue;
1298BigInteger.prototype.shortValue = bnShortValue;
1299BigInteger.prototype.signum = bnSigNum;
1300BigInteger.prototype.toByteArray = bnToByteArray;
1301BigInteger.prototype.equals = bnEquals;
1302BigInteger.prototype.min = bnMin;
1303BigInteger.prototype.max = bnMax;
1304BigInteger.prototype.and = bnAnd;
1305BigInteger.prototype.or = bnOr;
1306BigInteger.prototype.xor = bnXor;
1307BigInteger.prototype.andNot = bnAndNot;
1308BigInteger.prototype.not = bnNot;
1309BigInteger.prototype.shiftLeft = bnShiftLeft;
1310BigInteger.prototype.shiftRight = bnShiftRight;
1311BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
1312BigInteger.prototype.bitCount = bnBitCount;
1313BigInteger.prototype.testBit = bnTestBit;
1314BigInteger.prototype.setBit = bnSetBit;
1315BigInteger.prototype.clearBit = bnClearBit;
1316BigInteger.prototype.flipBit = bnFlipBit;
1317BigInteger.prototype.add = bnAdd;
1318BigInteger.prototype.subtract = bnSubtract;
1319BigInteger.prototype.multiply = bnMultiply;
1320BigInteger.prototype.divide = bnDivide;
1321BigInteger.prototype.remainder = bnRemainder;
1322BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
1323BigInteger.prototype.modPow = bnModPow;
1324BigInteger.prototype.modInverse = bnModInverse;
1325BigInteger.prototype.pow = bnPow;
1326BigInteger.prototype.gcd = bnGCD;
1327BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
1328
1329// BigInteger interfaces not implemented in jsbn:
1330
1331// BigInteger(int signum, byte[] magnitude)
1332// double doubleValue()
1333// float floatValue()
1334// int hashCode()
1335// long longValue()
1336// static BigInteger valueOf(long val)
1337// prng4.js - uses Arcfour as a PRNG
1338
1339function Arcfour() {
1340 this.i = 0;
1341 this.j = 0;
1342 this.S = new Array();
1343}
1344
1345// Initialize arcfour context from key, an array of ints, each from [0..255]
1346function ARC4init(key) {
1347 var i, j, t;
1348 for(i = 0; i < 256; ++i)
1349 this.S[i] = i;
1350 j = 0;
1351 for(i = 0; i < 256; ++i) {
1352 j = (j + this.S[i] + key[i % key.length]) & 255;
1353 t = this.S[i];
1354 this.S[i] = this.S[j];
1355 this.S[j] = t;
1356 }
1357 this.i = 0;
1358 this.j = 0;
1359}
1360
1361function ARC4next() {
1362 var t;
1363 this.i = (this.i + 1) & 255;
1364 this.j = (this.j + this.S[this.i]) & 255;
1365 t = this.S[this.i];
1366 this.S[this.i] = this.S[this.j];
1367 this.S[this.j] = t;
1368 return this.S[(t + this.S[this.i]) & 255];
1369}
1370
1371Arcfour.prototype.init = ARC4init;
1372Arcfour.prototype.next = ARC4next;
1373
1374// Plug in your RNG constructor here
1375function prng_newstate() {
1376 return new Arcfour();
1377}
1378
1379// Pool size must be a multiple of 4 and greater than 32.
1380// An array of bytes the size of the pool will be passed to init()
1381var rng_psize = 256;
1382// Random number generator - requires a PRNG backend, e.g. prng4.js
1383
1384// For best results, put code like
1385// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
1386// in your main HTML document.
1387
1388var rng_state;
1389var rng_pool;
1390var rng_pptr;
1391
1392// Mix in a 32-bit integer into the pool
1393function rng_seed_int(x) {
1394 rng_pool[rng_pptr++] ^= x & 255;
1395 rng_pool[rng_pptr++] ^= (x >> 8) & 255;
1396 rng_pool[rng_pptr++] ^= (x >> 16) & 255;
1397 rng_pool[rng_pptr++] ^= (x >> 24) & 255;
1398 if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
1399}
1400
1401// Mix in the current time (w/milliseconds) into the pool
1402function rng_seed_time() {
1403 // Use pre-computed date to avoid making the benchmark
1404 // results dependent on the current date.
1405 rng_seed_int(1122926989487);
1406}
1407
1408// Initialize the pool with junk if needed.
1409if(rng_pool == null) {
1410 rng_pool = new Array();
1411 rng_pptr = 0;
1412 var t;
1413 while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
1414 t = Math.floor(65536 * Math.random());
1415 rng_pool[rng_pptr++] = t >>> 8;
1416 rng_pool[rng_pptr++] = t & 255;
1417 }
1418 rng_pptr = 0;
1419 rng_seed_time();
1420 //rng_seed_int(window.screenX);
1421 //rng_seed_int(window.screenY);
1422}
1423
1424function rng_get_byte() {
1425 if(rng_state == null) {
1426 rng_seed_time();
1427 rng_state = prng_newstate();
1428 rng_state.init(rng_pool);
1429 for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
1430 rng_pool[rng_pptr] = 0;
1431 rng_pptr = 0;
1432 //rng_pool = null;
1433 }
1434 // TODO: allow reseeding after first request
1435 return rng_state.next();
1436}
1437
1438function rng_get_bytes(ba) {
1439 var i;
1440 for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
1441}
1442
1443function SecureRandom() {}
1444
1445SecureRandom.prototype.nextBytes = rng_get_bytes;
1446// Depends on jsbn.js and rng.js
1447
1448// convert a (hex) string to a bignum object
1449function parseBigInt(str,r) {
1450 return new BigInteger(str,r);
1451}
1452
1453function linebrk(s,n) {
1454 var ret = "";
1455 var i = 0;
1456 while(i + n < s.length) {
1457 ret += s.substring(i,i+n) + "\n";
1458 i += n;
1459 }
1460 return ret + s.substring(i,s.length);
1461}
1462
1463function byte2Hex(b) {
1464 if(b < 0x10)
1465 return "0" + b.toString(16);
1466 else
1467 return b.toString(16);
1468}
1469
1470// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
1471function pkcs1pad2(s,n) {
1472 if(n < s.length + 11) {
1473 alert("Message too long for RSA");
1474 return null;
1475 }
1476 var ba = new Array();
1477 var i = s.length - 1;
1478 while(i >= 0 && n > 0) ba[--n] = s.charCodeAt(i--);
1479 ba[--n] = 0;
1480 var rng = new SecureRandom();
1481 var x = new Array();
1482 while(n > 2) { // random non-zero pad
1483 x[0] = 0;
1484 while(x[0] == 0) rng.nextBytes(x);
1485 ba[--n] = x[0];
1486 }
1487 ba[--n] = 2;
1488 ba[--n] = 0;
1489 return new BigInteger(ba);
1490}
1491
1492// "empty" RSA key constructor
1493function RSAKey() {
1494 this.n = null;
1495 this.e = 0;
1496 this.d = null;
1497 this.p = null;
1498 this.q = null;
1499 this.dmp1 = null;
1500 this.dmq1 = null;
1501 this.coeff = null;
1502}
1503
1504// Set the public key fields N and e from hex strings
1505function RSASetPublic(N,E) {
1506 if(N != null && E != null && N.length > 0 && E.length > 0) {
1507 this.n = parseBigInt(N,16);
1508 this.e = parseInt(E,16);
1509 }
1510 else
1511 alert("Invalid RSA public key");
1512}
1513
1514// Perform raw public operation on "x": return x^e (mod n)
1515function RSADoPublic(x) {
1516 return x.modPowInt(this.e, this.n);
1517}
1518
1519// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
1520function RSAEncrypt(text) {
1521 var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
1522 if(m == null) return null;
1523 var c = this.doPublic(m);
1524 if(c == null) return null;
1525 var h = c.toString(16);
1526 if((h.length & 1) == 0) return h; else return "0" + h;
1527}
1528
1529// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
1530//function RSAEncryptB64(text) {
1531// var h = this.encrypt(text);
1532// if(h) return hex2b64(h); else return null;
1533//}
1534
1535// protected
1536RSAKey.prototype.doPublic = RSADoPublic;
1537
1538// public
1539RSAKey.prototype.setPublic = RSASetPublic;
1540RSAKey.prototype.encrypt = RSAEncrypt;
1541//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
1542// Depends on rsa.js and jsbn2.js
1543
1544// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
1545function pkcs1unpad2(d,n) {
1546 var b = d.toByteArray();
1547 var i = 0;
1548 while(i < b.length && b[i] == 0) ++i;
1549 if(b.length-i != n-1 || b[i] != 2)
1550 return null;
1551 ++i;
1552 while(b[i] != 0)
1553 if(++i >= b.length) return null;
1554 var ret = "";
1555 while(++i < b.length)
1556 ret += String.fromCharCode(b[i]);
1557 return ret;
1558}
1559
1560// Set the private key fields N, e, and d from hex strings
1561function RSASetPrivate(N,E,D) {
1562 if(N != null && E != null && N.length > 0 && E.length > 0) {
1563 this.n = parseBigInt(N,16);
1564 this.e = parseInt(E,16);
1565 this.d = parseBigInt(D,16);
1566 }
1567 else
1568 alert("Invalid RSA private key");
1569}
1570
1571// Set the private key fields N, e, d and CRT params from hex strings
1572function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {
1573 if(N != null && E != null && N.length > 0 && E.length > 0) {
1574 this.n = parseBigInt(N,16);
1575 this.e = parseInt(E,16);
1576 this.d = parseBigInt(D,16);
1577 this.p = parseBigInt(P,16);
1578 this.q = parseBigInt(Q,16);
1579 this.dmp1 = parseBigInt(DP,16);
1580 this.dmq1 = parseBigInt(DQ,16);
1581 this.coeff = parseBigInt(C,16);
1582 }
1583 else
1584 alert("Invalid RSA private key");
1585}
1586
1587// Generate a new random private key B bits long, using public expt E
1588function RSAGenerate(B,E) {
1589 var rng = new SecureRandom();
1590 var qs = B>>1;
1591 this.e = parseInt(E,16);
1592 var ee = new BigInteger(E,16);
1593 for(;;) {
1594 for(;;) {
1595 this.p = new BigInteger(B-qs,1,rng);
1596 if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
1597 }
1598 for(;;) {
1599 this.q = new BigInteger(qs,1,rng);
1600 if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
1601 }
1602 if(this.p.compareTo(this.q) <= 0) {
1603 var t = this.p;
1604 this.p = this.q;
1605 this.q = t;
1606 }
1607 var p1 = this.p.subtract(BigInteger.ONE);
1608 var q1 = this.q.subtract(BigInteger.ONE);
1609 var phi = p1.multiply(q1);
1610 if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
1611 this.n = this.p.multiply(this.q);
1612 this.d = ee.modInverse(phi);
1613 this.dmp1 = this.d.mod(p1);
1614 this.dmq1 = this.d.mod(q1);
1615 this.coeff = this.q.modInverse(this.p);
1616 break;
1617 }
1618 }
1619}
1620
1621// Perform raw private operation on "x": return x^d (mod n)
1622function RSADoPrivate(x) {
1623 if(this.p == null || this.q == null)
1624 return x.modPow(this.d, this.n);
1625
1626 // TODO: re-calculate any missing CRT params
1627 var xp = x.mod(this.p).modPow(this.dmp1, this.p);
1628 var xq = x.mod(this.q).modPow(this.dmq1, this.q);
1629
1630 while(xp.compareTo(xq) < 0)
1631 xp = xp.add(this.p);
1632 return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
1633}
1634
1635// Return the PKCS#1 RSA decryption of "ctext".
1636// "ctext" is an even-length hex string and the output is a plain string.
1637function RSADecrypt(ctext) {
1638 var c = parseBigInt(ctext, 16);
1639 var m = this.doPrivate(c);
1640 if(m == null) return null;
1641 return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);
1642}
1643
1644// Return the PKCS#1 RSA decryption of "ctext".
1645// "ctext" is a Base64-encoded string and the output is a plain string.
1646//function RSAB64Decrypt(ctext) {
1647// var h = b64tohex(ctext);
1648// if(h) return this.decrypt(h); else return null;
1649//}
1650
1651// protected
1652RSAKey.prototype.doPrivate = RSADoPrivate;
1653
1654// public
1655RSAKey.prototype.setPrivate = RSASetPrivate;
1656RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
1657RSAKey.prototype.generate = RSAGenerate;
1658RSAKey.prototype.decrypt = RSADecrypt;
1659//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;
1660
1661
1662var nValue="a5261939975948bb7a58dffe5ff54e65f0498f9175f5a09288810b8975871e99af3b5dd94057b0fc07535f5f97444504fa35169d461d0d30cf0192e307727c065168c788771c561a9400fb49175e9e6aa4e23fe11af69e9412dd23b0cb6684c4c2429bce139e848ab26d0829073351f4acd36074eafd036a5eb83359d2a698d3";
1663var eValue="10001";
1664var dValue="8e9912f6d3645894e8d38cb58c0db81ff516cf4c7e5a14c7f1eddb1459d2cded4d8d293fc97aee6aefb861859c8b6a3d1dfe710463e1f9ddc72048c09751971c4a580aa51eb523357a3cc48d31cfad1d4a165066ed92d4748fb6571211da5cb14bc11b6e2df7c1a559e6d5ac1cd5c94703a22891464fba23d0d965086277a161";
1665var pValue="d090ce58a92c75233a6486cb0a9209bf3583b64f540c76f5294bb97d285eed33aec220bde14b2417951178ac152ceab6da7090905b478195498b352048f15e7d";
1666var qValue="cab575dc652bb66df15a0359609d51d1db184750c00c6698b90ef3465c99655103edbf0d54c56aec0ce3c4d22592338092a126a0cc49f65a4a30d222b411e58f";
1667var dmp1Value="1a24bca8e273df2f0e47c199bbf678604e7df7215480c77c8db39f49b000ce2cf7500038acfff5433b7d582a01f1826e6f4d42e1c57f5e1fef7b12aabc59fd25";
1668var dmq1Value="3d06982efbbe47339e1f6d36b1216b8a741d410b0c662f54f7118b27b9a4ec9d914337eb39841d8666f3034408cf94f5b62f11c402fc994fe15a05493150d9fd";
1669var coeffValue="3a3e731acd8960b7ff9eb81a7ff93bd1cfa74cbd56987db58b4594fb09c09084db1734c8143f98b602b981aaa9243ca28deb69b5b280ee8dcee0fd2625e53250";
1670
1671setupEngine(am3, 28);
1672
1673var TEXT = "The quick brown fox jumped over the extremely lazy frog! " +
1674 "Now is the time for all good men to come to the party.";
1675var encrypted;
1676
1677function encrypt() {
1678 var RSA = new RSAKey();
1679 RSA.setPublic(nValue, eValue);
1680 RSA.setPrivateEx(nValue, eValue, dValue, pValue, qValue, dmp1Value, dmq1Value, coeffValue);
1681 encrypted = RSA.encrypt(TEXT);
1682}
1683
1684function decrypt() {
1685 var RSA = new RSAKey();
1686 RSA.setPublic(nValue, eValue);
1687 RSA.setPrivateEx(nValue, eValue, dValue, pValue, qValue, dmp1Value, dmq1Value, coeffValue);
1688 var decrypted = RSA.decrypt(encrypted);
1689 if (decrypted != TEXT) {
1690 throw new Error("Crypto operation failed");
1691 }
1692}
1693
1694for (var i = 0; i < 8; ++i) {
1695 encrypt();
1696 decrypt();
1697}