PageRenderTime 101ms CodeModel.GetById 24ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 14ms

/flash-src/third-party/com/hurlant/math/BigInteger.as

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