2 * Copyright (c) 2003-2005 Tom Wu
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
20 * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 * In addition, the following condition applies:
28 * All redistributions must retain an intact copy of this copyright notice
33 // The code has been adapted for use as a benchmark by Google.
34 var Crypto
= new BenchmarkSuite('Crypto', 266181, [
35 new Benchmark("Encrypt", encrypt
),
36 new Benchmark("Decrypt", decrypt
)
40 // Basic JavaScript BN library - subset useful for RSA encryption.
53 // JavaScript engine analysis
54 var canary
= 0xdeadbeefcafe;
55 var j_lm
= ((canary
&0xffffff)==0xefcafe);
57 // (public) Constructor
58 function BigInteger(a
,b
,c
) {
59 this.array
= new Array();
61 if("number" == typeof a
) this.fromNumber(a
,b
,c
);
62 else if(b
== null && "string" != typeof a
) this.fromString(a
,256);
63 else this.fromString(a
,b
);
66 // return new, unset BigInteger
67 function nbi() { return new BigInteger(null); }
69 // am: Compute w_j += (x*this_i), propagate carries,
70 // c is initial carry, returns final carry.
71 // c < 3*dvalue, x < 2*dvalue, this_i < dvalue
72 // We need to select the fastest one that works in this environment.
74 // am1: use a single mult and divide to get the high bits,
75 // max digit bits should be 26 because
76 // max internal value = 2*dvalue^2-2*dvalue (< 2^53)
77 function am1(i
,x
,w
,j
,c
,n
) {
78 var this_array
= this.array
;
79 var w_array
= w
.array
;
81 var v
= x
*this_array
[i
++]+w_array
[j
]+c
;
82 c
= Math
.floor(v
/0x4000000);
83 w_array
[j
++] = v
&0x3ffffff;
88 // am2 avoids a big mult-and-extract completely.
89 // Max digit bits should be <= 30 because we do bitwise ops
90 // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
91 function am2(i
,x
,w
,j
,c
,n
) {
92 var this_array
= this.array
;
93 var w_array
= w
.array
;
94 var xl
= x
&0x7fff, xh
= x
>>15;
96 var l
= this_array
[i
]&0x7fff;
97 var h
= this_array
[i
++]>>15;
99 l
= xl
*l
+((m
&0x7fff)<<15)+w_array
[j
]+(c
&0x3fffffff);
100 c
= (l
>>>30)+(m
>>>15)+xh
*h
+(c
>>>30);
101 w_array
[j
++] = l
&0x3fffffff;
106 // Alternately, set max digit bits to 28 since some
107 // browsers slow down when dealing with 32-bit numbers.
108 function am3(i
,x
,w
,j
,c
,n
) {
109 var this_array
= this.array
;
110 var w_array
= w
.array
;
112 var xl
= x
&0x3fff, xh
= x
>>14;
114 var l
= this_array
[i
]&0x3fff;
115 var h
= this_array
[i
++]>>14;
117 l
= xl
*l
+((m
&0x3fff)<<14)+w_array
[j
]+c
;
118 c
= (l
>>28)+(m
>>14)+xh
*h
;
119 w_array
[j
++] = l
&0xfffffff;
124 // This is tailored to VMs with 2-bit tagging. It makes sure
125 // that all the computations stay within the 29 bits available.
126 function am4(i
,x
,w
,j
,c
,n
) {
127 var this_array
= this.array
;
128 var w_array
= w
.array
;
130 var xl
= x
&0x1fff, xh
= x
>>13;
132 var l
= this_array
[i
]&0x1fff;
133 var h
= this_array
[i
++]>>13;
135 l
= xl
*l
+((m
&0x1fff)<<13)+w_array
[j
]+c
;
136 c
= (l
>>26)+(m
>>13)+xh
*h
;
137 w_array
[j
++] = l
&0x3ffffff;
142 // am3/28 is best for SM, Rhino, but am4/26 is best for v8.
143 // Kestrel (Opera 9.5) gets its best result with am4/26.
144 // IE7 does 9% better with am3/28 than with am4/26.
145 // Firefox (SM) gets 10% faster with am3/28 than with am4/26.
147 setupEngine = function(fn
, bits
) {
148 BigInteger
.prototype.am
= fn
;
152 BI_DM
= ((1<<dbits
)-1);
156 BI_FV
= Math
.pow(2,BI_FP
);
158 BI_F2
= 2*dbits
-BI_FP
;
163 var BI_RM
= "0123456789abcdefghijklmnopqrstuvwxyz";
164 var BI_RC
= new Array();
166 rr
= "0".charCodeAt(0);
167 for(vv
= 0; vv
<= 9; ++vv
) BI_RC
[rr
++] = vv
;
168 rr
= "a".charCodeAt(0);
169 for(vv
= 10; vv
< 36; ++vv
) BI_RC
[rr
++] = vv
;
170 rr
= "A".charCodeAt(0);
171 for(vv
= 10; vv
< 36; ++vv
) BI_RC
[rr
++] = vv
;
173 function int2char(n
) { return BI_RM
.charAt(n
); }
174 function intAt(s
,i
) {
175 var c
= BI_RC
[s
.charCodeAt(i
)];
176 return (c
==null)?-1:c
;
179 // (protected) copy this to r
180 function bnpCopyTo(r
) {
181 var this_array
= this.array
;
182 var r_array
= r
.array
;
184 for(var i
= this.t
-1; i
>= 0; --i
) r_array
[i
] = this_array
[i
];
189 // (protected) set from integer value x, -DV <= x < DV
190 function bnpFromInt(x
) {
191 var this_array
= this.array
;
194 if(x
> 0) this_array
[0] = x
;
195 else if(x
< -1) this_array
[0] = x
+DV
;
199 // return bigint initialized to value
200 function nbv(i
) { var r
= nbi(); r
.fromInt(i
); return r
; }
202 // (protected) set from string and radix
203 function bnpFromString(s
,b
) {
204 var this_array
= this.array
;
207 else if(b
== 8) k
= 3;
208 else if(b
== 256) k
= 8; // byte array
209 else if(b
== 2) k
= 1;
210 else if(b
== 32) k
= 5;
211 else if(b
== 4) k
= 2;
212 else { this.fromRadix(s
,b
); return; }
215 var i
= s
.length
, mi
= false, sh
= 0;
217 var x
= (k
==8)?s
[i
]&0xff:intAt(s
,i
);
219 if(s
.charAt(i
) == "-") mi
= true;
224 this_array
[this.t
++] = x
;
225 else if(sh
+k
> BI_DB
) {
226 this_array
[this.t
-1] |= (x
&((1<<(BI_DB
-sh
))-1))<<sh
;
227 this_array
[this.t
++] = (x
>>(BI_DB
-sh
));
230 this_array
[this.t
-1] |= x
<<sh
;
232 if(sh
>= BI_DB
) sh
-= BI_DB
;
234 if(k
== 8 && (s
[0]&0x80) != 0) {
236 if(sh
> 0) this_array
[this.t
-1] |= ((1<<(BI_DB
-sh
))-1)<<sh
;
239 if(mi
) BigInteger
.ZERO
.subTo(this,this);
242 // (protected) clamp off excess high words
243 function bnpClamp() {
244 var this_array
= this.array
;
245 var c
= this.s
&BI_DM
;
246 while(this.t
> 0 && this_array
[this.t
-1] == c
) --this.t
;
249 // (public) return string representation in given radix
250 function bnToString(b
) {
251 var this_array
= this.array
;
252 if(this.s
< 0) return "-"+this.negate().toString(b
);
255 else if(b
== 8) k
= 3;
256 else if(b
== 2) k
= 1;
257 else if(b
== 32) k
= 5;
258 else if(b
== 4) k
= 2;
259 else return this.toRadix(b
);
260 var km
= (1<<k
)-1, d
, m
= false, r
= "", i
= this.t
;
261 var p
= BI_DB
-(i
*BI_DB
)%k
;
263 if(p
< BI_DB
&& (d
= this_array
[i
]>>p
) > 0) { m
= true; r
= int2char(d
); }
266 d
= (this_array
[i
]&((1<<p
)-1))<<(k
-p
);
267 d
|= this_array
[--i
]>>(p
+=BI_DB
-k
);
270 d
= (this_array
[i
]>>(p
-=k
))&km
;
271 if(p
<= 0) { p
+= BI_DB
; --i
; }
274 if(m
) r
+= int2char(d
);
281 function bnNegate() { var r
= nbi(); BigInteger
.ZERO
.subTo(this,r
); return r
; }
284 function bnAbs() { return (this.s
<0)?this.negate():this; }
286 // (public) return + if this > a, - if this < a, 0 if equal
287 function bnCompareTo(a
) {
288 var this_array
= this.array
;
289 var a_array
= a
.array
;
296 while(--i
>= 0) if((r
=this_array
[i
]-a_array
[i
]) != 0) return r
;
300 // returns bit length of the integer x
303 if((t
=x
>>>16) != 0) { x
= t
; r
+= 16; }
304 if((t
=x
>>8) != 0) { x
= t
; r
+= 8; }
305 if((t
=x
>>4) != 0) { x
= t
; r
+= 4; }
306 if((t
=x
>>2) != 0) { x
= t
; r
+= 2; }
307 if((t
=x
>>1) != 0) { x
= t
; r
+= 1; }
311 // (public) return the number of bits in "this"
312 function bnBitLength() {
313 var this_array
= this.array
;
314 if(this.t
<= 0) return 0;
315 return BI_DB
*(this.t
-1)+nbits(this_array
[this.t
-1]^(this.s
&BI_DM
));
318 // (protected) r = this << n*DB
319 function bnpDLShiftTo(n
,r
) {
320 var this_array
= this.array
;
321 var r_array
= r
.array
;
323 for(i
= this.t
-1; i
>= 0; --i
) r_array
[i
+n
] = this_array
[i
];
324 for(i
= n
-1; i
>= 0; --i
) r_array
[i
] = 0;
329 // (protected) r = this >> n*DB
330 function bnpDRShiftTo(n
,r
) {
331 var this_array
= this.array
;
332 var r_array
= r
.array
;
333 for(var i
= n
; i
< this.t
; ++i
) r_array
[i
-n
] = this_array
[i
];
334 r
.t
= Math
.max(this.t
-n
,0);
338 // (protected) r = this << n
339 function bnpLShiftTo(n
,r
) {
340 var this_array
= this.array
;
341 var r_array
= r
.array
;
345 var ds
= Math
.floor(n
/BI_DB
), c
= (this.s
<<bs
)&BI_DM
, i
;
346 for(i
= this.t
-1; i
>= 0; --i
) {
347 r_array
[i
+ds
+1] = (this_array
[i
]>>cbs
)|c
;
348 c
= (this_array
[i
]&bm
)<<bs
;
350 for(i
= ds
-1; i
>= 0; --i
) r_array
[i
] = 0;
357 // (protected) r = this >> n
358 function bnpRShiftTo(n
,r
) {
359 var this_array
= this.array
;
360 var r_array
= r
.array
;
362 var ds
= Math
.floor(n
/BI_DB
);
363 if(ds
>= this.t
) { r
.t
= 0; return; }
367 r_array
[0] = this_array
[ds
]>>bs
;
368 for(var i
= ds
+1; i
< this.t
; ++i
) {
369 r_array
[i
-ds
-1] |= (this_array
[i
]&bm
)<<cbs
;
370 r_array
[i
-ds
] = this_array
[i
]>>bs
;
372 if(bs
> 0) r_array
[this.t
-ds
-1] |= (this.s
&bm
)<<cbs
;
377 // (protected) r = this - a
378 function bnpSubTo(a
,r
) {
379 var this_array
= this.array
;
380 var r_array
= r
.array
;
381 var a_array
= a
.array
;
382 var i
= 0, c
= 0, m
= Math
.min(a
.t
,this.t
);
384 c
+= this_array
[i
]-a_array
[i
];
385 r_array
[i
++] = c
&BI_DM
;
392 r_array
[i
++] = c
&BI_DM
;
401 r_array
[i
++] = c
&BI_DM
;
407 if(c
< -1) r_array
[i
++] = BI_DV
+c
;
408 else if(c
> 0) r_array
[i
++] = c
;
413 // (protected) r = this * a, r != this,a (HAC 14.12)
414 // "this" should be the larger one if appropriate.
415 function bnpMultiplyTo(a
,r
) {
416 var this_array
= this.array
;
417 var r_array
= r
.array
;
418 var x
= this.abs(), y
= a
.abs();
419 var y_array
= y
.array
;
423 while(--i
>= 0) r_array
[i
] = 0;
424 for(i
= 0; i
< y
.t
; ++i
) r_array
[i
+x
.t
] = x
.am(0,y_array
[i
],r
,i
,0,x
.t
);
427 if(this.s
!= a
.s
) BigInteger
.ZERO
.subTo(r
,r
);
430 // (protected) r = this^2, r != this (HAC 14.16)
431 function bnpSquareTo(r
) {
433 var x_array
= x
.array
;
434 var r_array
= r
.array
;
437 while(--i
>= 0) r_array
[i
] = 0;
438 for(i
= 0; i
< x
.t
-1; ++i
) {
439 var c
= x
.am(i
,x_array
[i
],r
,2*i
,0,1);
440 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
) {
441 r_array
[i
+x
.t
] -= BI_DV
;
442 r_array
[i
+x
.t
+1] = 1;
445 if(r
.t
> 0) r_array
[r
.t
-1] += x
.am(i
,x_array
[i
],r
,2*i
,0,1);
450 // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
451 // r != q, this != m. q or r may be null.
452 function bnpDivRemTo(m
,q
,r
) {
454 if(pm
.t
<= 0) return;
457 if(q
!= null) q
.fromInt(0);
458 if(r
!= null) this.copyTo(r
);
461 if(r
== null) r
= nbi();
462 var y
= nbi(), ts
= this.s
, ms
= m
.s
;
463 var pm_array
= pm
.array
;
464 var nsh
= BI_DB
-nbits(pm_array
[pm
.t
-1]); // normalize modulus
465 if(nsh
> 0) { pm
.lShiftTo(nsh
,y
); pt
.lShiftTo(nsh
,r
); }
466 else { pm
.copyTo(y
); pt
.copyTo(r
); }
469 var y_array
= y
.array
;
470 var y0
= y_array
[ys
-1];
472 var yt
= y0
*(1<<BI_F1
)+((ys
>1)?y_array
[ys
-2]>>BI_F2
:0);
473 var d1
= BI_FV
/yt, d2 = (1<<BI_F1)/yt, e
= 1<<BI_F2
;
474 var i
= r
.t
, j
= i
-ys
, t
= (q
==null)?nbi():q
;
477 var r_array
= r
.array
;
478 if(r
.compareTo(t
) >= 0) {
482 BigInteger
.ONE
.dlShiftTo(ys
,t
);
483 t
.subTo(y
,y
); // "negative" y so we can replace sub with am later
484 while(y
.t
< ys
) y_array
[y
.t
++] = 0;
486 // Estimate quotient digit
487 var qd
= (r_array
[--i
]==y0
)?BI_DM
:Math
.floor(r_array
[i
]*d1
+(r_array
[i
-1]+e
)*d2
);
488 if((r_array
[i
]+=y
.am(0,qd
,r
,j
,0,ys
)) < qd
) { // Try it out
491 while(r_array
[i
] < --qd
) r
.subTo(t
,r
);
496 if(ts
!= ms
) BigInteger
.ZERO
.subTo(q
,q
);
500 if(nsh
> 0) r
.rShiftTo(nsh
,r
); // Denormalize remainder
501 if(ts
< 0) BigInteger
.ZERO
.subTo(r
,r
);
504 // (public) this mod a
507 this.abs().divRemTo(a
,null,r
);
508 if(this.s
< 0 && r
.compareTo(BigInteger
.ZERO
) > 0) a
.subTo(r
,r
);
512 // Modular reduction using "classic" algorithm
513 function Classic(m
) { this.m
= m
; }
514 function cConvert(x
) {
515 if(x
.s
< 0 || x
.compareTo(this.m
) >= 0) return x
.mod(this.m
);
518 function cRevert(x
) { return x
; }
519 function cReduce(x
) { x
.divRemTo(this.m
,null,x
); }
520 function cMulTo(x
,y
,r
) { x
.multiplyTo(y
,r
); this.reduce(r
); }
521 function cSqrTo(x
,r
) { x
.squareTo(r
); this.reduce(r
); }
523 Classic
.prototype.convert
= cConvert
;
524 Classic
.prototype.revert
= cRevert
;
525 Classic
.prototype.reduce
= cReduce
;
526 Classic
.prototype.mulTo
= cMulTo
;
527 Classic
.prototype.sqrTo
= cSqrTo
;
529 // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
533 // xy(2-xy) = (1+km)(1-km)
534 // x[y(2-xy)] = 1-k^2m^2
535 // x[y(2-xy)] == 1 (mod m^2)
536 // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
537 // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
538 // JS multiply "overflows" differently from C/C++, so care is needed here.
539 function bnpInvDigit() {
540 var this_array
= this.array
;
541 if(this.t
< 1) return 0;
542 var x
= this_array
[0];
543 if((x
&1) == 0) return 0;
544 var y
= x
&3; // y == 1/x mod 2^2
545 y
= (y
*(2-(x
&0xf)*y
))&0xf; // y == 1/x mod 2^4
546 y
= (y
*(2-(x
&0xff)*y
))&0xff; // y == 1/x mod 2^8
547 y
= (y
*(2-(((x
&0xffff)*y
)&0xffff)))&0xffff; // y == 1/x mod 2^16
548 // last step - calculate inverse mod DV directly;
549 // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
550 y
= (y
*(2-x
*y
%BI_DV
))%BI_DV
; // y == 1/x mod 2^dbits
551 // we really want the negative inverse, and -DV < y < DV
552 return (y
>0)?BI_DV
-y
:-y
;
555 // Montgomery reduction
556 function Montgomery(m
) {
558 this.mp
= m
.invDigit();
559 this.mpl
= this.mp
&0x7fff;
560 this.mph
= this.mp
>>15;
561 this.um
= (1<<(BI_DB
-15))-1;
566 function montConvert(x
) {
568 x
.abs().dlShiftTo(this.m
.t
,r
);
569 r
.divRemTo(this.m
,null,r
);
570 if(x
.s
< 0 && r
.compareTo(BigInteger
.ZERO
) > 0) this.m
.subTo(r
,r
);
575 function montRevert(x
) {
582 // x = x/R mod m (HAC 14.32)
583 function montReduce(x
) {
584 var x_array
= x
.array
;
585 while(x
.t
<= this.mt2
) // pad x so am has enough room later
587 for(var i
= 0; i
< this.m
.t
; ++i
) {
588 // faster way of calculating u0 = x[i]*mp mod DV
589 var j
= x_array
[i
]&0x7fff;
590 var u0
= (j
*this.mpl
+(((j
*this.mph
+(x_array
[i
]>>15)*this.mpl
)&this.um
)<<15))&BI_DM
;
591 // use am to combine the multiply-shift-add into one call
593 x_array
[j
] += this.m
.am(0,u0
,x
,i
,0,this.m
.t
);
595 while(x_array
[j
] >= BI_DV
) { x_array
[j
] -= BI_DV
; x_array
[++j
]++; }
598 x
.drShiftTo(this.m
.t
,x
);
599 if(x
.compareTo(this.m
) >= 0) x
.subTo(this.m
,x
);
602 // r = "x^2/R mod m"; x != r
603 function montSqrTo(x
,r
) { x
.squareTo(r
); this.reduce(r
); }
605 // r = "xy/R mod m"; x,y != r
606 function montMulTo(x
,y
,r
) { x
.multiplyTo(y
,r
); this.reduce(r
); }
608 Montgomery
.prototype.convert
= montConvert
;
609 Montgomery
.prototype.revert
= montRevert
;
610 Montgomery
.prototype.reduce
= montReduce
;
611 Montgomery
.prototype.mulTo
= montMulTo
;
612 Montgomery
.prototype.sqrTo
= montSqrTo
;
614 // (protected) true iff this is even
615 function bnpIsEven() {
616 var this_array
= this.array
;
617 return ((this.t
>0)?(this_array
[0]&1):this.s
) == 0;
620 // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
621 function bnpExp(e
,z
) {
622 if(e
> 0xffffffff || e
< 1) return BigInteger
.ONE
;
623 var r
= nbi(), r2
= nbi(), g
= z
.convert(this), i
= nbits(e
)-1;
627 if((e
&(1<<i
)) > 0) z
.mulTo(r2
,g
,r
);
628 else { var t
= r
; r
= r2
; r2
= t
; }
633 // (public) this^e % m, 0 <= e < 2^32
634 function bnModPowInt(e
,m
) {
636 if(e
< 256 || m
.isEven()) z
= new Classic(m
); else z
= new Montgomery(m
);
637 return this.exp(e
,z
);
641 BigInteger
.prototype.copyTo
= bnpCopyTo
;
642 BigInteger
.prototype.fromInt
= bnpFromInt
;
643 BigInteger
.prototype.fromString
= bnpFromString
;
644 BigInteger
.prototype.clamp
= bnpClamp
;
645 BigInteger
.prototype.dlShiftTo
= bnpDLShiftTo
;
646 BigInteger
.prototype.drShiftTo
= bnpDRShiftTo
;
647 BigInteger
.prototype.lShiftTo
= bnpLShiftTo
;
648 BigInteger
.prototype.rShiftTo
= bnpRShiftTo
;
649 BigInteger
.prototype.subTo
= bnpSubTo
;
650 BigInteger
.prototype.multiplyTo
= bnpMultiplyTo
;
651 BigInteger
.prototype.squareTo
= bnpSquareTo
;
652 BigInteger
.prototype.divRemTo
= bnpDivRemTo
;
653 BigInteger
.prototype.invDigit
= bnpInvDigit
;
654 BigInteger
.prototype.isEven
= bnpIsEven
;
655 BigInteger
.prototype.exp
= bnpExp
;
658 BigInteger
.prototype.toString
= bnToString
;
659 BigInteger
.prototype.negate
= bnNegate
;
660 BigInteger
.prototype.abs
= bnAbs
;
661 BigInteger
.prototype.compareTo
= bnCompareTo
;
662 BigInteger
.prototype.bitLength
= bnBitLength
;
663 BigInteger
.prototype.mod
= bnMod
;
664 BigInteger
.prototype.modPowInt
= bnModPowInt
;
667 BigInteger
.ZERO
= nbv(0);
668 BigInteger
.ONE
= nbv(1);
669 // Copyright (c) 2005 Tom Wu
670 // All Rights Reserved.
671 // See "LICENSE" for details.
673 // Extended JavaScript BN functions, required for RSA private ops.
676 function bnClone() { var r
= nbi(); this.copyTo(r
); return r
; }
678 // (public) return value as integer
679 function bnIntValue() {
680 var this_array
= this.array
;
682 if(this.t
== 1) return this_array
[0]-BI_DV
;
683 else if(this.t
== 0) return -1;
685 else if(this.t
== 1) return this_array
[0];
686 else if(this.t
== 0) return 0;
687 // assumes 16 < DB < 32
688 return ((this_array
[1]&((1<<(32-BI_DB
))-1))<<BI_DB
)|this_array
[0];
691 // (public) return value as byte
692 function bnByteValue() {
693 var this_array
= this.array
;
694 return (this.t
==0)?this.s
:(this_array
[0]<<24)>>24;
697 // (public) return value as short (assumes DB>=16)
698 function bnShortValue() {
699 var this_array
= this.array
;
700 return (this.t
==0)?this.s
:(this_array
[0]<<16)>>16;
703 // (protected) return x s.t. r^x < DV
704 function bnpChunkSize(r
) { return Math
.floor(Math
.LN2
*BI_DB
/Math
.log(r
)); }
706 // (public) 0 if this == 0, 1 if this > 0
707 function bnSigNum() {
708 var this_array
= this.array
;
709 if(this.s
< 0) return -1;
710 else if(this.t
<= 0 || (this.t
== 1 && this_array
[0] <= 0)) return 0;
714 // (protected) convert to radix string
715 function bnpToRadix(b
) {
716 if(b
== null) b
= 10;
717 if(this.signum() == 0 || b
< 2 || b
> 36) return "0";
718 var cs
= this.chunkSize(b
);
719 var a
= Math
.pow(b
,cs
);
720 var d
= nbv(a
), y
= nbi(), z
= nbi(), r
= "";
721 this.divRemTo(d
,y
,z
);
722 while(y
.signum() > 0) {
723 r
= (a
+z
.intValue()).toString(b
).substr(1) + r
;
726 return z
.intValue().toString(b
) + r
;
729 // (protected) convert from radix string
730 function bnpFromRadix(s
,b
) {
732 if(b
== null) b
= 10;
733 var cs
= this.chunkSize(b
);
734 var d
= Math
.pow(b
,cs
), mi
= false, j
= 0, w
= 0;
735 for(var i
= 0; i
< s
.length
; ++i
) {
738 if(s
.charAt(i
) == "-" && this.signum() == 0) mi
= true;
744 this.dAddOffset(w
,0);
750 this.dMultiply(Math
.pow(b
,j
));
751 this.dAddOffset(w
,0);
753 if(mi
) BigInteger
.ZERO
.subTo(this,this);
756 // (protected) alternate constructor
757 function bnpFromNumber(a
,b
,c
) {
758 if("number" == typeof b
) {
759 // new BigInteger(int,int,RNG)
760 if(a
< 2) this.fromInt(1);
762 this.fromNumber(a
,c
);
763 if(!this.testBit(a
-1)) // force MSB set
764 this.bitwiseTo(BigInteger
.ONE
.shiftLeft(a
-1),op_or
,this);
765 if(this.isEven()) this.dAddOffset(1,0); // force odd
766 while(!this.isProbablePrime(b
)) {
767 this.dAddOffset(2,0);
768 if(this.bitLength() > a
) this.subTo(BigInteger
.ONE
.shiftLeft(a
-1),this);
773 // new BigInteger(int,RNG)
774 var x
= new Array(), t
= a
&7;
777 if(t
> 0) x
[0] &= ((1<<t
)-1); else x
[0] = 0;
778 this.fromString(x
,256);
782 // (public) convert to bigendian byte array
783 function bnToByteArray() {
784 var this_array
= this.array
;
785 var i
= this.t
, r
= new Array();
787 var p
= BI_DB
-(i
*BI_DB
)%8, d
, k
= 0;
789 if(p
< BI_DB
&& (d
= this_array
[i
]>>p
) != (this.s
&BI_DM
)>>p
)
790 r
[k
++] = d
|(this.s
<<(BI_DB
-p
));
793 d
= (this_array
[i
]&((1<<p
)-1))<<(8-p
);
794 d
|= this_array
[--i
]>>(p
+=BI_DB
-8);
797 d
= (this_array
[i
]>>(p
-=8))&0xff;
798 if(p
<= 0) { p
+= BI_DB
; --i
; }
800 if((d
&0x80) != 0) d
|= -256;
801 if(k
== 0 && (this.s
&0x80) != (d
&0x80)) ++k
;
802 if(k
> 0 || d
!= this.s
) r
[k
++] = d
;
808 function bnEquals(a
) { return(this.compareTo(a
)==0); }
809 function bnMin(a
) { return(this.compareTo(a
)<0)?this:a
; }
810 function bnMax(a
) { return(this.compareTo(a
)>0)?this:a
; }
812 // (protected) r = this op a (bitwise)
813 function bnpBitwiseTo(a
,op
,r
) {
814 var this_array
= this.array
;
815 var a_array
= a
.array
;
816 var r_array
= r
.array
;
817 var i
, f
, m
= Math
.min(a
.t
,this.t
);
818 for(i
= 0; i
< m
; ++i
) r_array
[i
] = op(this_array
[i
],a_array
[i
]);
821 for(i
= m
; i
< this.t
; ++i
) r_array
[i
] = op(this_array
[i
],f
);
826 for(i
= m
; i
< a
.t
; ++i
) r_array
[i
] = op(f
,a_array
[i
]);
829 r
.s
= op(this.s
,a
.s
);
834 function op_and(x
,y
) { return x
&y
; }
835 function bnAnd(a
) { var r
= nbi(); this.bitwiseTo(a
,op_and
,r
); return r
; }
838 function op_or(x
,y
) { return x
|y
; }
839 function bnOr(a
) { var r
= nbi(); this.bitwiseTo(a
,op_or
,r
); return r
; }
842 function op_xor(x
,y
) { return x
^y
; }
843 function bnXor(a
) { var r
= nbi(); this.bitwiseTo(a
,op_xor
,r
); return r
; }
845 // (public) this & ~a
846 function op_andnot(x
,y
) { return x
&~y
; }
847 function bnAndNot(a
) { var r
= nbi(); this.bitwiseTo(a
,op_andnot
,r
); return r
; }
851 var this_array
= this.array
;
853 var r_array
= r
.array
;
855 for(var i
= 0; i
< this.t
; ++i
) r_array
[i
] = BI_DM
&~this_array
[i
];
861 // (public) this << n
862 function bnShiftLeft(n
) {
864 if(n
< 0) this.rShiftTo(-n
,r
); else this.lShiftTo(n
,r
);
868 // (public) this >> n
869 function bnShiftRight(n
) {
871 if(n
< 0) this.lShiftTo(-n
,r
); else this.rShiftTo(n
,r
);
875 // return index of lowest 1-bit in x, x < 2^31
877 if(x
== 0) return -1;
879 if((x
&0xffff) == 0) { x
>>= 16; r
+= 16; }
880 if((x
&0xff) == 0) { x
>>= 8; r
+= 8; }
881 if((x
&0xf) == 0) { x
>>= 4; r
+= 4; }
882 if((x
&3) == 0) { x
>>= 2; r
+= 2; }
887 // (public) returns index of lowest 1-bit (or -1 if none)
888 function bnGetLowestSetBit() {
889 var this_array
= this.array
;
890 for(var i
= 0; i
< this.t
; ++i
)
891 if(this_array
[i
] != 0) return i
*BI_DB
+lbit(this_array
[i
]);
892 if(this.s
< 0) return this.t
*BI_DB
;
896 // return number of 1 bits in x
899 while(x
!= 0) { x
&= x
-1; ++r
; }
903 // (public) return number of set bits
904 function bnBitCount() {
905 var r
= 0, x
= this.s
&BI_DM
;
906 for(var i
= 0; i
< this.t
; ++i
) r
+= cbit(this_array
[i
]^x
);
910 // (public) true iff nth bit is set
911 function bnTestBit(n
) {
912 var this_array
= this.array
;
913 var j
= Math
.floor(n
/BI_DB
);
914 if(j
>= this.t
) return(this.s
!=0);
915 return((this_array
[j
]&(1<<(n
%BI_DB
)))!=0);
918 // (protected) this op (1<<n)
919 function bnpChangeBit(n
,op
) {
920 var r
= BigInteger
.ONE
.shiftLeft(n
);
921 this.bitwiseTo(r
,op
,r
);
925 // (public) this | (1<<n)
926 function bnSetBit(n
) { return this.changeBit(n
,op_or
); }
928 // (public) this & ~(1<<n)
929 function bnClearBit(n
) { return this.changeBit(n
,op_andnot
); }
931 // (public) this ^ (1<<n)
932 function bnFlipBit(n
) { return this.changeBit(n
,op_xor
); }
934 // (protected) r = this + a
935 function bnpAddTo(a
,r
) {
936 var this_array
= this.array
;
937 var a_array
= a
.array
;
938 var r_array
= r
.array
;
939 var i
= 0, c
= 0, m
= Math
.min(a
.t
,this.t
);
941 c
+= this_array
[i
]+a_array
[i
];
942 r_array
[i
++] = c
&BI_DM
;
949 r_array
[i
++] = c
&BI_DM
;
958 r_array
[i
++] = c
&BI_DM
;
964 if(c
> 0) r_array
[i
++] = c
;
965 else if(c
< -1) r_array
[i
++] = BI_DV
+c
;
971 function bnAdd(a
) { var r
= nbi(); this.addTo(a
,r
); return r
; }
974 function bnSubtract(a
) { var r
= nbi(); this.subTo(a
,r
); return r
; }
977 function bnMultiply(a
) { var r
= nbi(); this.multiplyTo(a
,r
); return r
; }
980 function bnDivide(a
) { var r
= nbi(); this.divRemTo(a
,r
,null); return r
; }
983 function bnRemainder(a
) { var r
= nbi(); this.divRemTo(a
,null,r
); return r
; }
985 // (public) [this/a,this%a]
986 function bnDivideAndRemainder(a
) {
987 var q
= nbi(), r
= nbi();
988 this.divRemTo(a
,q
,r
);
989 return new Array(q
,r
);
992 // (protected) this *= n, this >= 0, 1 < n < DV
993 function bnpDMultiply(n
) {
994 var this_array
= this.array
;
995 this_array
[this.t
] = this.am(0,n
-1,this,0,0,this.t
);
1000 // (protected) this += n << w words, this >= 0
1001 function bnpDAddOffset(n
,w
) {
1002 var this_array
= this.array
;
1003 while(this.t
<= w
) this_array
[this.t
++] = 0;
1005 while(this_array
[w
] >= BI_DV
) {
1006 this_array
[w
] -= BI_DV
;
1007 if(++w
>= this.t
) this_array
[this.t
++] = 0;
1013 function NullExp() {}
1014 function nNop(x
) { return x
; }
1015 function nMulTo(x
,y
,r
) { x
.multiplyTo(y
,r
); }
1016 function nSqrTo(x
,r
) { x
.squareTo(r
); }
1018 NullExp
.prototype.convert
= nNop
;
1019 NullExp
.prototype.revert
= nNop
;
1020 NullExp
.prototype.mulTo
= nMulTo
;
1021 NullExp
.prototype.sqrTo
= nSqrTo
;
1024 function bnPow(e
) { return this.exp(e
,new NullExp()); }
1026 // (protected) r = lower n words of "this * a", a.t <= n
1027 // "this" should be the larger one if appropriate.
1028 function bnpMultiplyLowerTo(a
,n
,r
) {
1029 var r_array
= r
.array
;
1030 var a_array
= a
.array
;
1031 var i
= Math
.min(this.t
+a
.t
,n
);
1032 r
.s
= 0; // assumes a,this >= 0
1034 while(i
> 0) r_array
[--i
] = 0;
1036 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
);
1037 for(j
= Math
.min(a
.t
,n
); i
< j
; ++i
) this.am(0,a_array
[i
],r
,i
,0,n
-i
);
1041 // (protected) r = "this * a" without lower n words, n > 0
1042 // "this" should be the larger one if appropriate.
1043 function bnpMultiplyUpperTo(a
,n
,r
) {
1044 var r_array
= r
.array
;
1045 var a_array
= a
.array
;
1047 var i
= r
.t
= this.t
+a
.t
-n
;
1048 r
.s
= 0; // assumes a,this >= 0
1049 while(--i
>= 0) r_array
[i
] = 0;
1050 for(i
= Math
.max(n
-this.t
,0); i
< a
.t
; ++i
)
1051 r_array
[this.t
+i
-n
] = this.am(n
-i
,a_array
[i
],r
,0,0,this.t
+i
-n
);
1056 // Barrett modular reduction
1057 function Barrett(m
) {
1061 BigInteger
.ONE
.dlShiftTo(2*m
.t
,this.r2
);
1062 this.mu
= this.r2
.divide(m
);
1066 function barrettConvert(x
) {
1067 if(x
.s
< 0 || x
.t
> 2*this.m
.t
) return x
.mod(this.m
);
1068 else if(x
.compareTo(this.m
) < 0) return x
;
1069 else { var r
= nbi(); x
.copyTo(r
); this.reduce(r
); return r
; }
1072 function barrettRevert(x
) { return x
; }
1074 // x = x mod m (HAC 14.42)
1075 function barrettReduce(x
) {
1076 x
.drShiftTo(this.m
.t
-1,this.r2
);
1077 if(x
.t
> this.m
.t
+1) { x
.t
= this.m
.t
+1; x
.clamp(); }
1078 this.mu
.multiplyUpperTo(this.r2
,this.m
.t
+1,this.q3
);
1079 this.m
.multiplyLowerTo(this.q3
,this.m
.t
+1,this.r2
);
1080 while(x
.compareTo(this.r2
) < 0) x
.dAddOffset(1,this.m
.t
+1);
1082 while(x
.compareTo(this.m
) >= 0) x
.subTo(this.m
,x
);
1085 // r = x^2 mod m; x != r
1086 function barrettSqrTo(x
,r
) { x
.squareTo(r
); this.reduce(r
); }
1088 // r = x*y mod m; x,y != r
1089 function barrettMulTo(x
,y
,r
) { x
.multiplyTo(y
,r
); this.reduce(r
); }
1091 Barrett
.prototype.convert
= barrettConvert
;
1092 Barrett
.prototype.revert
= barrettRevert
;
1093 Barrett
.prototype.reduce
= barrettReduce
;
1094 Barrett
.prototype.mulTo
= barrettMulTo
;
1095 Barrett
.prototype.sqrTo
= barrettSqrTo
;
1097 // (public) this^e % m (HAC 14.85)
1098 function bnModPow(e
,m
) {
1099 var e_array
= e
.array
;
1100 var i
= e
.bitLength(), k
, r
= nbv(1), z
;
1101 if(i
<= 0) return r
;
1102 else if(i
< 18) k
= 1;
1103 else if(i
< 48) k
= 3;
1104 else if(i
< 144) k
= 4;
1105 else if(i
< 768) k
= 5;
1112 z
= new Montgomery(m
);
1115 var g
= new Array(), n
= 3, k1
= k
-1, km
= (1<<k
)-1;
1116 g
[1] = z
.convert(this);
1122 z
.mulTo(g2
,g
[n
-2],g
[n
]);
1127 var j
= e
.t
-1, w
, is1
= true, r2
= nbi(), t
;
1128 i
= nbits(e_array
[j
])-1;
1130 if(i
>= k1
) w
= (e_array
[j
]>>(i
-k1
))&km
;
1132 w
= (e_array
[j
]&((1<<(i
+1))-1))<<(k1
-i
);
1133 if(j
> 0) w
|= e_array
[j
-1]>>(BI_DB
+i
-k1
);
1137 while((w
&1) == 0) { w
>>= 1; --n
; }
1138 if((i
-= n
) < 0) { i
+= BI_DB
; --j
; }
1139 if(is1
) { // ret == 1, don't bother squaring or multiplying it
1144 while(n
> 1) { z
.sqrTo(r
,r2
); z
.sqrTo(r2
,r
); n
-= 2; }
1145 if(n
> 0) z
.sqrTo(r
,r2
); else { t
= r
; r
= r2
; r2
= t
; }
1149 while(j
>= 0 && (e_array
[j
]&(1<<i
)) == 0) {
1150 z
.sqrTo(r
,r2
); t
= r
; r
= r2
; r2
= t
;
1151 if(--i
< 0) { i
= BI_DB
-1; --j
; }
1157 // (public) gcd(this,a) (HAC 14.54)
1159 var x
= (this.s
<0)?this.negate():this.clone();
1160 var y
= (a
.s
<0)?a
.negate():a
.clone();
1161 if(x
.compareTo(y
) < 0) { var t
= x
; x
= y
; y
= t
; }
1162 var i
= x
.getLowestSetBit(), g
= y
.getLowestSetBit();
1169 while(x
.signum() > 0) {
1170 if((i
= x
.getLowestSetBit()) > 0) x
.rShiftTo(i
,x
);
1171 if((i
= y
.getLowestSetBit()) > 0) y
.rShiftTo(i
,y
);
1172 if(x
.compareTo(y
) >= 0) {
1181 if(g
> 0) y
.lShiftTo(g
,y
);
1185 // (protected) this % n, n < 2^26
1186 function bnpModInt(n
) {
1187 var this_array
= this.array
;
1188 if(n
<= 0) return 0;
1189 var d
= BI_DV
%n
, r
= (this.s
<0)?n
-1:0;
1191 if(d
== 0) r
= this_array
[0]%n
;
1192 else for(var i
= this.t
-1; i
>= 0; --i
) r
= (d
*r
+this_array
[i
])%n
;
1196 // (public) 1/this % m (HAC 14.61)
1197 function bnModInverse(m
) {
1198 var ac
= m
.isEven();
1199 if((this.isEven() && ac
) || m
.signum() == 0) return BigInteger
.ZERO
;
1200 var u
= m
.clone(), v
= this.clone();
1201 var a
= nbv(1), b
= nbv(0), c
= nbv(0), d
= nbv(1);
1202 while(u
.signum() != 0) {
1206 if(!a
.isEven() || !b
.isEven()) { a
.addTo(this,a
); b
.subTo(m
,b
); }
1209 else if(!b
.isEven()) b
.subTo(m
,b
);
1215 if(!c
.isEven() || !d
.isEven()) { c
.addTo(this,c
); d
.subTo(m
,d
); }
1218 else if(!d
.isEven()) d
.subTo(m
,d
);
1221 if(u
.compareTo(v
) >= 0) {
1223 if(ac
) a
.subTo(c
,a
);
1228 if(ac
) c
.subTo(a
,c
);
1232 if(v
.compareTo(BigInteger
.ONE
) != 0) return BigInteger
.ZERO
;
1233 if(d
.compareTo(m
) >= 0) return d
.subtract(m
);
1234 if(d
.signum() < 0) d
.addTo(m
,d
); else return d
;
1235 if(d
.signum() < 0) return d
.add(m
); else return d
;
1238 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];
1239 var lplim
= (1<<26)/lowprimes
[lowprimes
.length
-1];
1241 // (public) test primality with certainty >= 1-.5^t
1242 function bnIsProbablePrime(t
) {
1243 var i
, x
= this.abs();
1244 var x_array
= x
.array
;
1245 if(x
.t
== 1 && x_array
[0] <= lowprimes
[lowprimes
.length
-1]) {
1246 for(i
= 0; i
< lowprimes
.length
; ++i
)
1247 if(x_array
[0] == lowprimes
[i
]) return true;
1250 if(x
.isEven()) return false;
1252 while(i
< lowprimes
.length
) {
1253 var m
= lowprimes
[i
], j
= i
+1;
1254 while(j
< lowprimes
.length
&& m
< lplim
) m
*= lowprimes
[j
++];
1256 while(i
< j
) if(m
%lowprimes
[i
++] == 0) return false;
1258 return x
.millerRabin(t
);
1261 // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
1262 function bnpMillerRabin(t
) {
1263 var n1
= this.subtract(BigInteger
.ONE
);
1264 var k
= n1
.getLowestSetBit();
1265 if(k
<= 0) return false;
1266 var r
= n1
.shiftRight(k
);
1268 if(t
> lowprimes
.length
) t
= lowprimes
.length
;
1270 for(var i
= 0; i
< t
; ++i
) {
1271 a
.fromInt(lowprimes
[i
]);
1272 var y
= a
.modPow(r
,this);
1273 if(y
.compareTo(BigInteger
.ONE
) != 0 && y
.compareTo(n1
) != 0) {
1275 while(j
++ < k
&& y
.compareTo(n1
) != 0) {
1276 y
= y
.modPowInt(2,this);
1277 if(y
.compareTo(BigInteger
.ONE
) == 0) return false;
1279 if(y
.compareTo(n1
) != 0) return false;
1286 BigInteger
.prototype.chunkSize
= bnpChunkSize
;
1287 BigInteger
.prototype.toRadix
= bnpToRadix
;
1288 BigInteger
.prototype.fromRadix
= bnpFromRadix
;
1289 BigInteger
.prototype.fromNumber
= bnpFromNumber
;
1290 BigInteger
.prototype.bitwiseTo
= bnpBitwiseTo
;
1291 BigInteger
.prototype.changeBit
= bnpChangeBit
;
1292 BigInteger
.prototype.addTo
= bnpAddTo
;
1293 BigInteger
.prototype.dMultiply
= bnpDMultiply
;
1294 BigInteger
.prototype.dAddOffset
= bnpDAddOffset
;
1295 BigInteger
.prototype.multiplyLowerTo
= bnpMultiplyLowerTo
;
1296 BigInteger
.prototype.multiplyUpperTo
= bnpMultiplyUpperTo
;
1297 BigInteger
.prototype.modInt
= bnpModInt
;
1298 BigInteger
.prototype.millerRabin
= bnpMillerRabin
;
1301 BigInteger
.prototype.clone
= bnClone
;
1302 BigInteger
.prototype.intValue
= bnIntValue
;
1303 BigInteger
.prototype.byteValue
= bnByteValue
;
1304 BigInteger
.prototype.shortValue
= bnShortValue
;
1305 BigInteger
.prototype.signum
= bnSigNum
;
1306 BigInteger
.prototype.toByteArray
= bnToByteArray
;
1307 BigInteger
.prototype.equals
= bnEquals
;
1308 BigInteger
.prototype.min
= bnMin
;
1309 BigInteger
.prototype.max
= bnMax
;
1310 BigInteger
.prototype.and
= bnAnd
;
1311 BigInteger
.prototype.or
= bnOr
;
1312 BigInteger
.prototype.xor
= bnXor
;
1313 BigInteger
.prototype.andNot
= bnAndNot
;
1314 BigInteger
.prototype.not
= bnNot
;
1315 BigInteger
.prototype.shiftLeft
= bnShiftLeft
;
1316 BigInteger
.prototype.shiftRight
= bnShiftRight
;
1317 BigInteger
.prototype.getLowestSetBit
= bnGetLowestSetBit
;
1318 BigInteger
.prototype.bitCount
= bnBitCount
;
1319 BigInteger
.prototype.testBit
= bnTestBit
;
1320 BigInteger
.prototype.setBit
= bnSetBit
;
1321 BigInteger
.prototype.clearBit
= bnClearBit
;
1322 BigInteger
.prototype.flipBit
= bnFlipBit
;
1323 BigInteger
.prototype.add
= bnAdd
;
1324 BigInteger
.prototype.subtract
= bnSubtract
;
1325 BigInteger
.prototype.multiply
= bnMultiply
;
1326 BigInteger
.prototype.divide
= bnDivide
;
1327 BigInteger
.prototype.remainder
= bnRemainder
;
1328 BigInteger
.prototype.divideAndRemainder
= bnDivideAndRemainder
;
1329 BigInteger
.prototype.modPow
= bnModPow
;
1330 BigInteger
.prototype.modInverse
= bnModInverse
;
1331 BigInteger
.prototype.pow
= bnPow
;
1332 BigInteger
.prototype.gcd
= bnGCD
;
1333 BigInteger
.prototype.isProbablePrime
= bnIsProbablePrime
;
1335 // BigInteger interfaces not implemented in jsbn:
1337 // BigInteger(int signum, byte[] magnitude)
1338 // double doubleValue()
1339 // float floatValue()
1342 // static BigInteger valueOf(long val)
1343 // prng4.js - uses Arcfour as a PRNG
1345 function Arcfour() {
1348 this.S
= new Array();
1351 // Initialize arcfour context from key, an array of ints, each from [0..255]
1352 function ARC4init(key
) {
1354 for(i
= 0; i
< 256; ++i
)
1357 for(i
= 0; i
< 256; ++i
) {
1358 j
= (j
+ this.S
[i
] + key
[i
% key
.length
]) & 255;
1360 this.S
[i
] = this.S
[j
];
1367 function ARC4next() {
1369 this.i
= (this.i
+ 1) & 255;
1370 this.j
= (this.j
+ this.S
[this.i
]) & 255;
1372 this.S
[this.i
] = this.S
[this.j
];
1374 return this.S
[(t
+ this.S
[this.i
]) & 255];
1377 Arcfour
.prototype.init
= ARC4init
;
1378 Arcfour
.prototype.next
= ARC4next
;
1380 // Plug in your RNG constructor here
1381 function prng_newstate() {
1382 return new Arcfour();
1385 // Pool size must be a multiple of 4 and greater than 32.
1386 // An array of bytes the size of the pool will be passed to init()
1387 var rng_psize
= 256;
1388 // Random number generator - requires a PRNG backend, e.g. prng4.js
1390 // For best results, put code like
1391 // <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
1392 // in your main HTML document.
1398 // Mix in a 32-bit integer into the pool
1399 function rng_seed_int(x
) {
1400 rng_pool
[rng_pptr
++] ^= x
& 255;
1401 rng_pool
[rng_pptr
++] ^= (x
>> 8) & 255;
1402 rng_pool
[rng_pptr
++] ^= (x
>> 16) & 255;
1403 rng_pool
[rng_pptr
++] ^= (x
>> 24) & 255;
1404 if(rng_pptr
>= rng_psize
) rng_pptr
-= rng_psize
;
1407 // Mix in the current time (w/milliseconds) into the pool
1408 function rng_seed_time() {
1409 // Use pre-computed date to avoid making the benchmark
1410 // results dependent on the current date.
1411 rng_seed_int(1122926989487);
1414 // Initialize the pool with junk if needed.
1415 if(rng_pool
== null) {
1416 rng_pool
= new Array();
1419 while(rng_pptr
< rng_psize
) { // extract some randomness from Math.random()
1420 t
= Math
.floor(65536 * Math
.random());
1421 rng_pool
[rng_pptr
++] = t
>>> 8;
1422 rng_pool
[rng_pptr
++] = t
& 255;
1426 //rng_seed_int(window.screenX);
1427 //rng_seed_int(window.screenY);
1430 function rng_get_byte() {
1431 if(rng_state
== null) {
1433 rng_state
= prng_newstate();
1434 rng_state
.init(rng_pool
);
1435 for(rng_pptr
= 0; rng_pptr
< rng_pool
.length
; ++rng_pptr
)
1436 rng_pool
[rng_pptr
] = 0;
1440 // TODO: allow reseeding after first request
1441 return rng_state
.next();
1444 function rng_get_bytes(ba
) {
1446 for(i
= 0; i
< ba
.length
; ++i
) ba
[i
] = rng_get_byte();
1449 function SecureRandom() {}
1451 SecureRandom
.prototype.nextBytes
= rng_get_bytes
;
1452 // Depends on jsbn.js and rng.js
1454 // convert a (hex) string to a bignum object
1455 function parseBigInt(str
,r
) {
1456 return new BigInteger(str
,r
);
1459 function linebrk(s
,n
) {
1462 while(i
+ n
< s
.length
) {
1463 ret
+= s
.substring(i
,i
+n
) + "\n";
1466 return ret
+ s
.substring(i
,s
.length
);
1469 function byte2Hex(b
) {
1471 return "0" + b
.toString(16);
1473 return b
.toString(16);
1476 // PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
1477 function pkcs1pad2(s
,n
) {
1478 if(n
< s
.length
+ 11) {
1479 alert("Message too long for RSA");
1482 var ba
= new Array();
1483 var i
= s
.length
- 1;
1484 while(i
>= 0 && n
> 0) ba
[--n
] = s
.charCodeAt(i
--);
1486 var rng
= new SecureRandom();
1487 var x
= new Array();
1488 while(n
> 2) { // random non-zero pad
1490 while(x
[0] == 0) rng
.nextBytes(x
);
1495 return new BigInteger(ba
);
1498 // "empty" RSA key constructor
1510 // Set the public key fields N and e from hex strings
1511 function RSASetPublic(N
,E
) {
1512 if(N
!= null && E
!= null && N
.length
> 0 && E
.length
> 0) {
1513 this.n
= parseBigInt(N
,16);
1514 this.e
= parseInt(E
,16);
1517 alert("Invalid RSA public key");
1520 // Perform raw public operation on "x": return x^e (mod n)
1521 function RSADoPublic(x
) {
1522 return x
.modPowInt(this.e
, this.n
);
1525 // Return the PKCS#1 RSA encryption of "text" as an even-length hex string
1526 function RSAEncrypt(text
) {
1527 var m
= pkcs1pad2(text
,(this.n
.bitLength()+7)>>3);
1528 if(m
== null) return null;
1529 var c
= this.doPublic(m
);
1530 if(c
== null) return null;
1531 var h
= c
.toString(16);
1532 if((h
.length
& 1) == 0) return h
; else return "0" + h
;
1535 // Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
1536 //function RSAEncryptB64(text) {
1537 // var h = this.encrypt(text);
1538 // if(h) return hex2b64(h); else return null;
1542 RSAKey
.prototype.doPublic
= RSADoPublic
;
1545 RSAKey
.prototype.setPublic
= RSASetPublic
;
1546 RSAKey
.prototype.encrypt
= RSAEncrypt
;
1547 //RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
1548 // Depends on rsa.js and jsbn2.js
1550 // Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
1551 function pkcs1unpad2(d
,n
) {
1552 var b
= d
.toByteArray();
1554 while(i
< b
.length
&& b
[i
] == 0) ++i
;
1555 if(b
.length
-i
!= n
-1 || b
[i
] != 2)
1559 if(++i
>= b
.length
) return null;
1561 while(++i
< b
.length
)
1562 ret
+= String
.fromCharCode(b
[i
]);
1566 // Set the private key fields N, e, and d from hex strings
1567 function RSASetPrivate(N
,E
,D
) {
1568 if(N
!= null && E
!= null && N
.length
> 0 && E
.length
> 0) {
1569 this.n
= parseBigInt(N
,16);
1570 this.e
= parseInt(E
,16);
1571 this.d
= parseBigInt(D
,16);
1574 alert("Invalid RSA private key");
1577 // Set the private key fields N, e, d and CRT params from hex strings
1578 function RSASetPrivateEx(N
,E
,D
,P
,Q
,DP
,DQ
,C
) {
1579 if(N
!= null && E
!= null && N
.length
> 0 && E
.length
> 0) {
1580 this.n
= parseBigInt(N
,16);
1581 this.e
= parseInt(E
,16);
1582 this.d
= parseBigInt(D
,16);
1583 this.p
= parseBigInt(P
,16);
1584 this.q
= parseBigInt(Q
,16);
1585 this.dmp1
= parseBigInt(DP
,16);
1586 this.dmq1
= parseBigInt(DQ
,16);
1587 this.coeff
= parseBigInt(C
,16);
1590 alert("Invalid RSA private key");
1593 // Generate a new random private key B bits long, using public expt E
1594 function RSAGenerate(B
,E
) {
1595 var rng
= new SecureRandom();
1597 this.e
= parseInt(E
,16);
1598 var ee
= new BigInteger(E
,16);
1601 this.p
= new BigInteger(B
-qs
,1,rng
);
1602 if(this.p
.subtract(BigInteger
.ONE
).gcd(ee
).compareTo(BigInteger
.ONE
) == 0 && this.p
.isProbablePrime(10)) break;
1605 this.q
= new BigInteger(qs
,1,rng
);
1606 if(this.q
.subtract(BigInteger
.ONE
).gcd(ee
).compareTo(BigInteger
.ONE
) == 0 && this.q
.isProbablePrime(10)) break;
1608 if(this.p
.compareTo(this.q
) <= 0) {
1613 var p1
= this.p
.subtract(BigInteger
.ONE
);
1614 var q1
= this.q
.subtract(BigInteger
.ONE
);
1615 var phi
= p1
.multiply(q1
);
1616 if(phi
.gcd(ee
).compareTo(BigInteger
.ONE
) == 0) {
1617 this.n
= this.p
.multiply(this.q
);
1618 this.d
= ee
.modInverse(phi
);
1619 this.dmp1
= this.d
.mod(p1
);
1620 this.dmq1
= this.d
.mod(q1
);
1621 this.coeff
= this.q
.modInverse(this.p
);
1627 // Perform raw private operation on "x": return x^d (mod n)
1628 function RSADoPrivate(x
) {
1629 if(this.p
== null || this.q
== null)
1630 return x
.modPow(this.d
, this.n
);
1632 // TODO: re-calculate any missing CRT params
1633 var xp
= x
.mod(this.p
).modPow(this.dmp1
, this.p
);
1634 var xq
= x
.mod(this.q
).modPow(this.dmq1
, this.q
);
1636 while(xp
.compareTo(xq
) < 0)
1637 xp
= xp
.add(this.p
);
1638 return xp
.subtract(xq
).multiply(this.coeff
).mod(this.p
).multiply(this.q
).add(xq
);
1641 // Return the PKCS#1 RSA decryption of "ctext".
1642 // "ctext" is an even-length hex string and the output is a plain string.
1643 function RSADecrypt(ctext
) {
1644 var c
= parseBigInt(ctext
, 16);
1645 var m
= this.doPrivate(c
);
1646 if(m
== null) return null;
1647 return pkcs1unpad2(m
, (this.n
.bitLength()+7)>>3);
1650 // Return the PKCS#1 RSA decryption of "ctext".
1651 // "ctext" is a Base64-encoded string and the output is a plain string.
1652 //function RSAB64Decrypt(ctext) {
1653 // var h = b64tohex(ctext);
1654 // if(h) return this.decrypt(h); else return null;
1658 RSAKey
.prototype.doPrivate
= RSADoPrivate
;
1661 RSAKey
.prototype.setPrivate
= RSASetPrivate
;
1662 RSAKey
.prototype.setPrivateEx
= RSASetPrivateEx
;
1663 RSAKey
.prototype.generate
= RSAGenerate
;
1664 RSAKey
.prototype.decrypt
= RSADecrypt
;
1665 //RSAKey.prototype.b64_decrypt = RSAB64Decrypt;
1668 nValue
="a5261939975948bb7a58dffe5ff54e65f0498f9175f5a09288810b8975871e99af3b5dd94057b0fc07535f5f97444504fa35169d461d0d30cf0192e307727c065168c788771c561a9400fb49175e9e6aa4e23fe11af69e9412dd23b0cb6684c4c2429bce139e848ab26d0829073351f4acd36074eafd036a5eb83359d2a698d3";
1670 dValue
="8e9912f6d3645894e8d38cb58c0db81ff516cf4c7e5a14c7f1eddb1459d2cded4d8d293fc97aee6aefb861859c8b6a3d1dfe710463e1f9ddc72048c09751971c4a580aa51eb523357a3cc48d31cfad1d4a165066ed92d4748fb6571211da5cb14bc11b6e2df7c1a559e6d5ac1cd5c94703a22891464fba23d0d965086277a161";
1671 pValue
="d090ce58a92c75233a6486cb0a9209bf3583b64f540c76f5294bb97d285eed33aec220bde14b2417951178ac152ceab6da7090905b478195498b352048f15e7d";
1672 qValue
="cab575dc652bb66df15a0359609d51d1db184750c00c6698b90ef3465c99655103edbf0d54c56aec0ce3c4d22592338092a126a0cc49f65a4a30d222b411e58f";
1673 dmp1Value
="1a24bca8e273df2f0e47c199bbf678604e7df7215480c77c8db39f49b000ce2cf7500038acfff5433b7d582a01f1826e6f4d42e1c57f5e1fef7b12aabc59fd25";
1674 dmq1Value
="3d06982efbbe47339e1f6d36b1216b8a741d410b0c662f54f7118b27b9a4ec9d914337eb39841d8666f3034408cf94f5b62f11c402fc994fe15a05493150d9fd";
1675 coeffValue
="3a3e731acd8960b7ff9eb81a7ff93bd1cfa74cbd56987db58b4594fb09c09084db1734c8143f98b602b981aaa9243ca28deb69b5b280ee8dcee0fd2625e53250";
1677 setupEngine(am3
, 28);
1679 var TEXT
= "The quick brown fox jumped over the extremely lazy frog! " +
1680 "Now is the time for all good men to come to the party.";
1683 function encrypt() {
1684 var RSA
= new RSAKey();
1685 RSA
.setPublic(nValue
, eValue
);
1686 RSA
.setPrivateEx(nValue
, eValue
, dValue
, pValue
, qValue
, dmp1Value
, dmq1Value
, coeffValue
);
1687 encrypted
= RSA
.encrypt(TEXT
);
1690 function decrypt() {
1691 var RSA
= new RSAKey();
1692 RSA
.setPublic(nValue
, eValue
);
1693 RSA
.setPrivateEx(nValue
, eValue
, dValue
, pValue
, qValue
, dmp1Value
, dmq1Value
, coeffValue
);
1694 var decrypted
= RSA
.decrypt(encrypted
);
1695 if (decrypted
!= TEXT
) {
1696 throw new Error("Crypto operation failed");