diff -r 436a31d11f1d -r 70c9688a1486 tweetcast/client/lib/websocket-js/flash-src/third-party/com/hurlant/math/BigInteger.as --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tweetcast/client/lib/websocket-js/flash-src/third-party/com/hurlant/math/BigInteger.as Thu Oct 06 12:39:29 2011 +0200 @@ -0,0 +1,1543 @@ +/** + * BigInteger + * + * An ActionScript 3 implementation of BigInteger (light version) + * Copyright (c) 2007 Henri Torgemane + * + * Derived from: + * The jsbn library, Copyright (c) 2003-2005 Tom Wu + * + * See LICENSE.txt for full license information. + */ +package com.hurlant.math +{ + + import com.hurlant.crypto.prng.Random; + import com.hurlant.util.Hex; + import com.hurlant.util.Memory; + + import flash.utils.ByteArray; + use namespace bi_internal; + + public class BigInteger + { + public static const DB:int = 30; // number of significant bits per chunk + public static const DV:int = (1<0) { + if (p>p)>0) { + m = true; + r = d.toString(36); + } + while (i >= 0) { + if (p>(p+=DB-k); + } else { + d = (a[i]>>(p-=k))&km; + if (p<=0) { + p += DB; + --i; + } + } + if (d>0) { + m = true; + } + if (m) { + r += d.toString(36); + } + } + } + return m?r:"0"; + } + public function toArray(array:ByteArray):uint { + const k:int = 8; + const km:int = (1<<8)-1; + var d:int = 0; + var i:int = t; + var p:int = DB-(i*DB)%k; + var m:Boolean = false; + var c:int = 0; + if (i-->0) { + if (p>p)>0) { + m = true; + array.writeByte(d); + c++; + } + while (i >= 0) { + if (p>(p+=DB-k); + } else { + d = (a[i]>>(p-=k))&km; + if (p<=0) { + p += DB; + --i; + } + } + if (d>0) { + m = true; + } + if (m) { + array.writeByte(d); + c++; + } + } + } + return c; + } + /** + * best-effort attempt to fit into a Number. + * precision can be lost if it just can't fit. + */ + public function valueOf():Number { + if (s==-1) { + return -negate().valueOf(); + } + var coef:Number = 1; + var value:Number = 0; + for (var i:uint=0;i v, - if this < v, 0 if equal + */ + public function compareTo(v:BigInteger):int { + var r:int = s - v.s; + if (r!=0) { + return r; + } + var i:int = t; + r = i-v.t; + if (r!=0) { + return r; + } + while (--i >=0) { + r=a[i]-v.a[i]; + if (r != 0) return r; + } + return 0; + } + /** + * returns bit length of the integer x + */ + bi_internal function nbits(x:int):int { + var r:int = 1; + var t:int; + if ((t=x>>>16) != 0) { x = t; r += 16; } + if ((t=x>>8) != 0) { x = t; r += 8; } + if ((t=x>>4) != 0) { x = t; r += 4; } + if ((t=x>>2) != 0) { x = t; r += 2; } + if ((t=x>>1) != 0) { x = t; r += 1; } + return r; + } + /** + * returns the number of bits in this + */ + public function bitLength():int { + if (t<=0) return 0; + return DB*(t-1)+nbits(a[t-1]^(s&DM)); + } + /** + * + * @param v + * @return this % v + * + */ + public function mod(v:BigInteger):BigInteger { + var r:BigInteger = nbi(); + abs().divRemTo(v,null,r); + if (s<0 && r.compareTo(ZERO)>0) { + v.subTo(r,r); + } + return r; + } + /** + * this^e % m, 0 <= e < 2^32 + */ + public function modPowInt(e:int, m:BigInteger):BigInteger { + var z:IReduction; + if (e<256 || m.isEven()) { + z = new ClassicReduction(m); + } else { + z = new MontgomeryReduction(m); + } + return exp(e, z); + } + + /** + * copy this to r + */ + bi_internal function copyTo(r:BigInteger):void { + for (var i:int = t-1; i>=0; --i) { + r.a[i] = a[i]; + } + r.t = t; + r.s = s; + } + /** + * set from integer value "value", -DV <= value < DV + */ + bi_internal function fromInt(value:int):void { + t = 1; + s = (value<0)?-1:0; + if (value>0) { + a[0] = value; + } else if (value<-1) { + a[0] = value+DV; + } else { + t = 0; + } + } + /** + * set from ByteArray and length, + * starting a current position + * If length goes beyond the array, pad with zeroes. + */ + bi_internal function fromArray(value:ByteArray, length:int, unsigned:Boolean = false):void { + var p:int = value.position; + var i:int = p+length; + var sh:int = 0; + const k:int = 8; + t = 0; + s = 0; + while (--i >= p) { + var x:int = i DB) { + a[t-1] |= (x&((1<<(DB-sh))-1))<>(DB-sh); + } else { + a[t-1] |= x<= DB) sh -= DB; + } + if (!unsigned && (value[0]&0x80)==0x80) { + s = -1; + if (sh > 0) { + a[t-1] |= ((1<<(DB-sh))-1)<0 && a[t-1]==c) { + --t; + } + } + /** + * r = this << n*DB + */ + bi_internal function dlShiftTo(n:int, r:BigInteger):void { + var i:int; + for (i=t-1; i>=0; --i) { + r.a[i+n] = a[i]; + } + for (i=n-1; i>=0; --i) { + r.a[i] = 0; + } + r.t = t+n; + r.s = s; + } + /** + * r = this >> n*DB + */ + bi_internal function drShiftTo(n:int, r:BigInteger):void { + var i:int; + for (i=n; i=0; --i) { + r.a[i+ds+1] = (a[i]>>cbs)|c; + c = (a[i]&bm)<=0; --i) { + r.a[i] = 0; + } + r.a[ds] = c; + r.t = t+ds+1; + r.s = s; + r.clamp(); + } + /** + * r = this >> n + */ + bi_internal function rShiftTo(n:int, r:BigInteger):void { + r.s = s; + var ds:int = n/DB; + if (ds >= t) { + r.t = 0; + return; + } + var bs:int = n%DB; + var cbs:int = DB-bs; + var bm:int = (1<>bs; + var i:int; + for (i=ds+1; i>bs; + } + if (bs>0) { + r.a[t-ds-1] |= (s&bm)<>= DB; + } + if (v.t < t) { + c -= v.s; + while (i< t) { + c+= a[i]; + r.a[i++] = c&DM; + c >>= DB; + } + c += s; + } else { + c += s; + while (i < v.t) { + c -= v.a[i]; + r.a[i++] = c&DM; + c >>= DB; + } + c -= v.s; + } + r.s = (c<0)?-1:0; + if (c<-1) { + r.a[i++] = DV+c; + } else if (c>0) { + r.a[i++] = c; + } + r.t = i; + r.clamp(); + } + /** + * am: Compute w_j += (x*this_i), propagates carries, + * c is initial carry, returns final carry. + * c < 3*dvalue, x < 2*dvalue, this_i < dvalue + */ + bi_internal function am(i:int,x:int,w:BigInteger,j:int,c:int,n:int):int { + var xl:int = x&0x7fff; + var xh:int = x>>15; + while(--n >= 0) { + var l:int = a[i]&0x7fff; + var h:int = a[i++]>>15; + var m:int = xh*l + h*xl; + l = xl*l + ((m&0x7fff)<<15)+w.a[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w.a[j++] = l&0x3fffffff; + } + return c; + } + /** + * r = this * v, r != this,a (HAC 14.12) + * "this" should be the larger one if appropriate + */ + bi_internal function multiplyTo(v:BigInteger, r:BigInteger):void { + var x:BigInteger = abs(); + var y:BigInteger = v.abs(); + var i:int = x.t; + r.t = i+y.t; + while (--i >= 0) { + r.a[i] = 0; + } + for (i=0; i=0) r.a[i] = 0; + for (i=0; i= DV) { + r.a[i+x.t] -= DV; + r.a[i+x.t+1] = 1; + } + } + if (r.t>0) { + r.a[r.t-1] += x.am(i, x.a[i], r, 2*i, 0, 1); + } + r.s = 0; + r.clamp(); + } + /** + * divide this by m, quotient and remainder to q, r (HAC 14.20) + * r != q, this != m. q or r may be null. + */ + bi_internal function divRemTo(m:BigInteger, q:BigInteger = null, r:BigInteger = null):void { + var pm:BigInteger = m.abs(); + if (pm.t <= 0) return; + var pt:BigInteger = abs(); + if (pt.t < pm.t) { + if (q!=null) q.fromInt(0); + if (r!=null) copyTo(r); + return; + } + if (r==null) r = nbi(); + var y:BigInteger = nbi(); + var ts:int = s; + var ms:int = m.s; + var nsh:int = DB-nbits(pm.a[pm.t-1]); // normalize modulus + if (nsh>0) { + pm.lShiftTo(nsh, y); + pt.lShiftTo(nsh, r); + } else { + pm.copyTo(y); + pt.copyTo(r); + } + var ys:int = y.t; + var y0:int = y.a[ys-1]; + if (y0==0) return; + var yt:Number = y0*(1<1)?y.a[ys-2]>>F2:0); + var d1:Number = FV/yt; + var d2:Number = (1<=0) { + r.a[r.t++] = 1; + r.subTo(t,r); + } + ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later. + while(y.t= 0) { + // Estimate quotient digit + var qd:int = (r.a[--i]==y0)?DM:Number(r.a[i])*d1+(Number(r.a[i-1])+e)*d2; + if ((r.a[i]+= y.am(0, qd, r, j, 0, ys))0) { + r.rShiftTo(nsh, r); // Denormalize remainder + } + if (ts<0) { + ZERO.subTo(r,r); + } + } + /** + * return "-1/this % 2^DB"; useful for Mont. reduction + * justification: + * xy == 1 (mod n) + * xy = 1+km + * xy(2-xy) = (1+km)(1-km) + * x[y(2-xy)] = 1-k^2.m^2 + * x[y(2-xy)] == 1 (mod m^2) + * if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + * should reduce x and y(2-xy) by m^2 at each step to keep size bounded + * [XXX unit test the living shit out of this.] + */ + bi_internal function invDigit():int { + if (t<1) return 0; + var x:int = a[0]; + if ((x&1)==0) return 0; + var y:int = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf )*y)) &0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y)) &0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + // XXX 48 bit ints? Whaaaa? is there an implicit float conversion in here? + y = (y*(2-x*y%DV))%DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?DV-y:-y; + } + /** + * true iff this is even + */ + bi_internal function isEven():Boolean { + return ((t>0)?(a[0]&1):s) == 0; + } + /** + * this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + */ + bi_internal function exp(e:int, z:IReduction):BigInteger { + if (e > 0xffffffff || e < 1) return ONE; + var r:BigInteger = nbi(); + var r2:BigInteger = nbi(); + var g:BigInteger = z.convert(this); + var i:int = nbits(e)-1; + g.copyTo(r); + while(--i>=0) { + z.sqrTo(r, r2); + if ((e&(1<0) { + z.mulTo(r2,g,r); + } else { + var t:BigInteger = r; + r = r2; + r2 = t; + } + + } + return z.revert(r); + } + bi_internal function intAt(str:String, index:int):int { + return parseInt(str.charAt(index), 36); + } + + + protected function nbi():* { + return new BigInteger; + } + /** + * return bigint initialized to value + */ + public static function nbv(value:int):BigInteger { + var bn:BigInteger = new BigInteger; + bn.fromInt(value); + return bn; + } + + + // Functions above are sufficient for RSA encryption. + // The stuff below is useful for decryption and key generation + + 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]; + public static const lplim:int = (1<<26)/lowprimes[lowprimes.length-1]; + + + public function clone():BigInteger { + var r:BigInteger = new BigInteger; + this.copyTo(r); + return r; + } + + /** + * + * @return value as integer + * + */ + public function intValue():int { + if (s<0) { + if (t==1) { + return a[0]-DV; + } else if (t==0) { + return -1; + } + } else if (t==1) { + return a[0]; + } else if (t==0) { + return 0; + } + // assumes 16 < DB < 32 + return ((a[1]&((1<<(32-DB))-1))<>24; + } + + /** + * + * @return value as short (assumes DB>=16) + * + */ + public function shortValue():int { + return (t==0)?s:(a[0]<<16)>>16; + } + + /** + * + * @param r + * @return x s.t. r^x < DV + * + */ + protected function chunkSize(r:Number):int { + return Math.floor(Math.LN2*DB/Math.log(r)); + } + + /** + * + * @return 0 if this ==0, 1 if this >0 + * + */ + public function sigNum():int { + if (s<0) { + return -1; + } else if (t<=0 || (t==1 && a[0]<=0)) { + return 0; + } else{ + return 1; + } + } + + /** + * + * @param b: radix to use + * @return a string representing the integer converted to the radix. + * + */ + protected function toRadix(b:uint=10):String { + if (sigNum()==0 || b<2 || b>32) return "0"; + var cs:int = chunkSize(b); + var a:Number = Math.pow(b, cs); + var d:BigInteger = nbv(a); + var y:BigInteger = nbi(); + var z:BigInteger = nbi(); + var r:String = ""; + divRemTo(d, y, z); + while (y.sigNum()>0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; + } + + /** + * + * @param s a string to convert from using radix. + * @param b a radix + * + */ + protected function fromRadix(s:String, b:int = 10):void { + fromInt(0); + var cs:int = chunkSize(b); + var d:Number = Math.pow(b, cs); + var mi:Boolean = false; + var j:int = 0; + var w:int = 0; + for (var i:int=0;i= cs) { + dMultiply(d); + dAddOffset(w,0); + j=0; + w=0; + } + } + if (j>0) { + dMultiply(Math.pow(b,j)); + dAddOffset(w,0); + } + if (mi) { + BigInteger.ZERO.subTo(this, this); + } + } + + // XXX function fromNumber not written yet. + + /** + * + * @return a byte array. + * + */ + public function toByteArray():ByteArray { + var i:int = t; + var r:ByteArray = new ByteArray; + r[0] = s; + var p:int = DB-(i*DB)%8; + var d:int; + var k:int=0; + if (i-->0) { + if (p>p)!=(s&DM)>>p) { + r[k++] = d|(s<<(DB-p)); + } + while (i>=0) { + if(p<8) { + d = (a[i]&((1<>(p+=DB-8); + } else { + d = (a[i]>>(p-=8))&0xff; + if (p<=0) { + p += DB; + --i; + } + } + if ((d&0x80)!=0) d|=-256; + if (k==0 && (s&0x80)!=(d&0x80)) ++k; + if (k>0 || d!=s) r[k++] = d; + } + } + return r; + } + + public function equals(a:BigInteger):Boolean { + return compareTo(a)==0; + } + public function min(a:BigInteger):BigInteger { + return (compareTo(a)<0)?this:a; + } + public function max(a:BigInteger):BigInteger { + return (compareTo(a)>0)?this:a; + } + + /** + * + * @param a a BigInteger to perform the operation with + * @param op a Function implementing the operation + * @param r a BigInteger to store the result of the operation + * + */ + protected function bitwiseTo(a:BigInteger, op:Function, r:BigInteger):void { + var i:int; + var f:int; + var m:int = Math.min(a.t, t); + for (i=0; i>= 16; r += 16; } + if ((x&0xff) == 0) { x>>= 8; r += 8; } + if ((x&0xf) == 0) { x>>= 4; r += 4; } + if ((x&0x3) == 0) { x>>= 2; r += 2; } + if ((x&0x1) == 0) ++r; + return r; + } + + /** + * + * @return index of lowest 1-bit (or -1 if none) + * + */ + public function getLowestSetBit():int { + for (var i:int=0;i=t) { + return s!=0; + } + return ((a[j]&(1<<(n%DB)))!=0); + } + + /** + * + * @param n + * @param op + * @return this op (1<>=DB; + } + if (a.t < t) { + c += a.s; + while (i>= DB; + } + c += s; + } else { + c += s; + while (i>= DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if (c>0) { + r.a[i++] = c; + } else if (c<-1) { + r.a[i++] = DV+c; + } + r.t = i; + r.clamp(); + } + + /** + * + * @param a + * @return this + a + * + */ + public function add(a:BigInteger):BigInteger { + var r:BigInteger = new BigInteger; + addTo(a,r); + return r; + } + + /** + * + * @param a + * @return this - a + * + */ + public function subtract(a:BigInteger):BigInteger { + var r:BigInteger = new BigInteger; + subTo(a,r); + return r; + } + + /** + * + * @param a + * @return this * a + * + */ + public function multiply(a:BigInteger):BigInteger { + var r:BigInteger = new BigInteger; + multiplyTo(a,r); + return r; + } + + /** + * + * @param a + * @return this / a + * + */ + public function divide(a:BigInteger):BigInteger { + var r:BigInteger = new BigInteger; + divRemTo(a, r, null); + return r; + } + + public function remainder(a:BigInteger):BigInteger { + var r:BigInteger = new BigInteger; + divRemTo(a, null, r); + return r; + } + + /** + * + * @param a + * @return [this/a, this%a] + * + */ + public function divideAndRemainder(a:BigInteger):Array { + var q:BigInteger = new BigInteger; + var r:BigInteger = new BigInteger; + divRemTo(a, q, r); + return [q,r]; + } + + /** + * + * this *= n, this >=0, 1 < n < DV + * + * @param n + * + */ + bi_internal function dMultiply(n:int):void { + a[t] = am(0, n-1, this, 0, 0, t); + ++t; + clamp(); + } + + /** + * + * this += n << w words, this >= 0 + * + * @param n + * @param w + * + */ + bi_internal function dAddOffset(n:int, w:int):void { + while (t<=w) { + a[t++] = 0; + } + a[w] += n; + while (a[w] >= DV) { + a[w] -= DV; + if (++w >= t) { + a[t++] = 0; + } + ++a[w]; + } + } + + /** + * + * @param e + * @return this^e + * + */ + public function pow(e:int):BigInteger { + return exp(e, new NullReduction); + } + + /** + * + * @param a + * @param n + * @param r = lower n words of "this * a", a.t <= n + * + */ + bi_internal function multiplyLowerTo(a:BigInteger, n:int, r:BigInteger):void { + var i:int = Math.min(t+a.t, n); + r.s = 0; // assumes a, this >= 0 + r.t = i; + while (i>0) { + r.a[--i]=0; + } + var j:int; + for (j=r.t-t;i 0 + * + */ + bi_internal function multiplyUpperTo(a:BigInteger, n:int, r:BigInteger):void { + --n; + var i:int = r.t = t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while (--i>=0) { + r.a[i] = 0; + } + for (i=Math.max(n-t,0);i 1) { + var g2:BigInteger = new BigInteger; + z.sqrTo(g[1], g2); + while (n<=km) { + g[n] = new BigInteger; + z.mulTo(g2, g[n-2], g[n]); + n += 2; + } + } + + var j:int = e.t-1; + var w:int; + var is1:Boolean = true; + var r2:BigInteger = new BigInteger; + var t:BigInteger; + i = nbits(e.a[j])-1; + while (j>=0) { + if (i>=k1) { + w = (e.a[j]>>(i-k1))&km; + } else { + w = (e.a[j]&((1<<(i+1))-1))<<(k1-i); + if (j>0) { + w |= e.a[j-1]>>(DB+i-k1); + } + } + n = k; + while ((w&1)==0) { + w >>= 1; + --n; + } + if ((i -= n) <0) { + i += DB; + --j; + } + if (is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } else { + while (n>1) { + z.sqrTo(r, r2); + z.sqrTo(r2, r); + n -= 2; + } + if (n>0) { + z.sqrTo(r, r2); + } else { + t = r; + r = r2; + r2 = t; + } + z.mulTo(r2, g[w], r); + } + while (j>=0 && (e.a[j]&(1<0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.sigNum()>0) { + if ((i = x.getLowestSetBit()) >0) { + x.rShiftTo(i, x); + } + if ((i = y.getLowestSetBit()) >0) { + y.rShiftTo(i, y); + } + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g>0) { + y.lShiftTo(g, y); + } + return y; + } + + /** + * + * @param n + * @return this % n, n < 2^DB + * + */ + protected function modInt(n:int):int { + if (n<=0) return 0; + var d:int = DV%n; + var r:int = (s<0)?n-1:0; + if (t>0) { + if (d==0) { + r = a[0]%n; + } else { + for (var i:int=t-1;i>=0;--i) { + r = (d*r+a[i])%n; + } + } + } + return r; + } + + /** + * + * @param m + * @return 1/this %m (HAC 14.61) + * + */ + public function modInverse(m:BigInteger):BigInteger { + var ac:Boolean = m.isEven(); + if ((isEven()&&ac) || m.sigNum()==0) { + return BigInteger.ZERO; + } + var u:BigInteger = m.clone(); + var v:BigInteger = clone(); + var a:BigInteger = nbv(1); + var b:BigInteger = nbv(0); + var c:BigInteger = nbv(0); + var d:BigInteger = nbv(1); + while (u.sigNum()!=0) { + while (u.isEven()) { + u.rShiftTo(1,u); + if (ac) { + if (!a.isEven() || !b.isEven()) { + a.addTo(this,a); + b.subTo(m,b); + } + a.rShiftTo(1,a); + } else if (!b.isEven()) { + b.subTo(m,b); + } + b.rShiftTo(1,b); + } + while (v.isEven()) { + v.rShiftTo(1,v); + if (ac) { + if (!c.isEven() || !d.isEven()) { + c.addTo(this,c); + d.subTo(m,d); + } + c.rShiftTo(1,c); + } else if (!d.isEven()) { + d.subTo(m,d); + } + d.rShiftTo(1,d); + } + if (u.compareTo(v)>=0) { + u.subTo(v,u); + if (ac) { + a.subTo(c,a); + } + b.subTo(d,b); + } else { + v.subTo(u,v); + if (ac) { + c.subTo(a,c); + } + d.subTo(b,d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) { + return BigInteger.ZERO; + } + if (d.compareTo(m) >= 0) { + return d.subtract(m); + } + if (d.sigNum()<0) { + d.addTo(m,d); + } else { + return d; + } + if (d.sigNum()<0) { + return d.add(m); + } else { + return d; + } + } + + /** + * + * @param t + * @return primality with certainty >= 1-.5^t + * + */ + public function isProbablePrime(t:int):Boolean { + var i:int; + var x:BigInteger = abs(); + if (x.t == 1 && x.a[0]<=lowprimes[lowprimes.length-1]) { + for (i=0;i>1; + if (t>lowprimes.length) { + t = lowprimes.length; + } + var a:BigInteger = new BigInteger; + for (var i:int=0;ibits) subTo(BigInteger.ONE.shiftLeft(bits-1),this); + } + } + + } +}