3 <script src=
"../htmlrunner.js"></script>
6 * Copyright (c) 2003-2005 Tom Wu
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
22 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
24 * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
25 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
26 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
27 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
28 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 * In addition, the following condition applies:
32 * All redistributions must retain an intact copy of this copyright notice
37 // The code has been adapted for use as a benchmark by Google.
39 // Basic JavaScript BN library - subset useful for RSA encryption.
52 // JavaScript engine analysis
53 var canary
= 0xdeadbeefcafe;
54 var j_lm
= ((canary
&0xffffff)==0xefcafe);
56 // (public) Constructor
57 function BigInteger(a
,b
,c
) {
58 this.array
= new Array();
60 if("number" == typeof a
) this.fromNumber(a
,b
,c
);
61 else if(b
== null && "string" != typeof a
) this.fromString(a
,256);
62 else this.fromString(a
,b
);
65 // return new, unset BigInteger
66 function nbi() { return new BigInteger(null); }
68 // am: Compute w_j += (x*this_i), propagate carries,
69 // c is initial carry, returns final carry.
70 // c < 3*dvalue, x < 2*dvalue, this_i < dvalue
71 // We need to select the fastest one that works in this environment.
73 // am1: use a single mult and divide to get the high bits,
74 // max digit bits should be 26 because
75 // max internal value = 2*dvalue^2-2*dvalue (< 2^53)
76 function am1(i
,x
,w
,j
,c
,n
) {
77 var this_array
= this.array
;
78 var w_array
= w
.array
;
80 var v
= x
*this_array
[i
++]+w_array
[j
]+c
;
81 c
= Math
.floor(v
/0x4000000);
82 w_array
[j
++] = v
&0x3ffffff;
87 // am2 avoids a big mult-and-extract completely.
88 // Max digit bits should be <= 30 because we do bitwise ops
89 // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
90 function am2(i
,x
,w
,j
,c
,n
) {
91 var this_array
= this.array
;
92 var w_array
= w
.array
;
93 var xl
= x
&0x7fff, xh
= x
>>15;
95 var l
= this_array
[i
]&0x7fff;
96 var h
= this_array
[i
++]>>15;
98 l
= xl
*l
+((m
&0x7fff)<<15)+w_array
[j
]+(c
&0x3fffffff);
99 c
= (l
>>>30)+(m
>>>15)+xh
*h
+(c
>>>30);
100 w_array
[j
++] = l
&0x3fffffff;
105 // Alternately, set max digit bits to 28 since some
106 // browsers slow down when dealing with 32-bit numbers.
107 function am3(i
,x
,w
,j
,c
,n
) {
108 var this_array
= this.array
;
109 var w_array
= w
.array
;
111 var xl
= x
&0x3fff, xh
= x
>>14;
113 var l
= this_array
[i
]&0x3fff;
114 var h
= this_array
[i
++]>>14;
116 l
= xl
*l
+((m
&0x3fff)<<14)+w_array
[j
]+c
;
117 c
= (l
>>28)+(m
>>14)+xh
*h
;
118 w_array
[j
++] = l
&0xfffffff;
123 // This is tailored to VMs with 2-bit tagging. It makes sure
124 // that all the computations stay within the 29 bits available.
125 function am4(i
,x
,w
,j
,c
,n
) {
126 var this_array
= this.array
;
127 var w_array
= w
.array
;
129 var xl
= x
&0x1fff, xh
= x
>>13;
131 var l
= this_array
[i
]&0x1fff;
132 var h
= this_array
[i
++]>>13;
134 l
= xl
*l
+((m
&0x1fff)<<13)+w_array
[j
]+c
;
135 c
= (l
>>26)+(m
>>13)+xh
*h
;
136 w_array
[j
++] = l
&0x3ffffff;
141 // am3/28 is best for SM, Rhino, but am4/26 is best for v8.
142 // Kestrel (Opera 9.5) gets its best result with am4/26.
143 // IE7 does 9% better with am3/28 than with am4/26.
144 // Firefox (SM) gets 10% faster with am3/28 than with am4/26.
146 setupEngine = function(fn
, bits
) {
147 BigInteger
.prototype.am
= fn
;
151 BI_DM
= ((1<<dbits
)-1);
155 BI_FV
= Math
.pow(2,BI_FP
);
157 BI_F2
= 2*dbits
-BI_FP
;
162 var BI_RM
= "0123456789abcdefghijklmnopqrstuvwxyz";
163 var BI_RC
= new Array();
165 rr
= "0".charCodeAt(0);
166 for(vv
= 0; vv
<= 9; ++vv
) BI_RC
[rr
++] = vv
;
167 rr
= "a".charCodeAt(0);
168 for(vv
= 10; vv
< 36; ++vv
) BI_RC
[rr
++] = vv
;
169 rr
= "A".charCodeAt(0);
170 for(vv
= 10; vv
< 36; ++vv
) BI_RC
[rr
++] = vv
;
172 function int2char(n
) { return BI_RM
.charAt(n
); }
173 function intAt(s
,i
) {
174 var c
= BI_RC
[s
.charCodeAt(i
)];
175 return (c
==null)?-1:c
;
178 // (protected) copy this to r
179 function bnpCopyTo(r
) {
180 var this_array
= this.array
;
181 var r_array
= r
.array
;
183 for(var i
= this.t
-1; i
>= 0; --i
) r_array
[i
] = this_array
[i
];
188 // (protected) set from integer value x, -DV <= x < DV
189 function bnpFromInt(x
) {
190 var this_array
= this.array
;
193 if(x
> 0) this_array
[0] = x
;
194 else if(x
< -1) this_array
[0] = x
+DV
;
198 // return bigint initialized to value
199 function nbv(i
) { var r
= nbi(); r
.fromInt(i
); return r
; }
201 // (protected) set from string and radix
202 function bnpFromString(s
,b
) {
203 var this_array
= this.array
;
206 else if(b
== 8) k
= 3;
207 else if(b
== 256) k
= 8; // byte array
208 else if(b
== 2) k
= 1;
209 else if(b
== 32) k
= 5;
210 else if(b
== 4) k
= 2;
211 else { this.fromRadix(s
,b
); return; }
214 var i
= s
.length
, mi
= false, sh
= 0;
216 var x
= (k
==8)?s
[i
]&0xff:intAt(s
,i
);
218 if(s
.charAt(i
) == "-") mi
= true;
223 this_array
[this.t
++] = x
;
224 else if(sh
+k
> BI_DB
) {
225 this_array
[this.t
-1] |= (x
&((1<<(BI_DB
-sh
))-1))<<sh
;
226 this_array
[this.t
++] = (x
>>(BI_DB
-sh
));
229 this_array
[this.t
-1] |= x
<<sh
;
231 if(sh
>= BI_DB
) sh
-= BI_DB
;
233 if(k
== 8 && (s
[0]&0x80) != 0) {
235 if(sh
> 0) this_array
[this.t
-1] |= ((1<<(BI_DB
-sh
))-1)<<sh
;
238 if(mi
) BigInteger
.ZERO
.subTo(this,this);
241 // (protected) clamp off excess high words
242 function bnpClamp() {
243 var this_array
= this.array
;
244 var c
= this.s
&BI_DM
;
245 while(this.t
> 0 && this_array
[this.t
-1] == c
) --this.t
;
248 // (public) return string representation in given radix
249 function bnToString(b
) {
250 var this_array
= this.array
;
251 if(this.s
< 0) return "-"+this.negate().toString(b
);
254 else if(b
== 8) k
= 3;
255 else if(b
== 2) k
= 1;
256 else if(b
== 32) k
= 5;
257 else if(b
== 4) k
= 2;
258 else return this.toRadix(b
);
259 var km
= (1<<k
)-1, d
, m
= false, r
= "", i
= this.t
;
260 var p
= BI_DB
-(i
*BI_DB
)%k
;
262 if(p
< BI_DB
&& (d
= this_array
[i
]>>p
) > 0) { m
= true; r
= int2char(d
); }
265 d
= (this_array
[i
]&((1<<p
)-1))<<(k
-p
);
266 d
|= this_array
[--i
]>>(p
+=BI_DB
-k
);
269 d
= (this_array
[i
]>>(p
-=k
))&km
;
270 if(p
<= 0) { p
+= BI_DB
; --i
; }
273 if(m
) r
+= int2char(d
);
280 function bnNegate() { var r
= nbi(); BigInteger
.ZERO
.subTo(this,r
); return r
; }
283 function bnAbs() { return (this.s
<0)?this.negate():this; }
285 // (public) return + if this > a, - if this < a, 0 if equal
286 function bnCompareTo(a
) {
287 var this_array
= this.array
;
288 var a_array
= a
.array
;
295 while(--i
>= 0) if((r
=this_array
[i
]-a_array
[i
]) != 0) return r
;
299 // returns bit length of the integer x
302 if((t
=x
>>>16) != 0) { x
= t
; r
+= 16; }
303 if((t
=x
>>8) != 0) { x
= t
; r
+= 8; }
304 if((t
=x
>>4) != 0) { x
= t
; r
+= 4; }
305 if((t
=x
>>2) != 0) { x
= t
; r
+= 2; }
306 if((t
=x
>>1) != 0) { x
= t
; r
+= 1; }
310 // (public) return the number of bits in "this"
311 function bnBitLength() {
312 var this_array
= this.array
;
313 if(this.t
<= 0) return 0;
314 return BI_DB
*(this.t
-1)+nbits(this_array
[this.t
-1]^(this.s
&BI_DM
));
317 // (protected) r = this << n*DB
318 function bnpDLShiftTo(n
,r
) {
319 var this_array
= this.array
;
320 var r_array
= r
.array
;
322 for(i
= this.t
-1; i
>= 0; --i
) r_array
[i
+n
] = this_array
[i
];
323 for(i
= n
-1; i
>= 0; --i
) r_array
[i
] = 0;
328 // (protected) r = this >> n*DB
329 function bnpDRShiftTo(n
,r
) {
330 var this_array
= this.array
;
331 var r_array
= r
.array
;
332 for(var i
= n
; i
< this.t
; ++i
) r_array
[i
-n
] = this_array
[i
];
333 r
.t
= Math
.max(this.t
-n
,0);
337 // (protected) r = this << n
338 function bnpLShiftTo(n
,r
) {
339 var this_array
= this.array
;
340 var r_array
= r
.array
;
344 var ds
= Math
.floor(n
/BI_DB
), c
= (this.s
<<bs
)&BI_DM
, i
;
345 for(i
= this.t
-1; i
>= 0; --i
) {
346 r_array
[i
+ds
+1] = (this_array
[i
]>>cbs
)|c
;
347 c
= (this_array
[i
]&bm
)<<bs
;
349 for(i
= ds
-1; i
>= 0; --i
) r_array
[i
] = 0;
356 // (protected) r = this >> n
357 function bnpRShiftTo(n
,r
) {
358 var this_array
= this.array
;
359 var r_array
= r
.array
;
361 var ds
= Math
.floor(n
/BI_DB
);
362 if(ds
>= this.t
) { r
.t
= 0; return; }
366 r_array
[0] = this_array
[ds
]>>bs
;
367 for(var i
= ds
+1; i
< this.t
; ++i
) {
368 r_array
[i
-ds
-1] |= (this_array
[i
]&bm
)<<cbs
;
369 r_array
[i
-ds
] = this_array
[i
]>>bs
;
371 if(bs
> 0) r_array
[this.t
-ds
-1] |= (this.s
&bm
)<<cbs
;
376 // (protected) r = this - a
377 function bnpSubTo(a
,r
) {
378 var this_array
= this.array
;
379 var r_array
= r
.array
;
380 var a_array
= a
.array
;
381 var i
= 0, c
= 0, m
= Math
.min(a
.t
,this.t
);
383 c
+= this_array
[i
]-a_array
[i
];
384 r_array
[i
++] = c
&BI_DM
;
391 r_array
[i
++] = c
&BI_DM
;
400 r_array
[i
++] = c
&BI_DM
;
406 if(c
< -1) r_array
[i
++] = BI_DV
+c
;
407 else if(c
> 0) r_array
[i
++] = c
;
412 // (protected) r = this * a, r != this,a (HAC 14.12)
413 // "this" should be the larger one if appropriate.
414 function bnpMultiplyTo(a
,r
) {
415 var this_array
= this.array
;
416 var r_array
= r
.array
;
417 var x
= this.abs(), y
= a
.abs();
418 var y_array
= y
.array
;
422 while(--i
>= 0) r_array
[i
] = 0;
423 for(i
= 0; i
< y
.t
; ++i
) r_array
[i
+x
.t
] = x
.am(0,y_array
[i
],r
,i
,0,x
.t
);
426 if(this.s
!= a
.s
) BigInteger
.ZERO
.subTo(r
,r
);
429 // (protected) r = this^2, r != this (HAC 14.16)
430 function bnpSquareTo(r
) {
432 var x_array
= x
.array
;
433 var r_array
= r
.array
;
436 while(--i
>= 0) r_array
[i
] = 0;
437 for(i
= 0; i
< x
.t
-1; ++i
) {
438 var c
= x
.am(i
,x_array
[i
],r
,2*i
,0,1);
439 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
) {
440 r_array
[i
+x
.t
] -= BI_DV
;
441 r_array
[i
+x
.t
+1] = 1;
444 if(r
.t
> 0) r_array
[r
.t
-1] += x
.am(i
,x_array
[i
],r
,2*i
,0,1);
449 // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
450 // r != q, this != m. q or r may be null.
451 function bnpDivRemTo(m
,q
,r
) {
453 if(pm
.t
<= 0) return;
456 if(q
!= null) q
.fromInt(0);
457 if(r
!= null) this.copyTo(r
);
460 if(r
== null) r
= nbi();
461 var y
= nbi(), ts
= this.s
, ms
= m
.s
;
462 var pm_array
= pm
.array
;
463 var nsh
= BI_DB
-nbits(pm_array
[pm
.t
-1]); // normalize modulus
464 if(nsh
> 0) { pm
.lShiftTo(nsh
,y
); pt
.lShiftTo(nsh
,r
); }
465 else { pm
.copyTo(y
); pt
.copyTo(r
); }
468 var y_array
= y
.array
;
469 var y0
= y_array
[ys
-1];
471 var yt
= y0
*(1<<BI_F1
)+((ys
>1)?y_array
[ys
-2]>>BI_F2
:0);
472 var d1
= BI_FV
/yt, d2 = (1<<BI_F1)/yt, e
= 1<<BI_F2
;
473 var i
= r
.t
, j
= i
-ys
, t
= (q
==null)?nbi():q
;
476 var r_array
= r
.array
;
477 if(r
.compareTo(t
) >= 0) {
481 BigInteger
.ONE
.dlShiftTo(ys
,t
);
482 t
.subTo(y
,y
); // "negative" y so we can replace sub with am later
483 while(y
.t
< ys
) y_array
[y
.t
++] = 0;
485 // Estimate quotient digit
486 var qd
= (r_array
[--i
]==y0
)?BI_DM
:Math
.floor(r_array
[i
]*d1
+(r_array
[i
-1]+e
)*d2
);
487 if((r_array
[i
]+=y
.am(0,qd
,r
,j
,0,ys
)) < qd
) { // Try it out
490 while(r_array
[i
] < --qd
) r
.subTo(t
,r
);
495 if(ts
!= ms
) BigInteger
.ZERO
.subTo(q
,q
);
499 if(nsh
> 0) r
.rShiftTo(nsh
,r
); // Denormalize remainder
500 if(ts
< 0) BigInteger
.ZERO
.subTo(r
,r
);
503 // (public) this mod a
506 this.abs().divRemTo(a
,null,r
);
507 if(this.s
< 0 && r
.compareTo(BigInteger
.ZERO
) > 0) a
.subTo(r
,r
);
511 // Modular reduction using "classic" algorithm
512 function Classic(m
) { this.m
= m
; }
513 function cConvert(x
) {
514 if(x
.s
< 0 || x
.compareTo(this.m
) >= 0) return x
.mod(this.m
);
517 function cRevert(x
) { return x
; }
518 function cReduce(x
) { x
.divRemTo(this.m
,null,x
); }
519 function cMulTo(x
,y
,r
) { x
.multiplyTo(y
,r
); this.reduce(r
); }
520 function cSqrTo(x
,r
) { x
.squareTo(r
); this.reduce(r
); }
522 Classic
.prototype.convert
= cConvert
;
523 Classic
.prototype.revert
= cRevert
;
524 Classic
.prototype.reduce
= cReduce
;
525 Classic
.prototype.mulTo
= cMulTo
;
526 Classic
.prototype.sqrTo
= cSqrTo
;
528 // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
532 // xy(2-xy) = (1+km)(1-km)
533 // x[y(2-xy)] = 1-k^2m^2
534 // x[y(2-xy)] == 1 (mod m^2)
535 // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
536 // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
537 // JS multiply "overflows" differently from C/C++, so care is needed here.
538 function bnpInvDigit() {
539 var this_array
= this.array
;
540 if(this.t
< 1) return 0;
541 var x
= this_array
[0];
542 if((x
&1) == 0) return 0;
543 var y
= x
&3; // y == 1/x mod 2^2
544 y
= (y
*(2-(x
&0xf)*y
))&0xf; // y == 1/x mod 2^4
545 y
= (y
*(2-(x
&0xff)*y
))&0xff; // y == 1/x mod 2^8
546 y
= (y
*(2-(((x
&0xffff)*y
)&0xffff)))&0xffff; // y == 1/x mod 2^16
547 // last step - calculate inverse mod DV directly;
548 // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
549 y
= (y
*(2-x
*y
%BI_DV
))%BI_DV
; // y == 1/x mod 2^dbits
550 // we really want the negative inverse, and -DV < y < DV
551 return (y
>0)?BI_DV
-y
:-y
;
554 // Montgomery reduction
555 function Montgomery(m
) {
557 this.mp
= m
.invDigit();
558 this.mpl
= this.mp
&0x7fff;
559 this.mph
= this.mp
>>15;
560 this.um
= (1<<(BI_DB
-15))-1;
565 function montConvert(x
) {
567 x
.abs().dlShiftTo(this.m
.t
,r
);
568 r
.divRemTo(this.m
,null,r
);
569 if(x
.s
< 0 && r
.compareTo(BigInteger
.ZERO
) > 0) this.m
.subTo(r
,r
);
574 function montRevert(x
) {
581 // x = x/R mod m (HAC 14.32)
582 function montReduce(x
) {
583 var x_array
= x
.array
;
584 while(x
.t
<= this.mt2
) // pad x so am has enough room later
586 for(var i
= 0; i
< this.m
.t
; ++i
) {
587 // faster way of calculating u0 = x[i]*mp mod DV
588 var j
= x_array
[i
]&0x7fff;
589 var u0
= (j
*this.mpl
+(((j
*this.mph
+(x_array
[i
]>>15)*this.mpl
)&this.um
)<<15))&BI_DM
;
590 // use am to combine the multiply-shift-add into one call
592 x_array
[j
] += this.m
.am(0,u0
,x
,i
,0,this.m
.t
);
594 while(x_array
[j
] >= BI_DV
) { x_array
[j
] -= BI_DV
; x_array
[++j
]++; }
597 x
.drShiftTo(this.m
.t
,x
);
598 if(x
.compareTo(this.m
) >= 0) x
.subTo(this.m
,x
);
601 // r = "x^2/R mod m"; x != r
602 function montSqrTo(x
,r
) { x
.squareTo(r
); this.reduce(r
); }
604 // r = "xy/R mod m"; x,y != r
605 function montMulTo(x
,y
,r
) { x
.multiplyTo(y
,r
); this.reduce(r
); }
607 Montgomery
.prototype.convert
= montConvert
;
608 Montgomery
.prototype.revert
= montRevert
;
609 Montgomery
.prototype.reduce
= montReduce
;
610 Montgomery
.prototype.mulTo
= montMulTo
;
611 Montgomery
.prototype.sqrTo
= montSqrTo
;
613 // (protected) true iff this is even
614 function bnpIsEven() {
615 var this_array
= this.array
;
616 return ((this.t
>0)?(this_array
[0]&1):this.s
) == 0;
619 // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
620 function bnpExp(e
,z
) {
621 if(e
> 0xffffffff || e
< 1) return BigInteger
.ONE
;
622 var r
= nbi(), r2
= nbi(), g
= z
.convert(this), i
= nbits(e
)-1;
626 if((e
&(1<<i
)) > 0) z
.mulTo(r2
,g
,r
);
627 else { var t
= r
; r
= r2
; r2
= t
; }
632 // (public) this^e % m, 0 <= e < 2^32
633 function bnModPowInt(e
,m
) {
635 if(e
< 256 || m
.isEven()) z
= new Classic(m
); else z
= new Montgomery(m
);
636 return this.exp(e
,z
);
640 BigInteger
.prototype.copyTo
= bnpCopyTo
;
641 BigInteger
.prototype.fromInt
= bnpFromInt
;
642 BigInteger
.prototype.fromString
= bnpFromString
;
643 BigInteger
.prototype.clamp
= bnpClamp
;
644 BigInteger
.prototype.dlShiftTo
= bnpDLShiftTo
;
645 BigInteger
.prototype.drShiftTo
= bnpDRShiftTo
;
646 BigInteger
.prototype.lShiftTo
= bnpLShiftTo
;
647 BigInteger
.prototype.rShiftTo
= bnpRShiftTo
;
648 BigInteger
.prototype.subTo
= bnpSubTo
;
649 BigInteger
.prototype.multiplyTo
= bnpMultiplyTo
;
650 BigInteger
.prototype.squareTo
= bnpSquareTo
;
651 BigInteger
.prototype.divRemTo
= bnpDivRemTo
;
652 BigInteger
.prototype.invDigit
= bnpInvDigit
;
653 BigInteger
.prototype.isEven
= bnpIsEven
;
654 BigInteger
.prototype.exp
= bnpExp
;
657 BigInteger
.prototype.toString
= bnToString
;
658 BigInteger
.prototype.negate
= bnNegate
;
659 BigInteger
.prototype.abs
= bnAbs
;
660 BigInteger
.prototype.compareTo
= bnCompareTo
;
661 BigInteger
.prototype.bitLength
= bnBitLength
;
662 BigInteger
.prototype.mod
= bnMod
;
663 BigInteger
.prototype.modPowInt
= bnModPowInt
;
666 BigInteger
.ZERO
= nbv(0);
667 BigInteger
.ONE
= nbv(1);
668 // Copyright (c) 2005 Tom Wu
669 // All Rights Reserved.
670 // See "LICENSE" for details.
672 // Extended JavaScript BN functions, required for RSA private ops.
675 function bnClone() { var r
= nbi(); this.copyTo(r
); return r
; }
677 // (public) return value as integer
678 function bnIntValue() {
679 var this_array
= this.array
;
681 if(this.t
== 1) return this_array
[0]-BI_DV
;
682 else if(this.t
== 0) return -1;
684 else if(this.t
== 1) return this_array
[0];
685 else if(this.t
== 0) return 0;
686 // assumes 16 < DB < 32
687 return ((this_array
[1]&((1<<(32-BI_DB
))-1))<<BI_DB
)|this_array
[0];
690 // (public) return value as byte
691 function bnByteValue() {
692 var this_array
= this.array
;
693 return (this.t
==0)?this.s
:(this_array
[0]<<24)>>24;
696 // (public) return value as short (assumes DB>=16)
697 function bnShortValue() {
698 var this_array
= this.array
;
699 return (this.t
==0)?this.s
:(this_array
[0]<<16)>>16;
702 // (protected) return x s.t. r^x < DV
703 function bnpChunkSize(r
) { return Math
.floor(Math
.LN2
*BI_DB
/Math
.log(r
)); }
705 // (public) 0 if this == 0, 1 if this > 0
706 function bnSigNum() {
707 var this_array
= this.array
;
708 if(this.s
< 0) return -1;
709 else if(this.t
<= 0 || (this.t
== 1 && this_array
[0] <= 0)) return 0;
713 // (protected) convert to radix string
714 function bnpToRadix(b
) {
715 if(b
== null) b
= 10;
716 if(this.signum() == 0 || b
< 2 || b
> 36) return "0";
717 var cs
= this.chunkSize(b
);
718 var a
= Math
.pow(b
,cs
);
719 var d
= nbv(a
), y
= nbi(), z
= nbi(), r
= "";
720 this.divRemTo(d
,y
,z
);
721 while(y
.signum() > 0) {
722 r
= (a
+z
.intValue()).toString(b
).substr(1) + r
;
725 return z
.intValue().toString(b
) + r
;
728 // (protected) convert from radix string
729 function bnpFromRadix(s
,b
) {
731 if(b
== null) b
= 10;
732 var cs
= this.chunkSize(b
);
733 var d
= Math
.pow(b
,cs
), mi
= false, j
= 0, w
= 0;
734 for(var i
= 0; i
< s
.length
; ++i
) {
737 if(s
.charAt(i
) == "-" && this.signum() == 0) mi
= true;
743 this.dAddOffset(w
,0);
749 this.dMultiply(Math
.pow(b
,j
));
750 this.dAddOffset(w
,0);
752 if(mi
) BigInteger
.ZERO
.subTo(this,this);
755 // (protected) alternate constructor
756 function bnpFromNumber(a
,b
,c
) {
757 if("number" == typeof b
) {
758 // new BigInteger(int,int,RNG)
759 if(a
< 2) this.fromInt(1);
761 this.fromNumber(a
,c
);
762 if(!this.testBit(a
-1)) // force MSB set
763 this.bitwiseTo(BigInteger
.ONE
.shiftLeft(a
-1),op_or
,this);
764 if(this.isEven()) this.dAddOffset(1,0); // force odd
765 while(!this.isProbablePrime(b
)) {
766 this.dAddOffset(2,0);
767 if(this.bitLength() > a
) this.subTo(BigInteger
.ONE
.shiftLeft(a
-1),this);
772 // new BigInteger(int,RNG)
773 var x
= new Array(), t
= a
&7;
776 if(t
> 0) x
[0] &= ((1<<t
)-1); else x
[0] = 0;
777 this.fromString(x
,256);
781 // (public) convert to bigendian byte array
782 function bnToByteArray() {
783 var this_array
= this.array
;
784 var i
= this.t
, r
= new Array();
786 var p
= BI_DB
-(i
*BI_DB
)%8, d
, k
= 0;
788 if(p
< BI_DB
&& (d
= this_array
[i
]>>p
) != (this.s
&BI_DM
)>>p
)
789 r
[k
++] = d
|(this.s
<<(BI_DB
-p
));
792 d
= (this_array
[i
]&((1<<p
)-1))<<(8-p
);
793 d
|= this_array
[--i
]>>(p
+=BI_DB
-8);
796 d
= (this_array
[i
]>>(p
-=8))&0xff;
797 if(p
<= 0) { p
+= BI_DB
; --i
; }
799 if((d
&0x80) != 0) d
|= -256;
800 if(k
== 0 && (this.s
&0x80) != (d
&0x80)) ++k
;
801 if(k
> 0 || d
!= this.s
) r
[k
++] = d
;
807 function bnEquals(a
) { return(this.compareTo(a
)==0); }
808 function bnMin(a
) { return(this.compareTo(a
)<0)?this:a
; }
809 function bnMax(a
) { return(this.compareTo(a
)>0)?this:a
; }
811 // (protected) r = this op a (bitwise)
812 function bnpBitwiseTo(a
,op
,r
) {
813 var this_array
= this.array
;
814 var a_array
= a
.array
;
815 var r_array
= r
.array
;
816 var i
, f
, m
= Math
.min(a
.t
,this.t
);
817 for(i
= 0; i
< m
; ++i
) r_array
[i
] = op(this_array
[i
],a_array
[i
]);
820 for(i
= m
; i
< this.t
; ++i
) r_array
[i
] = op(this_array
[i
],f
);
825 for(i
= m
; i
< a
.t
; ++i
) r_array
[i
] = op(f
,a_array
[i
]);
828 r
.s
= op(this.s
,a
.s
);
833 function op_and(x
,y
) { return x
&y
; }
834 function bnAnd(a
) { var r
= nbi(); this.bitwiseTo(a
,op_and
,r
); return r
; }
837 function op_or(x
,y
) { return x
|y
; }
838 function bnOr(a
) { var r
= nbi(); this.bitwiseTo(a
,op_or
,r
); return r
; }
841 function op_xor(x
,y
) { return x
^y
; }
842 function bnXor(a
) { var r
= nbi(); this.bitwiseTo(a
,op_xor
,r
); return r
; }
844 // (public) this & ~a
845 function op_andnot(x
,y
) { return x
&~y
; }
846 function bnAndNot(a
) { var r
= nbi(); this.bitwiseTo(a
,op_andnot
,r
); return r
; }
850 var this_array
= this.array
;
852 var r_array
= r
.array
;
854 for(var i
= 0; i
< this.t
; ++i
) r_array
[i
] = BI_DM
&~this_array
[i
];
860 // (public) this << n
861 function bnShiftLeft(n
) {
863 if(n
< 0) this.rShiftTo(-n
,r
); else this.lShiftTo(n
,r
);
867 // (public) this >> n
868 function bnShiftRight(n
) {
870 if(n
< 0) this.lShiftTo(-n
,r
); else this.rShiftTo(n
,r
);
874 // return index of lowest 1-bit in x, x < 2^31
876 if(x
== 0) return -1;
878 if((x
&0xffff) == 0) { x
>>= 16; r
+= 16; }
879 if((x
&0xff) == 0) { x
>>= 8; r
+= 8; }
880 if((x
&0xf) == 0) { x
>>= 4; r
+= 4; }
881 if((x
&3) == 0) { x
>>= 2; r
+= 2; }
886 // (public) returns index of lowest 1-bit (or -1 if none)
887 function bnGetLowestSetBit() {
888 var this_array
= this.array
;
889 for(var i
= 0; i
< this.t
; ++i
)
890 if(this_array
[i
] != 0) return i
*BI_DB
+lbit(this_array
[i
]);
891 if(this.s
< 0) return this.t
*BI_DB
;
895 // return number of 1 bits in x
898 while(x
!= 0) { x
&= x
-1; ++r
; }
902 // (public) return number of set bits
903 function bnBitCount() {
904 var r
= 0, x
= this.s
&BI_DM
;
905 for(var i
= 0; i
< this.t
; ++i
) r
+= cbit(this_array
[i
]^x
);
909 // (public) true iff nth bit is set
910 function bnTestBit(n
) {
911 var this_array
= this.array
;
912 var j
= Math
.floor(n
/BI_DB
);
913 if(j
>= this.t
) return(this.s
!=0);
914 return((this_array
[j
]&(1<<(n
%BI_DB
)))!=0);
917 // (protected) this op (1<<n)
918 function bnpChangeBit(n
,op
) {
919 var r
= BigInteger
.ONE
.shiftLeft(n
);
920 this.bitwiseTo(r
,op
,r
);
924 // (public) this | (1<<n)
925 function bnSetBit(n
) { return this.changeBit(n
,op_or
); }
927 // (public) this & ~(1<<n)
928 function bnClearBit(n
) { return this.changeBit(n
,op_andnot
); }
930 // (public) this ^ (1<<n)
931 function bnFlipBit(n
) { return this.changeBit(n
,op_xor
); }
933 // (protected) r = this + a
934 function bnpAddTo(a
,r
) {
935 var this_array
= this.array
;
936 var a_array
= a
.array
;
937 var r_array
= r
.array
;
938 var i
= 0, c
= 0, m
= Math
.min(a
.t
,this.t
);
940 c
+= this_array
[i
]+a_array
[i
];
941 r_array
[i
++] = c
&BI_DM
;
948 r_array
[i
++] = c
&BI_DM
;
957 r_array
[i
++] = c
&BI_DM
;
963 if(c
> 0) r_array
[i
++] = c
;
964 else if(c
< -1) r_array
[i
++] = BI_DV
+c
;
970 function bnAdd(a
) { var r
= nbi(); this.addTo(a
,r
); return r
; }
973 function bnSubtract(a
) { var r
= nbi(); this.subTo(a
,r
); return r
; }
976 function bnMultiply(a
) { var r
= nbi(); this.multiplyTo(a
,r
); return r
; }
979 function bnDivide(a
) { var r
= nbi(); this.divRemTo(a
,r
,null); return r
; }
982 function bnRemainder(a
) { var r
= nbi(); this.divRemTo(a
,null,r
); return r
; }
984 // (public) [this/a,this%a]
985 function bnDivideAndRemainder(a
) {
986 var q
= nbi(), r
= nbi();
987 this.divRemTo(a
,q
,r
);
988 return new Array(q
,r
);
991 // (protected) this *= n, this >= 0, 1 < n < DV
992 function bnpDMultiply(n
) {
993 var this_array
= this.array
;
994 this_array
[this.t
] = this.am(0,n
-1,this,0,0,this.t
);
999 // (protected) this += n << w words, this >= 0
1000 function bnpDAddOffset(n
,w
) {
1001 var this_array
= this.array
;
1002 while(this.t
<= w
) this_array
[this.t
++] = 0;
1004 while(this_array
[w
] >= BI_DV
) {
1005 this_array
[w
] -= BI_DV
;
1006 if(++w
>= this.t
) this_array
[this.t
++] = 0;
1012 function NullExp() {}
1013 function nNop(x
) { return x
; }
1014 function nMulTo(x
,y
,r
) { x
.multiplyTo(y
,r
); }
1015 function nSqrTo(x
,r
) { x
.squareTo(r
); }
1017 NullExp
.prototype.convert
= nNop
;
1018 NullExp
.prototype.revert
= nNop
;
1019 NullExp
.prototype.mulTo
= nMulTo
;
1020 NullExp
.prototype.sqrTo
= nSqrTo
;
1023 function bnPow(e
) { return this.exp(e
,new NullExp()); }
1025 // (protected) r = lower n words of "this * a", a.t <= n
1026 // "this" should be the larger one if appropriate.
1027 function bnpMultiplyLowerTo(a
,n
,r
) {
1028 var r_array
= r
.array
;
1029 var a_array
= a
.array
;
1030 var i
= Math
.min(this.t
+a
.t
,n
);
1031 r
.s
= 0; // assumes a,this >= 0
1033 while(i
> 0) r_array
[--i
] = 0;
1035 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
);
1036 for(j
= Math
.min(a
.t
,n
); i
< j
; ++i
) this.am(0,a_array
[i
],r
,i
,0,n
-i
);
1040 // (protected) r = "this * a" without lower n words, n > 0
1041 // "this" should be the larger one if appropriate.
1042 function bnpMultiplyUpperTo(a
,n
,r
) {
1043 var r_array
= r
.array
;
1044 var a_array
= a
.array
;
1046 var i
= r
.t
= this.t
+a
.t
-n
;
1047 r
.s
= 0; // assumes a,this >= 0
1048 while(--i
>= 0) r_array
[i
] = 0;
1049 for(i
= Math
.max(n
-this.t
,0); i
< a
.t
; ++i
)
1050 r_array
[this.t
+i
-n
] = this.am(n
-i
,a_array
[i
],r
,0,0,this.t
+i
-n
);
1055 // Barrett modular reduction
1056 function Barrett(m
) {
1060 BigInteger
.ONE
.dlShiftTo(2*m
.t
,this.r2
);
1061 this.mu
= this.r2
.divide(m
);
1065 function barrettConvert(x
) {
1066 if(x
.s
< 0 || x
.t
> 2*this.m
.t
) return x
.mod(this.m
);
1067 else if(x
.compareTo(this.m
) < 0) return x
;
1068 else { var r
= nbi(); x
.copyTo(r
); this.reduce(r
); return r
; }
1071 function barrettRevert(x
) { return x
; }
1073 // x = x mod m (HAC 14.42)
1074 function barrettReduce(x
) {
1075 x
.drShiftTo(this.m
.t
-1,this.r2
);
1076 if(x
.t
> this.m
.t
+1) { x
.t
= this.m
.t
+1; x
.clamp(); }
1077 this.mu
.multiplyUpperTo(this.r2
,this.m
.t
+1,this.q3
);
1078 this.m
.multiplyLowerTo(this.q3
,this.m
.t
+1,this.r2
);
1079 while(x
.compareTo(this.r2
) < 0) x
.dAddOffset(1,this.m
.t
+1);
1081 while(x
.compareTo(this.m
) >= 0) x
.subTo(this.m
,x
);
1084 // r = x^2 mod m; x != r
1085 function barrettSqrTo(x
,r
) { x
.squareTo(r
); this.reduce(r
); }
1087 // r = x*y mod m; x,y != r
1088 function barrettMulTo(x
,y
,r
) { x
.multiplyTo(y
,r
); this.reduce(r
); }
1090 Barrett
.prototype.convert
= barrettConvert
;
1091 Barrett
.prototype.revert
= barrettRevert
;
1092 Barrett
.prototype.reduce
= barrettReduce
;
1093 Barrett
.prototype.mulTo
= barrettMulTo
;
1094 Barrett
.prototype.sqrTo
= barrettSqrTo
;
1096 // (public) this^e % m (HAC 14.85)
1097 function bnModPow(e
,m
) {
1098 var e_array
= e
.array
;
1099 var i
= e
.bitLength(), k
, r
= nbv(1), z
;
1100 if(i
<= 0) return r
;
1101 else if(i
< 18) k
= 1;
1102 else if(i
< 48) k
= 3;
1103 else if(i
< 144) k
= 4;
1104 else if(i
< 768) k
= 5;
1111 z
= new Montgomery(m
);
1114 var g
= new Array(), n
= 3, k1
= k
-1, km
= (1<<k
)-1;
1115 g
[1] = z
.convert(this);
1121 z
.mulTo(g2
,g
[n
-2],g
[n
]);
1126 var j
= e
.t
-1, w
, is1
= true, r2
= nbi(), t
;
1127 i
= nbits(e_array
[j
])-1;
1129 if(i
>= k1
) w
= (e_array
[j
]>>(i
-k1
))&km
;
1131 w
= (e_array
[j
]&((1<<(i
+1))-1))<<(k1
-i
);
1132 if(j
> 0) w
|= e_array
[j
-1]>>(BI_DB
+i
-k1
);
1136 while((w
&1) == 0) { w
>>= 1; --n
; }
1137 if((i
-= n
) < 0) { i
+= BI_DB
; --j
; }
1138 if(is1
) { // ret == 1, don't bother squaring or multiplying it
1143 while(n
> 1) { z
.sqrTo(r
,r2
); z
.sqrTo(r2
,r
); n
-= 2; }
1144 if(n
> 0) z
.sqrTo(r
,r2
); else { t
= r
; r
= r2
; r2
= t
; }
1148 while(j
>= 0 && (e_array
[j
]&(1<<i
)) == 0) {
1149 z
.sqrTo(r
,r2
); t
= r
; r
= r2
; r2
= t
;
1150 if(--i
< 0) { i
= BI_DB
-1; --j
; }
1156 // (public) gcd(this,a) (HAC 14.54)
1158 var x
= (this.s
<0)?this.negate():this.clone();
1159 var y
= (a
.s
<0)?a
.negate():a
.clone();
1160 if(x
.compareTo(y
) < 0) { var t
= x
; x
= y
; y
= t
; }
1161 var i
= x
.getLowestSetBit(), g
= y
.getLowestSetBit();
1168 while(x
.signum() > 0) {
1169 if((i
= x
.getLowestSetBit()) > 0) x
.rShiftTo(i
,x
);
1170 if((i
= y
.getLowestSetBit()) > 0) y
.rShiftTo(i
,y
);
1171 if(x
.compareTo(y
) >= 0) {
1180 if(g
> 0) y
.lShiftTo(g
,y
);
1184 // (protected) this % n, n < 2^26
1185 function bnpModInt(n
) {
1186 var this_array
= this.array
;
1187 if(n
<= 0) return 0;
1188 var d
= BI_DV
%n
, r
= (this.s
<0)?n
-1:0;
1190 if(d
== 0) r
= this_array
[0]%n
;
1191 else for(var i
= this.t
-1; i
>= 0; --i
) r
= (d
*r
+this_array
[i
])%n
;
1195 // (public) 1/this % m (HAC 14.61)
1196 function bnModInverse(m
) {
1197 var ac
= m
.isEven();
1198 if((this.isEven() && ac
) || m
.signum() == 0) return BigInteger
.ZERO
;
1199 var u
= m
.clone(), v
= this.clone();
1200 var a
= nbv(1), b
= nbv(0), c
= nbv(0), d
= nbv(1);
1201 while(u
.signum() != 0) {
1205 if(!a
.isEven() || !b
.isEven()) { a
.addTo(this,a
); b
.subTo(m
,b
); }
1208 else if(!b
.isEven()) b
.subTo(m
,b
);
1214 if(!c
.isEven() || !d
.isEven()) { c
.addTo(this,c
); d
.subTo(m
,d
); }
1217 else if(!d
.isEven()) d
.subTo(m
,d
);
1220 if(u
.compareTo(v
) >= 0) {
1222 if(ac
) a
.subTo(c
,a
);
1227 if(ac
) c
.subTo(a
,c
);
1231 if(v
.compareTo(BigInteger
.ONE
) != 0) return BigInteger
.ZERO
;
1232 if(d
.compareTo(m
) >= 0) return d
.subtract(m
);
1233 if(d
.signum() < 0) d
.addTo(m
,d
); else return d
;
1234 if(d
.signum() < 0) return d
.add(m
); else return d
;
1237 var 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];
1238 var lplim
= (1<<26)/lowprimes
[lowprimes
.length
-1];
1240 // (public) test primality with certainty >= 1-.5^t
1241 function bnIsProbablePrime(t
) {
1242 var i
, x
= this.abs();
1243 var x_array
= x
.array
;
1244 if(x
.t
== 1 && x_array
[0] <= lowprimes
[lowprimes
.length
-1]) {
1245 for(i
= 0; i
< lowprimes
.length
; ++i
)
1246 if(x_array
[0] == lowprimes
[i
]) return true;
1249 if(x
.isEven()) return false;
1251 while(i
< lowprimes
.length
) {
1252 var m
= lowprimes
[i
], j
= i
+1;
1253 while(j
< lowprimes
.length
&& m
< lplim
) m
*= lowprimes
[j
++];
1255 while(i
< j
) if(m
%lowprimes
[i
++] == 0) return false;
1257 return x
.millerRabin(t
);
1260 // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
1261 function bnpMillerRabin(t
) {
1262 var n1
= this.subtract(BigInteger
.ONE
);
1263 var k
= n1
.getLowestSetBit();
1264 if(k
<= 0) return false;
1265 var r
= n1
.shiftRight(k
);
1267 if(t
> lowprimes
.length
) t
= lowprimes
.length
;
1269 for(var i
= 0; i
< t
; ++i
) {
1270 a
.fromInt(lowprimes
[i
]);
1271 var y
= a
.modPow(r
,this);
1272 if(y
.compareTo(BigInteger
.ONE
) != 0 && y
.compareTo(n1
) != 0) {
1274 while(j
++ < k
&& y
.compareTo(n1
) != 0) {
1275 y
= y
.modPowInt(2,this);
1276 if(y
.compareTo(BigInteger
.ONE
) == 0) return false;
1278 if(y
.compareTo(n1
) != 0) return false;
1285 BigInteger
.prototype.chunkSize
= bnpChunkSize
;
1286 BigInteger
.prototype.toRadix
= bnpToRadix
;
1287 BigInteger
.prototype.fromRadix
= bnpFromRadix
;
1288 BigInteger
.prototype.fromNumber
= bnpFromNumber
;
1289 BigInteger
.prototype.bitwiseTo
= bnpBitwiseTo
;
1290 BigInteger
.prototype.changeBit
= bnpChangeBit
;
1291 BigInteger
.prototype.addTo
= bnpAddTo
;
1292 BigInteger
.prototype.dMultiply
= bnpDMultiply
;
1293 BigInteger
.prototype.dAddOffset
= bnpDAddOffset
;
1294 BigInteger
.prototype.multiplyLowerTo
= bnpMultiplyLowerTo
;
1295 BigInteger
.prototype.multiplyUpperTo
= bnpMultiplyUpperTo
;
1296 BigInteger
.prototype.modInt
= bnpModInt
;
1297 BigInteger
.prototype.millerRabin
= bnpMillerRabin
;
1300 BigInteger
.prototype.clone
= bnClone
;
1301 BigInteger
.prototype.intValue
= bnIntValue
;
1302 BigInteger
.prototype.byteValue
= bnByteValue
;
1303 BigInteger
.prototype.shortValue
= bnShortValue
;
1304 BigInteger
.prototype.signum
= bnSigNum
;
1305 BigInteger
.prototype.toByteArray
= bnToByteArray
;
1306 BigInteger
.prototype.equals
= bnEquals
;
1307 BigInteger
.prototype.min
= bnMin
;
1308 BigInteger
.prototype.max
= bnMax
;
1309 BigInteger
.prototype.and
= bnAnd
;
1310 BigInteger
.prototype.or
= bnOr
;
1311 BigInteger
.prototype.xor
= bnXor
;
1312 BigInteger
.prototype.andNot
= bnAndNot
;
1313 BigInteger
.prototype.not
= bnNot
;
1314 BigInteger
.prototype.shiftLeft
= bnShiftLeft
;
1315 BigInteger
.prototype.shiftRight
= bnShiftRight
;
1316 BigInteger
.prototype.getLowestSetBit
= bnGetLowestSetBit
;
1317 BigInteger
.prototype.bitCount
= bnBitCount
;
1318 BigInteger
.prototype.testBit
= bnTestBit
;
1319 BigInteger
.prototype.setBit
= bnSetBit
;
1320 BigInteger
.prototype.clearBit
= bnClearBit
;
1321 BigInteger
.prototype.flipBit
= bnFlipBit
;
1322 BigInteger
.prototype.add
= bnAdd
;
1323 BigInteger
.prototype.subtract
= bnSubtract
;
1324 BigInteger
.prototype.multiply
= bnMultiply
;
1325 BigInteger
.prototype.divide
= bnDivide
;
1326 BigInteger
.prototype.remainder
= bnRemainder
;
1327 BigInteger
.prototype.divideAndRemainder
= bnDivideAndRemainder
;
1328 BigInteger
.prototype.modPow
= bnModPow
;
1329 BigInteger
.prototype.modInverse
= bnModInverse
;
1330 BigInteger
.prototype.pow
= bnPow
;
1331 BigInteger
.prototype.gcd
= bnGCD
;
1332 BigInteger
.prototype.isProbablePrime
= bnIsProbablePrime
;
1334 // BigInteger interfaces not implemented in jsbn:
1336 // BigInteger(int signum, byte[] magnitude)
1337 // double doubleValue()
1338 // float floatValue()
1341 // static BigInteger valueOf(long val)
1342 // prng4.js - uses Arcfour as a PRNG
1344 function Arcfour() {
1347 this.S
= new Array();
1350 // Initialize arcfour context from key, an array of ints, each from [0..255]
1351 function ARC4init(key
) {
1353 for(i
= 0; i
< 256; ++i
)
1356 for(i
= 0; i
< 256; ++i
) {
1357 j
= (j
+ this.S
[i
] + key
[i
% key
.length
]) & 255;
1359 this.S
[i
] = this.S
[j
];
1366 function ARC4next() {
1368 this.i
= (this.i
+ 1) & 255;
1369 this.j
= (this.j
+ this.S
[this.i
]) & 255;
1371 this.S
[this.i
] = this.S
[this.j
];
1373 return this.S
[(t
+ this.S
[this.i
]) & 255];
1376 Arcfour
.prototype.init
= ARC4init
;
1377 Arcfour
.prototype.next
= ARC4next
;
1379 // Plug in your RNG constructor here
1380 function prng_newstate() {
1381 return new Arcfour();
1384 // Pool size must be a multiple of 4 and greater than 32.
1385 // An array of bytes the size of the pool will be passed to init()
1386 var rng_psize
= 256;
1387 // Random number generator - requires a PRNG backend, e.g. prng4.js
1389 // For best results, put code like
1390 // <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
1391 // in your main HTML document.
1397 // Mix in a 32-bit integer into the pool
1398 function rng_seed_int(x
) {
1399 rng_pool
[rng_pptr
++] ^= x
& 255;
1400 rng_pool
[rng_pptr
++] ^= (x
>> 8) & 255;
1401 rng_pool
[rng_pptr
++] ^= (x
>> 16) & 255;
1402 rng_pool
[rng_pptr
++] ^= (x
>> 24) & 255;
1403 if(rng_pptr
>= rng_psize
) rng_pptr
-= rng_psize
;
1406 // Mix in the current time (w/milliseconds) into the pool
1407 function rng_seed_time() {
1408 // Use pre-computed date to avoid making the benchmark
1409 // results dependent on the current date.
1410 rng_seed_int(1122926989487);
1413 // Initialize the pool with junk if needed.
1414 if(rng_pool
== null) {
1415 rng_pool
= new Array();
1418 while(rng_pptr
< rng_psize
) { // extract some randomness from Math.random()
1419 t
= Math
.floor(65536 * Math
.random());
1420 rng_pool
[rng_pptr
++] = t
>>> 8;
1421 rng_pool
[rng_pptr
++] = t
& 255;
1425 //rng_seed_int(window.screenX);
1426 //rng_seed_int(window.screenY);
1429 function rng_get_byte() {
1430 if(rng_state
== null) {
1432 rng_state
= prng_newstate();
1433 rng_state
.init(rng_pool
);
1434 for(rng_pptr
= 0; rng_pptr
< rng_pool
.length
; ++rng_pptr
)
1435 rng_pool
[rng_pptr
] = 0;
1439 // TODO: allow reseeding after first request
1440 return rng_state
.next();
1443 function rng_get_bytes(ba
) {
1445 for(i
= 0; i
< ba
.length
; ++i
) ba
[i
] = rng_get_byte();
1448 function SecureRandom() {}
1450 SecureRandom
.prototype.nextBytes
= rng_get_bytes
;
1451 // Depends on jsbn.js and rng.js
1453 // convert a (hex) string to a bignum object
1454 function parseBigInt(str
,r
) {
1455 return new BigInteger(str
,r
);
1458 function linebrk(s
,n
) {
1461 while(i
+ n
< s
.length
) {
1462 ret
+= s
.substring(i
,i
+n
) + "\n";
1465 return ret
+ s
.substring(i
,s
.length
);
1468 function byte2Hex(b
) {
1470 return "0" + b
.toString(16);
1472 return b
.toString(16);
1475 // PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
1476 function pkcs1pad2(s
,n
) {
1477 if(n
< s
.length
+ 11) {
1478 alert("Message too long for RSA");
1481 var ba
= new Array();
1482 var i
= s
.length
- 1;
1483 while(i
>= 0 && n
> 0) ba
[--n
] = s
.charCodeAt(i
--);
1485 var rng
= new SecureRandom();
1486 var x
= new Array();
1487 while(n
> 2) { // random non-zero pad
1489 while(x
[0] == 0) rng
.nextBytes(x
);
1494 return new BigInteger(ba
);
1497 // "empty" RSA key constructor
1509 // Set the public key fields N and e from hex strings
1510 function RSASetPublic(N
,E
) {
1511 if(N
!= null && E
!= null && N
.length
> 0 && E
.length
> 0) {
1512 this.n
= parseBigInt(N
,16);
1513 this.e
= parseInt(E
,16);
1516 alert("Invalid RSA public key");
1519 // Perform raw public operation on "x": return x^e (mod n)
1520 function RSADoPublic(x
) {
1521 return x
.modPowInt(this.e
, this.n
);
1524 // Return the PKCS#1 RSA encryption of "text" as an even-length hex string
1525 function RSAEncrypt(text
) {
1526 var m
= pkcs1pad2(text
,(this.n
.bitLength()+7)>>3);
1527 if(m
== null) return null;
1528 var c
= this.doPublic(m
);
1529 if(c
== null) return null;
1530 var h
= c
.toString(16);
1531 if((h
.length
& 1) == 0) return h
; else return "0" + h
;
1534 // Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
1535 //function RSAEncryptB64(text) {
1536 // var h = this.encrypt(text);
1537 // if(h) return hex2b64(h); else return null;
1541 RSAKey
.prototype.doPublic
= RSADoPublic
;
1544 RSAKey
.prototype.setPublic
= RSASetPublic
;
1545 RSAKey
.prototype.encrypt
= RSAEncrypt
;
1546 //RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
1547 // Depends on rsa.js and jsbn2.js
1549 // Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
1550 function pkcs1unpad2(d
,n
) {
1551 var b
= d
.toByteArray();
1553 while(i
< b
.length
&& b
[i
] == 0) ++i
;
1554 if(b
.length
-i
!= n
-1 || b
[i
] != 2)
1558 if(++i
>= b
.length
) return null;
1560 while(++i
< b
.length
)
1561 ret
+= String
.fromCharCode(b
[i
]);
1565 // Set the private key fields N, e, and d from hex strings
1566 function RSASetPrivate(N
,E
,D
) {
1567 if(N
!= null && E
!= null && N
.length
> 0 && E
.length
> 0) {
1568 this.n
= parseBigInt(N
,16);
1569 this.e
= parseInt(E
,16);
1570 this.d
= parseBigInt(D
,16);
1573 alert("Invalid RSA private key");
1576 // Set the private key fields N, e, d and CRT params from hex strings
1577 function RSASetPrivateEx(N
,E
,D
,P
,Q
,DP
,DQ
,C
) {
1578 if(N
!= null && E
!= null && N
.length
> 0 && E
.length
> 0) {
1579 this.n
= parseBigInt(N
,16);
1580 this.e
= parseInt(E
,16);
1581 this.d
= parseBigInt(D
,16);
1582 this.p
= parseBigInt(P
,16);
1583 this.q
= parseBigInt(Q
,16);
1584 this.dmp1
= parseBigInt(DP
,16);
1585 this.dmq1
= parseBigInt(DQ
,16);
1586 this.coeff
= parseBigInt(C
,16);
1589 alert("Invalid RSA private key");
1592 // Generate a new random private key B bits long, using public expt E
1593 function RSAGenerate(B
,E
) {
1594 var rng
= new SecureRandom();
1596 this.e
= parseInt(E
,16);
1597 var ee
= new BigInteger(E
,16);
1600 this.p
= new BigInteger(B
-qs
,1,rng
);
1601 if(this.p
.subtract(BigInteger
.ONE
).gcd(ee
).compareTo(BigInteger
.ONE
) == 0 && this.p
.isProbablePrime(10)) break;
1604 this.q
= new BigInteger(qs
,1,rng
);
1605 if(this.q
.subtract(BigInteger
.ONE
).gcd(ee
).compareTo(BigInteger
.ONE
) == 0 && this.q
.isProbablePrime(10)) break;
1607 if(this.p
.compareTo(this.q
) <= 0) {
1612 var p1
= this.p
.subtract(BigInteger
.ONE
);
1613 var q1
= this.q
.subtract(BigInteger
.ONE
);
1614 var phi
= p1
.multiply(q1
);
1615 if(phi
.gcd(ee
).compareTo(BigInteger
.ONE
) == 0) {
1616 this.n
= this.p
.multiply(this.q
);
1617 this.d
= ee
.modInverse(phi
);
1618 this.dmp1
= this.d
.mod(p1
);
1619 this.dmq1
= this.d
.mod(q1
);
1620 this.coeff
= this.q
.modInverse(this.p
);
1626 // Perform raw private operation on "x": return x^d (mod n)
1627 function RSADoPrivate(x
) {
1628 if(this.p
== null || this.q
== null)
1629 return x
.modPow(this.d
, this.n
);
1631 // TODO: re-calculate any missing CRT params
1632 var xp
= x
.mod(this.p
).modPow(this.dmp1
, this.p
);
1633 var xq
= x
.mod(this.q
).modPow(this.dmq1
, this.q
);
1635 while(xp
.compareTo(xq
) < 0)
1636 xp
= xp
.add(this.p
);
1637 return xp
.subtract(xq
).multiply(this.coeff
).mod(this.p
).multiply(this.q
).add(xq
);
1640 // Return the PKCS#1 RSA decryption of "ctext".
1641 // "ctext" is an even-length hex string and the output is a plain string.
1642 function RSADecrypt(ctext
) {
1643 var c
= parseBigInt(ctext
, 16);
1644 var m
= this.doPrivate(c
);
1645 if(m
== null) return null;
1646 return pkcs1unpad2(m
, (this.n
.bitLength()+7)>>3);
1649 // Return the PKCS#1 RSA decryption of "ctext".
1650 // "ctext" is a Base64-encoded string and the output is a plain string.
1651 //function RSAB64Decrypt(ctext) {
1652 // var h = b64tohex(ctext);
1653 // if(h) return this.decrypt(h); else return null;
1657 RSAKey
.prototype.doPrivate
= RSADoPrivate
;
1660 RSAKey
.prototype.setPrivate
= RSASetPrivate
;
1661 RSAKey
.prototype.setPrivateEx
= RSASetPrivateEx
;
1662 RSAKey
.prototype.generate
= RSAGenerate
;
1663 RSAKey
.prototype.decrypt
= RSADecrypt
;
1664 //RSAKey.prototype.b64_decrypt = RSAB64Decrypt;
1667 nValue
="a5261939975948bb7a58dffe5ff54e65f0498f9175f5a09288810b8975871e99af3b5dd94057b0fc07535f5f97444504fa35169d461d0d30cf0192e307727c065168c788771c561a9400fb49175e9e6aa4e23fe11af69e9412dd23b0cb6684c4c2429bce139e848ab26d0829073351f4acd36074eafd036a5eb83359d2a698d3";
1669 dValue
="8e9912f6d3645894e8d38cb58c0db81ff516cf4c7e5a14c7f1eddb1459d2cded4d8d293fc97aee6aefb861859c8b6a3d1dfe710463e1f9ddc72048c09751971c4a580aa51eb523357a3cc48d31cfad1d4a165066ed92d4748fb6571211da5cb14bc11b6e2df7c1a559e6d5ac1cd5c94703a22891464fba23d0d965086277a161";
1670 pValue
="d090ce58a92c75233a6486cb0a9209bf3583b64f540c76f5294bb97d285eed33aec220bde14b2417951178ac152ceab6da7090905b478195498b352048f15e7d";
1671 qValue
="cab575dc652bb66df15a0359609d51d1db184750c00c6698b90ef3465c99655103edbf0d54c56aec0ce3c4d22592338092a126a0cc49f65a4a30d222b411e58f";
1672 dmp1Value
="1a24bca8e273df2f0e47c199bbf678604e7df7215480c77c8db39f49b000ce2cf7500038acfff5433b7d582a01f1826e6f4d42e1c57f5e1fef7b12aabc59fd25";
1673 dmq1Value
="3d06982efbbe47339e1f6d36b1216b8a741d410b0c662f54f7118b27b9a4ec9d914337eb39841d8666f3034408cf94f5b62f11c402fc994fe15a05493150d9fd";
1674 coeffValue
="3a3e731acd8960b7ff9eb81a7ff93bd1cfa74cbd56987db58b4594fb09c09084db1734c8143f98b602b981aaa9243ca28deb69b5b280ee8dcee0fd2625e53250";
1676 setupEngine(am3
, 28);
1678 var TEXT
= "The quick brown fox jumped over the extremely lazy frog! " +
1679 "Now is the time for all good men to come to the party.";
1682 window
.onload = function(){ startTest("v8-crypto", 'f0250ffa');
1684 test("RSA Encrypt", function encrypt() {
1685 var RSA
= new RSAKey();
1686 RSA
.setPublic(nValue
, eValue
);
1687 RSA
.setPrivateEx(nValue
, eValue
, dValue
, pValue
, qValue
, dmp1Value
, dmq1Value
, coeffValue
);
1688 encrypted
= RSA
.encrypt(TEXT
);
1691 test("RSA Decrypt", function decrypt() {
1692 var RSA
= new RSAKey();
1693 RSA
.setPublic(nValue
, eValue
);
1694 RSA
.setPrivateEx(nValue
, eValue
, dValue
, pValue
, qValue
, dmp1Value
, dmq1Value
, coeffValue
);
1695 var decrypted
= RSA
.decrypt(encrypted
);
1696 if (decrypted
!= TEXT
) {
1697 throw new Error("Crypto operation failed");