>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);
+ }
+ }
+
+ }
+}
diff --git a/include/as3crypto_patched/src/com/hurlant/math/ClassicReduction.as b/include/as3crypto_patched/src/com/hurlant/math/ClassicReduction.as
new file mode 100755
index 00000000..ea9f17cf
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/math/ClassicReduction.as
@@ -0,0 +1,35 @@
+package com.hurlant.math
+{
+ use namespace bi_internal;
+
+ /**
+ * Modular reduction using "classic" algorithm
+ */
+ internal class ClassicReduction implements IReduction
+ {
+ private var m:BigInteger;
+ public function ClassicReduction(m:BigInteger) {
+ this.m = m;
+ }
+ public function convert(x:BigInteger):BigInteger {
+ if (x.s<0 || x.compareTo(m)>=0) {
+ return x.mod(m);
+ }
+ return x;
+ }
+ public function revert(x:BigInteger):BigInteger {
+ return x;
+ }
+ public function reduce(x:BigInteger):void {
+ x.divRemTo(m, null,x);
+ }
+ public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void {
+ x.multiplyTo(y,r);
+ reduce(r);
+ }
+ public function sqrTo(x:BigInteger, r:BigInteger):void {
+ x.squareTo(r);
+ reduce(r);
+ }
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/math/IReduction.as b/include/as3crypto_patched/src/com/hurlant/math/IReduction.as
new file mode 100755
index 00000000..210a0543
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/math/IReduction.as
@@ -0,0 +1,11 @@
+package com.hurlant.math
+{
+ internal interface IReduction
+ {
+ function convert(x:BigInteger):BigInteger;
+ function revert(x:BigInteger):BigInteger;
+ function reduce(x:BigInteger):void;
+ function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void;
+ function sqrTo(x:BigInteger, r:BigInteger):void;
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/math/MontgomeryReduction.as b/include/as3crypto_patched/src/com/hurlant/math/MontgomeryReduction.as
new file mode 100755
index 00000000..47a16d6f
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/math/MontgomeryReduction.as
@@ -0,0 +1,85 @@
+package com.hurlant.math
+{
+ use namespace bi_internal;
+ /**
+ * Montgomery reduction
+ */
+ internal class MontgomeryReduction implements IReduction
+ {
+ private var m:BigInteger;
+ private var mp:int;
+ private var mpl:int;
+ private var mph:int;
+ private var um:int;
+ private var mt2:int;
+ public function MontgomeryReduction(m:BigInteger) {
+ this.m = m;
+ mp = m.invDigit();
+ mpl = mp & 0x7fff;
+ mph = mp>>15;
+ um = (1<<(BigInteger.DB-15))-1;
+ mt2 = 2*m.t;
+ }
+ /**
+ * xR mod m
+ */
+ public function convert(x:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ x.abs().dlShiftTo(m.t, r);
+ r.divRemTo(m, null, r);
+ if (x.s<0 && r.compareTo(BigInteger.ZERO)>0) {
+ m.subTo(r,r);
+ }
+ return r;
+ }
+ /**
+ * x/R mod m
+ */
+ public function revert(x:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ x.copyTo(r);
+ reduce(r);
+ return r;
+ }
+ /**
+ * x = x/R mod m (HAC 14.32)
+ */
+ public function reduce(x:BigInteger):void {
+ while (x.t<=mt2) { // pad x so am has enough room later
+ x.a[x.t++] = 0;
+ }
+ for (var i:int=0; i>15)*mpl)&um)<<15))&BigInteger.DM;
+ // use am to combine the multiply-shift-add into one call
+ j = i+m.t;
+ x.a[j] += m.am(0, u0, x, i, 0, m.t);
+ // propagate carry
+ while (x.a[j]>=BigInteger.DV) {
+ x.a[j] -= BigInteger.DV;
+ x.a[++j]++;
+ }
+ }
+ x.clamp();
+ x.drShiftTo(m.t, x);
+ if (x.compareTo(m)>=0) {
+ x.subTo(m,x);
+ }
+ }
+ /**
+ * r = "x^2/R mod m"; x != r
+ */
+ public function sqrTo(x:BigInteger, r:BigInteger):void {
+ x.squareTo(r);
+ reduce(r);
+ }
+ /**
+ * r = "xy/R mod m"; x,y != r
+ */
+ public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void {
+ x.multiplyTo(y,r);
+ reduce(r);
+ }
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/math/NullReduction.as b/include/as3crypto_patched/src/com/hurlant/math/NullReduction.as
new file mode 100755
index 00000000..5b55832e
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/math/NullReduction.as
@@ -0,0 +1,34 @@
+package com.hurlant.math
+{
+ use namespace bi_internal;
+ /**
+ * A "null" reducer
+ */
+ public class NullReduction implements IReduction
+ {
+ public function revert(x:BigInteger):BigInteger
+ {
+ return x;
+ }
+
+ public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void
+ {
+ x.multiplyTo(y,r);
+ }
+
+ public function sqrTo(x:BigInteger, r:BigInteger):void
+ {
+ x.squareTo(r);
+ }
+
+ public function convert(x:BigInteger):BigInteger
+ {
+ return x;
+ }
+
+ public function reduce(x:BigInteger):void
+ {
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/math/bi_internal.as b/include/as3crypto_patched/src/com/hurlant/math/bi_internal.as
new file mode 100755
index 00000000..dc86aad7
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/math/bi_internal.as
@@ -0,0 +1,11 @@
+/**
+ * bi_internal
+ *
+ * A namespace. w00t.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.math {
+ public namespace bi_internal = "http://crypto.hurlant.com/BigInteger";
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/ArrayUtil.as b/include/as3crypto_patched/src/com/hurlant/util/ArrayUtil.as
new file mode 100755
index 00000000..b02b8d52
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/util/ArrayUtil.as
@@ -0,0 +1,25 @@
+/**
+ * ArrayUtil
+ *
+ * A class that allows to compare two ByteArrays.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util {
+ import flash.utils.ByteArray;
+
+
+ public class ArrayUtil {
+
+ public static function equals(a1:ByteArray, a2:ByteArray):Boolean {
+ if (a1.length != a2.length) return false;
+ var l:int = a1.length;
+ for (var i:int=0;i
+ * LastModified: Oct 26, 2009
+ * This library is free. You can redistribute it and/or modify it.
+ */
+package com.hurlant.util{
+ import flash.utils.ByteArray;
+
+ public class Base64
+ {
+ private static const _encodeChars : Vector. = InitEncoreChar();
+ private static const _decodeChars : Vector. = InitDecodeChar();
+
+ public static function encodeByteArray(data : ByteArray) : String
+ {
+ var out : ByteArray = new ByteArray();
+ //Presetting the length keep the memory smaller and optimize speed since there is no "grow" needed
+ out.length = (2 + data.length - ((data.length + 2) % 3)) * 4 / 3; //Preset length //1.6 to 1.5 ms
+ var i : int = 0;
+ var r : int = data.length % 3;
+ var len : int = data.length - r;
+ var c : int; //read (3) character AND write (4) characters
+
+ while (i < len)
+ {
+ //Read 3 Characters (8bit * 3 = 24 bits)
+ c = data[i++] << 16 | data[i++] << 8 | data[i++];
+
+ //Cannot optimize this to read int because of the positioning overhead. (as3 bytearray seek is slow)
+ //Convert to 4 Characters (6 bit * 4 = 24 bits)
+ c = (_encodeChars[c >>> 18] << 24) | (_encodeChars[c >>> 12 & 0x3f] << 16) | (_encodeChars[c >>> 6 & 0x3f] << 8) | _encodeChars[c & 0x3f];
+
+ //Optimization: On older and slower computer, do one write Int instead of 4 write byte: 1.5 to 0.71 ms
+ out.writeInt(c);
+ /*
+ out.writeByte(_encodeChars[c >> 18] );
+ out.writeByte(_encodeChars[c >> 12 & 0x3f]);
+ out.writeByte(_encodeChars[c >> 6 & 0x3f]);
+ out.writeByte(_encodeChars[c & 0x3f]);
+ */
+ }
+
+ if (r == 1) //Need two "=" padding
+ {
+ //Read one char, write two chars, write padding
+ c = data[i];
+ c = (_encodeChars[c >>> 2] << 24) | (_encodeChars[(c & 0x03) << 4] << 16) | 61 << 8 | 61;
+ out.writeInt(c);
+ }
+ else if (r == 2) //Need one "=" padding
+ {
+ c = data[i++] << 8 | data[i];
+ c = (_encodeChars[c >>> 10] << 24) | (_encodeChars[c >>> 4 & 0x3f] << 16) | (_encodeChars[(c & 0x0f) << 2] << 8) | 61;
+ out.writeInt(c);
+ }
+
+ out.position = 0;
+ return out.readUTFBytes(out.length);
+ }
+
+
+ public static function decodeToByteArray(str : String) : ByteArray
+ {
+ var c1 : int;
+ var c2 : int;
+ var c3 : int;
+ var c4 : int;
+ var i : int;
+ var len : int;
+ var out : ByteArray;
+ len = str.length;
+ i = 0;
+ out = new ByteArray();
+ var byteString : ByteArray = new ByteArray();
+ byteString.writeUTFBytes(str);
+ while (i < len)
+ {
+ //c1
+ do
+ {
+ c1 = _decodeChars[byteString[i++]];
+ } while (i < len && c1 == -1);
+ if (c1 == -1) break;
+
+ //c2
+ do
+ {
+ c2 = _decodeChars[byteString[i++]];
+ } while (i < len && c2 == -1);
+ if (c2 == -1) break;
+
+ out.writeByte((c1 << 2) | ((c2 & 0x30) >> 4));
+
+ //c3
+ do
+ {
+ c3 = byteString[i++];
+ if (c3 == 61) return out;
+
+ c3 = _decodeChars[c3];
+ } while (i < len && c3 == -1);
+ if (c3 == -1) break;
+
+ out.writeByte(((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2));
+
+ //c4
+ do {
+ c4 = byteString[i++];
+ if (c4 == 61) return out;
+
+ c4 = _decodeChars[c4];
+ } while (i < len && c4 == -1);
+ if (c4 == -1) break;
+
+ out.writeByte(((c3 & 0x03) << 6) | c4);
+
+ }
+
+ out.position = 0;
+
+ return out;
+ }
+
+ public static function encode(data : String) : String {
+ // Convert string to ByteArray
+ var bytes : ByteArray = new ByteArray();
+ bytes.writeUTFBytes(data);
+
+ // Return encoded ByteArray
+ return encodeByteArray(bytes);
+ }
+
+ public static function decode(data : String) : String {
+ // Decode data to ByteArray
+ var bytes : ByteArray = decodeToByteArray(data);
+
+ // Convert to string and return
+ return bytes.readUTFBytes(bytes.length);
+ }
+
+ public static function InitEncoreChar() : Vector.
+ {
+ var encodeChars : Vector. = new Vector.();
+ // We could push the number directly, but i think it's nice to see the characters (with no overhead on encode/decode)
+ var chars : String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ for (var i : int = 0; i < 64; i++)
+ {
+ encodeChars.push(chars.charCodeAt(i));
+ }
+ /*
+ encodeChars.push(
+ 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 97, 98, 99, 100, 101, 102,
+ 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 43, 47);
+ */
+ return encodeChars;
+ }
+
+ public static function InitDecodeChar() : Vector.
+ {
+ var decodeChars : Vector. = new Vector.();
+
+ decodeChars.push(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
+ - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ return decodeChars;
+ }
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/Hex.as b/include/as3crypto_patched/src/com/hurlant/util/Hex.as
new file mode 100755
index 00000000..98d887b9
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/util/Hex.as
@@ -0,0 +1,66 @@
+/**
+ * Hex
+ *
+ * Utility class to convert Hex strings to ByteArray or String types.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util
+{
+ import flash.utils.ByteArray;
+
+ public class Hex
+ {
+ /**
+ * Support straight hex, or colon-laced hex.
+ * (that means 23:03:0e:f0, but *NOT* 23:3:e:f0)
+ * Whitespace characters are ignored.
+ */
+ public static function toArray(hex:String):ByteArray {
+ hex = hex.replace(/\s|:/gm,'');
+ var a:ByteArray = new ByteArray;
+ if (hex.length&1==1) hex="0"+hex;
+ for (var i:uint=0;i=0x80) {
+ // long form of length
+ var count:int = len & 0x7f;
+ len = 0;
+ while (count>0) {
+ len = (len<<8) | der.readUnsignedByte();
+ count--;
+ }
+ }
+ // data
+ var b:ByteArray
+ switch (type) {
+ case 0x00: // WHAT IS THIS THINGY? (seen as 0xa0)
+ // (note to self: read a spec someday.)
+ // for now, treat as a sequence.
+ case 0x10: // SEQUENCE/SEQUENCE OF. whatever
+ // treat as an array
+ var p:int = der.position;
+ var o:Sequence = new Sequence(type, len);
+ var arrayStruct:Array = structure as Array;
+ if (arrayStruct!=null) {
+ // copy the array, as we destroy it later.
+ arrayStruct = arrayStruct.concat();
+ }
+ while (der.position < p+len) {
+ var tmpStruct:Object = null
+ if (arrayStruct!=null) {
+ tmpStruct = arrayStruct.shift();
+ }
+ if (tmpStruct!=null) {
+ while (tmpStruct && tmpStruct.optional) {
+ // make sure we have something that looks reasonable. XXX I'm winging it here..
+ var wantConstructed:Boolean = (tmpStruct.value is Array);
+ var isConstructed:Boolean = isConstructedType(der);
+ if (wantConstructed!=isConstructed) {
+ // not found. put default stuff, or null
+ o.push(tmpStruct.defaultValue);
+ o[tmpStruct.name] = tmpStruct.defaultValue;
+ // try the next thing
+ tmpStruct = arrayStruct.shift();
+ } else {
+ break;
+ }
+ }
+ }
+ if (tmpStruct!=null) {
+ var name:String = tmpStruct.name;
+ var value:* = tmpStruct.value;
+ if (tmpStruct.extract) {
+ // we need to keep a binary copy of this element
+ var size:int = getLengthOfNextElement(der);
+ var ba:ByteArray = new ByteArray;
+ ba.writeBytes(der, der.position, size);
+ o[name+"_bin"] = ba;
+ }
+ var obj:IAsn1Type = DER.parse(der, value);
+ o.push(obj);
+ o[name] = obj;
+ } else {
+ o.push(DER.parse(der));
+ }
+ }
+ return o;
+ case 0x11: // SET/SET OF
+ p = der.position;
+ var s:Set = new Set(type, len);
+ while (der.position < p+len) {
+ s.push(DER.parse(der));
+ }
+ return s;
+ case 0x02: // INTEGER
+ // put in a BigInteger
+ b = new ByteArray;
+ der.readBytes(b,0,len);
+ b.position=0;
+ return new Integer(type, len, b);
+ case 0x06: // OBJECT IDENTIFIER:
+ b = new ByteArray;
+ der.readBytes(b,0,len);
+ b.position=0;
+ return new ObjectIdentifier(type, len, b);
+ default:
+ trace("I DONT KNOW HOW TO HANDLE DER stuff of TYPE "+type);
+ // fall through
+ case 0x03: // BIT STRING
+ if (der[der.position]==0) {
+ //trace("Horrible Bit String pre-padding removal hack."); // I wish I had the patience to find a spec for this.
+ der.position++;
+ len--;
+ }
+ case 0x04: // OCTET STRING
+ // stuff in a ByteArray for now.
+ var bs:ByteString = new ByteString(type, len);
+ der.readBytes(bs,0,len);
+ return bs;
+ case 0x05: // NULL
+ // if len!=0, something's horribly wrong.
+ // should I check?
+ return null;
+ case 0x13: // PrintableString
+ var ps:PrintableString = new PrintableString(type, len);
+ ps.setString(der.readMultiByte(len, "US-ASCII"));
+ return ps;
+ case 0x22: // XXX look up what this is. openssl uses this to store my email.
+ case 0x14: // T61String - an horrible format we don't even pretend to support correctly
+ ps = new PrintableString(type, len);
+ ps.setString(der.readMultiByte(len, "latin1"));
+ return ps;
+ case 0x17: // UTCTime
+ var ut:UTCTime = new UTCTime(type, len);
+ ut.setUTCTime(der.readMultiByte(len, "US-ASCII"));
+ return ut;
+ }
+ }
+
+ private static function getLengthOfNextElement(b:ByteArray):int {
+ var p:uint = b.position;
+ // length
+ b.position++;
+ var len:int = b.readUnsignedByte();
+ if (len>=0x80) {
+ // long form of length
+ var count:int = len & 0x7f;
+ len = 0;
+ while (count>0) {
+ len = (len<<8) | b.readUnsignedByte();
+ count--;
+ }
+ }
+ len += b.position-p; // length of length
+ b.position = p;
+ return len;
+ }
+ private static function isConstructedType(b:ByteArray):Boolean {
+ var type:int = b[b.position];
+ return (type&0x20)!=0;
+ }
+
+ public static function wrapDER(type:int, data:ByteArray):ByteArray {
+ var d:ByteArray = new ByteArray;
+ d.writeByte(type);
+ var len:int = data.length;
+ if (len<128) {
+ d.writeByte(len);
+ } else if (len<256) {
+ d.writeByte(1 | 0x80);
+ d.writeByte(len);
+ } else if (len<65536) {
+ d.writeByte(2 | 0x80);
+ d.writeByte(len>>8);
+ d.writeByte(len);
+ } else if (len<65536*256) {
+ d.writeByte(3 | 0x80);
+ d.writeByte(len>>16);
+ d.writeByte(len>>8);
+ d.writeByte(len);
+ } else {
+ d.writeByte(4 | 0x80);
+ d.writeByte(len>>24);
+ d.writeByte(len>>16);
+ d.writeByte(len>>8);
+ d.writeByte(len);
+ }
+ d.writeBytes(data);
+ d.position=0;
+ return d;
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/IAsn1Type.as b/include/as3crypto_patched/src/com/hurlant/util/der/IAsn1Type.as
new file mode 100755
index 00000000..f4f2112a
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/util/der/IAsn1Type.as
@@ -0,0 +1,21 @@
+/**
+ * IAsn1Type
+ *
+ * An interface for Asn-1 types.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+
+ public interface IAsn1Type
+ {
+ function getType():uint;
+ function getLength():uint;
+
+ function toDER():ByteArray;
+
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/Integer.as b/include/as3crypto_patched/src/com/hurlant/util/der/Integer.as
new file mode 100755
index 00000000..e2f045c9
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/util/der/Integer.as
@@ -0,0 +1,44 @@
+/**
+ * Integer
+ *
+ * An ASN1 type for an Integer, represented with a BigInteger
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import com.hurlant.math.BigInteger;
+ import flash.utils.ByteArray;
+
+ public class Integer extends BigInteger implements IAsn1Type
+ {
+ private var type:uint;
+ private var len:uint;
+
+ public function Integer(type:uint, length:uint, b:ByteArray) {
+ this.type = type;
+ this.len = length;
+ super(b);
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ override public function toString(radix:Number=0):String {
+ return DER.indent+"Integer["+type+"]["+len+"]["+super.toString(16)+"]";
+ }
+
+ public function toDER():ByteArray {
+ return null;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/OID.as b/include/as3crypto_patched/src/com/hurlant/util/der/OID.as
new file mode 100755
index 00000000..4d43d955
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/util/der/OID.as
@@ -0,0 +1,35 @@
+/**
+ * OID
+ *
+ * A list of various ObjectIdentifiers.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ public class OID
+ {
+
+ public static const RSA_ENCRYPTION:String = "1.2.840.113549.1.1.1";
+ public static const MD2_WITH_RSA_ENCRYPTION:String = "1.2.840.113549.1.1.2";
+ public static const MD5_WITH_RSA_ENCRYPTION:String = "1.2.840.113549.1.1.4";
+ public static const SHA1_WITH_RSA_ENCRYPTION:String = "1.2.840.113549.1.1.5";
+ public static const MD2_ALGORITHM:String = "1.2.840.113549.2.2";
+ public static const MD5_ALGORITHM:String = "1.2.840.113549.2.5";
+ public static const DSA:String = "1.2.840.10040.4.1";
+ public static const DSA_WITH_SHA1:String = "1.2.840.10040.4.3";
+ public static const DH_PUBLIC_NUMBER:String = "1.2.840.10046.2.1";
+ public static const SHA1_ALGORITHM:String = "1.3.14.3.2.26";
+
+ public static const COMMON_NAME:String = "2.5.4.3";
+ public static const SURNAME:String = "2.5.4.4";
+ public static const COUNTRY_NAME:String = "2.5.4.6";
+ public static const LOCALITY_NAME:String = "2.5.4.7";
+ public static const STATE_NAME:String = "2.5.4.8";
+ public static const ORGANIZATION_NAME:String = "2.5.4.10";
+ public static const ORG_UNIT_NAME:String = "2.5.4.11";
+ public static const TITLE:String = "2.5.4.12";
+
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/ObjectIdentifier.as b/include/as3crypto_patched/src/com/hurlant/util/der/ObjectIdentifier.as
new file mode 100755
index 00000000..932acd7b
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/util/der/ObjectIdentifier.as
@@ -0,0 +1,112 @@
+/**
+ * ObjectIdentifier
+ *
+ * An ASN1 type for an ObjectIdentifier
+ * We store the oid in an Array.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+
+ public class ObjectIdentifier implements IAsn1Type
+ {
+ private var type:uint;
+ private var len:uint;
+ private var oid:Array;
+
+ public function ObjectIdentifier(type:uint, length:uint, b:*) {
+ this.type = type;
+ this.len = length;
+ if (b is ByteArray) {
+ parse(b as ByteArray);
+ } else if (b is String) {
+ generate(b as String);
+ } else {
+ throw new Error("Invalid call to new ObjectIdentifier");
+ }
+ }
+
+ private function generate(s:String):void {
+ oid = s.split(".");
+ }
+
+ private function parse(b:ByteArray):void {
+ // parse stuff
+ // first byte = 40*value1 + value2
+ var o:uint = b.readUnsignedByte();
+ var a:Array = []
+ a.push(uint(o/40));
+ a.push(uint(o%40));
+ var v:uint = 0;
+ while (b.bytesAvailable>0) {
+ o = b.readUnsignedByte();
+ var last:Boolean = (o&0x80)==0;
+ o &= 0x7f;
+ v = v*128 + o;
+ if (last) {
+ a.push(v);
+ v = 0;
+ }
+ }
+ oid = a;
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ public function toDER():ByteArray {
+ var tmp:Array = [];
+ tmp[0] = oid[0]*40 + oid[1];
+ for (var i:int=2;i>7)|0x80 );
+ tmp.push( v&0x7f );
+ } else if (v<128*128*128) {
+ tmp.push( (v>>14)|0x80 );
+ tmp.push( (v>>7)&0x7f | 0x80 );
+ tmp.push( v&0x7f);
+ } else if (v<128*128*128*128) {
+ tmp.push( (v>>21)|0x80 );
+ tmp.push( (v>>14) & 0x7f | 0x80 );
+ tmp.push( (v>>7) & 0x7f | 0x80 );
+ tmp.push( v & 0x7f );
+ } else {
+ throw new Error("OID element bigger than we thought. :(");
+ }
+ }
+ len = tmp.length;
+ if (type==0) {
+ type = 6;
+ }
+ tmp.unshift(len); // assume length is small enough to fit here.
+ tmp.unshift(type);
+ var b:ByteArray = new ByteArray;
+ for (i=0;i, null ]; ( apparently, that's an X-509 Algorithm Identifier.
+ if (arr[0][0].toString()!=OID.RSA_ENCRYPTION) {
+ return null;
+ }
+ // arr[1] is a ByteArray begging to be parsed as DER
+ arr[1].position = 1; // there's a 0x00 byte up front. find out why later. like, read a spec.
+ obj = DER.parse(arr[1]);
+ if (obj is Array) {
+ arr = obj as Array;
+ // arr[0] = modulus
+ // arr[1] = public expt.
+ return new RSAKey(arr[0], arr[1]);
+ } else {
+ return null;
+ }
+ } else {
+ // dunno
+ return null;
+ }
+ }
+
+ public static function readCertIntoArray(str:String):ByteArray {
+ var tmp:ByteArray = extractBinary(CERTIFICATE_HEADER, CERTIFICATE_FOOTER, str);
+ return tmp;
+ }
+
+ private static function extractBinary(header:String, footer:String, str:String):ByteArray {
+ var i:int = str.indexOf(header);
+ if (i==-1) return null;
+ i += header.length;
+ var j:int = str.indexOf(footer);
+ if (j==-1) return null;
+ var b64:String = str.substring(i, j);
+ // remove whitesapces.
+ b64 = b64.replace(/\s/mg, '');
+ // decode
+ return Base64.decodeToByteArray(b64);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/PrintableString.as b/include/as3crypto_patched/src/com/hurlant/util/der/PrintableString.as
new file mode 100755
index 00000000..ed1775e2
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/util/der/PrintableString.as
@@ -0,0 +1,49 @@
+/**
+ * PrintableString
+ *
+ * An ASN1 type for a PrintableString, held within a String
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+
+ public class PrintableString implements IAsn1Type
+ {
+ protected var type:uint;
+ protected var len:uint;
+ protected var str:String;
+
+ public function PrintableString(type:uint, length:uint) {
+ this.type = type;
+ this.len = length;
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ public function setString(s:String):void {
+ str = s;
+ }
+ public function getString():String {
+ return str;
+ }
+
+ public function toString():String {
+ return DER.indent+str;
+ }
+
+ public function toDER():ByteArray {
+ return null; // XXX not implemented
+ }
+ }
+}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/Sequence.as b/include/as3crypto_patched/src/com/hurlant/util/der/Sequence.as
new file mode 100755
index 00000000..c3524142
--- /dev/null
+++ b/include/as3crypto_patched/src/com/hurlant/util/der/Sequence.as
@@ -0,0 +1,90 @@
+/**
+ * Sequence
+ *
+ * An ASN1 type for a Sequence, implemented as an Array
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+
+ public dynamic class Sequence extends Array implements IAsn1Type
+ {
+ protected var type:uint;
+ protected var len:uint;
+
+ public function Sequence(type:uint = 0x30, length:uint = 0x00) {
+ this.type = type;
+ this.len = length;
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ public function toDER():ByteArray {
+ var tmp:ByteArray = new ByteArray;
+ for (var i:int=0;i
+
+
+ com.Test
+ Test
+ 1.0
+ Test
+ Test
+ (c) 2007
+
+ bin/Test.swf
+ Test
+ standard
+ false
+ true
+ true
+ true
+ true
+ 1024
+ 768
+ 100
+ 50
+ 300 300
+ 800 800
+
+ Test
+ Test
+
+
+
+ false
+ false
+
\ No newline at end of file
diff --git a/include/as3crypto_patched/test/Test.mxml b/include/as3crypto_patched/test/Test.mxml
new file mode 100644
index 00000000..0121fcee
--- /dev/null
+++ b/include/as3crypto_patched/test/Test.mxml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/include/as3crypto_patched/test/suite/AllTests.as b/include/as3crypto_patched/test/suite/AllTests.as
new file mode 100644
index 00000000..a7ac7d5f
--- /dev/null
+++ b/include/as3crypto_patched/test/suite/AllTests.as
@@ -0,0 +1,16 @@
+package suite {
+
+ import flexunit.framework.TestSuite;
+
+ public class AllTests extends TestSuite {
+
+ public function AllTests() {
+ super();
+ // Add tests here
+ // For examples, see: http://code.google.com/p/as3flexunitlib/wiki/Resources
+ //addTest(SomeTest.suite());
+ }
+
+ }
+
+}
\ No newline at end of file