BigInteger-ext.js 17 KB

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