PageRenderTime 438ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/js/lib/Socket.IO-node/support/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/math/BigInteger.as

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
ActionScript | 1543 lines | 1136 code | 66 blank | 341 comment | 285 complexity | 7eb5efb1c2cc2a19d158053ed8c12e40 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. /**
  2. * BigInteger
  3. *
  4. * An ActionScript 3 implementation of BigInteger (light version)
  5. * Copyright (c) 2007 Henri Torgemane
  6. *
  7. * Derived from:
  8. * The jsbn library, Copyright (c) 2003-2005 Tom Wu
  9. *
  10. * See LICENSE.txt for full license information.
  11. */
  12. package com.hurlant.math
  13. {
  14. import com.hurlant.crypto.prng.Random;
  15. import com.hurlant.util.Hex;
  16. import com.hurlant.util.Memory;
  17. import flash.utils.ByteArray;
  18. use namespace bi_internal;
  19. public class BigInteger
  20. {
  21. public static const DB:int = 30; // number of significant bits per chunk
  22. public static const DV:int = (1<<DB);
  23. public static const DM:int = (DV-1); // Max value in a chunk
  24. public static const BI_FP:int = 52;
  25. public static const FV:Number = Math.pow(2, BI_FP);
  26. public static const F1:int = BI_FP - DB;
  27. public static const F2:int = 2*DB - BI_FP;
  28. public static const ZERO:BigInteger = nbv(0);
  29. public static const ONE:BigInteger = nbv(1);
  30. /*bi_internal */public var t:int; // number of chunks.
  31. bi_internal var s:int; // sign
  32. bi_internal var a:Array; // chunks
  33. /**
  34. *
  35. * @param value
  36. * @param radix WARNING: If value is ByteArray, this holds the number of bytes to use.
  37. * @param unsigned
  38. *
  39. */
  40. public function BigInteger(value:* = null, radix:int = 0, unsigned:Boolean = false) {
  41. a = new Array;
  42. if (value is String) {
  43. if (radix&&radix!=16) throw new Error("BigInteger construction with radix!=16 is not supported.");
  44. value = Hex.toArray(value);
  45. radix=0;
  46. }
  47. if (value is ByteArray) {
  48. var array:ByteArray = value as ByteArray;
  49. var length:int = radix || (array.length - array.position);
  50. fromArray(array, length, unsigned);
  51. }
  52. }
  53. public function dispose():void {
  54. var r:Random = new Random;
  55. for (var i:uint=0;i<a.length;i++) {
  56. a[i] = r.nextByte();
  57. delete a[i];
  58. }
  59. a=null;
  60. t=0;
  61. s=0;
  62. Memory.gc();
  63. }
  64. public function toString(radix:Number=16):String {
  65. if (s<0) return "-"+negate().toString(radix);
  66. var k:int;
  67. switch (radix) {
  68. case 2: k=1; break;
  69. case 4: k=2; break;
  70. case 8: k=3; break;
  71. case 16: k=4; break;
  72. case 32: k=5; break;
  73. default:
  74. // return toRadix(radix);
  75. }
  76. var km:int = (1<<k)-1;
  77. var d:int = 0;
  78. var m:Boolean = false;
  79. var r:String = "";
  80. var i:int = t;
  81. var p:int = DB-(i*DB)%k;
  82. if (i-->0) {
  83. if (p<DB && (d=a[i]>>p)>0) {
  84. m = true;
  85. r = d.toString(36);
  86. }
  87. while (i >= 0) {
  88. if (p<k) {
  89. d = (a[i]&((1<<p)-1))<<(k-p);
  90. d|= a[--i]>>(p+=DB-k);
  91. } else {
  92. d = (a[i]>>(p-=k))&km;
  93. if (p<=0) {
  94. p += DB;
  95. --i;
  96. }
  97. }
  98. if (d>0) {
  99. m = true;
  100. }
  101. if (m) {
  102. r += d.toString(36);
  103. }
  104. }
  105. }
  106. return m?r:"0";
  107. }
  108. public function toArray(array:ByteArray):uint {
  109. const k:int = 8;
  110. const km:int = (1<<8)-1;
  111. var d:int = 0;
  112. var i:int = t;
  113. var p:int = DB-(i*DB)%k;
  114. var m:Boolean = false;
  115. var c:int = 0;
  116. if (i-->0) {
  117. if (p<DB && (d=a[i]>>p)>0) {
  118. m = true;
  119. array.writeByte(d);
  120. c++;
  121. }
  122. while (i >= 0) {
  123. if (p<k) {
  124. d = (a[i]&((1<<p)-1))<<(k-p);
  125. d|= a[--i]>>(p+=DB-k);
  126. } else {
  127. d = (a[i]>>(p-=k))&km;
  128. if (p<=0) {
  129. p += DB;
  130. --i;
  131. }
  132. }
  133. if (d>0) {
  134. m = true;
  135. }
  136. if (m) {
  137. array.writeByte(d);
  138. c++;
  139. }
  140. }
  141. }
  142. return c;
  143. }
  144. /**
  145. * best-effort attempt to fit into a Number.
  146. * precision can be lost if it just can't fit.
  147. */
  148. public function valueOf():Number {
  149. if (s==-1) {
  150. return -negate().valueOf();
  151. }
  152. var coef:Number = 1;
  153. var value:Number = 0;
  154. for (var i:uint=0;i<t;i++) {
  155. value += a[i]*coef;
  156. coef *= DV;
  157. }
  158. return value;
  159. }
  160. /**
  161. * -this
  162. */
  163. public function negate():BigInteger {
  164. var r:BigInteger = nbi();
  165. ZERO.subTo(this, r);
  166. return r;
  167. }
  168. /**
  169. * |this|
  170. */
  171. public function abs():BigInteger {
  172. return (s<0)?negate():this;
  173. }
  174. /**
  175. * return + if this > v, - if this < v, 0 if equal
  176. */
  177. public function compareTo(v:BigInteger):int {
  178. var r:int = s - v.s;
  179. if (r!=0) {
  180. return r;
  181. }
  182. var i:int = t;
  183. r = i-v.t;
  184. if (r!=0) {
  185. return r;
  186. }
  187. while (--i >=0) {
  188. r=a[i]-v.a[i];
  189. if (r != 0) return r;
  190. }
  191. return 0;
  192. }
  193. /**
  194. * returns bit length of the integer x
  195. */
  196. bi_internal function nbits(x:int):int {
  197. var r:int = 1;
  198. var t:int;
  199. if ((t=x>>>16) != 0) { x = t; r += 16; }
  200. if ((t=x>>8) != 0) { x = t; r += 8; }
  201. if ((t=x>>4) != 0) { x = t; r += 4; }
  202. if ((t=x>>2) != 0) { x = t; r += 2; }
  203. if ((t=x>>1) != 0) { x = t; r += 1; }
  204. return r;
  205. }
  206. /**
  207. * returns the number of bits in this
  208. */
  209. public function bitLength():int {
  210. if (t<=0) return 0;
  211. return DB*(t-1)+nbits(a[t-1]^(s&DM));
  212. }
  213. /**
  214. *
  215. * @param v
  216. * @return this % v
  217. *
  218. */
  219. public function mod(v:BigInteger):BigInteger {
  220. var r:BigInteger = nbi();
  221. abs().divRemTo(v,null,r);
  222. if (s<0 && r.compareTo(ZERO)>0) {
  223. v.subTo(r,r);
  224. }
  225. return r;
  226. }
  227. /**
  228. * this^e % m, 0 <= e < 2^32
  229. */
  230. public function modPowInt(e:int, m:BigInteger):BigInteger {
  231. var z:IReduction;
  232. if (e<256 || m.isEven()) {
  233. z = new ClassicReduction(m);
  234. } else {
  235. z = new MontgomeryReduction(m);
  236. }
  237. return exp(e, z);
  238. }
  239. /**
  240. * copy this to r
  241. */
  242. bi_internal function copyTo(r:BigInteger):void {
  243. for (var i:int = t-1; i>=0; --i) {
  244. r.a[i] = a[i];
  245. }
  246. r.t = t;
  247. r.s = s;
  248. }
  249. /**
  250. * set from integer value "value", -DV <= value < DV
  251. */
  252. bi_internal function fromInt(value:int):void {
  253. t = 1;
  254. s = (value<0)?-1:0;
  255. if (value>0) {
  256. a[0] = value;
  257. } else if (value<-1) {
  258. a[0] = value+DV;
  259. } else {
  260. t = 0;
  261. }
  262. }
  263. /**
  264. * set from ByteArray and length,
  265. * starting a current position
  266. * If length goes beyond the array, pad with zeroes.
  267. */
  268. bi_internal function fromArray(value:ByteArray, length:int, unsigned:Boolean = false):void {
  269. var p:int = value.position;
  270. var i:int = p+length;
  271. var sh:int = 0;
  272. const k:int = 8;
  273. t = 0;
  274. s = 0;
  275. while (--i >= p) {
  276. var x:int = i<value.length?value[i]:0;
  277. if (sh == 0) {
  278. a[t++] = x;
  279. } else if (sh+k > DB) {
  280. a[t-1] |= (x&((1<<(DB-sh))-1))<<sh;
  281. a[t++] = x>>(DB-sh);
  282. } else {
  283. a[t-1] |= x<<sh;
  284. }
  285. sh += k;
  286. if (sh >= DB) sh -= DB;
  287. }
  288. if (!unsigned && (value[0]&0x80)==0x80) {
  289. s = -1;
  290. if (sh > 0) {
  291. a[t-1] |= ((1<<(DB-sh))-1)<<sh;
  292. }
  293. }
  294. clamp();
  295. value.position = Math.min(p+length,value.length);
  296. }
  297. /**
  298. * clamp off excess high words
  299. */
  300. bi_internal function clamp():void {
  301. var c:int = s&DM;
  302. while (t>0 && a[t-1]==c) {
  303. --t;
  304. }
  305. }
  306. /**
  307. * r = this << n*DB
  308. */
  309. bi_internal function dlShiftTo(n:int, r:BigInteger):void {
  310. var i:int;
  311. for (i=t-1; i>=0; --i) {
  312. r.a[i+n] = a[i];
  313. }
  314. for (i=n-1; i>=0; --i) {
  315. r.a[i] = 0;
  316. }
  317. r.t = t+n;
  318. r.s = s;
  319. }
  320. /**
  321. * r = this >> n*DB
  322. */
  323. bi_internal function drShiftTo(n:int, r:BigInteger):void {
  324. var i:int;
  325. for (i=n; i<t; ++i) {
  326. r.a[i-n] = a[i];
  327. }
  328. r.t = Math.max(t-n,0);
  329. r.s = s;
  330. }
  331. /**
  332. * r = this << n
  333. */
  334. bi_internal function lShiftTo(n:int, r:BigInteger):void {
  335. var bs:int = n%DB;
  336. var cbs:int = DB-bs;
  337. var bm:int = (1<<cbs)-1;
  338. var ds:int = n/DB;
  339. var c:int = (s<<bs)&DM;
  340. var i:int;
  341. for (i=t-1; i>=0; --i) {
  342. r.a[i+ds+1] = (a[i]>>cbs)|c;
  343. c = (a[i]&bm)<<bs;
  344. }
  345. for (i=ds-1; i>=0; --i) {
  346. r.a[i] = 0;
  347. }
  348. r.a[ds] = c;
  349. r.t = t+ds+1;
  350. r.s = s;
  351. r.clamp();
  352. }
  353. /**
  354. * r = this >> n
  355. */
  356. bi_internal function rShiftTo(n:int, r:BigInteger):void {
  357. r.s = s;
  358. var ds:int = n/DB;
  359. if (ds >= t) {
  360. r.t = 0;
  361. return;
  362. }
  363. var bs:int = n%DB;
  364. var cbs:int = DB-bs;
  365. var bm:int = (1<<bs)-1;
  366. r.a[0] = a[ds]>>bs;
  367. var i:int;
  368. for (i=ds+1; i<t; ++i) {
  369. r.a[i-ds-1] |= (a[i]&bm)<<cbs;
  370. r.a[i-ds] = a[i]>>bs;
  371. }
  372. if (bs>0) {
  373. r.a[t-ds-1] |= (s&bm)<<cbs;
  374. }
  375. r.t = t-ds;
  376. r.clamp();
  377. }
  378. /**
  379. * r = this - v
  380. */
  381. bi_internal function subTo(v:BigInteger, r:BigInteger):void {
  382. var i:int = 0;
  383. var c:int = 0;
  384. var m:int = Math.min(v.t, t);
  385. while (i<m) {
  386. c += a[i] - v.a[i];
  387. r.a[i++] = c & DM;
  388. c >>= DB;
  389. }
  390. if (v.t < t) {
  391. c -= v.s;
  392. while (i< t) {
  393. c+= a[i];
  394. r.a[i++] = c&DM;
  395. c >>= DB;
  396. }
  397. c += s;
  398. } else {
  399. c += s;
  400. while (i < v.t) {
  401. c -= v.a[i];
  402. r.a[i++] = c&DM;
  403. c >>= DB;
  404. }
  405. c -= v.s;
  406. }
  407. r.s = (c<0)?-1:0;
  408. if (c<-1) {
  409. r.a[i++] = DV+c;
  410. } else if (c>0) {
  411. r.a[i++] = c;
  412. }
  413. r.t = i;
  414. r.clamp();
  415. }
  416. /**
  417. * am: Compute w_j += (x*this_i), propagates carries,
  418. * c is initial carry, returns final carry.
  419. * c < 3*dvalue, x < 2*dvalue, this_i < dvalue
  420. */
  421. bi_internal function am(i:int,x:int,w:BigInteger,j:int,c:int,n:int):int {
  422. var xl:int = x&0x7fff;
  423. var xh:int = x>>15;
  424. while(--n >= 0) {
  425. var l:int = a[i]&0x7fff;
  426. var h:int = a[i++]>>15;
  427. var m:int = xh*l + h*xl;
  428. l = xl*l + ((m&0x7fff)<<15)+w.a[j]+(c&0x3fffffff);
  429. c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
  430. w.a[j++] = l&0x3fffffff;
  431. }
  432. return c;
  433. }
  434. /**
  435. * r = this * v, r != this,a (HAC 14.12)
  436. * "this" should be the larger one if appropriate
  437. */
  438. bi_internal function multiplyTo(v:BigInteger, r:BigInteger):void {
  439. var x:BigInteger = abs();
  440. var y:BigInteger = v.abs();
  441. var i:int = x.t;
  442. r.t = i+y.t;
  443. while (--i >= 0) {
  444. r.a[i] = 0;
  445. }
  446. for (i=0; i<y.t; ++i) {
  447. r.a[i+x.t] = x.am(0, y.a[i], r, i, 0, x.t);
  448. }
  449. r.s = 0;
  450. r.clamp();
  451. if (s!=v.s) {
  452. ZERO.subTo(r, r);
  453. }
  454. }
  455. /**
  456. * r = this^2, r != this (HAC 14.16)
  457. */
  458. bi_internal function squareTo(r:BigInteger):void {
  459. var x:BigInteger = abs();
  460. var i:int = r.t = 2*x.t;
  461. while (--i>=0) r.a[i] = 0;
  462. for (i=0; i<x.t-1; ++i) {
  463. var c:int = x.am(i, x.a[i], r, 2*i, 0, 1);
  464. if ((r.a[i+x.t] += x.am(i+1, 2*x.a[i], r, 2*i+1, c, x.t-i-1)) >= DV) {
  465. r.a[i+x.t] -= DV;
  466. r.a[i+x.t+1] = 1;
  467. }
  468. }
  469. if (r.t>0) {
  470. r.a[r.t-1] += x.am(i, x.a[i], r, 2*i, 0, 1);
  471. }
  472. r.s = 0;
  473. r.clamp();
  474. }
  475. /**
  476. * divide this by m, quotient and remainder to q, r (HAC 14.20)
  477. * r != q, this != m. q or r may be null.
  478. */
  479. bi_internal function divRemTo(m:BigInteger, q:BigInteger = null, r:BigInteger = null):void {
  480. var pm:BigInteger = m.abs();
  481. if (pm.t <= 0) return;
  482. var pt:BigInteger = abs();
  483. if (pt.t < pm.t) {
  484. if (q!=null) q.fromInt(0);
  485. if (r!=null) copyTo(r);
  486. return;
  487. }
  488. if (r==null) r = nbi();
  489. var y:BigInteger = nbi();
  490. var ts:int = s;
  491. var ms:int = m.s;
  492. var nsh:int = DB-nbits(pm.a[pm.t-1]); // normalize modulus
  493. if (nsh>0) {
  494. pm.lShiftTo(nsh, y);
  495. pt.lShiftTo(nsh, r);
  496. } else {
  497. pm.copyTo(y);
  498. pt.copyTo(r);
  499. }
  500. var ys:int = y.t;
  501. var y0:int = y.a[ys-1];
  502. if (y0==0) return;
  503. var yt:Number = y0*(1<<F1)+((ys>1)?y.a[ys-2]>>F2:0);
  504. var d1:Number = FV/yt;
  505. var d2:Number = (1<<F1)/yt;
  506. var e:Number = 1<<F2;
  507. var i:int = r.t;
  508. var j:int = i-ys;
  509. var t:BigInteger = (q==null)?nbi():q;
  510. y.dlShiftTo(j,t);
  511. if (r.compareTo(t)>=0) {
  512. r.a[r.t++] = 1;
  513. r.subTo(t,r);
  514. }
  515. ONE.dlShiftTo(ys,t);
  516. t.subTo(y,y); // "negative" y so we can replace sub with am later.
  517. while(y.t<ys) y.(y.t++, 0);
  518. while(--j >= 0) {
  519. // Estimate quotient digit
  520. var qd:int = (r.a[--i]==y0)?DM:Number(r.a[i])*d1+(Number(r.a[i-1])+e)*d2;
  521. if ((r.a[i]+= y.am(0, qd, r, j, 0, ys))<qd) { // Try it out
  522. y.dlShiftTo(j, t);
  523. r.subTo(t,r);
  524. while (r.a[i]<--qd) {
  525. r.subTo(t,r);
  526. }
  527. }
  528. }
  529. if (q!=null) {
  530. r.drShiftTo(ys,q);
  531. if (ts!=ms) {
  532. ZERO.subTo(q,q);
  533. }
  534. }
  535. r.t = ys;
  536. r.clamp();
  537. if (nsh>0) {
  538. r.rShiftTo(nsh, r); // Denormalize remainder
  539. }
  540. if (ts<0) {
  541. ZERO.subTo(r,r);
  542. }
  543. }
  544. /**
  545. * return "-1/this % 2^DB"; useful for Mont. reduction
  546. * justification:
  547. * xy == 1 (mod n)
  548. * xy = 1+km
  549. * xy(2-xy) = (1+km)(1-km)
  550. * x[y(2-xy)] = 1-k^2.m^2
  551. * x[y(2-xy)] == 1 (mod m^2)
  552. * if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
  553. * should reduce x and y(2-xy) by m^2 at each step to keep size bounded
  554. * [XXX unit test the living shit out of this.]
  555. */
  556. bi_internal function invDigit():int {
  557. if (t<1) return 0;
  558. var x:int = a[0];
  559. if ((x&1)==0) return 0;
  560. var y:int = x&3; // y == 1/x mod 2^2
  561. y = (y*(2-(x&0xf )*y)) &0xf; // y == 1/x mod 2^4
  562. y = (y*(2-(x&0xff)*y)) &0xff; // y == 1/x mod 2^8
  563. y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
  564. // last step - calculate inverse mod DV directly;
  565. // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
  566. // XXX 48 bit ints? Whaaaa? is there an implicit float conversion in here?
  567. y = (y*(2-x*y%DV))%DV; // y == 1/x mod 2^dbits
  568. // we really want the negative inverse, and -DV < y < DV
  569. return (y>0)?DV-y:-y;
  570. }
  571. /**
  572. * true iff this is even
  573. */
  574. bi_internal function isEven():Boolean {
  575. return ((t>0)?(a[0]&1):s) == 0;
  576. }
  577. /**
  578. * this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
  579. */
  580. bi_internal function exp(e:int, z:IReduction):BigInteger {
  581. if (e > 0xffffffff || e < 1) return ONE;
  582. var r:BigInteger = nbi();
  583. var r2:BigInteger = nbi();
  584. var g:BigInteger = z.convert(this);
  585. var i:int = nbits(e)-1;
  586. g.copyTo(r);
  587. while(--i>=0) {
  588. z.sqrTo(r, r2);
  589. if ((e&(1<<i))>0) {
  590. z.mulTo(r2,g,r);
  591. } else {
  592. var t:BigInteger = r;
  593. r = r2;
  594. r2 = t;
  595. }
  596. }
  597. return z.revert(r);
  598. }
  599. bi_internal function intAt(str:String, index:int):int {
  600. return parseInt(str.charAt(index), 36);
  601. }
  602. protected function nbi():* {
  603. return new BigInteger;
  604. }
  605. /**
  606. * return bigint initialized to value
  607. */
  608. public static function nbv(value:int):BigInteger {
  609. var bn:BigInteger = new BigInteger;
  610. bn.fromInt(value);
  611. return bn;
  612. }
  613. // Functions above are sufficient for RSA encryption.
  614. // The stuff below is useful for decryption and key generation
  615. public static const lowprimes:Array = [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];
  616. public static const lplim:int = (1<<26)/lowprimes[lowprimes.length-1];
  617. public function clone():BigInteger {
  618. var r:BigInteger = new BigInteger;
  619. this.copyTo(r);
  620. return r;
  621. }
  622. /**
  623. *
  624. * @return value as integer
  625. *
  626. */
  627. public function intValue():int {
  628. if (s<0) {
  629. if (t==1) {
  630. return a[0]-DV;
  631. } else if (t==0) {
  632. return -1;
  633. }
  634. } else if (t==1) {
  635. return a[0];
  636. } else if (t==0) {
  637. return 0;
  638. }
  639. // assumes 16 < DB < 32
  640. return ((a[1]&((1<<(32-DB))-1))<<DB)|a[0];
  641. }
  642. /**
  643. *
  644. * @return value as byte
  645. *
  646. */
  647. public function byteValue():int {
  648. return (t==0)?s:(a[0]<<24)>>24;
  649. }
  650. /**
  651. *
  652. * @return value as short (assumes DB>=16)
  653. *
  654. */
  655. public function shortValue():int {
  656. return (t==0)?s:(a[0]<<16)>>16;
  657. }
  658. /**
  659. *
  660. * @param r
  661. * @return x s.t. r^x < DV
  662. *
  663. */
  664. protected function chunkSize(r:Number):int {
  665. return Math.floor(Math.LN2*DB/Math.log(r));
  666. }
  667. /**
  668. *
  669. * @return 0 if this ==0, 1 if this >0
  670. *
  671. */
  672. public function sigNum():int {
  673. if (s<0) {
  674. return -1;
  675. } else if (t<=0 || (t==1 && a[0]<=0)) {
  676. return 0;
  677. } else{
  678. return 1;
  679. }
  680. }
  681. /**
  682. *
  683. * @param b: radix to use
  684. * @return a string representing the integer converted to the radix.
  685. *
  686. */
  687. protected function toRadix(b:uint=10):String {
  688. if (sigNum()==0 || b<2 || b>32) return "0";
  689. var cs:int = chunkSize(b);
  690. var a:Number = Math.pow(b, cs);
  691. var d:BigInteger = nbv(a);
  692. var y:BigInteger = nbi();
  693. var z:BigInteger = nbi();
  694. var r:String = "";
  695. divRemTo(d, y, z);
  696. while (y.sigNum()>0) {
  697. r = (a+z.intValue()).toString(b).substr(1) + r;
  698. y.divRemTo(d,y,z);
  699. }
  700. return z.intValue().toString(b) + r;
  701. }
  702. /**
  703. *
  704. * @param s a string to convert from using radix.
  705. * @param b a radix
  706. *
  707. */
  708. protected function fromRadix(s:String, b:int = 10):void {
  709. fromInt(0);
  710. var cs:int = chunkSize(b);
  711. var d:Number = Math.pow(b, cs);
  712. var mi:Boolean = false;
  713. var j:int = 0;
  714. var w:int = 0;
  715. for (var i:int=0;i<s.length;++i) {
  716. var x:int = intAt(s, i);
  717. if (x<0) {
  718. if (s.charAt(i) == "-" && sigNum() == 0) {
  719. mi = true;
  720. }
  721. continue;
  722. }
  723. w = b*w+x;
  724. if (++j >= cs) {
  725. dMultiply(d);
  726. dAddOffset(w,0);
  727. j=0;
  728. w=0;
  729. }
  730. }
  731. if (j>0) {
  732. dMultiply(Math.pow(b,j));
  733. dAddOffset(w,0);
  734. }
  735. if (mi) {
  736. BigInteger.ZERO.subTo(this, this);
  737. }
  738. }
  739. // XXX function fromNumber not written yet.
  740. /**
  741. *
  742. * @return a byte array.
  743. *
  744. */
  745. public function toByteArray():ByteArray {
  746. var i:int = t;
  747. var r:ByteArray = new ByteArray;
  748. r[0] = s;
  749. var p:int = DB-(i*DB)%8;
  750. var d:int;
  751. var k:int=0;
  752. if (i-->0) {
  753. if (p<DB && (d=a[i]>>p)!=(s&DM)>>p) {
  754. r[k++] = d|(s<<(DB-p));
  755. }
  756. while (i>=0) {
  757. if(p<8) {
  758. d = (a[i]&((1<<p)-1))<<(8-p);
  759. d|= a[--i]>>(p+=DB-8);
  760. } else {
  761. d = (a[i]>>(p-=8))&0xff;
  762. if (p<=0) {
  763. p += DB;
  764. --i;
  765. }
  766. }
  767. if ((d&0x80)!=0) d|=-256;
  768. if (k==0 && (s&0x80)!=(d&0x80)) ++k;
  769. if (k>0 || d!=s) r[k++] = d;
  770. }
  771. }
  772. return r;
  773. }
  774. public function equals(a:BigInteger):Boolean {
  775. return compareTo(a)==0;
  776. }
  777. public function min(a:BigInteger):BigInteger {
  778. return (compareTo(a)<0)?this:a;
  779. }
  780. public function max(a:BigInteger):BigInteger {
  781. return (compareTo(a)>0)?this:a;
  782. }
  783. /**
  784. *
  785. * @param a a BigInteger to perform the operation with
  786. * @param op a Function implementing the operation
  787. * @param r a BigInteger to store the result of the operation
  788. *
  789. */
  790. protected function bitwiseTo(a:BigInteger, op:Function, r:BigInteger):void {
  791. var i:int;
  792. var f:int;
  793. var m:int = Math.min(a.t, t);
  794. for (i=0; i<m; ++i) {
  795. r.a[i] = op(this.a[i],a.a[i]);
  796. }
  797. if (a.t<t) {
  798. f = a.s&DM;
  799. for (i=m;i<t;++i) {
  800. r.a[i] = op(this.a[i],f);
  801. }
  802. r.t = t;
  803. } else {
  804. f = s&DM;
  805. for (i=m;i<a.t;++i) {
  806. r.a[i] = op(f,a.a[i]);
  807. }
  808. r.t = a.t;
  809. }
  810. r.s = op(s, a.s);
  811. r.clamp();
  812. }
  813. private function op_and(x:int, y:int):int {return x&y;}
  814. public function and(a:BigInteger):BigInteger {
  815. var r:BigInteger = new BigInteger;
  816. bitwiseTo(a, op_and, r);
  817. return r;
  818. }
  819. private function op_or(x:int, y:int):int {return x|y;}
  820. public function or(a:BigInteger):BigInteger {
  821. var r:BigInteger = new BigInteger;
  822. bitwiseTo(a, op_or, r);
  823. return r;
  824. }
  825. private function op_xor(x:int, y:int):int {return x^y;}
  826. public function xor(a:BigInteger):BigInteger {
  827. var r:BigInteger = new BigInteger;
  828. bitwiseTo(a, op_xor, r);
  829. return r;
  830. }
  831. private function op_andnot(x:int, y:int):int { return x&~y;}
  832. public function andNot(a:BigInteger):BigInteger {
  833. var r:BigInteger = new BigInteger;
  834. bitwiseTo(a, op_andnot, r);
  835. return r;
  836. }
  837. public function not():BigInteger {
  838. var r:BigInteger = new BigInteger;
  839. for (var i:int=0;i<t;++i) {
  840. r[i] = DM&~a[i];
  841. }
  842. r.t = t;
  843. r.s = ~s;
  844. return r;
  845. }
  846. public function shiftLeft(n:int):BigInteger {
  847. var r:BigInteger = new BigInteger;
  848. if (n<0) {
  849. rShiftTo(-n, r);
  850. } else {
  851. lShiftTo(n, r);
  852. }
  853. return r;
  854. }
  855. public function shiftRight(n:int):BigInteger {
  856. var r:BigInteger = new BigInteger;
  857. if (n<0) {
  858. lShiftTo(-n, r);
  859. } else {
  860. rShiftTo(n, r);
  861. }
  862. return r;
  863. }
  864. /**
  865. *
  866. * @param x
  867. * @return index of lowet 1-bit in x, x < 2^31
  868. *
  869. */
  870. private function lbit(x:int):int {
  871. if (x==0) return -1;
  872. var r:int = 0;
  873. if ((x&0xffff)==0) { x>>= 16; r += 16; }
  874. if ((x&0xff) == 0) { x>>= 8; r += 8; }
  875. if ((x&0xf) == 0) { x>>= 4; r += 4; }
  876. if ((x&0x3) == 0) { x>>= 2; r += 2; }
  877. if ((x&0x1) == 0) ++r;
  878. return r;
  879. }
  880. /**
  881. *
  882. * @return index of lowest 1-bit (or -1 if none)
  883. *
  884. */
  885. public function getLowestSetBit():int {
  886. for (var i:int=0;i<t;++i) {
  887. if (a[i]!=0) return i*DB+lbit(a[i]);
  888. }
  889. if (s<0) return t*DB;
  890. return -1;
  891. }
  892. /**
  893. *
  894. * @param x
  895. * @return number of 1 bits in x
  896. *
  897. */
  898. private function cbit(x:int):int {
  899. var r:uint =0;
  900. while (x!=0) { x &= x-1; ++r }
  901. return r;
  902. }
  903. /**
  904. *
  905. * @return number of set bits
  906. *
  907. */
  908. public function bitCount():int {
  909. var r:int=0;
  910. var x:int = s&DM;
  911. for (var i:int=0;i<t;++i) {
  912. r += cbit(a[i]^x);
  913. }
  914. return r;
  915. }
  916. /**
  917. *
  918. * @param n
  919. * @return true iff nth bit is set
  920. *
  921. */
  922. public function testBit(n:int):Boolean {
  923. var j:int = Math.floor(n/DB);
  924. if (j>=t) {
  925. return s!=0;
  926. }
  927. return ((a[j]&(1<<(n%DB)))!=0);
  928. }
  929. /**
  930. *
  931. * @param n
  932. * @param op
  933. * @return this op (1<<n)
  934. *
  935. */
  936. protected function changeBit(n:int,op:Function):BigInteger {
  937. var r:BigInteger = BigInteger.ONE.shiftLeft(n);
  938. bitwiseTo(r, op, r);
  939. return r;
  940. }
  941. /**
  942. *
  943. * @param n
  944. * @return this | (1<<n)
  945. *
  946. */
  947. public function setBit(n:int):BigInteger { return changeBit(n, op_or); }
  948. /**
  949. *
  950. * @param n
  951. * @return this & ~(1<<n)
  952. *
  953. */
  954. public function clearBit(n:int):BigInteger { return changeBit(n, op_andnot); }
  955. /**
  956. *
  957. * @param n
  958. * @return this ^ (1<<n)
  959. *
  960. */
  961. public function flipBit(n:int):BigInteger { return changeBit(n, op_xor); }
  962. /**
  963. *
  964. * @param a
  965. * @param r = this + a
  966. *
  967. */
  968. protected function addTo(a:BigInteger, r:BigInteger):void {
  969. var i:int = 0;
  970. var c:int = 0;
  971. var m:int = Math.min(a.t, t);
  972. while (i<m) {
  973. c += this.a[i] + a.a[i];
  974. r.a[i++] = c&DM;
  975. c>>=DB;
  976. }
  977. if (a.t < t) {
  978. c += a.s;
  979. while (i<t) {
  980. c += this.a[i];
  981. r.a[i++] = c&DM;
  982. c >>= DB;
  983. }
  984. c += s;
  985. } else {
  986. c += s;
  987. while (i<a.t) {
  988. c += a.a[i];
  989. r.a[i++] = c&DM;
  990. c >>= DB;
  991. }
  992. c += a.s;
  993. }
  994. r.s = (c<0)?-1:0;
  995. if (c>0) {
  996. r.a[i++] = c;
  997. } else if (c<-1) {
  998. r.a[i++] = DV+c;
  999. }
  1000. r.t = i;
  1001. r.clamp();
  1002. }
  1003. /**
  1004. *
  1005. * @param a
  1006. * @return this + a
  1007. *
  1008. */
  1009. public function add(a:BigInteger):BigInteger {
  1010. var r:BigInteger = new BigInteger;
  1011. addTo(a,r);
  1012. return r;
  1013. }
  1014. /**
  1015. *
  1016. * @param a
  1017. * @return this - a
  1018. *
  1019. */
  1020. public function subtract(a:BigInteger):BigInteger {
  1021. var r:BigInteger = new BigInteger;
  1022. subTo(a,r);
  1023. return r;
  1024. }
  1025. /**
  1026. *
  1027. * @param a
  1028. * @return this * a
  1029. *
  1030. */
  1031. public function multiply(a:BigInteger):BigInteger {
  1032. var r:BigInteger = new BigInteger;
  1033. multiplyTo(a,r);
  1034. return r;
  1035. }
  1036. /**
  1037. *
  1038. * @param a
  1039. * @return this / a
  1040. *
  1041. */
  1042. public function divide(a:BigInteger):BigInteger {
  1043. var r:BigInteger = new BigInteger;
  1044. divRemTo(a, r, null);
  1045. return r;
  1046. }
  1047. public function remainder(a:BigInteger):BigInteger {
  1048. var r:BigInteger = new BigInteger;
  1049. divRemTo(a, null, r);
  1050. return r;
  1051. }
  1052. /**
  1053. *
  1054. * @param a
  1055. * @return [this/a, this%a]
  1056. *
  1057. */
  1058. public function divideAndRemainder(a:BigInteger):Array {
  1059. var q:BigInteger = new BigInteger;
  1060. var r:BigInteger = new BigInteger;
  1061. divRemTo(a, q, r);
  1062. return [q,r];
  1063. }
  1064. /**
  1065. *
  1066. * this *= n, this >=0, 1 < n < DV
  1067. *
  1068. * @param n
  1069. *
  1070. */
  1071. bi_internal function dMultiply(n:int):void {
  1072. a[t] = am(0, n-1, this, 0, 0, t);
  1073. ++t;
  1074. clamp();
  1075. }
  1076. /**
  1077. *
  1078. * this += n << w words, this >= 0
  1079. *
  1080. * @param n
  1081. * @param w
  1082. *
  1083. */
  1084. bi_internal function dAddOffset(n:int, w:int):void {
  1085. while (t<=w) {
  1086. a[t++] = 0;
  1087. }
  1088. a[w] += n;
  1089. while (a[w] >= DV) {
  1090. a[w] -= DV;
  1091. if (++w >= t) {
  1092. a[t++] = 0;
  1093. }
  1094. ++a[w];
  1095. }
  1096. }
  1097. /**
  1098. *
  1099. * @param e
  1100. * @return this^e
  1101. *
  1102. */
  1103. public function pow(e:int):BigInteger {
  1104. return exp(e, new NullReduction);
  1105. }
  1106. /**
  1107. *
  1108. * @param a
  1109. * @param n
  1110. * @param r = lower n words of "this * a", a.t <= n
  1111. *
  1112. */
  1113. bi_internal function multiplyLowerTo(a:BigInteger, n:int, r:BigInteger):void {
  1114. var i:int = Math.min(t+a.t, n);
  1115. r.s = 0; // assumes a, this >= 0
  1116. r.t = i;
  1117. while (i>0) {
  1118. r.a[--i]=0;
  1119. }
  1120. var j:int;
  1121. for (j=r.t-t;i<j;++i) {
  1122. r.a[i+t] = am(0, a.a[i], r, i, 0, t);
  1123. }
  1124. for (j=Math.min(a.t,n);i<j;++i) {
  1125. am(0, a.a[i], r, i, 0, n-i);
  1126. }
  1127. r.clamp();
  1128. }
  1129. /**
  1130. *
  1131. * @param a
  1132. * @param n
  1133. * @param r = "this * a" without lower n words, n > 0
  1134. *
  1135. */
  1136. bi_internal function multiplyUpperTo(a:BigInteger, n:int, r:BigInteger):void {
  1137. --n;
  1138. var i:int = r.t = t+a.t-n;
  1139. r.s = 0; // assumes a,this >= 0
  1140. while (--i>=0) {
  1141. r.a[i] = 0;
  1142. }
  1143. for (i=Math.max(n-t,0);i<a.t;++i) {
  1144. r.a[t+i-n] = am(n-i, a.a[i], r, 0, 0, t+i-n);
  1145. }
  1146. r.clamp();
  1147. r.drShiftTo(1,r);
  1148. }
  1149. /**
  1150. *
  1151. * @param e
  1152. * @param m
  1153. * @return this^e % m (HAC 14.85)
  1154. *
  1155. */
  1156. public function modPow(e:BigInteger, m:BigInteger):BigInteger {
  1157. var i:int = e.bitLength();
  1158. var k:int;
  1159. var r:BigInteger = nbv(1);
  1160. var z:IReduction;
  1161. if (i<=0) {
  1162. return r;
  1163. } else if (i<18) {
  1164. k=1;
  1165. } else if (i<48) {
  1166. k=3;
  1167. } else if (i<144) {
  1168. k=4;
  1169. } else if (i<768) {
  1170. k=5;
  1171. } else {
  1172. k=6;
  1173. }
  1174. if (i<8) {
  1175. z = new ClassicReduction(m);
  1176. } else if (m.isEven()) {
  1177. z = new BarrettReduction(m);
  1178. } else {
  1179. z = new MontgomeryReduction(m);
  1180. }
  1181. // precomputation
  1182. var g:Array = [];
  1183. var n:int = 3;
  1184. var k1:int = k-1;
  1185. var km:int = (1<<k)-1;
  1186. g[1] = z.convert(this);
  1187. if (k > 1) {
  1188. var g2:BigInteger = new BigInteger;
  1189. z.sqrTo(g[1], g2);
  1190. while (n<=km) {
  1191. g[n] = new BigInteger;
  1192. z.mulTo(g2, g[n-2], g[n]);
  1193. n += 2;
  1194. }
  1195. }
  1196. var j:int = e.t-1;
  1197. var w:int;
  1198. var is1:Boolean = true;
  1199. var r2:BigInteger = new BigInteger;
  1200. var t:BigInteger;
  1201. i = nbits(e.a[j])-1;
  1202. while (j>=0) {
  1203. if (i>=k1) {
  1204. w = (e.a[j]>>(i-k1))&km;
  1205. } else {
  1206. w = (e.a[j]&((1<<(i+1))-1))<<(k1-i);
  1207. if (j>0) {
  1208. w |= e.a[j-1]>>(DB+i-k1);
  1209. }
  1210. }
  1211. n = k;
  1212. while ((w&1)==0) {
  1213. w >>= 1;
  1214. --n;
  1215. }
  1216. if ((i -= n) <0) {
  1217. i += DB;
  1218. --j;
  1219. }
  1220. if (is1) { // ret == 1, don't bother squaring or multiplying it
  1221. g[w].copyTo(r);
  1222. is1 = false;
  1223. } else {
  1224. while (n>1) {
  1225. z.sqrTo(r, r2);
  1226. z.sqrTo(r2, r);
  1227. n -= 2;
  1228. }
  1229. if (n>0) {
  1230. z.sqrTo(r, r2);
  1231. } else {
  1232. t = r;
  1233. r = r2;
  1234. r2 = t;
  1235. }
  1236. z.mulTo(r2, g[w], r);
  1237. }
  1238. while (j>=0 && (e.a[j]&(1<<i)) == 0) {
  1239. z.sqrTo(r, r2);
  1240. t = r;
  1241. r = r2;
  1242. r2 = t;
  1243. if (--i<0) {
  1244. i = DB-1;
  1245. --j;
  1246. }
  1247. }
  1248. }
  1249. return z.revert(r);
  1250. }
  1251. /**
  1252. *
  1253. * @param a
  1254. * @return gcd(this, a) (HAC 14.54)
  1255. *
  1256. */
  1257. public function gcd(a:BigInteger):BigInteger {
  1258. var x:BigInteger = (s<0)?negate():clone();
  1259. var y:BigInteger = (a.s<0)?a.negate():a.clone();
  1260. if (x.compareTo(y)<0) {
  1261. var t:BigInteger=x;
  1262. x=y;
  1263. y=t;
  1264. }
  1265. var i:int = x.getLowestSetBit();
  1266. var g:int = y.getLowestSetBit();
  1267. if (g<0) return x;
  1268. if (i<g) g= i;
  1269. if (g>0) {
  1270. x.rShiftTo(g, x);
  1271. y.rShiftTo(g, y);
  1272. }
  1273. while (x.sigNum()>0) {
  1274. if ((i = x.getLowestSetBit()) >0) {
  1275. x.rShiftTo(i, x);
  1276. }
  1277. if ((i = y.getLowestSetBit()) >0) {
  1278. y.rShiftTo(i, y);
  1279. }
  1280. if (x.compareTo(y) >= 0) {
  1281. x.subTo(y, x);
  1282. x.rShiftTo(1, x);
  1283. } else {
  1284. y.subTo(x, y);
  1285. y.rShiftTo(1, y);
  1286. }
  1287. }
  1288. if (g>0) {
  1289. y.lShiftTo(g, y);
  1290. }
  1291. return y;
  1292. }
  1293. /**
  1294. *
  1295. * @param n
  1296. * @return this % n, n < 2^DB
  1297. *
  1298. */
  1299. protected function modInt(n:int):int {
  1300. if (n<=0) return 0;
  1301. var d:int = DV%n;
  1302. var r:int = (s<0)?n-1:0;
  1303. if (t>0) {
  1304. if (d==0) {
  1305. r = a[0]%n;
  1306. } else {
  1307. for (var i:int=t-1;i>=0;--i) {
  1308. r = (d*r+a[i])%n;
  1309. }
  1310. }
  1311. }
  1312. return r;
  1313. }
  1314. /**
  1315. *
  1316. * @param m
  1317. * @return 1/this %m (HAC 14.61)
  1318. *
  1319. */
  1320. public function modInverse(m:BigInteger):BigInteger {
  1321. var ac:Boolean = m.isEven();
  1322. if ((isEven()&&ac) || m.sigNum()==0) {
  1323. return BigInteger.ZERO;
  1324. }
  1325. var u:BigInteger = m.clone();
  1326. var v:BigInteger = clone();
  1327. var a:BigInteger = nbv(1);
  1328. var b:BigInteger = nbv(0);
  1329. var c:BigInteger = nbv(0);
  1330. var d:BigInteger = nbv(1);
  1331. while (u.sigNum()!=0) {
  1332. while (u.isEven()) {
  1333. u.rShiftTo(1,u);
  1334. if (ac) {
  1335. if (!a.isEven() || !b.isEven()) {
  1336. a.addTo(this,a);
  1337. b.subTo(m,b);
  1338. }
  1339. a.rShiftTo(1,a);
  1340. } else if (!b.isEven()) {
  1341. b.subTo(m,b);
  1342. }
  1343. b.rShiftTo(1,b);
  1344. }
  1345. while (v.isEven()) {
  1346. v.rShiftTo(1,v);
  1347. if (ac) {
  1348. if (!c.isEven() || !d.isEven()) {
  1349. c.addTo(this,c);
  1350. d.subTo(m,d);
  1351. }
  1352. c.rShiftTo(1,c);
  1353. } else if (!d.isEven()) {
  1354. d.subTo(m,d);
  1355. }
  1356. d.rShiftTo(1,d);
  1357. }
  1358. if (u.compareTo(v)>=0) {
  1359. u.subTo(v,u);
  1360. if (ac) {
  1361. a.subTo(c,a);
  1362. }
  1363. b.subTo(d,b);
  1364. } else {
  1365. v.subTo(u,v);
  1366. if (ac) {
  1367. c.subTo(a,c);
  1368. }
  1369. d.subTo(b,d);
  1370. }
  1371. }
  1372. if (v.compareTo(BigInteger.ONE) != 0) {
  1373. return BigInteger.ZERO;
  1374. }
  1375. if (d.compareTo(m) >= 0) {
  1376. return d.subtract(m);
  1377. }
  1378. if (d.sigNum()<0) {
  1379. d.addTo(m,d);
  1380. } else {
  1381. return d;
  1382. }
  1383. if (d.sigNum()<0) {
  1384. return d.add(m);
  1385. } else {
  1386. return d;
  1387. }
  1388. }
  1389. /**
  1390. *
  1391. * @param t
  1392. * @return primality with certainty >= 1-.5^t
  1393. *
  1394. */
  1395. public function isProbablePrime(t:int):Boolean {
  1396. var i:int;
  1397. var x:BigInteger = abs();
  1398. if (x.t == 1 && x.a[0]<=lowprimes[lowprimes.length-1]) {
  1399. for (i=0;i<lowprimes.length;++i) {
  1400. if (x[0]==lowprimes[i]) return true;
  1401. }
  1402. return false;
  1403. }
  1404. if (x.isEven()) return false;
  1405. i = 1;
  1406. while (i<lowprimes.length) {
  1407. var m:int = lowprimes[i];
  1408. var j:int = i+1;
  1409. while (j<lowprimes.length && m<lplim) {
  1410. m *= lowprimes[j++];
  1411. }
  1412. m = x.modInt(m);
  1413. while (i<j) {
  1414. if (m%lowprimes[i++]==0) {
  1415. return false;
  1416. }
  1417. }
  1418. }
  1419. return x.millerRabin(t);
  1420. }
  1421. /**
  1422. *
  1423. * @param t
  1424. * @return true if probably prime (HAC 4.24, Miller-Rabin)
  1425. *
  1426. */
  1427. protected function millerRabin(t:int):Boolean {
  1428. var n1:BigInteger = subtract(BigInteger.ONE);
  1429. var k:int = n1.getLowestSetBit();
  1430. if (k<=0) {
  1431. return false;
  1432. }
  1433. var r:BigInteger = n1.shiftRight(k);
  1434. t = (t+1)>>1;
  1435. if (t>lowprimes.length) {
  1436. t = lowprimes.length;
  1437. }
  1438. var a:BigInteger = new BigInteger;
  1439. for (var i:int=0;i<t;++i) {
  1440. a.fromInt(lowprimes[i]);
  1441. var y:BigInteger = a.modPow(r, this);
  1442. if (y.compareTo(BigInteger.ONE)!=0 && y.compareTo(n1)!=0) {
  1443. var j:int = 1;
  1444. while (j++<k && y.compareTo(n1)!=0) {
  1445. y = y.modPowInt(2, this);
  1446. if (y.compareTo(BigInteger.ONE)==0) {
  1447. return false;
  1448. }
  1449. }
  1450. if (y.compareTo(n1)!=0) {
  1451. return false;
  1452. }
  1453. }
  1454. }
  1455. return true;
  1456. }
  1457. /**
  1458. * Tweak our BigInteger until it looks prime enough
  1459. *
  1460. * @param bits
  1461. * @param t
  1462. *
  1463. */
  1464. public function primify(bits:int, t:int):void {
  1465. if (!testBit(bits-1)) { // force MSB set
  1466. bitwiseTo(BigInteger.ONE.shiftLeft(bits-1), op_or, this);
  1467. }
  1468. if (isEven()) {
  1469. dAddOffset(1,0); // force odd
  1470. }
  1471. while (!isProbablePrime(t)) {
  1472. dAddOffset(2,0);
  1473. while(bitLength()>bits) subTo(BigInteger.ONE.shiftLeft(bits-1),this);
  1474. }
  1475. }
  1476. }
  1477. }