on master help sign in
added support for bigints and int32, before both of than were working with js numbers(doubles)
8453697Rui Barreiro
jsrts/jsbn/jsbn.js+1341−1226
@@ -1,1238 +1,1353 @@
1−var i$bigInt = (function() {
1+var jsbn = (function(){
2+
2−// Copyright (c) 2005 Tom Wu
3+ // Copyright (c) 2005 Tom Wu
3−// All Rights Reserved.
4+ // All Rights Reserved.
4−// See "LICENSE" for details.
5+ // See "LICENSE" for details.
5−
6+
6−// Basic JavaScript BN library - subset useful for RSA encryption.
7+ // Basic JavaScript BN library - subset useful for RSA encryption.
7−
8+
8−// Bits per digit
9+ // Bits per digit
9−var dbits;
10+ var dbits;
10−
11+
11−// JavaScript engine analysis
12+ // JavaScript engine analysis
12−var canary = 0xdeadbeefcafe;
13+ var canary = 0xdeadbeefcafe;
13−var j_lm = ((canary&0xffffff)==0xefcafe);
14+ var j_lm = ((canary&0xffffff)==0xefcafe);
14−
15+
15−// (public) Constructor
16+ // (public) Constructor
16−function BigInteger(a,b,c) {
17+ function BigInteger(a,b,c) {
17− if(a != null)
18+ if(a != null)
18− if("number" == typeof a) this.fromNumber(a,b,c);
19+ if("number" == typeof a) this.fromNumber(a,b,c);
19− else if(b == null && "string" != typeof a) this.fromString(a,256);
20+ else if(b == null && "string" != typeof a) this.fromString(a,256);
20− else this.fromString(a,b);
21+ else this.fromString(a,b);
21−}
22+ }
22−
23+
23−// return new, unset BigInteger
24+ // return new, unset BigInteger
24−function nbi() { return new BigInteger(null); }
25+ function nbi() { return new BigInteger(null); }
25−
26+
26−// am: Compute w_j += (x*this_i), propagate carries,
27+ // am: Compute w_j += (x*this_i), propagate carries,
27−// c is initial carry, returns final carry.
28+ // c is initial carry, returns final carry.
28−// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
29+ // c < 3*dvalue, x < 2*dvalue, this_i < dvalue
29−// We need to select the fastest one that works in this environment.
30+ // We need to select the fastest one that works in this environment.
30−
31+
31−// am1: use a single mult and divide to get the high bits,
32+ // am1: use a single mult and divide to get the high bits,
32−// max digit bits should be 26 because
33+ // max digit bits should be 26 because
33−// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
34+ // max internal value = 2*dvalue^2-2*dvalue (< 2^53)
34−function am1(i,x,w,j,c,n) {
35+ function am1(i,x,w,j,c,n) {
35− while(--n >= 0) {
36+ while(--n >= 0) {
36− var v = x*this[i++]+w[j]+c;
37+ var v = x*this[i++]+w[j]+c;
37− c = Math.floor(v/0x4000000);
38+ c = Math.floor(v/0x4000000);
38− w[j++] = v&0x3ffffff;
39+ w[j++] = v&0x3ffffff;
39− }
40+ }
40− return c;
41+ return c;
41−}
42+ }
42−// am2 avoids a big mult-and-extract completely.
43+ // am2 avoids a big mult-and-extract completely.
43−// Max digit bits should be <= 30 because we do bitwise ops
44+ // Max digit bits should be <= 30 because we do bitwise ops
44−// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
45+ // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
45−function am2(i,x,w,j,c,n) {
46+ function am2(i,x,w,j,c,n) {
46− var xl = x&0x7fff, xh = x>>15;
47+ var xl = x&0x7fff, xh = x>>15;
47− while(--n >= 0) {
48+ while(--n >= 0) {
48− var l = this[i]&0x7fff;
49+ var l = this[i]&0x7fff;
49− var h = this[i++]>>15;
50+ var h = this[i++]>>15;
50− var m = xh*l+h*xl;
51+ var m = xh*l+h*xl;
51− l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
52+ l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
52− c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
53+ c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
53− w[j++] = l&0x3fffffff;
54+ w[j++] = l&0x3fffffff;
54− }
55+ }
55− return c;
56+ return c;
56−}
57+ }
57−// Alternately, set max digit bits to 28 since some
58+ // Alternately, set max digit bits to 28 since some
58−// browsers slow down when dealing with 32-bit numbers.
59+ // browsers slow down when dealing with 32-bit numbers.
59−function am3(i,x,w,j,c,n) {
60+ function am3(i,x,w,j,c,n) {
60− var xl = x&0x3fff, xh = x>>14;
61+ var xl = x&0x3fff, xh = x>>14;
61− while(--n >= 0) {
62+ while(--n >= 0) {
62− var l = this[i]&0x3fff;
63+ var l = this[i]&0x3fff;
63− var h = this[i++]>>14;
64+ var h = this[i++]>>14;
64− var m = xh*l+h*xl;
65+ var m = xh*l+h*xl;
65− l = xl*l+((m&0x3fff)<<14)+w[j]+c;
66+ l = xl*l+((m&0x3fff)<<14)+w[j]+c;
66− c = (l>>28)+(m>>14)+xh*h;
67+ c = (l>>28)+(m>>14)+xh*h;
67− w[j++] = l&0xfffffff;
68+ w[j++] = l&0xfffffff;
68− }
69+ }
69− return c;
70+ return c;
70−}
71+ }
71−var in_browser = typeof navigator !== "undefined"
72+ var inBrowser = typeof navigator !== "undefined";
72−if(in_browser && j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
73+ if(inBrowser && j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
73− BigInteger.prototype.am = am2;
74+ BigInteger.prototype.am = am2;
74− dbits = 30;
75+ dbits = 30;
75−}
76+ }
76−else if(in_browser && j_lm && (navigator.appName != "Netscape")) {
77+ else if(inBrowser && j_lm && (navigator.appName != "Netscape")) {
77− BigInteger.prototype.am = am1;
78+ BigInteger.prototype.am = am1;
78− dbits = 26;
79+ dbits = 26;
79−}
80+ }
80−else { // Mozilla/Netscape seems to prefer am3
81+ else { // Mozilla/Netscape seems to prefer am3
81− BigInteger.prototype.am = am3;
82+ BigInteger.prototype.am = am3;
82− dbits = 28;
83+ dbits = 28;
83−}
84+ }
84−
85+
85−BigInteger.prototype.DB = dbits;
86+ BigInteger.prototype.DB = dbits;
86−BigInteger.prototype.DM = ((1<<dbits)-1);
87+ BigInteger.prototype.DM = ((1<<dbits)-1);
87−BigInteger.prototype.DV = (1<<dbits);
88+ BigInteger.prototype.DV = (1<<dbits);
88−
89+
89−var BI_FP = 52;
90+ var BI_FP = 52;
90−BigInteger.prototype.FV = Math.pow(2,BI_FP);
91+ BigInteger.prototype.FV = Math.pow(2,BI_FP);
91−BigInteger.prototype.F1 = BI_FP-dbits;
92+ BigInteger.prototype.F1 = BI_FP-dbits;
92−BigInteger.prototype.F2 = 2*dbits-BI_FP;
93+ BigInteger.prototype.F2 = 2*dbits-BI_FP;
93−
94+
94−// Digit conversions
95+ // Digit conversions
95−var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
96+ var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
96−var BI_RC = new Array();
97+ var BI_RC = new Array();
97−var rr,vv;
98+ var rr,vv;
98−rr = "0".charCodeAt(0);
99+ rr = "0".charCodeAt(0);
99−for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
100+ for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
100−rr = "a".charCodeAt(0);
101+ rr = "a".charCodeAt(0);
101−for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
102+ for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
102−rr = "A".charCodeAt(0);
103+ rr = "A".charCodeAt(0);
103−for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
104+ for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
104−
105+
105−function int2char(n) { return BI_RM.charAt(n); }
106+ function int2char(n) { return BI_RM.charAt(n); }
106−function intAt(s,i) {
107+ function intAt(s,i) {
107− var c = BI_RC[s.charCodeAt(i)];
108+ var c = BI_RC[s.charCodeAt(i)];
108− return (c==null)?-1:c;
109+ return (c==null)?-1:c;
109−}
110+ }
110−
111+
111−// (protected) copy this to r
112+ // (protected) copy this to r
112−function bnpCopyTo(r) {
113+ function bnpCopyTo(r) {
113− for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
114+ for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
114− r.t = this.t;
115+ r.t = this.t;
115− r.s = this.s;
116+ r.s = this.s;
116−}
117+ }
117−
118+
118−// (protected) set from integer value x, -DV <= x < DV
119+ // (protected) set from integer value x, -DV <= x < DV
119−function bnpFromInt(x) {
120+ function bnpFromInt(x) {
120− this.t = 1;
121+ this.t = 1;
121− this.s = (x<0)?-1:0;
122+ this.s = (x<0)?-1:0;
122− if(x > 0) this[0] = x;
123+ if(x > 0) this[0] = x;
123− else if(x < -1) this[0] = x+this.DV;
124+ else if(x < -1) this[0] = x+this.DV;
124− else this.t = 0;
125+ else this.t = 0;
125−}
126+ }
126−
127+
127−// return bigint initialized to value
128+ // return bigint initialized to value
128−function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
129+ function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
129−
130+
130−// (protected) set from string and radix
131+ // (protected) set from string and radix
131−function bnpFromString(s,b) {
132+ function bnpFromString(s,b) {
132− var k;
133+ var k;
133− if(b == 16) k = 4;
134+ if(b == 16) k = 4;
134− else if(b == 8) k = 3;
135+ else if(b == 8) k = 3;
135− else if(b == 256) k = 8; // byte array
136+ else if(b == 256) k = 8; // byte array
136− else if(b == 2) k = 1;
137+ else if(b == 2) k = 1;
137− else if(b == 32) k = 5;
138+ else if(b == 32) k = 5;
138− else if(b == 4) k = 2;
139+ else if(b == 4) k = 2;
139− else { this.fromRadix(s,b); return; }
140+ else { this.fromRadix(s,b); return; }
140− this.t = 0;
141+ this.t = 0;
141− this.s = 0;
142+ this.s = 0;
142− var i = s.length, mi = false, sh = 0;
143+ var i = s.length, mi = false, sh = 0;
143− while(--i >= 0) {
144+ while(--i >= 0) {
144− var x = (k==8)?s[i]&0xff:intAt(s,i);
145+ var x = (k==8)?s[i]&0xff:intAt(s,i);
145− if(x < 0) {
146+ if(x < 0) {
146− if(s.charAt(i) == "-") mi = true;
147+ if(s.charAt(i) == "-") mi = true;
147− continue;
148+ continue;
148− }
149+ }
149− mi = false;
150+ mi = false;
150− if(sh == 0)
151+ if(sh == 0)
151− this[this.t++] = x;
152+ this[this.t++] = x;
152− else if(sh+k > this.DB) {
153+ else if(sh+k > this.DB) {
153− this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
154+ this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
154− this[this.t++] = (x>>(this.DB-sh));
155+ this[this.t++] = (x>>(this.DB-sh));
155− }
156+ }
156− else
157+ else
157− this[this.t-1] |= x<<sh;
158+ this[this.t-1] |= x<<sh;
158− sh += k;
159+ sh += k;
159− if(sh >= this.DB) sh -= this.DB;
160+ if(sh >= this.DB) sh -= this.DB;
160− }
161+ }
161− if(k == 8 && (s[0]&0x80) != 0) {
162+ if(k == 8 && (s[0]&0x80) != 0) {
162− this.s = -1;
163+ this.s = -1;
163− if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
164+ if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
164− }
165+ }
165− this.clamp();
166+ this.clamp();
166− if(mi) BigInteger.ZERO.subTo(this,this);
167+ if(mi) BigInteger.ZERO.subTo(this,this);
167−}
168+ }
168−
169+
169−// (protected) clamp off excess high words
170+ // (protected) clamp off excess high words
170−function bnpClamp() {
171+ function bnpClamp() {
171− var c = this.s&this.DM;
172+ var c = this.s&this.DM;
172− while(this.t > 0 && this[this.t-1] == c) --this.t;
173+ while(this.t > 0 && this[this.t-1] == c) --this.t;
173−}
174+ }
174−
175+
175−// (public) return string representation in given radix
176+ // (public) return string representation in given radix
176−function bnToString(b) {
177+ function bnToString(b) {
177− if(this.s < 0) return "-"+this.negate().toString(b);
178+ if(this.s < 0) return "-"+this.negate().toString(b);
178− var k;
179+ var k;
179− if(b == 16) k = 4;
180+ if(b == 16) k = 4;
180− else if(b == 8) k = 3;
181+ else if(b == 8) k = 3;
181− else if(b == 2) k = 1;
182+ else if(b == 2) k = 1;
182− else if(b == 32) k = 5;
183+ else if(b == 32) k = 5;
183− else if(b == 4) k = 2;
184+ else if(b == 4) k = 2;
184− else return this.toRadix(b);
185+ else return this.toRadix(b);
185− var km = (1<<k)-1, d, m = false, r = "", i = this.t;
186+ var km = (1<<k)-1, d, m = false, r = "", i = this.t;
186− var p = this.DB-(i*this.DB)%k;
187+ var p = this.DB-(i*this.DB)%k;
187− if(i-- > 0) {
188+ if(i-- > 0) {
188− if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
189+ if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
189− while(i >= 0) {
190+ while(i >= 0) {
190− if(p < k) {
191+ if(p < k) {
191− d = (this[i]&((1<<p)-1))<<(k-p);
192+ d = (this[i]&((1<<p)-1))<<(k-p);
192− d |= this[--i]>>(p+=this.DB-k);
193+ d |= this[--i]>>(p+=this.DB-k);
194+ }
195+ else {
196+ d = (this[i]>>(p-=k))&km;
197+ if(p <= 0) { p += this.DB; --i; }
198+ }
199+ if(d > 0) m = true;
200+ if(m) r += int2char(d);
201+ }
202+ }
203+ return m?r:"0";
204+ }
205+
206+ // (public) -this
207+ function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
208+
209+ // (public) |this|
210+ function bnAbs() { return (this.s<0)?this.negate():this; }
211+
212+ // (public) return + if this > a, - if this < a, 0 if equal
213+ function bnCompareTo(a) {
214+ var r = this.s-a.s;
215+ if(r != 0) return r;
216+ var i = this.t;
217+ r = i-a.t;
218+ if(r != 0) return (this.s<0)?-r:r;
219+ while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
220+ return 0;
221+ }
222+
223+ // returns bit length of the integer x
224+ function nbits(x) {
225+ var r = 1, t;
226+ if((t=x>>>16) != 0) { x = t; r += 16; }
227+ if((t=x>>8) != 0) { x = t; r += 8; }
228+ if((t=x>>4) != 0) { x = t; r += 4; }
229+ if((t=x>>2) != 0) { x = t; r += 2; }
230+ if((t=x>>1) != 0) { x = t; r += 1; }
231+ return r;
232+ }
233+
234+ // (public) return the number of bits in "this"
235+ function bnBitLength() {
236+ if(this.t <= 0) return 0;
237+ return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
238+ }
239+
240+ // (protected) r = this << n*DB
241+ function bnpDLShiftTo(n,r) {
242+ var i;
243+ for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
244+ for(i = n-1; i >= 0; --i) r[i] = 0;
245+ r.t = this.t+n;
246+ r.s = this.s;
247+ }
248+
249+ // (protected) r = this >> n*DB
250+ function bnpDRShiftTo(n,r) {
251+ for(var i = n; i < this.t; ++i) r[i-n] = this[i];
252+ r.t = Math.max(this.t-n,0);
253+ r.s = this.s;
254+ }
255+
256+ // (protected) r = this << n
257+ function bnpLShiftTo(n,r) {
258+ var bs = n%this.DB;
259+ var cbs = this.DB-bs;
260+ var bm = (1<<cbs)-1;
261+ var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
262+ for(i = this.t-1; i >= 0; --i) {
263+ r[i+ds+1] = (this[i]>>cbs)|c;
264+ c = (this[i]&bm)<<bs;
265+ }
266+ for(i = ds-1; i >= 0; --i) r[i] = 0;
267+ r[ds] = c;
268+ r.t = this.t+ds+1;
269+ r.s = this.s;
270+ r.clamp();
271+ }
272+
273+ // (protected) r = this >> n
274+ function bnpRShiftTo(n,r) {
275+ r.s = this.s;
276+ var ds = Math.floor(n/this.DB);
277+ if(ds >= this.t) { r.t = 0; return; }
278+ var bs = n%this.DB;
279+ var cbs = this.DB-bs;
280+ var bm = (1<<bs)-1;
281+ r[0] = this[ds]>>bs;
282+ for(var i = ds+1; i < this.t; ++i) {
283+ r[i-ds-1] |= (this[i]&bm)<<cbs;
284+ r[i-ds] = this[i]>>bs;
285+ }
286+ if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
287+ r.t = this.t-ds;
288+ r.clamp();
289+ }
290+
291+ // (protected) r = this - a
292+ function bnpSubTo(a,r) {
293+ var i = 0, c = 0, m = Math.min(a.t,this.t);
294+ while(i < m) {
295+ c += this[i]-a[i];
296+ r[i++] = c&this.DM;
297+ c >>= this.DB;
298+ }
299+ if(a.t < this.t) {
300+ c -= a.s;
301+ while(i < this.t) {
302+ c += this[i];
303+ r[i++] = c&this.DM;
304+ c >>= this.DB;
305+ }
306+ c += this.s;
193 }
307 }
194 else {
308 else {
195− d = (this[i]>>(p-=k))&km;
309+ c += this.s;
310+ while(i < a.t) {
311+ c -= a[i];
312+ r[i++] = c&this.DM;
196− if(p <= 0) { p += this.DB; --i; }
313+ c >>= this.DB;
314+ }
315+ c -= a.s;
316+ }
317+ r.s = (c<0)?-1:0;
318+ if(c < -1) r[i++] = this.DV+c;
319+ else if(c > 0) r[i++] = c;
320+ r.t = i;
321+ r.clamp();
322+ }
323+
324+ // (protected) r = this * a, r != this,a (HAC 14.12)
325+ // "this" should be the larger one if appropriate.
326+ function bnpMultiplyTo(a,r) {
327+ var x = this.abs(), y = a.abs();
328+ var i = x.t;
329+ r.t = i+y.t;
330+ while(--i >= 0) r[i] = 0;
331+ for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
332+ r.s = 0;
333+ r.clamp();
334+ if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
335+ }
336+
337+ // (protected) r = this^2, r != this (HAC 14.16)
338+ function bnpSquareTo(r) {
339+ var x = this.abs();
340+ var i = r.t = 2*x.t;
341+ while(--i >= 0) r[i] = 0;
342+ for(i = 0; i < x.t-1; ++i) {
343+ var c = x.am(i,x[i],r,2*i,0,1);
344+ if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
345+ r[i+x.t] -= x.DV;
346+ r[i+x.t+1] = 1;
347+ }
197 }
348 }
198− if(d > 0) m = true;
199− if(m) r += int2char(d);
200− }
201− }
202− return m?r:"0";
203−}
204−
205−// (public) -this
206−function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
207−
208−// (public) |this|
209−function bnAbs() { return (this.s<0)?this.negate():this; }
210−
211−// (public) return + if this > a, - if this < a, 0 if equal
212−function bnCompareTo(a) {
213− var r = this.s-a.s;
214− if(r != 0) return r;
215− var i = this.t;
216− r = i-a.t;
217− if(r != 0) return (this.s<0)?-r:r;
218− while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
219− return 0;
220−}
221−
222−// returns bit length of the integer x
223−function nbits(x) {
224− var r = 1, t;
225− if((t=x>>>16) != 0) { x = t; r += 16; }
226− if((t=x>>8) != 0) { x = t; r += 8; }
227− if((t=x>>4) != 0) { x = t; r += 4; }
228− if((t=x>>2) != 0) { x = t; r += 2; }
229− if((t=x>>1) != 0) { x = t; r += 1; }
230− return r;
231−}
232−
233−// (public) return the number of bits in "this"
234−function bnBitLength() {
235− if(this.t <= 0) return 0;
236− return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
237−}
238−
239−// (protected) r = this << n*DB
240−function bnpDLShiftTo(n,r) {
241− var i;
242− for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
243− for(i = n-1; i >= 0; --i) r[i] = 0;
244− r.t = this.t+n;
245− r.s = this.s;
246−}
247−
248−// (protected) r = this >> n*DB
249−function bnpDRShiftTo(n,r) {
250− for(var i = n; i < this.t; ++i) r[i-n] = this[i];
251− r.t = Math.max(this.t-n,0);
252− r.s = this.s;
253−}
254−
255−// (protected) r = this << n
256−function bnpLShiftTo(n,r) {
257− var bs = n%this.DB;
258− var cbs = this.DB-bs;
259− var bm = (1<<cbs)-1;
260− var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
261− for(i = this.t-1; i >= 0; --i) {
262− r[i+ds+1] = (this[i]>>cbs)|c;
263− c = (this[i]&bm)<<bs;
264− }
265− for(i = ds-1; i >= 0; --i) r[i] = 0;
266− r[ds] = c;
267− r.t = this.t+ds+1;
268− r.s = this.s;
269− r.clamp();
270−}
271−
272−// (protected) r = this >> n
273−function bnpRShiftTo(n,r) {
274− r.s = this.s;
275− var ds = Math.floor(n/this.DB);
276− if(ds >= this.t) { r.t = 0; return; }
277− var bs = n%this.DB;
278− var cbs = this.DB-bs;
279− var bm = (1<<bs)-1;
280− r[0] = this[ds]>>bs;
281− for(var i = ds+1; i < this.t; ++i) {
282− r[i-ds-1] |= (this[i]&bm)<<cbs;
283− r[i-ds] = this[i]>>bs;
284− }
285− if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
286− r.t = this.t-ds;
287− r.clamp();
288−}
289−
290−// (protected) r = this - a
291−function bnpSubTo(a,r) {
292− var i = 0, c = 0, m = Math.min(a.t,this.t);
293− while(i < m) {
294− c += this[i]-a[i];
295− r[i++] = c&this.DM;
296− c >>= this.DB;
297− }
298− if(a.t < this.t) {
299− c -= a.s;
300− while(i < this.t) {
301− c += this[i];
302− r[i++] = c&this.DM;
303− c >>= this.DB;
304− }
305− c += this.s;
306− }
307− else {
308− c += this.s;
309− while(i < a.t) {
310− c -= a[i];
311− r[i++] = c&this.DM;
312− c >>= this.DB;
313− }
314− c -= a.s;
315− }
316− r.s = (c<0)?-1:0;
317− if(c < -1) r[i++] = this.DV+c;
318− else if(c > 0) r[i++] = c;
319− r.t = i;
320− r.clamp();
321−}
322−
323−// (protected) r = this * a, r != this,a (HAC 14.12)
324−// "this" should be the larger one if appropriate.
325−function bnpMultiplyTo(a,r) {
326− var x = this.abs(), y = a.abs();
327− var i = x.t;
328− r.t = i+y.t;
329− while(--i >= 0) r[i] = 0;
330− for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
331− r.s = 0;
332− r.clamp();
333− if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
334−}
335−
336−// (protected) r = this^2, r != this (HAC 14.16)
337−function bnpSquareTo(r) {
338− var x = this.abs();
339− var i = r.t = 2*x.t;
340− while(--i >= 0) r[i] = 0;
341− for(i = 0; i < x.t-1; ++i) {
342− var c = x.am(i,x[i],r,2*i,0,1);
343− if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
344− r[i+x.t] -= x.DV;
345− r[i+x.t+1] = 1;
346− }
347− }
348− if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
349+ if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
349− r.s = 0;
350+ r.s = 0;
350− r.clamp();
351+ r.clamp();
351−}
352+ }
352−
353+
353−// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
354+ // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
354−// r != q, this != m. q or r may be null.
355+ // r != q, this != m. q or r may be null.
355−function bnpDivRemTo(m,q,r) {
356+ function bnpDivRemTo(m,q,r) {
356− var pm = m.abs();
357+ var pm = m.abs();
357− if(pm.t <= 0) return;
358+ if(pm.t <= 0) return;
358− var pt = this.abs();
359+ var pt = this.abs();
359− if(pt.t < pm.t) {
360+ if(pt.t < pm.t) {
360− if(q != null) q.fromInt(0);
361+ if(q != null) q.fromInt(0);
361− if(r != null) this.copyTo(r);
362+ if(r != null) this.copyTo(r);
362− return;
363+ return;
363− }
364+ }
364− if(r == null) r = nbi();
365+ if(r == null) r = nbi();
365− var y = nbi(), ts = this.s, ms = m.s;
366+ var y = nbi(), ts = this.s, ms = m.s;
366− var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
367+ var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
367− if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
368+ if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
368− else { pm.copyTo(y); pt.copyTo(r); }
369+ else { pm.copyTo(y); pt.copyTo(r); }
369− var ys = y.t;
370+ var ys = y.t;
370− var y0 = y[ys-1];
371+ var y0 = y[ys-1];
371− if(y0 == 0) return;
372+ if(y0 == 0) return;
372− var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
373+ var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
373− var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
374+ var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
374− var i = r.t, j = i-ys, t = (q==null)?nbi():q;
375+ var i = r.t, j = i-ys, t = (q==null)?nbi():q;
375− y.dlShiftTo(j,t);
376− if(r.compareTo(t) >= 0) {
377− r[r.t++] = 1;
378− r.subTo(t,r);
379− }
380− BigInteger.ONE.dlShiftTo(ys,t);
381− t.subTo(y,y); // "negative" y so we can replace sub with am later
382− while(y.t < ys) y[y.t++] = 0;
383− while(--j >= 0) {
384− // Estimate quotient digit
385− var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
386− if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
387 y.dlShiftTo(j,t);
376 y.dlShiftTo(j,t);
377+ if(r.compareTo(t) >= 0) {
378+ r[r.t++] = 1;
388− r.subTo(t,r);
379+ r.subTo(t,r);
380+ }
381+ BigInteger.ONE.dlShiftTo(ys,t);
382+ t.subTo(y,y); // "negative" y so we can replace sub with am later
383+ while(y.t < ys) y[y.t++] = 0;
384+ while(--j >= 0) {
385+ // Estimate quotient digit
386+ var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
387+ if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
388+ y.dlShiftTo(j,t);
389+ r.subTo(t,r);
389− while(r[i] < --qd) r.subTo(t,r);
390+ while(r[i] < --qd) r.subTo(t,r);
390− }
391+ }
391− }
392+ }
392− if(q != null) {
393+ if(q != null) {
393− r.drShiftTo(ys,q);
394+ r.drShiftTo(ys,q);
394− if(ts != ms) BigInteger.ZERO.subTo(q,q);
395+ if(ts != ms) BigInteger.ZERO.subTo(q,q);
395− }
396+ }
396− r.t = ys;
397+ r.t = ys;
397− r.clamp();
398+ r.clamp();
398− if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
399+ if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
399− if(ts < 0) BigInteger.ZERO.subTo(r,r);
400+ if(ts < 0) BigInteger.ZERO.subTo(r,r);
400−}
401+ }
401−
402+
402−// (public) this mod a
403+ // (public) this mod a
403−function bnMod(a) {
404+ function bnMod(a) {
404− var r = nbi();
405+ var r = nbi();
405− this.abs().divRemTo(a,null,r);
406+ this.abs().divRemTo(a,null,r);
406− if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
407+ if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
407− return r;
408+ return r;
408−}
409+ }
409−
410+
410−// Modular reduction using "classic" algorithm
411+ // Modular reduction using "classic" algorithm
411−function Classic(m) { this.m = m; }
412+ function Classic(m) { this.m = m; }
412−function cConvert(x) {
413+ function cConvert(x) {
413− if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
414+ if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
414− else return x;
415+ else return x;
415−}
416+ }
416−function cRevert(x) { return x; }
417+ function cRevert(x) { return x; }
417−function cReduce(x) { x.divRemTo(this.m,null,x); }
418+ function cReduce(x) { x.divRemTo(this.m,null,x); }
418−function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
419+ function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
419−function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
420+ function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
420−
421+
421−Classic.prototype.convert = cConvert;
422+ Classic.prototype.convert = cConvert;
422−Classic.prototype.revert = cRevert;
423+ Classic.prototype.revert = cRevert;
423−Classic.prototype.reduce = cReduce;
424+ Classic.prototype.reduce = cReduce;
424−Classic.prototype.mulTo = cMulTo;
425+ Classic.prototype.mulTo = cMulTo;
425−Classic.prototype.sqrTo = cSqrTo;
426+ Classic.prototype.sqrTo = cSqrTo;
426−
427+
427−// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
428+ // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
428−// justification:
429+ // justification:
429−// xy == 1 (mod m)
430+ // xy == 1 (mod m)
430−// xy = 1+km
431+ // xy = 1+km
431−// xy(2-xy) = (1+km)(1-km)
432+ // xy(2-xy) = (1+km)(1-km)
432−// x[y(2-xy)] = 1-k^2m^2
433+ // x[y(2-xy)] = 1-k^2m^2
433−// x[y(2-xy)] == 1 (mod m^2)
434+ // x[y(2-xy)] == 1 (mod m^2)
434−// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
435+ // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
435−// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
436+ // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
436−// JS multiply "overflows" differently from C/C++, so care is needed here.
437+ // JS multiply "overflows" differently from C/C++, so care is needed here.
437−function bnpInvDigit() {
438+ function bnpInvDigit() {
438− if(this.t < 1) return 0;
439+ if(this.t < 1) return 0;
439− var x = this[0];
440+ var x = this[0];
440− if((x&1) == 0) return 0;
441+ if((x&1) == 0) return 0;
441− var y = x&3; // y == 1/x mod 2^2
442+ var y = x&3; // y == 1/x mod 2^2
442− y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
443+ y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
443− y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
444+ y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
444− y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
445+ y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
445− // last step - calculate inverse mod DV directly;
446+ // last step - calculate inverse mod DV directly;
446− // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
447+ // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
447− y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
448+ y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
448− // we really want the negative inverse, and -DV < y < DV
449+ // we really want the negative inverse, and -DV < y < DV
449− return (y>0)?this.DV-y:-y;
450+ return (y>0)?this.DV-y:-y;
450−}
451+ }
451−
452+
452−// Montgomery reduction
453+ // Montgomery reduction
453−function Montgomery(m) {
454+ function Montgomery(m) {
454− this.m = m;
455+ this.m = m;
455− this.mp = m.invDigit();
456+ this.mp = m.invDigit();
456− this.mpl = this.mp&0x7fff;
457+ this.mpl = this.mp&0x7fff;
457− this.mph = this.mp>>15;
458+ this.mph = this.mp>>15;
458− this.um = (1<<(m.DB-15))-1;
459+ this.um = (1<<(m.DB-15))-1;
459− this.mt2 = 2*m.t;
460+ this.mt2 = 2*m.t;
460−}
461+ }
461−
462+
462−// xR mod m
463+ // xR mod m
463−function montConvert(x) {
464+ function montConvert(x) {
464− var r = nbi();
465+ var r = nbi();
465− x.abs().dlShiftTo(this.m.t,r);
466+ x.abs().dlShiftTo(this.m.t,r);
466− r.divRemTo(this.m,null,r);
467+ r.divRemTo(this.m,null,r);
467− if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
468+ if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
468− return r;
469+ return r;
469−}
470+ }
470−
471+
471−// x/R mod m
472+ // x/R mod m
472−function montRevert(x) {
473+ function montRevert(x) {
473− var r = nbi();
474+ var r = nbi();
474− x.copyTo(r);
475+ x.copyTo(r);
475− this.reduce(r);
476+ this.reduce(r);
476− return r;
477+ return r;
477−}
478+ }
478−
479+
479−// x = x/R mod m (HAC 14.32)
480+ // x = x/R mod m (HAC 14.32)
480−function montReduce(x) {
481+ function montReduce(x) {
481− while(x.t <= this.mt2) // pad x so am has enough room later
482+ while(x.t <= this.mt2) // pad x so am has enough room later
482− x[x.t++] = 0;
483+ x[x.t++] = 0;
483− for(var i = 0; i < this.m.t; ++i) {
484+ for(var i = 0; i < this.m.t; ++i) {
484− // faster way of calculating u0 = x[i]*mp mod DV
485+ // faster way of calculating u0 = x[i]*mp mod DV
485− var j = x[i]&0x7fff;
486+ var j = x[i]&0x7fff;
486− var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
487+ var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
487− // use am to combine the multiply-shift-add into one call
488+ // use am to combine the multiply-shift-add into one call
488− j = i+this.m.t;
489+ j = i+this.m.t;
489− x[j] += this.m.am(0,u0,x,i,0,this.m.t);
490+ x[j] += this.m.am(0,u0,x,i,0,this.m.t);
490− // propagate carry
491+ // propagate carry
491− while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
492+ while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
492− }
493− x.clamp();
494− x.drShiftTo(this.m.t,x);
495− if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
496−}
497−
498−// r = "x^2/R mod m"; x != r
499−function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
500−
501−// r = "xy/R mod m"; x,y != r
502−function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
503−
504−Montgomery.prototype.convert = montConvert;
505−Montgomery.prototype.revert = montRevert;
506−Montgomery.prototype.reduce = montReduce;
507−Montgomery.prototype.mulTo = montMulTo;
508−Montgomery.prototype.sqrTo = montSqrTo;
509−
510−// (protected) true iff this is even
511−function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
512−
513−// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
514−function bnpExp(e,z) {
515− if(e > 0xffffffff || e < 1) return BigInteger.ONE;
516− var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
517− g.copyTo(r);
518− while(--i >= 0) {
519− z.sqrTo(r,r2);
520− if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
521− else { var t = r; r = r2; r2 = t; }
522− }
523− return z.revert(r);
524−}
525−
526−// (public) this^e % m, 0 <= e < 2^32
527−function bnModPowInt(e,m) {
528− var z;
529− if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
530− return this.exp(e,z);
531−}
532−
533−// protected
534−BigInteger.prototype.copyTo = bnpCopyTo;
535−BigInteger.prototype.fromInt = bnpFromInt;
536−BigInteger.prototype.fromString = bnpFromString;
537−BigInteger.prototype.clamp = bnpClamp;
538−BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
539−BigInteger.prototype.drShiftTo = bnpDRShiftTo;
540−BigInteger.prototype.lShiftTo = bnpLShiftTo;
541−BigInteger.prototype.rShiftTo = bnpRShiftTo;
542−BigInteger.prototype.subTo = bnpSubTo;
543−BigInteger.prototype.multiplyTo = bnpMultiplyTo;
544−BigInteger.prototype.squareTo = bnpSquareTo;
545−BigInteger.prototype.divRemTo = bnpDivRemTo;
546−BigInteger.prototype.invDigit = bnpInvDigit;
547−BigInteger.prototype.isEven = bnpIsEven;
548−BigInteger.prototype.exp = bnpExp;
549−
550−// public
551−BigInteger.prototype.toString = bnToString;
552−BigInteger.prototype.negate = bnNegate;
553−BigInteger.prototype.abs = bnAbs;
554−BigInteger.prototype.compareTo = bnCompareTo;
555−BigInteger.prototype.bitLength = bnBitLength;
556−BigInteger.prototype.mod = bnMod;
557−BigInteger.prototype.modPowInt = bnModPowInt;
558−
559−// "constants"
560−BigInteger.ZERO = nbv(0);
561−BigInteger.ONE = nbv(1);
562−
563−// Copyright (c) 2005-2009 Tom Wu
564−// All Rights Reserved.
565−// See "LICENSE" for details.
566−
567−// Extended JavaScript BN functions, required for RSA private ops.
568−
569−// Version 1.1: new BigInteger("0", 10) returns "proper" zero
570−// Version 1.2: square() API, isProbablePrime fix
571−
572−// (public)
573−function bnClone() { var r = nbi(); this.copyTo(r); return r; }
574−
575−// (public) return value as integer
576−function bnIntValue() {
577− if(this.s < 0) {
578− if(this.t == 1) return this[0]-this.DV;
579− else if(this.t == 0) return -1;
580− }
581− else if(this.t == 1) return this[0];
582− else if(this.t == 0) return 0;
583− // assumes 16 < DB < 32
584− return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
585−}
586−
587−// (public) return value as byte
588−function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
589−
590−// (public) return value as short (assumes DB>=16)
591−function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
592−
593−// (protected) return x s.t. r^x < DV
594−function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
595−
596−// (public) 0 if this == 0, 1 if this > 0
597−function bnSigNum() {
598− if(this.s < 0) return -1;
599− else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
600− else return 1;
601−}
602−
603−// (protected) convert to radix string
604−function bnpToRadix(b) {
605− if(b == null) b = 10;
606− if(this.signum() == 0 || b < 2 || b > 36) return "0";
607− var cs = this.chunkSize(b);
608− var a = Math.pow(b,cs);
609− var d = nbv(a), y = nbi(), z = nbi(), r = "";
610− this.divRemTo(d,y,z);
611− while(y.signum() > 0) {
612− r = (a+z.intValue()).toString(b).substr(1) + r;
613− y.divRemTo(d,y,z);
614− }
615− return z.intValue().toString(b) + r;
616−}
617−
618−// (protected) convert from radix string
619−function bnpFromRadix(s,b) {
620− this.fromInt(0);
621− if(b == null) b = 10;
622− var cs = this.chunkSize(b);
623− var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
624− for(var i = 0; i < s.length; ++i) {
625− var x = intAt(s,i);
626− if(x < 0) {
627− if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
628− continue;
629− }
630− w = b*w+x;
631− if(++j >= cs) {
632− this.dMultiply(d);
633− this.dAddOffset(w,0);
634− j = 0;
635− w = 0;
636− }
637− }
638− if(j > 0) {
639− this.dMultiply(Math.pow(b,j));
640− this.dAddOffset(w,0);
641− }
642− if(mi) BigInteger.ZERO.subTo(this,this);
643−}
644−
645−// (protected) alternate constructor
646−function bnpFromNumber(a,b,c) {
647− if("number" == typeof b) {
648− // new BigInteger(int,int,RNG)
649− if(a < 2) this.fromInt(1);
650− else {
651− this.fromNumber(a,c);
652− if(!this.testBit(a-1)) // force MSB set
653− this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
654− if(this.isEven()) this.dAddOffset(1,0); // force odd
655− while(!this.isProbablePrime(b)) {
656− this.dAddOffset(2,0);
657− if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
658 }
493 }
494+ x.clamp();
495+ x.drShiftTo(this.m.t,x);
496+ if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
659 }
497 }
660− }
498+
661− else {
499+ // r = "x^2/R mod m"; x != r
662− // new BigInteger(int,RNG)
500+ function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
663− var x = new Array(), t = a&7;
501+
664− x.length = (a>>3)+1;
502+ // r = "xy/R mod m"; x,y != r
665− b.nextBytes(x);
503+ function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
666− if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
504+
667− this.fromString(x,256);
505+ Montgomery.prototype.convert = montConvert;
668− }
506+ Montgomery.prototype.revert = montRevert;
669−}
507+ Montgomery.prototype.reduce = montReduce;
670−
508+ Montgomery.prototype.mulTo = montMulTo;
671−// (public) convert to bigendian byte array
509+ Montgomery.prototype.sqrTo = montSqrTo;
510+
511+ // (protected) true iff this is even
512+ function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
513+
514+ // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
515+ function bnpExp(e,z) {
516+ if(e > 0xffffffff || e < 1) return BigInteger.ONE;
517+ var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
518+ g.copyTo(r);
519+ while(--i >= 0) {
520+ z.sqrTo(r,r2);
521+ if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
522+ else { var t = r; r = r2; r2 = t; }
523+ }
524+ return z.revert(r);
525+ }
526+
527+ // (public) this^e % m, 0 <= e < 2^32
528+ function bnModPowInt(e,m) {
529+ var z;
530+ if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
531+ return this.exp(e,z);
532+ }
533+
534+ // protected
535+ BigInteger.prototype.copyTo = bnpCopyTo;
536+ BigInteger.prototype.fromInt = bnpFromInt;
537+ BigInteger.prototype.fromString = bnpFromString;
538+ BigInteger.prototype.clamp = bnpClamp;
539+ BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
540+ BigInteger.prototype.drShiftTo = bnpDRShiftTo;
541+ BigInteger.prototype.lShiftTo = bnpLShiftTo;
542+ BigInteger.prototype.rShiftTo = bnpRShiftTo;
543+ BigInteger.prototype.subTo = bnpSubTo;
544+ BigInteger.prototype.multiplyTo = bnpMultiplyTo;
545+ BigInteger.prototype.squareTo = bnpSquareTo;
546+ BigInteger.prototype.divRemTo = bnpDivRemTo;
547+ BigInteger.prototype.invDigit = bnpInvDigit;
548+ BigInteger.prototype.isEven = bnpIsEven;
549+ BigInteger.prototype.exp = bnpExp;
550+
551+ // public
552+ BigInteger.prototype.toString = bnToString;
553+ BigInteger.prototype.negate = bnNegate;
554+ BigInteger.prototype.abs = bnAbs;
555+ BigInteger.prototype.compareTo = bnCompareTo;
556+ BigInteger.prototype.bitLength = bnBitLength;
557+ BigInteger.prototype.mod = bnMod;
558+ BigInteger.prototype.modPowInt = bnModPowInt;
559+
560+ // "constants"
561+ BigInteger.ZERO = nbv(0);
562+ BigInteger.ONE = nbv(1);
563+
564+ // Copyright (c) 2005-2009 Tom Wu
565+ // All Rights Reserved.
566+ // See "LICENSE" for details.
567+
568+ // Extended JavaScript BN functions, required for RSA private ops.
569+
570+ // Version 1.1: new BigInteger("0", 10) returns "proper" zero
571+ // Version 1.2: square() API, isProbablePrime fix
572+
573+ // (public)
574+ function bnClone() { var r = nbi(); this.copyTo(r); return r; }
575+
576+ // (public) return value as integer
672−function bnToByteArray() {
577+ function bnIntValue() {
673− var i = this.t, r = new Array();
578+ if(this.s < 0) {
674− r[0] = this.s;
579+ if(this.t == 1) return this[0]-this.DV;
675− var p = this.DB-(i*this.DB)%8, d, k = 0;
580+ else if(this.t == 0) return -1;
676− if(i-- > 0) {
581+ }
582+ else if(this.t == 1) return this[0];
583+ else if(this.t == 0) return 0;
584+ // assumes 16 < DB < 32
677− if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
585+ return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
678− r[k++] = d|(this.s<<(this.DB-p));
586+ }
679− while(i >= 0) {
587+
680− if(p < 8) {
588+ // (public) return value as byte
681− d = (this[i]&((1<<p)-1))<<(8-p);
589+ function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
682− d |= this[--i]>>(p+=this.DB-8);
590+
591+ // (public) return value as short (assumes DB>=16)
592+ function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
593+
594+ // (protected) return x s.t. r^x < DV
595+ function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
596+
597+ // (public) 0 if this == 0, 1 if this > 0
598+ function bnSigNum() {
599+ if(this.s < 0) return -1;
600+ else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
601+ else return 1;
602+ }
603+
604+ // (protected) convert to radix string
605+ function bnpToRadix(b) {
606+ if(b == null) b = 10;
607+ if(this.signum() == 0 || b < 2 || b > 36) return "0";
608+ var cs = this.chunkSize(b);
609+ var a = Math.pow(b,cs);
610+ var d = nbv(a), y = nbi(), z = nbi(), r = "";
611+ this.divRemTo(d,y,z);
612+ while(y.signum() > 0) {
613+ r = (a+z.intValue()).toString(b).substr(1) + r;
614+ y.divRemTo(d,y,z);
615+ }
616+ return z.intValue().toString(b) + r;
617+ }
618+
619+ // (protected) convert from radix string
620+ function bnpFromRadix(s,b) {
621+ this.fromInt(0);
622+ if(b == null) b = 10;
623+ var cs = this.chunkSize(b);
624+ var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
625+ for(var i = 0; i < s.length; ++i) {
626+ var x = intAt(s,i);
627+ if(x < 0) {
628+ if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
629+ continue;
630+ }
631+ w = b*w+x;
632+ if(++j >= cs) {
633+ this.dMultiply(d);
634+ this.dAddOffset(w,0);
635+ j = 0;
636+ w = 0;
637+ }
638+ }
639+ if(j > 0) {
640+ this.dMultiply(Math.pow(b,j));
641+ this.dAddOffset(w,0);
642+ }
643+ if(mi) BigInteger.ZERO.subTo(this,this);
644+ }
645+
646+ // (protected) alternate constructor
647+ function bnpFromNumber(a,b,c) {
648+ if("number" == typeof b) {
649+ // new BigInteger(int,int,RNG)
650+ if(a < 2) this.fromInt(1);
651+ else {
652+ this.fromNumber(a,c);
653+ if(!this.testBit(a-1)) // force MSB set
654+ this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
655+ if(this.isEven()) this.dAddOffset(1,0); // force odd
656+ while(!this.isProbablePrime(b)) {
657+ this.dAddOffset(2,0);
658+ if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
659+ }
660+ }
683 }
661 }
684 else {
662 else {
685− d = (this[i]>>(p-=8))&0xff;
663+ // new BigInteger(int,RNG)
686− if(p <= 0) { p += this.DB; --i; }
664+ var x = new Array(), t = a&7;
665+ x.length = (a>>3)+1;
666+ b.nextBytes(x);
667+ if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
668+ this.fromString(x,256);
687 }
669 }
688− if((d&0x80) != 0) d |= -256;
670+ }
689− if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
671+
690− if(k > 0 || d != this.s) r[k++] = d;
672+ // (public) convert to bigendian byte array
691− }
673+ function bnToByteArray() {
692− }
674+ var i = this.t, r = new Array();
693− return r;
675+ r[0] = this.s;
694−}
676+ var p = this.DB-(i*this.DB)%8, d, k = 0;
695−
677+ if(i-- > 0) {
696−function bnEquals(a) { return(this.compareTo(a)==0); }
678+ if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
697−function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
679+ r[k++] = d|(this.s<<(this.DB-p));
698−function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
680+ while(i >= 0) {
699−
681+ if(p < 8) {
700−// (protected) r = this op a (bitwise)
682+ d = (this[i]&((1<<p)-1))<<(8-p);
701−function bnpBitwiseTo(a,op,r) {
683+ d |= this[--i]>>(p+=this.DB-8);
702− var i, f, m = Math.min(a.t,this.t);
684+ }
703− for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
685+ else {
704− if(a.t < this.t) {
686+ d = (this[i]>>(p-=8))&0xff;
705− f = a.s&this.DM;
687+ if(p <= 0) { p += this.DB; --i; }
706− for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
688+ }
707− r.t = this.t;
689+ if((d&0x80) != 0) d |= -256;
708− }
690+ if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
709− else {
691+ if(k > 0 || d != this.s) r[k++] = d;
710− f = this.s&this.DM;
692+ }
711− for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
712− r.t = a.t;
713− }
714− r.s = op(this.s,a.s);
715− r.clamp();
716−}
717−
718−// (public) this & a
719−function op_and(x,y) { return x&y; }
720−function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
721−
722−// (public) this | a
723−function op_or(x,y) { return x|y; }
724−function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
725−
726−// (public) this ^ a
727−function op_xor(x,y) { return x^y; }
728−function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
729−
730−// (public) this & ~a
731−function op_andnot(x,y) { return x&~y; }
732−function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
733−
734−// (public) ~this
735−function bnNot() {
736− var r = nbi();
737− for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
738− r.t = this.t;
739− r.s = ~this.s;
740− return r;
741−}
742−
743−// (public) this << n
744−function bnShiftLeft(n) {
745− var r = nbi();
746− if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
747− return r;
748−}
749−
750−// (public) this >> n
751−function bnShiftRight(n) {
752− var r = nbi();
753− if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
754− return r;
755−}
756−
757−// return index of lowest 1-bit in x, x < 2^31
758−function lbit(x) {
759− if(x == 0) return -1;
760− var r = 0;
761− if((x&0xffff) == 0) { x >>= 16; r += 16; }
762− if((x&0xff) == 0) { x >>= 8; r += 8; }
763− if((x&0xf) == 0) { x >>= 4; r += 4; }
764− if((x&3) == 0) { x >>= 2; r += 2; }
765− if((x&1) == 0) ++r;
766− return r;
767−}
768−
769−// (public) returns index of lowest 1-bit (or -1 if none)
770−function bnGetLowestSetBit() {
771− for(var i = 0; i < this.t; ++i)
772− if(this[i] != 0) return i*this.DB+lbit(this[i]);
773− if(this.s < 0) return this.t*this.DB;
774− return -1;
775−}
776−
777−// return number of 1 bits in x
778−function cbit(x) {
779− var r = 0;
780− while(x != 0) { x &= x-1; ++r; }
781− return r;
782−}
783−
784−// (public) return number of set bits
785−function bnBitCount() {
786− var r = 0, x = this.s&this.DM;
787− for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
788− return r;
789−}
790−
791−// (public) true iff nth bit is set
792−function bnTestBit(n) {
793− var j = Math.floor(n/this.DB);
794− if(j >= this.t) return(this.s!=0);
795− return((this[j]&(1<<(n%this.DB)))!=0);
796−}
797−
798−// (protected) this op (1<<n)
799−function bnpChangeBit(n,op) {
800− var r = BigInteger.ONE.shiftLeft(n);
801− this.bitwiseTo(r,op,r);
802− return r;
803−}
804−
805−// (public) this | (1<<n)
806−function bnSetBit(n) { return this.changeBit(n,op_or); }
807−
808−// (public) this & ~(1<<n)
809−function bnClearBit(n) { return this.changeBit(n,op_andnot); }
810−
811−// (public) this ^ (1<<n)
812−function bnFlipBit(n) { return this.changeBit(n,op_xor); }
813−
814−// (protected) r = this + a
815−function bnpAddTo(a,r) {
816− var i = 0, c = 0, m = Math.min(a.t,this.t);
817− while(i < m) {
818− c += this[i]+a[i];
819− r[i++] = c&this.DM;
820− c >>= this.DB;
821− }
822− if(a.t < this.t) {
823− c += a.s;
824− while(i < this.t) {
825− c += this[i];
826− r[i++] = c&this.DM;
827− c >>= this.DB;
828− }
829− c += this.s;
830− }
831− else {
832− c += this.s;
833− while(i < a.t) {
834− c += a[i];
835− r[i++] = c&this.DM;
836− c >>= this.DB;
837− }
838− c += a.s;
839− }
840− r.s = (c<0)?-1:0;
841− if(c > 0) r[i++] = c;
842− else if(c < -1) r[i++] = this.DV+c;
843− r.t = i;
844− r.clamp();
845−}
846−
847−// (public) this + a
848−function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
849−
850−// (public) this - a
851−function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
852−
853−// (public) this * a
854−function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
855−
856−// (public) this^2
857−function bnSquare() { var r = nbi(); this.squareTo(r); return r; }
858−
859−// (public) this / a
860−function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
861−
862−// (public) this % a
863−function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
864−
865−// (public) [this/a,this%a]
866−function bnDivideAndRemainder(a) {
867− var q = nbi(), r = nbi();
868− this.divRemTo(a,q,r);
869− return new Array(q,r);
870−}
871−
872−// (protected) this *= n, this >= 0, 1 < n < DV
873−function bnpDMultiply(n) {
874− this[this.t] = this.am(0,n-1,this,0,0,this.t);
875− ++this.t;
876− this.clamp();
877−}
878−
879−// (protected) this += n << w words, this >= 0
880−function bnpDAddOffset(n,w) {
881− if(n == 0) return;
882− while(this.t <= w) this[this.t++] = 0;
883− this[w] += n;
884− while(this[w] >= this.DV) {
885− this[w] -= this.DV;
886− if(++w >= this.t) this[this.t++] = 0;
887− ++this[w];
888− }
889−}
890−
891−// A "null" reducer
892−function NullExp() {}
893−function nNop(x) { return x; }
894−function nMulTo(x,y,r) { x.multiplyTo(y,r); }
895−function nSqrTo(x,r) { x.squareTo(r); }
896−
897−NullExp.prototype.convert = nNop;
898−NullExp.prototype.revert = nNop;
899−NullExp.prototype.mulTo = nMulTo;
900−NullExp.prototype.sqrTo = nSqrTo;
901−
902−// (public) this^e
903−function bnPow(e) { return this.exp(e,new NullExp()); }
904−
905−// (protected) r = lower n words of "this * a", a.t <= n
906−// "this" should be the larger one if appropriate.
907−function bnpMultiplyLowerTo(a,n,r) {
908− var i = Math.min(this.t+a.t,n);
909− r.s = 0; // assumes a,this >= 0
910− r.t = i;
911− while(i > 0) r[--i] = 0;
912− var j;
913− for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
914− for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
915− r.clamp();
916−}
917−
918−// (protected) r = "this * a" without lower n words, n > 0
919−// "this" should be the larger one if appropriate.
920−function bnpMultiplyUpperTo(a,n,r) {
921− --n;
922− var i = r.t = this.t+a.t-n;
923− r.s = 0; // assumes a,this >= 0
924− while(--i >= 0) r[i] = 0;
925− for(i = Math.max(n-this.t,0); i < a.t; ++i)
926− r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
927− r.clamp();
928− r.drShiftTo(1,r);
929−}
930−
931−// Barrett modular reduction
932−function Barrett(m) {
933− // setup Barrett
934− this.r2 = nbi();
935− this.q3 = nbi();
936− BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
937− this.mu = this.r2.divide(m);
938− this.m = m;
939−}
940−
941−function barrettConvert(x) {
942− if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
943− else if(x.compareTo(this.m) < 0) return x;
944− else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
945−}
946−
947−function barrettRevert(x) { return x; }
948−
949−// x = x mod m (HAC 14.42)
950−function barrettReduce(x) {
951− x.drShiftTo(this.m.t-1,this.r2);
952− if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
953− this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
954− this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
955− while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
956− x.subTo(this.r2,x);
957− while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
958−}
959−
960−// r = x^2 mod m; x != r
961−function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
962−
963−// r = x*y mod m; x,y != r
964−function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
965−
966−Barrett.prototype.convert = barrettConvert;
967−Barrett.prototype.revert = barrettRevert;
968−Barrett.prototype.reduce = barrettReduce;
969−Barrett.prototype.mulTo = barrettMulTo;
970−Barrett.prototype.sqrTo = barrettSqrTo;
971−
972−// (public) this^e % m (HAC 14.85)
973−function bnModPow(e,m) {
974− var i = e.bitLength(), k, r = nbv(1), z;
975− if(i <= 0) return r;
976− else if(i < 18) k = 1;
977− else if(i < 48) k = 3;
978− else if(i < 144) k = 4;
979− else if(i < 768) k = 5;
980− else k = 6;
981− if(i < 8)
982− z = new Classic(m);
983− else if(m.isEven())
984− z = new Barrett(m);
985− else
986− z = new Montgomery(m);
987−
988− // precomputation
989− var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
990− g[1] = z.convert(this);
991− if(k > 1) {
992− var g2 = nbi();
993− z.sqrTo(g[1],g2);
994− while(n <= km) {
995− g[n] = nbi();
996− z.mulTo(g2,g[n-2],g[n]);
997− n += 2;
998− }
999− }
1000−
1001− var j = e.t-1, w, is1 = true, r2 = nbi(), t;
1002− i = nbits(e[j])-1;
1003− while(j >= 0) {
1004− if(i >= k1) w = (e[j]>>(i-k1))&km;
1005− else {
1006− w = (e[j]&((1<<(i+1))-1))<<(k1-i);
1007− if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
1008− }
1009−
1010− n = k;
1011− while((w&1) == 0) { w >>= 1; --n; }
1012− if((i -= n) < 0) { i += this.DB; --j; }
1013− if(is1) { // ret == 1, don't bother squaring or multiplying it
1014− g[w].copyTo(r);
1015− is1 = false;
1016− }
1017− else {
1018− while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
1019− if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
1020− z.mulTo(r2,g[w],r);
1021− }
1022−
1023− while(j >= 0 && (e[j]&(1<<i)) == 0) {
1024− z.sqrTo(r,r2); t = r; r = r2; r2 = t;
1025− if(--i < 0) { i = this.DB-1; --j; }
1026− }
1027− }
1028− return z.revert(r);
1029−}
1030−
1031−// (public) gcd(this,a) (HAC 14.54)
1032−function bnGCD(a) {
1033− var x = (this.s<0)?this.negate():this.clone();
1034− var y = (a.s<0)?a.negate():a.clone();
1035− if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
1036− var i = x.getLowestSetBit(), g = y.getLowestSetBit();
1037− if(g < 0) return x;
1038− if(i < g) g = i;
1039− if(g > 0) {
1040− x.rShiftTo(g,x);
1041− y.rShiftTo(g,y);
1042− }
1043− while(x.signum() > 0) {
1044− if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
1045− if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
1046− if(x.compareTo(y) >= 0) {
1047− x.subTo(y,x);
1048− x.rShiftTo(1,x);
1049− }
1050− else {
1051− y.subTo(x,y);
1052− y.rShiftTo(1,y);
1053− }
1054− }
1055− if(g > 0) y.lShiftTo(g,y);
1056− return y;
1057−}
1058−
1059−// (protected) this % n, n < 2^26
1060−function bnpModInt(n) {
1061− if(n <= 0) return 0;
1062− var d = this.DV%n, r = (this.s<0)?n-1:0;
1063− if(this.t > 0)
1064− if(d == 0) r = this[0]%n;
1065− else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
1066− return r;
1067−}
1068−
1069−// (public) 1/this % m (HAC 14.61)
1070−function bnModInverse(m) {
1071− var ac = m.isEven();
1072− if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
1073− var u = m.clone(), v = this.clone();
1074− var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
1075− while(u.signum() != 0) {
1076− while(u.isEven()) {
1077− u.rShiftTo(1,u);
1078− if(ac) {
1079− if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
1080− a.rShiftTo(1,a);
1081 }
693 }
1082− else if(!b.isEven()) b.subTo(m,b);
694+ return r;
1083− b.rShiftTo(1,b);
695+ }
1084− }
696+
1085− while(v.isEven()) {
697+ function bnEquals(a) { return(this.compareTo(a)==0); }
1086− v.rShiftTo(1,v);
698+ function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
1087− if(ac) {
699+ function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
1088− if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
700+
1089− c.rShiftTo(1,c);
701+ // (protected) r = this op a (bitwise)
702+ function bnpBitwiseTo(a,op,r) {
703+ var i, f, m = Math.min(a.t,this.t);
704+ for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
705+ if(a.t < this.t) {
706+ f = a.s&this.DM;
707+ for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
708+ r.t = this.t;
1090 }
709 }
1091− else if(!d.isEven()) d.subTo(m,d);
710+ else {
1092− d.rShiftTo(1,d);
711+ f = this.s&this.DM;
1093− }
1094− if(u.compareTo(v) >= 0) {
1095− u.subTo(v,u);
1096− if(ac) a.subTo(c,a);
1097− b.subTo(d,b);
1098− }
1099− else {
1100− v.subTo(u,v);
1101− if(ac) c.subTo(a,c);
1102− d.subTo(b,d);
1103− }
1104− }
1105− if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
1106− if(d.compareTo(m) >= 0) return d.subtract(m);
1107− if(d.signum() < 0) d.addTo(m,d); else return d;
1108− if(d.signum() < 0) return d.add(m); else return d;
1109−}
1110−
1111−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,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];
1112−var lplim = (1<<26)/lowprimes[lowprimes.length-1];
1113−
1114−// (public) test primality with certainty >= 1-.5^t
1115−function bnIsProbablePrime(t) {
1116− var i, x = this.abs();
1117− if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
1118− for(i = 0; i < lowprimes.length; ++i)
1119− if(x[0] == lowprimes[i]) return true;
1120− return false;
1121− }
1122− if(x.isEven()) return false;
1123− i = 1;
1124− while(i < lowprimes.length) {
1125− var m = lowprimes[i], j = i+1;
1126− while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
1127− m = x.modInt(m);
1128− while(i < j) if(m%lowprimes[i++] == 0) return false;
1129− }
1130− return x.millerRabin(t);
1131−}
1132−
1133−// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
1134−function bnpMillerRabin(t) {
1135− var n1 = this.subtract(BigInteger.ONE);
1136− var k = n1.getLowestSetBit();
1137− if(k <= 0) return false;
1138− var r = n1.shiftRight(k);
1139− t = (t+1)>>1;
1140− if(t > lowprimes.length) t = lowprimes.length;
1141− var a = nbi();
1142− for(var i = 0; i < t; ++i) {
712+ for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
1143− //Pick bases at random, instead of starting at 2
713+ r.t = a.t;
1144− a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]);
1145− var y = a.modPow(r,this);
1146− if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
1147− var j = 1;
1148− while(j++ < k && y.compareTo(n1) != 0) {
1149− y = y.modPowInt(2,this);
1150− if(y.compareTo(BigInteger.ONE) == 0) return false;
1151 }
714 }
1152− if(y.compareTo(n1) != 0) return false;
715+ r.s = op(this.s,a.s);
1153− }
716+ r.clamp();
1154− }
717+ }
1155− return true;
718+
1156−}
719+ // (public) this & a
1157−
720+ function op_and(x,y) { return x&y; }
1158−// protected
721+ function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
1159−BigInteger.prototype.chunkSize = bnpChunkSize;
722+
1160−BigInteger.prototype.toRadix = bnpToRadix;
723+ // (public) this | a
1161−BigInteger.prototype.fromRadix = bnpFromRadix;
724+ function op_or(x,y) { return x|y; }
1162−BigInteger.prototype.fromNumber = bnpFromNumber;
725+ function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
1163−BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
726+
1164−BigInteger.prototype.changeBit = bnpChangeBit;
727+ // (public) this ^ a
1165−BigInteger.prototype.addTo = bnpAddTo;
728+ function op_xor(x,y) { return x^y; }
1166−BigInteger.prototype.dMultiply = bnpDMultiply;
729+ function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
1167−BigInteger.prototype.dAddOffset = bnpDAddOffset;
730+
1168−BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
731+ // (public) this & ~a
1169−BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
732+ function op_andnot(x,y) { return x&~y; }
1170−BigInteger.prototype.modInt = bnpModInt;
733+ function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
1171−BigInteger.prototype.millerRabin = bnpMillerRabin;
734+
1172−
735+ // (public) ~this
1173−// public
736+ function bnNot() {
1174−BigInteger.prototype.clone = bnClone;
737+ var r = nbi();
1175−BigInteger.prototype.intValue = bnIntValue;
738+ for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
1176−BigInteger.prototype.byteValue = bnByteValue;
739+ r.t = this.t;
1177−BigInteger.prototype.shortValue = bnShortValue;
740+ r.s = ~this.s;
1178−BigInteger.prototype.signum = bnSigNum;
741+ return r;
1179−BigInteger.prototype.toByteArray = bnToByteArray;
742+ }
1180−BigInteger.prototype.equals = bnEquals;
743+
1181−BigInteger.prototype.min = bnMin;
744+ // (public) this << n
1182−BigInteger.prototype.max = bnMax;
745+ function bnShiftLeft(n) {
1183−BigInteger.prototype.and = bnAnd;
746+ var r = nbi();
1184−BigInteger.prototype.or = bnOr;
747+ if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
1185−BigInteger.prototype.xor = bnXor;
748+ return r;
1186−BigInteger.prototype.andNot = bnAndNot;
749+ }
1187−BigInteger.prototype.not = bnNot;
750+
1188−BigInteger.prototype.shiftLeft = bnShiftLeft;
751+ // (public) this >> n
1189−BigInteger.prototype.shiftRight = bnShiftRight;
752+ function bnShiftRight(n) {
1190−BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
753+ var r = nbi();
1191−BigInteger.prototype.bitCount = bnBitCount;
754+ if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
1192−BigInteger.prototype.testBit = bnTestBit;
755+ return r;
1193−BigInteger.prototype.setBit = bnSetBit;
756+ }
1194−BigInteger.prototype.clearBit = bnClearBit;
757+
1195−BigInteger.prototype.flipBit = bnFlipBit;
758+ // return index of lowest 1-bit in x, x < 2^31
1196−BigInteger.prototype.add = bnAdd;
759+ function lbit(x) {
1197−BigInteger.prototype.subtract = bnSubtract;
760+ if(x == 0) return -1;
1198−BigInteger.prototype.multiply = bnMultiply;
761+ var r = 0;
1199−BigInteger.prototype.divide = bnDivide;
762+ if((x&0xffff) == 0) { x >>= 16; r += 16; }
1200−BigInteger.prototype.remainder = bnRemainder;
763+ if((x&0xff) == 0) { x >>= 8; r += 8; }
1201−BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
764+ if((x&0xf) == 0) { x >>= 4; r += 4; }
1202−BigInteger.prototype.modPow = bnModPow;
765+ if((x&3) == 0) { x >>= 2; r += 2; }
1203−BigInteger.prototype.modInverse = bnModInverse;
766+ if((x&1) == 0) ++r;
1204−BigInteger.prototype.pow = bnPow;
767+ return r;
1205−BigInteger.prototype.gcd = bnGCD;
768+ }
1206−BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
769+
1207−
770+ // (public) returns index of lowest 1-bit (or -1 if none)
1208−// JSBN-specific extension
771+ function bnGetLowestSetBit() {
1209−BigInteger.prototype.square = bnSquare;
772+ for(var i = 0; i < this.t; ++i)
1210−
773+ if(this[i] != 0) return i*this.DB+lbit(this[i]);
1211−// BigInteger interfaces not implemented in jsbn:
774+ if(this.s < 0) return this.t*this.DB;
1212−
775+ return -1;
1213−// BigInteger(int signum, byte[] magnitude)
776+ }
1214−// double doubleValue()
777+
1215−// float floatValue()
778+ // return number of 1 bits in x
1216−// int hashCode()
779+ function cbit(x) {
1217−// long longValue()
780+ var r = 0;
1218−//
781+ while(x != 0) { x &= x-1; ++r; }
1219−BigInteger.prototype.lesser = function(rhs) {
782+ return r;
1220− return this.compareTo(rhs) < 0
783+ }
1221−}
784+
1222−BigInteger.prototype.lesserOrEquals = function(rhs) {
785+ // (public) return number of set bits
1223− return this.compareTo(rhs) <= 0
786+ function bnBitCount() {
1224−}
787+ var r = 0, x = this.s&this.DM;
1225−BigInteger.prototype.greater = function(rhs) {
788+ for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
1226− return this.compareTo(rhs) > 0
789+ return r;
1227−}
790+ }
1228−BigInteger.prototype.greaterOrEquals = function(rhs) {
791+
1229− return this.compareTo(rhs) >= 0
792+ // (public) true iff nth bit is set
1230−}
793+ function bnTestBit(n) {
1231−
794+ var j = Math.floor(n/this.DB);
1232−return function(val) {
795+ if(j >= this.t) return(this.s!=0);
1233− return new BigInteger(val);
796+ return((this[j]&(1<<(n%this.DB)))!=0);
1234−}
797+ }
1235−})();
798+
1236−
799+ // (protected) this op (1<<n)
1237−var i$ZERO = i$bigInt("0");
800+ function bnpChangeBit(n,op) {
1238−var i$ONE = i$bigInt("1");
801+ var r = BigInteger.ONE.shiftLeft(n);
802+ this.bitwiseTo(r,op,r);
803+ return r;
804+ }
805+
806+ // (public) this | (1<<n)
807+ function bnSetBit(n) { return this.changeBit(n,op_or); }
808+
809+ // (public) this & ~(1<<n)
810+ function bnClearBit(n) { return this.changeBit(n,op_andnot); }
811+
812+ // (public) this ^ (1<<n)
813+ function bnFlipBit(n) { return this.changeBit(n,op_xor); }
814+
815+ // (protected) r = this + a
816+ function bnpAddTo(a,r) {
817+ var i = 0, c = 0, m = Math.min(a.t,this.t);
818+ while(i < m) {
819+ c += this[i]+a[i];
820+ r[i++] = c&this.DM;
821+ c >>= this.DB;
822+ }
823+ if(a.t < this.t) {
824+ c += a.s;
825+ while(i < this.t) {
826+ c += this[i];
827+ r[i++] = c&this.DM;
828+ c >>= this.DB;
829+ }
830+ c += this.s;
831+ }
832+ else {
833+ c += this.s;
834+ while(i < a.t) {
835+ c += a[i];
836+ r[i++] = c&this.DM;
837+ c >>= this.DB;
838+ }
839+ c += a.s;
840+ }
841+ r.s = (c<0)?-1:0;
842+ if(c > 0) r[i++] = c;
843+ else if(c < -1) r[i++] = this.DV+c;
844+ r.t = i;
845+ r.clamp();
846+ }
847+
848+ // (public) this + a
849+ function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
850+
851+ // (public) this - a
852+ function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
853+
854+ // (public) this * a
855+ function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
856+
857+ // (public) this^2
858+ function bnSquare() { var r = nbi(); this.squareTo(r); return r; }
859+
860+ // (public) this / a
861+ function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
862+
863+ // (public) this % a
864+ function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
865+
866+ // (public) [this/a,this%a]
867+ function bnDivideAndRemainder(a) {
868+ var q = nbi(), r = nbi();
869+ this.divRemTo(a,q,r);
870+ return new Array(q,r);
871+ }
872+
873+ // (protected) this *= n, this >= 0, 1 < n < DV
874+ function bnpDMultiply(n) {
875+ this[this.t] = this.am(0,n-1,this,0,0,this.t);
876+ ++this.t;
877+ this.clamp();
878+ }
879+
880+ // (protected) this += n << w words, this >= 0
881+ function bnpDAddOffset(n,w) {
882+ if(n == 0) return;
883+ while(this.t <= w) this[this.t++] = 0;
884+ this[w] += n;
885+ while(this[w] >= this.DV) {
886+ this[w] -= this.DV;
887+ if(++w >= this.t) this[this.t++] = 0;
888+ ++this[w];
889+ }
890+ }
891+
892+ // A "null" reducer
893+ function NullExp() {}
894+ function nNop(x) { return x; }
895+ function nMulTo(x,y,r) { x.multiplyTo(y,r); }
896+ function nSqrTo(x,r) { x.squareTo(r); }
897+
898+ NullExp.prototype.convert = nNop;
899+ NullExp.prototype.revert = nNop;
900+ NullExp.prototype.mulTo = nMulTo;
901+ NullExp.prototype.sqrTo = nSqrTo;
902+
903+ // (public) this^e
904+ function bnPow(e) { return this.exp(e,new NullExp()); }
905+
906+ // (protected) r = lower n words of "this * a", a.t <= n
907+ // "this" should be the larger one if appropriate.
908+ function bnpMultiplyLowerTo(a,n,r) {
909+ var i = Math.min(this.t+a.t,n);
910+ r.s = 0; // assumes a,this >= 0
911+ r.t = i;
912+ while(i > 0) r[--i] = 0;
913+ var j;
914+ for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
915+ for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
916+ r.clamp();
917+ }
918+
919+ // (protected) r = "this * a" without lower n words, n > 0
920+ // "this" should be the larger one if appropriate.
921+ function bnpMultiplyUpperTo(a,n,r) {
922+ --n;
923+ var i = r.t = this.t+a.t-n;
924+ r.s = 0; // assumes a,this >= 0
925+ while(--i >= 0) r[i] = 0;
926+ for(i = Math.max(n-this.t,0); i < a.t; ++i)
927+ r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
928+ r.clamp();
929+ r.drShiftTo(1,r);
930+ }
931+
932+ // Barrett modular reduction
933+ function Barrett(m) {
934+ // setup Barrett
935+ this.r2 = nbi();
936+ this.q3 = nbi();
937+ BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
938+ this.mu = this.r2.divide(m);
939+ this.m = m;
940+ }
941+
942+ function barrettConvert(x) {
943+ if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
944+ else if(x.compareTo(this.m) < 0) return x;
945+ else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
946+ }
947+
948+ function barrettRevert(x) { return x; }
949+
950+ // x = x mod m (HAC 14.42)
951+ function barrettReduce(x) {
952+ x.drShiftTo(this.m.t-1,this.r2);
953+ if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
954+ this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
955+ this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
956+ while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
957+ x.subTo(this.r2,x);
958+ while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
959+ }
960+
961+ // r = x^2 mod m; x != r
962+ function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
963+
964+ // r = x*y mod m; x,y != r
965+ function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
966+
967+ Barrett.prototype.convert = barrettConvert;
968+ Barrett.prototype.revert = barrettRevert;
969+ Barrett.prototype.reduce = barrettReduce;
970+ Barrett.prototype.mulTo = barrettMulTo;
971+ Barrett.prototype.sqrTo = barrettSqrTo;
972+
973+ // (public) this^e % m (HAC 14.85)
974+ function bnModPow(e,m) {
975+ var i = e.bitLength(), k, r = nbv(1), z;
976+ if(i <= 0) return r;
977+ else if(i < 18) k = 1;
978+ else if(i < 48) k = 3;
979+ else if(i < 144) k = 4;
980+ else if(i < 768) k = 5;
981+ else k = 6;
982+ if(i < 8)
983+ z = new Classic(m);
984+ else if(m.isEven())
985+ z = new Barrett(m);
986+ else
987+ z = new Montgomery(m);
988+
989+ // precomputation
990+ var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
991+ g[1] = z.convert(this);
992+ if(k > 1) {
993+ var g2 = nbi();
994+ z.sqrTo(g[1],g2);
995+ while(n <= km) {
996+ g[n] = nbi();
997+ z.mulTo(g2,g[n-2],g[n]);
998+ n += 2;
999+ }
1000+ }
1001+
1002+ var j = e.t-1, w, is1 = true, r2 = nbi(), t;
1003+ i = nbits(e[j])-1;
1004+ while(j >= 0) {
1005+ if(i >= k1) w = (e[j]>>(i-k1))&km;
1006+ else {
1007+ w = (e[j]&((1<<(i+1))-1))<<(k1-i);
1008+ if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
1009+ }
1010+
1011+ n = k;
1012+ while((w&1) == 0) { w >>= 1; --n; }
1013+ if((i -= n) < 0) { i += this.DB; --j; }
1014+ if(is1) { // ret == 1, don't bother squaring or multiplying it
1015+ g[w].copyTo(r);
1016+ is1 = false;
1017+ }
1018+ else {
1019+ while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
1020+ if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
1021+ z.mulTo(r2,g[w],r);
1022+ }
1023+
1024+ while(j >= 0 && (e[j]&(1<<i)) == 0) {
1025+ z.sqrTo(r,r2); t = r; r = r2; r2 = t;
1026+ if(--i < 0) { i = this.DB-1; --j; }
1027+ }
1028+ }
1029+ return z.revert(r);
1030+ }
1031+
1032+ // (public) gcd(this,a) (HAC 14.54)
1033+ function bnGCD(a) {
1034+ var x = (this.s<0)?this.negate():this.clone();
1035+ var y = (a.s<0)?a.negate():a.clone();
1036+ if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
1037+ var i = x.getLowestSetBit(), g = y.getLowestSetBit();
1038+ if(g < 0) return x;
1039+ if(i < g) g = i;
1040+ if(g > 0) {
1041+ x.rShiftTo(g,x);
1042+ y.rShiftTo(g,y);
1043+ }
1044+ while(x.signum() > 0) {
1045+ if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
1046+ if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
1047+ if(x.compareTo(y) >= 0) {
1048+ x.subTo(y,x);
1049+ x.rShiftTo(1,x);
1050+ }
1051+ else {
1052+ y.subTo(x,y);
1053+ y.rShiftTo(1,y);
1054+ }
1055+ }
1056+ if(g > 0) y.lShiftTo(g,y);
1057+ return y;
1058+ }
1059+
1060+ // (protected) this % n, n < 2^26
1061+ function bnpModInt(n) {
1062+ if(n <= 0) return 0;
1063+ var d = this.DV%n, r = (this.s<0)?n-1:0;
1064+ if(this.t > 0)
1065+ if(d == 0) r = this[0]%n;
1066+ else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
1067+ return r;
1068+ }
1069+
1070+ // (public) 1/this % m (HAC 14.61)
1071+ function bnModInverse(m) {
1072+ var ac = m.isEven();
1073+ if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
1074+ var u = m.clone(), v = this.clone();
1075+ var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
1076+ while(u.signum() != 0) {
1077+ while(u.isEven()) {
1078+ u.rShiftTo(1,u);
1079+ if(ac) {
1080+ if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
1081+ a.rShiftTo(1,a);
1082+ }
1083+ else if(!b.isEven()) b.subTo(m,b);
1084+ b.rShiftTo(1,b);
1085+ }
1086+ while(v.isEven()) {
1087+ v.rShiftTo(1,v);
1088+ if(ac) {
1089+ if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
1090+ c.rShiftTo(1,c);
1091+ }
1092+ else if(!d.isEven()) d.subTo(m,d);
1093+ d.rShiftTo(1,d);
1094+ }
1095+ if(u.compareTo(v) >= 0) {
1096+ u.subTo(v,u);
1097+ if(ac) a.subTo(c,a);
1098+ b.subTo(d,b);
1099+ }
1100+ else {
1101+ v.subTo(u,v);
1102+ if(ac) c.subTo(a,c);
1103+ d.subTo(b,d);
1104+ }
1105+ }
1106+ if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
1107+ if(d.compareTo(m) >= 0) return d.subtract(m);
1108+ if(d.signum() < 0) d.addTo(m,d); else return d;
1109+ if(d.signum() < 0) return d.add(m); else return d;
1110+ }
1111+
1112+ 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,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];
1113+ var lplim = (1<<26)/lowprimes[lowprimes.length-1];
1114+
1115+ // (public) test primality with certainty >= 1-.5^t
1116+ function bnIsProbablePrime(t) {
1117+ var i, x = this.abs();
1118+ if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
1119+ for(i = 0; i < lowprimes.length; ++i)
1120+ if(x[0] == lowprimes[i]) return true;
1121+ return false;
1122+ }
1123+ if(x.isEven()) return false;
1124+ i = 1;
1125+ while(i < lowprimes.length) {
1126+ var m = lowprimes[i], j = i+1;
1127+ while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
1128+ m = x.modInt(m);
1129+ while(i < j) if(m%lowprimes[i++] == 0) return false;
1130+ }
1131+ return x.millerRabin(t);
1132+ }
1133+
1134+ // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
1135+ function bnpMillerRabin(t) {
1136+ var n1 = this.subtract(BigInteger.ONE);
1137+ var k = n1.getLowestSetBit();
1138+ if(k <= 0) return false;
1139+ var r = n1.shiftRight(k);
1140+ t = (t+1)>>1;
1141+ if(t > lowprimes.length) t = lowprimes.length;
1142+ var a = nbi();
1143+ for(var i = 0; i < t; ++i) {
1144+ //Pick bases at random, instead of starting at 2
1145+ a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]);
1146+ var y = a.modPow(r,this);
1147+ if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
1148+ var j = 1;
1149+ while(j++ < k && y.compareTo(n1) != 0) {
1150+ y = y.modPowInt(2,this);
1151+ if(y.compareTo(BigInteger.ONE) == 0) return false;
1152+ }
1153+ if(y.compareTo(n1) != 0) return false;
1154+ }
1155+ }
1156+ return true;
1157+ }
1158+
1159+ // protected
1160+ BigInteger.prototype.chunkSize = bnpChunkSize;
1161+ BigInteger.prototype.toRadix = bnpToRadix;
1162+ BigInteger.prototype.fromRadix = bnpFromRadix;
1163+ BigInteger.prototype.fromNumber = bnpFromNumber;
1164+ BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
1165+ BigInteger.prototype.changeBit = bnpChangeBit;
1166+ BigInteger.prototype.addTo = bnpAddTo;
1167+ BigInteger.prototype.dMultiply = bnpDMultiply;
1168+ BigInteger.prototype.dAddOffset = bnpDAddOffset;
1169+ BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
1170+ BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
1171+ BigInteger.prototype.modInt = bnpModInt;
1172+ BigInteger.prototype.millerRabin = bnpMillerRabin;
1173+
1174+ // public
1175+ BigInteger.prototype.clone = bnClone;
1176+ BigInteger.prototype.intValue = bnIntValue;
1177+ BigInteger.prototype.byteValue = bnByteValue;
1178+ BigInteger.prototype.shortValue = bnShortValue;
1179+ BigInteger.prototype.signum = bnSigNum;
1180+ BigInteger.prototype.toByteArray = bnToByteArray;
1181+ BigInteger.prototype.equals = bnEquals;
1182+ BigInteger.prototype.min = bnMin;
1183+ BigInteger.prototype.max = bnMax;
1184+ BigInteger.prototype.and = bnAnd;
1185+ BigInteger.prototype.or = bnOr;
1186+ BigInteger.prototype.xor = bnXor;
1187+ BigInteger.prototype.andNot = bnAndNot;
1188+ BigInteger.prototype.not = bnNot;
1189+ BigInteger.prototype.shiftLeft = bnShiftLeft;
1190+ BigInteger.prototype.shiftRight = bnShiftRight;
1191+ BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
1192+ BigInteger.prototype.bitCount = bnBitCount;
1193+ BigInteger.prototype.testBit = bnTestBit;
1194+ BigInteger.prototype.setBit = bnSetBit;
1195+ BigInteger.prototype.clearBit = bnClearBit;
1196+ BigInteger.prototype.flipBit = bnFlipBit;
1197+ BigInteger.prototype.add = bnAdd;
1198+ BigInteger.prototype.subtract = bnSubtract;
1199+ BigInteger.prototype.multiply = bnMultiply;
1200+ BigInteger.prototype.divide = bnDivide;
1201+ BigInteger.prototype.remainder = bnRemainder;
1202+ BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
1203+ BigInteger.prototype.modPow = bnModPow;
1204+ BigInteger.prototype.modInverse = bnModInverse;
1205+ BigInteger.prototype.pow = bnPow;
1206+ BigInteger.prototype.gcd = bnGCD;
1207+ BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
1208+
1209+ // JSBN-specific extension
1210+ BigInteger.prototype.square = bnSquare;
1211+
1212+ // Expose the Barrett function
1213+ BigInteger.prototype.Barrett = Barrett
1214+
1215+ // BigInteger interfaces not implemented in jsbn:
1216+
1217+ // BigInteger(int signum, byte[] magnitude)
1218+ // double doubleValue()
1219+ // float floatValue()
1220+ // int hashCode()
1221+ // long longValue()
1222+ // static BigInteger valueOf(long val)
1223+
1224+ // Random number generator - requires a PRNG backend, e.g. prng4.js
1225+
1226+ // For best results, put code like
1227+ // <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
1228+ // in your main HTML document.
1229+
1230+ var rng_state;
1231+ var rng_pool;
1232+ var rng_pptr;
1233+
1234+ // Mix in a 32-bit integer into the pool
1235+ function rng_seed_int(x) {
1236+ rng_pool[rng_pptr++] ^= x & 255;
1237+ rng_pool[rng_pptr++] ^= (x >> 8) & 255;
1238+ rng_pool[rng_pptr++] ^= (x >> 16) & 255;
1239+ rng_pool[rng_pptr++] ^= (x >> 24) & 255;
1240+ if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
1241+ }
1242+
1243+ // Mix in the current time (w/milliseconds) into the pool
1244+ function rng_seed_time() {
1245+ rng_seed_int(new Date().getTime());
1246+ }
1247+
1248+ // Initialize the pool with junk if needed.
1249+ if(rng_pool == null) {
1250+ rng_pool = new Array();
1251+ rng_pptr = 0;
1252+ var t;
1253+ if(typeof window !== "undefined" && window.crypto) {
1254+ if (window.crypto.getRandomValues) {
1255+ // Use webcrypto if available
1256+ var ua = new Uint8Array(32);
1257+ window.crypto.getRandomValues(ua);
1258+ for(t = 0; t < 32; ++t)
1259+ rng_pool[rng_pptr++] = ua[t];
1260+ }
1261+ else if(navigator.appName == "Netscape" && navigator.appVersion < "5") {
1262+ // Extract entropy (256 bits) from NS4 RNG if available
1263+ var z = window.crypto.random(32);
1264+ for(t = 0; t < z.length; ++t)
1265+ rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
1266+ }
1267+ }
1268+ while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
1269+ t = Math.floor(65536 * Math.random());
1270+ rng_pool[rng_pptr++] = t >>> 8;
1271+ rng_pool[rng_pptr++] = t & 255;
1272+ }
1273+ rng_pptr = 0;
1274+ rng_seed_time();
1275+ //rng_seed_int(window.screenX);
1276+ //rng_seed_int(window.screenY);
1277+ }
1278+
1279+ function rng_get_byte() {
1280+ if(rng_state == null) {
1281+ rng_seed_time();
1282+ rng_state = prng_newstate();
1283+ rng_state.init(rng_pool);
1284+ for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
1285+ rng_pool[rng_pptr] = 0;
1286+ rng_pptr = 0;
1287+ //rng_pool = null;
1288+ }
1289+ // TODO: allow reseeding after first request
1290+ return rng_state.next();
1291+ }
1292+
1293+ function rng_get_bytes(ba) {
1294+ var i;
1295+ for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
1296+ }
1297+
1298+ function SecureRandom() {}
1299+
1300+ SecureRandom.prototype.nextBytes = rng_get_bytes;
1301+
1302+ // prng4.js - uses Arcfour as a PRNG
1303+
1304+ function Arcfour() {
1305+ this.i = 0;
1306+ this.j = 0;
1307+ this.S = new Array();
1308+ }
1309+
1310+ // Initialize arcfour context from key, an array of ints, each from [0..255]
1311+ function ARC4init(key) {
1312+ var i, j, t;
1313+ for(i = 0; i < 256; ++i)
1314+ this.S[i] = i;
1315+ j = 0;
1316+ for(i = 0; i < 256; ++i) {
1317+ j = (j + this.S[i] + key[i % key.length]) & 255;
1318+ t = this.S[i];
1319+ this.S[i] = this.S[j];
1320+ this.S[j] = t;
1321+ }
1322+ this.i = 0;
1323+ this.j = 0;
1324+ }
1325+
1326+ function ARC4next() {
1327+ var t;
1328+ this.i = (this.i + 1) & 255;
1329+ this.j = (this.j + this.S[this.i]) & 255;
1330+ t = this.S[this.i];
1331+ this.S[this.i] = this.S[this.j];
1332+ this.S[this.j] = t;
1333+ return this.S[(t + this.S[this.i]) & 255];
1334+ }
1335+
1336+ Arcfour.prototype.init = ARC4init;
1337+ Arcfour.prototype.next = ARC4next;
1338+
1339+ // Plug in your RNG constructor here
1340+ function prng_newstate() {
1341+ return new Arcfour();
1342+ }
1343+
1344+ // Pool size must be a multiple of 4 and greater than 32.
1345+ // An array of bytes the size of the pool will be passed to init()
1346+ var rng_psize = 256;
1347+
1348+ return {
1349+ BigInteger: BigInteger,
1350+ SecureRandom: SecureRandom
1351+ };
1352+
1353+}).call(this);
src/IRTS/JavaScript/AST.hs+42−12
@@ -5,7 +5,7 @@ Copyright :
5License : BSD3
5License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8−{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}
8+{-# LANGUAGE DeriveDataTypeable, OverloadedStrings, PatternGuards #-}
9
9
10module IRTS.JavaScript.AST( JsAST(..)
10module IRTS.JavaScript.AST( JsAST(..)
11 , jsAst2Text
11 , jsAst2Text
@@ -15,13 +15,14 @@ module IRTS.JavaScript.AST( JsAST(..)
15import Data.Text (Text)
15import Data.Text (Text)
16import qualified Data.Text as T
16import qualified Data.Text as T
17import Data.Data
17import Data.Data
18+import Data.Char
19+import Numeric
18
20
19data JsAST = JsEmpty
21data JsAST = JsEmpty
20 | JsNull
22 | JsNull
21 | JsLambda [Text] JsAST
23 | JsLambda [Text] JsAST
22 | JsCurryLambda [Text] JsAST
24 | JsCurryLambda [Text] JsAST
23 | JsFun Text [Text] JsAST
25 | JsFun Text [Text] JsAST
24−-- | JsCurryFun Text [Text] JsAST
25 | JsReturn JsAST
26 | JsReturn JsAST
26 | JsApp Text [JsAST]
27 | JsApp Text [JsAST]
27 | JsCurryApp JsAST [JsAST]
28 | JsCurryApp JsAST [JsAST]
@@ -30,20 +31,18 @@ data JsAST = JsEmpty
30 | JsSeq JsAST JsAST
31 | JsSeq JsAST JsAST
31 | JsConst Text JsAST
32 | JsConst Text JsAST
32 | JsLet Text JsAST
33 | JsLet Text JsAST
33− -- | JsLetList [(Text, JsAST)]
34 | JsSetVar Text JsAST
34 | JsSetVar Text JsAST
35 | JsArrayProj JsAST JsAST
35 | JsArrayProj JsAST JsAST
36+ | JsNum Double
36 | JsInt Int
37 | JsInt Int
37− | JsInteger Integer
38− | JsDouble Double
39− | JsStr Text
38+ | JsStr String
40 | JsArray [JsAST]
39 | JsArray [JsAST]
41 | JsSwitchCase JsAST [(JsAST, JsAST)] (Maybe JsAST)
40 | JsSwitchCase JsAST [(JsAST, JsAST)] (Maybe JsAST)
42 | JsError JsAST
41 | JsError JsAST
43 | JsErrorExp JsAST
42 | JsErrorExp JsAST
44 | JsBinOp Text JsAST JsAST
43 | JsBinOp Text JsAST JsAST
45 | JsForeign Text [JsAST]
44 | JsForeign Text [JsAST]
46− | JsB2I JsAST
45+ -- | JsB2I JsAST
47 | JsWhileTrue JsAST
46 | JsWhileTrue JsAST
48 -- | JsFor (JsAST, JsAST, JsAST) JsAST
47 -- | JsFor (JsAST, JsAST, JsAST) JsAST
49 | JsContinue
48 | JsContinue
@@ -55,6 +54,37 @@ data JsAST = JsEmpty
55 deriving (Show, Eq, Data, Typeable)
54 deriving (Show, Eq, Data, Typeable)
56
55
57
56
57+translateChar :: Char -> String
58+translateChar ch
59+ | '\a' <- ch = "\\u0007"
60+ | '\b' <- ch = "\\b"
61+ | '\f' <- ch = "\\f"
62+ | '\n' <- ch = "\\n"
63+ | '\r' <- ch = "\\r"
64+ | '\t' <- ch = "\\t"
65+ | '\v' <- ch = "\\v"
66+ | '\SO' <- ch = "\\u000E"
67+ | '\DEL' <- ch = "\\u007F"
68+ | '\\' <- ch = "\\\\"
69+ | '\"' <- ch = "\\\""
70+ | '\'' <- ch = "\\\'"
71+ | ch `elem` asciiTab = "\\u" ++ fill (showHex (ord ch) "")
72+ | ord ch > 255 = "\\u" ++ fill (showHex (ord ch) "")
73+ | otherwise = [ch]
74+ where
75+ fill :: String -> String
76+ fill s = case length s of
77+ 1 -> "000" ++ s
78+ 2 -> "00" ++ s
79+ 3 -> "0" ++ s
80+ _ -> s
81+
82+ asciiTab =
83+ ['\NUL', '\SOH', '\STX', '\ETX', '\EOT', '\ENQ', '\ACK', '\BEL',
84+ '\BS', '\HT', '\LF', '\VT', '\FF', '\CR', '\SO', '\SI',
85+ '\DLE', '\DC1', '\DC2', '\DC3', '\DC4', '\NAK', '\SYN', '\ETB',
86+ '\CAN', '\EM', '\SUB', '\ESC', '\FS', '\GS', '\RS', '\US']
87+
58indent :: Text -> Text
88indent :: Text -> Text
59indent x =
89indent x =
60 let l = T.lines x
90 let l = T.lines x
@@ -113,10 +143,10 @@ jsAst2Text (JsLet name exp) = T.concat [ "let ", name, " = ", jsAst2Text exp]
113--jsAst2Text (JsLetList lst) = T.concat [ "let ", T.intercalate ", " (map (\(n,v) -> T.concat [n, " = ", jsAst2Text v] ) lst) ]
143--jsAst2Text (JsLetList lst) = T.concat [ "let ", T.intercalate ", " (map (\(n,v) -> T.concat [n, " = ", jsAst2Text v] ) lst) ]
114jsAst2Text (JsSetVar name exp) = T.concat [ name, " = ", jsAst2Text exp]
144jsAst2Text (JsSetVar name exp) = T.concat [ name, " = ", jsAst2Text exp]
115jsAst2Text (JsArrayProj i exp) = T.concat [ jsAst2Text exp, "[", jsAst2Text i, "]"]
145jsAst2Text (JsArrayProj i exp) = T.concat [ jsAst2Text exp, "[", jsAst2Text i, "]"]
116−jsAst2Text (JsInt i) = T.pack $ show i
146+jsAst2Text (JsInt i) = T.pack $ show i ++ "|0"
117−jsAst2Text (JsDouble d) = T.pack $ show d
147+jsAst2Text (JsNum d) = T.pack $ show d
118−jsAst2Text (JsInteger i) = T.pack $ show i
148+--jsAst2Text (JsInteger i) = T.pack $ show i
119−jsAst2Text (JsStr s) = T.pack $ show s
149+jsAst2Text (JsStr s) = "\"" `T.append` T.pack (concatMap translateChar s) `T.append` "\""
120jsAst2Text (JsArray l) = T.concat [ "[", T.intercalate ", " (map jsAst2Text l), "]"]
150jsAst2Text (JsArray l) = T.concat [ "[", T.intercalate ", " (map jsAst2Text l), "]"]
121jsAst2Text (JsSwitchCase exp l d) =
151jsAst2Text (JsSwitchCase exp l d) =
122 T.concat [ "switch(", jsAst2Text exp, "){\n"
152 T.concat [ "switch(", jsAst2Text exp, "){\n"
@@ -134,7 +164,7 @@ jsAst2Text (JsForeign code args) =
134 let args_repl c i [] = c
164 let args_repl c i [] = c
135 args_repl c i (t:r) = args_repl (T.replace ("%" `T.append` T.pack (show i)) t c) (i+1) r
165 args_repl c i (t:r) = args_repl (T.replace ("%" `T.append` T.pack (show i)) t c) (i+1) r
136 in T.concat ["(", args_repl code 0 (map jsAst2Text args), ")"]
166 in T.concat ["(", args_repl code 0 (map jsAst2Text args), ")"]
137−jsAst2Text (JsB2I x) = jsAst2Text $ JsBinOp "+" x (JsInt 0)
167+--jsAst2Text (JsB2I x) = jsAst2Text $ JsBinOp "+" x (JsNum 0)
138jsAst2Text (JsWhileTrue w) =
168jsAst2Text (JsWhileTrue w) =
139 T.concat [ "while(true){\n"
169 T.concat [ "while(true){\n"
140 , indent $ jsAst2Text w
170 , indent $ jsAst2Text w
src/IRTS/JavaScript/Codegen.hs+108−45
@@ -17,22 +17,21 @@ import IRTS.CodegenCommon
17import IRTS.Lang
17import IRTS.Lang
18import Idris.Core.TT
18import Idris.Core.TT
19import IRTS.LangOpts
19import IRTS.LangOpts
20−
21import IRTS.JavaScript.AST
20import IRTS.JavaScript.AST
22import IRTS.JavaScript.LangTransforms
21import IRTS.JavaScript.LangTransforms
22+import IRTS.System
23
23
24import Data.Maybe (fromJust)
24import Data.Maybe (fromJust)
25import Data.Text (Text)
25import Data.Text (Text)
26import qualified Data.Text as T
26import qualified Data.Text as T
27import qualified Data.Text.IO as TIO
27import qualified Data.Text.IO as TIO
28−import Data.Char
29import Data.Set (Set)
28import Data.Set (Set)
30import qualified Data.Set as Set
29import qualified Data.Set as Set
31import Data.Map.Strict (Map)
30import Data.Map.Strict (Map)
32import qualified Data.Map.Strict as Map
31import qualified Data.Map.Strict as Map
33import Data.List (nub)
32import Data.List (nub)
34import System.Directory (doesFileExist)
33import System.Directory (doesFileExist)
35−import System.FilePath (combine)
34+import System.FilePath
36import Control.Monad.Trans.State
35import Control.Monad.Trans.State
37import System.Environment
36import System.Environment
38
37
@@ -40,15 +39,17 @@ import GHC.Generics (Generic)
40import Data.Data
39import Data.Data
41import Data.Generics.Uniplate.Data
40import Data.Generics.Uniplate.Data
42import Data.List
41import Data.List
42+import Data.Char
43
43
44data Partial = Partial Name Int Int deriving (Eq, Ord)
44data Partial = Partial Name Int Int deriving (Eq, Ord)
45
45
46data CGStats = CGStats { usedWriteStr :: Bool
46data CGStats = CGStats { usedWriteStr :: Bool
47+ , usedBigInt :: Bool
47 , partialApplications :: Set Partial
48 , partialApplications :: Set Partial
48 }
49 }
49
50
50emptyStats :: CGStats
51emptyStats :: CGStats
51−emptyStats = CGStats {usedWriteStr = False, partialApplications = Set.empty}
52+emptyStats = CGStats {usedWriteStr = False, partialApplications = Set.empty, usedBigInt = False}
52
53
53data CGConf = CGConf { header :: Text
54data CGConf = CGConf { header :: Text
54 , footer :: Text
55 , footer :: Text
@@ -88,12 +89,20 @@ codegenJs conf ci =
88 writeFile (outputFile ci ++ ".LDeclsDebug") $ (unlines $ intersperse "" $ map show used) ++ "\n\n\n"
89 writeFile (outputFile ci ++ ".LDeclsDebug") $ (unlines $ intersperse "" $ map show used) ++ "\n\n\n"
89 else pure ()
90 else pure ()
90
91
91− let (out, stats) = doCodegen conf defs used --T.intercalate "\n" $ map (doCodegen conf defs) used
92+ let (out, stats) = doCodegen conf defs used
93+
94+ path <- getIdrisJSRTSDir
95+ jsbn <- if usedBigInt stats
96+ then TIO.readFile $ path </> "jsbn/jsbn.js"
97+ else return ""
98+
99+
92 out `deepseq` if debug then putStrLn $ "Finished generating code" else pure ()
100 out `deepseq` if debug then putStrLn $ "Finished generating code" else pure ()
93 includes <- get_includes $ includes ci
101 includes <- get_includes $ includes ci
94 TIO.writeFile (outputFile ci) $ T.concat [ header conf
102 TIO.writeFile (outputFile ci) $ T.concat [ header conf
95 , "\"use strict\";\n\n"
103 , "\"use strict\";\n\n"
96 , "(function(){\n\n"
104 , "(function(){\n\n"
105+ , jsbn
97 , initialization conf stats
106 , initialization conf stats
98 , doPartials (partialApplications stats)
107 , doPartials (partialApplications stats)
99 , includes, "\n"
108 , includes, "\n"
@@ -101,7 +110,7 @@ codegenJs conf ci =
101 , out, "\n"
110 , out, "\n"
102 , "\n"
111 , "\n"
103 , jsName (sMN 0 "runMain"), "();\n\n"
112 , jsName (sMN 0 "runMain"), "();\n\n"
104− , "\n}())"
113+ , "\n}.call(this))"
105 , footer conf
114 , footer conf
106 ]
115 ]
107
116
@@ -130,7 +139,9 @@ doCodegen :: CGConf -> LDefs -> [LDecl] -> (Text, CGStats)
130doCodegen conf defs decls =
139doCodegen conf defs decls =
131 let xs = map (doCodegenDecl conf defs) decls
140 let xs = map (doCodegenDecl conf defs) decls
132 groupCGStats x y = CGStats {usedWriteStr = usedWriteStr x || usedWriteStr y
141 groupCGStats x y = CGStats {usedWriteStr = usedWriteStr x || usedWriteStr y
133− , partialApplications = partialApplications x `Set.union` partialApplications y }
142+ , partialApplications = partialApplications x `Set.union` partialApplications y
143+ , usedBigInt = usedBigInt x || usedBigInt y
144+ }
134 in (T.intercalate "\n" $ map fst xs, foldl' groupCGStats emptyStats (map snd xs) )
145 in (T.intercalate "\n" $ map fst xs, foldl' groupCGStats emptyStats (map snd xs) )
135
146
136doCodegenDecl :: CGConf -> LDefs -> LDecl -> (Text, CGStats)
147doCodegenDecl :: CGConf -> LDefs -> LDecl -> (Text, CGStats)
@@ -152,6 +163,7 @@ data CGBodyState = CGBodyState { defs :: LDefs
152 , isTailRec :: Bool
163 , isTailRec :: Bool
153 , conf :: CGConf
164 , conf :: CGConf
154 , usedWrite :: Bool
165 , usedWrite :: Bool
166+ , usedITBig :: Bool
155 , partialApps :: Set Partial
167 , partialApps :: Set Partial
156 }
168 }
157
169
@@ -222,6 +234,7 @@ cgFun cnf dfs n args def =
222 , isTailRec = False
234 , isTailRec = False
223 , conf = cnf
235 , conf = cnf
224 , usedWrite = False
236 , usedWrite = False
237+ , usedITBig = False
225 , partialApps = Set.empty
238 , partialApps = Set.empty
226 }
239 }
227 )
240 )
@@ -230,14 +243,17 @@ cgFun cnf dfs n args def =
230 (declareUsedOptimArgs $ usedArgsTailCallOptim st)
243 (declareUsedOptimArgs $ usedArgsTailCallOptim st)
231 (JsWhileTrue ((seqJs decs) `JsSeq` res))
244 (JsWhileTrue ((seqJs decs) `JsSeq` res))
232 else (seqJs decs) `JsSeq` res
245 else (seqJs decs) `JsSeq` res
233− in (JsFun fnName argNames $ body, CGStats {usedWriteStr = usedWrite st, partialApplications = partialApps st})
246+ in (JsFun fnName argNames $ body, CGStats {usedWriteStr = usedWrite st, partialApplications = partialApps st, usedBigInt = usedITBig st})
234
247
235getSwitchJs :: JsAST -> [LAlt] -> JsAST
248getSwitchJs :: JsAST -> [LAlt] -> JsAST
236getSwitchJs x alts =
249getSwitchJs x alts =
237 if any conCase alts then JsArrayProj (JsInt 0) x
250 if any conCase alts then JsArrayProj (JsInt 0) x
238− else x
251+ else if any constBigIntCase alts then JsForeign "%0.toString()" [x]
252+ else x
239 where conCase (LConCase _ _ _ _) = True
253 where conCase (LConCase _ _ _ _) = True
240 conCase _ = False
254 conCase _ = False
255+ constBigIntCase (LConstCase (BI _) _) = True
256+ constBigIntCase _ = False
241
257
242addRT :: BodyResTarget -> JsAST -> JsAST
258addRT :: BodyResTarget -> JsAST -> JsAST
243addRT ReturnBT x = JsReturn x
259addRT ReturnBT x = JsReturn x
@@ -357,14 +373,17 @@ cgBody rt (LCase _ e alts) =
357 pure (d ++ [decSw, JsLet resName JsNull, sw], JsVar resName)
373 pure (d ++ [decSw, JsLet resName JsNull, sw], JsVar resName)
358 (DecConstBT nvar) ->
374 (DecConstBT nvar) ->
359 pure (d ++ [decSw, JsLet nvar JsNull], sw)
375 pure (d ++ [decSw, JsLet nvar JsNull], sw)
360−cgBody rt (LConst c) = pure ([], (addRT rt) $ cgConst c)
376+cgBody rt (LConst c) =
377+ do
378+ cst <- cgConst c
379+ pure ([], (addRT rt) $ cst)
361cgBody rt (LOp op args) =
380cgBody rt (LOp op args) =
362 do
381 do
363 z <- mapM (cgBody GetExpBT) args
382 z <- mapM (cgBody GetExpBT) args
364 res <- cgOp op (map snd z)
383 res <- cgOp op (map snd z)
365 pure $ (concat $ map fst z, addRT rt $ res)
384 pure $ (concat $ map fst z, addRT rt $ res)
366cgBody rt LNothing = pure ([], addRT rt JsNull)
385cgBody rt LNothing = pure ([], addRT rt JsNull)
367−cgBody rt (LError x) = pure ([JsError $ JsStr $ T.pack $ x], addRT rt JsNull)
386+cgBody rt (LError x) = pure ([JsError $ JsStr x], addRT rt JsNull)
368cgBody rt x@(LForeign dres (FStr code) args ) =
387cgBody rt x@(LForeign dres (FStr code) args ) =
369 do
388 do
370 z <- mapM (cgBody GetExpBT) (map snd args)
389 z <- mapM (cgBody GetExpBT) (map snd args)
@@ -384,7 +403,14 @@ cgAlts rt resName scrvar ((LConstCase t exp):r) =
384 do
403 do
385 (d, v) <- cgBody (altsRT resName rt) exp
404 (d, v) <- cgBody (altsRT resName rt) exp
386 (ar, def) <- cgAlts rt resName scrvar r
405 (ar, def) <- cgAlts rt resName scrvar r
406+ cst <- case t of
407+ BI _ ->
408+ do
409+ setUsedITBig
410+ c' <- cgConst t
411+ pure $ JsForeign "%0.toString()" [c']
412+ _ -> cgConst t
387− pure ((cgConst t, JsSeq (seqJs d) v) : ar, def)
413+ pure ((cst, JsSeq (seqJs d) v) : ar, def)
388cgAlts rt resName scrvar ((LDefaultCase exp):r) =
414cgAlts rt resName scrvar ((LDefaultCase exp):r) =
389 do
415 do
390 (d, v) <- cgBody (altsRT resName rt) exp
416 (d, v) <- cgBody (altsRT resName rt) exp
@@ -421,53 +447,90 @@ cgForeignRes (FCon (UN "JS_Ptr")) x = x
421cgForeignRes (FCon (UN "JS_Float")) x = x
447cgForeignRes (FCon (UN "JS_Float")) x = x
422cgForeignRes desc val = error $ "Foreign return type " ++ show desc ++ " not supported yet."
448cgForeignRes desc val = error $ "Foreign return type " ++ show desc ++ " not supported yet."
423
449
450+setUsedITBig :: State CGBodyState ()
451+setUsedITBig = modify (\s -> s {usedITBig = True})
452+
453+
424−cgConst :: Const -> JsAST
454+cgConst :: Const -> State CGBodyState JsAST
425−cgConst (I i) = JsInt i
455+cgConst (I i) = pure $ JsInt i
426−cgConst (BI i) = JsInteger i
456+cgConst (BI i) =
457+ do
458+ setUsedITBig
459+ pure $ JsForeign "new jsbn.BigInteger(%0)" [JsStr $ show i]
427−cgConst (Ch c) = JsInt $ ord c
460+cgConst (Ch c) = pure $ JsStr [c]
428−cgConst (Str s) = JsStr $ T.pack s
461+cgConst (Str s) = pure $ JsStr s
429−cgConst (Fl f) = JsDouble f
462+cgConst (Fl f) = pure $ JsNum f
430cgConst (B8 x) = error "error B8"
463cgConst (B8 x) = error "error B8"
431cgConst (B16 x) = error "error B16"
464cgConst (B16 x) = error "error B16"
432cgConst (B32 x) = error "error B32"
465cgConst (B32 x) = error "error B32"
433cgConst (B64 x) = error "error B64"
466cgConst (B64 x) = error "error B64"
434−cgConst x | isTypeConst x = JsInt 0
467+cgConst x | isTypeConst x = pure $ JsInt 0
435cgConst x = error $ "Constant " ++ show x ++ " not compilable yet"
468cgConst x = error $ "Constant " ++ show x ++ " not compilable yet"
436
469
470+jsB2I :: JsAST -> JsAST
471+jsB2I x = JsForeign "%0 ? 1|0 : 0|0" [x]
472+
437cgOp :: PrimFn -> [JsAST] -> State CGBodyState JsAST
473cgOp :: PrimFn -> [JsAST] -> State CGBodyState JsAST
438−cgOp (LPlus _) [l, r] = pure $ JsBinOp "+" l r
474+cgOp (LPlus ATFloat) [l, r] = pure $ JsBinOp "+" l r
475+cgOp (LPlus (ATInt ITNative)) [l, r] = pure $ JsForeign "%0+%1|0" [l,r]
476+cgOp (LPlus (ATInt ITBig)) [l, r] =
477+ do
478+ setUsedITBig
479+ pure $ JsMethod l "add" [r]
439−cgOp (LMinus _) [l, r] = pure $ JsBinOp "-" l r
480+cgOp (LMinus ATFloat) [l, r] = pure $ JsBinOp "-" l r
481+cgOp (LMinus (ATInt ITNative)) [l, r] = pure $ JsForeign "%0-%1|0" [l,r]
482+cgOp (LMinus (ATInt ITBig)) [l, r] =
483+ do
484+ setUsedITBig
485+ pure $ JsMethod l "subtract" [r]
440−cgOp (LTimes _) [l, r] = pure $ JsBinOp "*" l r
486+cgOp (LTimes ATFloat) [l, r] = pure $ JsBinOp "*" l r
441−cgOp (LEq _) [l, r] = pure $ JsB2I $ JsBinOp "==" l r
487+cgOp (LEq ATFloat) [l, r] = pure $ jsB2I $ JsBinOp "==" l r
488+cgOp (LEq (ATInt ITNative)) [l, r] = pure $ jsB2I $ JsBinOp "==" l r
489+cgOp (LEq (ATInt ITChar)) [l,r] = pure $ jsB2I $ JsBinOp "==" l r
490+cgOp (LEq (ATInt ITBig)) [l, r] =
491+ do
492+ setUsedITBig
493+ pure $ jsB2I $ JsMethod l "equals" [r]
494+cgOp (LSLt ATFloat) [l, r] = pure $ jsB2I $ JsBinOp "<" l r
442−cgOp (LSLt _) [l, r] = pure $ JsB2I $ JsBinOp "<" l r
495+cgOp (LSLt (ATInt ITChar)) [l, r] = pure $ jsB2I $ JsBinOp "<" l r
496+cgOp (LSLt (ATInt ITBig)) [l, r] =
497+ do
498+ setUsedITBig
499+ pure $ jsB2I $ JsForeign "%0.compareTo(%1) < 0" [l,r]
443−cgOp (LSLe _) [l, r] = pure $ JsB2I $ JsBinOp "<=" l r
500+cgOp (LSLe ATFloat) [l, r] = pure $ jsB2I $ JsBinOp "<=" l r
444−cgOp (LSGt _) [l, r] = pure $ JsB2I $ JsBinOp ">" l r
501+cgOp (LSGt ATFloat) [l, r] = pure $ jsB2I $ JsBinOp ">" l r
445−cgOp (LSGe _) [l, r] = pure $ JsB2I $ JsBinOp ">=" l r
502+cgOp (LSGe ATFloat) [l, r] = pure $ jsB2I $ JsBinOp ">=" l r
446−cgOp LStrEq [l,r] = pure $ JsB2I $ JsBinOp "==" l r
503+cgOp LStrEq [l,r] = pure $ jsB2I $ JsBinOp "==" l r
447cgOp LStrLen [x] = pure $ JsForeign "%0.length" [x]
504cgOp LStrLen [x] = pure $ JsForeign "%0.length" [x]
448−cgOp LStrHead [x] = pure $ JsMethod x "charCodeAt" [JsInt 0]
505+cgOp LStrHead [x] = pure $ JsArrayProj (JsInt 0) x
449−cgOp LStrIndex [x, y] = pure $ JsMethod x "charCodeAt" [y]
506+cgOp LStrIndex [x, y] = pure $ JsArrayProj y x
450cgOp LStrTail [x] = pure $ JsMethod x "slice" [JsInt 1]
507cgOp LStrTail [x] = pure $ JsMethod x "slice" [JsInt 1]
451−cgOp LStrLt [l, r] = pure $ JsB2I $ JsBinOp "<" l r
508+cgOp LStrLt [l, r] = pure $ jsB2I $ JsBinOp "<" l r
452−cgOp (LFloatStr) [x] = pure $ JsBinOp "+" x (JsStr "")
509+cgOp (LFloatStr) [x] = pure $ JsApp "String" [x]
453−cgOp (LIntStr _) [x] = pure $ JsBinOp "+" x (JsStr "")
510+cgOp (LIntStr ITNative) [x] = pure $ JsApp "String" [x]
511+cgOp (LIntStr ITBig) [x] =
512+ do
513+ setUsedITBig
514+ pure $ JsForeign "%0.toString()" [x]
454−cgOp (LFloatInt _) [x] = pure $ JsApp "Math.trunc" [x]
515+--cgOp (LFloatInt _) [x] = pure $ JsApp "Math.trunc" [x]
455−cgOp (LStrInt _) [x] = pure $ JsBinOp "||" (JsApp "parseInt" [x]) (JsInt 0)
516+--cgOp (LStrInt _) [x] = pure $ JsBinOp "||" (JsApp "parseInt" [x]) (JsInt 0)
456−cgOp (LStrFloat) [x] = pure $ JsBinOp "||" (JsApp "parseFloat" [x]) (JsInt 0)
517+cgOp (LStrFloat) [x] = pure $ JsApp "parseFloat" [x]
457−cgOp (LChInt _) [x] = pure $ x
518+cgOp (LChInt _) [x] = pure $ JsForeign "%0.charCodeAt(0)|0" [x]
458−cgOp (LIntCh _) [x] = pure $ x
519+--cgOp (LIntCh _) [x] = pure $ x
459−cgOp (LSExt _ _) [x] = pure $ x
520+cgOp (LSExt ITNative ITBig) [x] =
521+ do
522+ setUsedITBig
523+ pure $ JsForeign "new jsbn.BigInteger(String(%0))" [x]
460−cgOp (LZExt _ _) [x] = pure $ x
524+--cgOp (LZExt _ _) [x] = pure $ x
461−cgOp (LIntFloat _) [x] = pure $ x
525+--cgOp (LIntFloat _) [x] = pure $ x
462−cgOp (LSDiv _) [x,y] = pure $ JsBinOp "/" x y
526+--cgOp (LSDiv _) [x,y] = pure $ JsBinOp "/" x y
463cgOp LWriteStr [_,str] =
527cgOp LWriteStr [_,str] =
464 do
528 do
465 s <- get
529 s <- get
466 put $ s {usedWrite = True}
530 put $ s {usedWrite = True}
467 pure $ JsForeign (writeStrTemplate $ conf s) [str]
531 pure $ JsForeign (writeStrTemplate $ conf s) [str]
468− --pure $ JsApp "console.log" [str]
469cgOp LStrConcat [l,r] = pure $ JsBinOp "+" l r
532cgOp LStrConcat [l,r] = pure $ JsBinOp "+" l r
470−cgOp LStrCons [l,r] = pure $ JsForeign "String.fromCharCode(%0) + %1" [l,r]
533+cgOp LStrCons [l,r] = pure $ JsForeign "%0+%1" [l,r] --JsForeign "String.fromCharCode(%0) + %1" [l,r]
471−cgOp (LSRem (ATInt _)) [l,r] = pure $ JsBinOp "%" l r
534+--cgOp (LSRem (ATInt _)) [l,r] = pure $ JsBinOp "%" l r
472cgOp LCrash [l] = pure $ JsErrorExp l
535cgOp LCrash [l] = pure $ JsErrorExp l
473cgOp op exps = error ("Operator " ++ show (op, exps) ++ " not implemented")
536cgOp op exps = error ("Operator " ++ show (op, exps) ++ " not implemented")