ecdsa works! now time for some tests...

This commit is contained in:
Mike Hamburg 2010-10-07 19:02:59 -07:00
parent 017ff8c82b
commit 624b61197e
5 changed files with 336 additions and 168 deletions

View File

@ -1,14 +1,14 @@
/** /**
* Constructs a new bignum from another bignum, a number or a hex string. * Constructs a new bignum from another bignum, a number or a hex string.
*/ */
function bn(it) { sjcl.bn = function(it) {
this.initWith(it); this.initWith(it);
} }
bn.prototype = { sjcl.bn.prototype = {
radix: 24, radix: 24,
maxMul: 8, maxMul: 8,
_class: bn, _class: sjcl.bn,
copy: function() { copy: function() {
return new this._class(this); return new this._class(this);
@ -103,29 +103,116 @@ bn.prototype = {
/** this += that. Does not normalize. */ /** this += that. Does not normalize. */
addM: function(that) { addM: function(that) {
if (typeof(that) !== "object") { that = new this._class(that); } if (typeof(that) !== "object") { that = new this._class(that); }
var i; var i, l=this.limbs, ll=that.limbs;
for (i=this.limbs.length; i<that.limbs.length; i++) { for (i=l.length; i<ll.length; i++) {
this.limbs[i] = 0; l[i] = 0;
} }
for (i=0; i<that.limbs.length; i++) { for (i=0; i<ll.length; i++) {
this.limbs[i] += that.limbs[i]; l[i] += ll[i];
} }
return this; return this;
}, },
/** this *= 2. Requires normalized; ends up normalized. */
doubleM: function() {
var i, carry=0, tmp, r=this.radix, m=this.radixMask, l=this.limbs;
for (i=0; i<l.length; i++) {
tmp = l[i];
tmp = tmp+tmp+carry;
l[i] = tmp & m;
carry = tmp >> r;
}
if (carry) l.push(carry);
return this;
},
/** this /= 2, rounded down. Requires normalized; ends up normalized. */
halveM: function() {
var i, carry=0, tmp, r=this.radix, l=this.limbs;
for (i=l.length-1; i>=0; i--) {
tmp = l[i];
l[i] = (tmp+carry)>>1;
carry = (tmp&1) << r;
}
if (!l[l.length-1]) l.pop();
return this;
},
/** this -= that. Does not normalize. */ /** this -= that. Does not normalize. */
subM: function(that) { subM: function(that) {
if (typeof(that) !== "object") { that = new this._class(that); } if (typeof(that) !== "object") { that = new this._class(that); }
var i; var i, l=this.limbs, ll=that.limbs;
for (i=this.limbs.length; i<that.limbs.length; i++) { for (i=l.length; i<ll.length; i++) {
this.limbs[i] = 0; l[i] = 0;
} }
for (i=0; i<that.limbs.length; i++) { for (i=0; i<ll.length; i++) {
this.limbs[i] -= that.limbs[i]; l[i] -= ll[i];
} }
return this; return this;
}, },
mod: function(that) {
that = new sjcl.bn(that).normalize(); // copy before we begin
var out = new sjcl.bn(this).normalize(), ci=0;
for (; out.greaterEquals(that); ci++) {
that.doubleM();
}
for (; ci > 0; ci--) {
that.halveM();
if (out.greaterEquals(that)) {
out.subM(that).normalize();
}
}
return out.trim();
},
/** return inverse mod prime p. p must be odd. Binary extended Euclidean algorithm mod p. */
inverseMod: function(p) {
var a = new sjcl.bn(1), b = new sjcl.bn(0), x = new sjcl.bn(this), y = new sjcl.bn(p), tmp, i, nz=1;
if (!(p.limbs[0] & 1)) {
throw (new sjcl.exception.invalid("inverseMod: p must be odd"));
}
// invariant: y is odd
do {
if (x.limbs[0] & 1) {
if (!x.greaterEquals(y)) {
// x < y; swap everything
tmp = x; x = y; y = tmp;
tmp = a; a = b; b = tmp;
}
x.subM(y);
x.normalize();
if (!a.greaterEquals(b)) {
a.addM(p);
}
a.subM(b);
}
// cut everything in half
x.halveM();
if (a.limbs[0] & 1) {
a.addM(p);
}
a.normalize();
a.halveM();
// check for termination: x ?= 0
for (i=nz=0; i<x.limbs.length; i++) {
nz |= x.limbs[i];
}
} while(nz);
if (!y.equals(1)) {
throw (new sjcl.exception.invalid("inverseMod: p and x must be relatively prime"));
}
return b;
},
/** this + that. Does not normalize. */ /** this + that. Does not normalize. */
add: function(that) { add: function(that) {
return this.copy().addM(that); return this.copy().addM(that);
@ -184,6 +271,13 @@ bn.prototype = {
return out; return out;
}, },
trim: function() {
var l = this.limbs, p;
do { p = l.pop() } while (l.length && p == 0);
l.push(p);
return this;
},
/** Reduce mod a modulus. Stubbed for subclassing. */ /** Reduce mod a modulus. Stubbed for subclassing. */
reduce: function() { reduce: function() {
return this; return this;
@ -218,20 +312,55 @@ bn.prototype = {
} }
limbs[i] += carry; limbs[i] += carry;
return this; return this;
},
/** Serialize to a bit array */
toBits: function(len) {
this.fullReduce();
len = len || this.exponent || this.limbs.length * this.radix;
var i = Math.floor((len-1)/24), w=sjcl.bitArray, e = (len + 7 & -8) % this.radix || this.radix;
out = [w.partial(e, this.getLimb(i))];
for (i--; i >= 0; i--) {
out = w.concat(out, [w.partial(this.radix, this.getLimb(i))]);
}
return out;
},
/** Return the length in bits, rounded up to the nearest byte. */
bitLength: function() {
this.fullReduce();
var out = this.radix * (this.limbs.length - 1);
var b = this.limbs[this.limbs.length - 1];
for (; b; b >>= 1) {
out ++;
}
return out+7 & -8;
} }
}; };
/* Initialization routines for bignum library. */ sjcl.bn.fromBits = function(bits) {
(function init(){ var out = new this(), words=[], w=sjcl.bitArray, t = this.prototype,
bn.prototype.ipv = 1 / (bn.prototype.placeVal = Math.pow(2,bn.prototype.radix)); l = Math.min(this.bitLength || 0x100000000, w.bitLength(bits)), e = l % t.radix || t.radix;
bn.prototype.radixMask = (1 << bn.prototype.radix) - 1;
})(); words[0] = w.extract(bits, 0, e);
for (; e < l; e += t.radix) {
words.unshift(w.extract(bits, e, t.radix));
}
out.limbs = words;
return out;
};
sjcl.bn.prototype.ipv = 1 / (sjcl.bn.prototype.placeVal = Math.pow(2,sjcl.bn.prototype.radix))
sjcl.bn.prototype.radixMask = (1 << sjcl.bn.prototype.radix) - 1;
/** /**
* Creates a new subclass of bn, based on reduction modulo a pseudo-Mersenne prime, * Creates a new subclass of bn, based on reduction modulo a pseudo-Mersenne prime,
* i.e. a prime of the form 2^e + sum(a * 2^b),where the sum is negative and sparse. * i.e. a prime of the form 2^e + sum(a * 2^b),where the sum is negative and sparse.
*/ */
function pseudoMersennePrime(exponent, coeff) { sjcl.bn.pseudoMersennePrime = function(exponent, coeff) {
function p(it) { function p(it) {
this.initWith(it); this.initWith(it);
/*if (this.limbs[this.modOffset]) { /*if (this.limbs[this.modOffset]) {
@ -239,7 +368,7 @@ function pseudoMersennePrime(exponent, coeff) {
}*/ }*/
} }
var ppr = p.prototype = new bn(), i, tmp, mo; var ppr = p.prototype = new sjcl.bn(), i, tmp, mo;
mo = ppr.modOffset = Math.ceil(tmp = exponent / ppr.radix); mo = ppr.modOffset = Math.ceil(tmp = exponent / ppr.radix);
ppr.exponent = exponent; ppr.exponent = exponent;
ppr.offset = []; ppr.offset = [];
@ -248,7 +377,7 @@ function pseudoMersennePrime(exponent, coeff) {
ppr.fullMask = 0; ppr.fullMask = 0;
ppr.fullOffset = []; ppr.fullOffset = [];
ppr.fullFactor = []; ppr.fullFactor = [];
ppr.modulus = p.modulus = new bn(Math.pow(2,exponent)); ppr.modulus = p.modulus = new sjcl.bn(Math.pow(2,exponent));
ppr.fullMask = 0|-Math.pow(2, exponent % ppr.radix); ppr.fullMask = 0|-Math.pow(2, exponent % ppr.radix);
@ -257,7 +386,7 @@ function pseudoMersennePrime(exponent, coeff) {
ppr.fullOffset[i] = Math.ceil(coeff[i][0] / ppr.radix - tmp); ppr.fullOffset[i] = Math.ceil(coeff[i][0] / ppr.radix - tmp);
ppr.factor[i] = coeff[i][1] * Math.pow(1/2, exponent - coeff[i][0] + ppr.offset[i] * ppr.radix); ppr.factor[i] = coeff[i][1] * Math.pow(1/2, exponent - coeff[i][0] + ppr.offset[i] * ppr.radix);
ppr.fullFactor[i] = coeff[i][1] * Math.pow(1/2, exponent - coeff[i][0] + ppr.fullOffset[i] * ppr.radix); ppr.fullFactor[i] = coeff[i][1] * Math.pow(1/2, exponent - coeff[i][0] + ppr.fullOffset[i] * ppr.radix);
ppr.modulus.addM(new bn(Math.pow(2,coeff[i][0])*coeff[i][1])); ppr.modulus.addM(new sjcl.bn(Math.pow(2,coeff[i][0])*coeff[i][1]));
ppr.minOffset = Math.min(ppr.minOffset, -ppr.offset[i]); // conservative ppr.minOffset = Math.min(ppr.minOffset, -ppr.offset[i]); // conservative
} }
ppr._class = p; ppr._class = p;
@ -336,49 +465,29 @@ function pseudoMersennePrime(exponent, coeff) {
return (this.power(this.modulus.sub(2))); return (this.power(this.modulus.sub(2)));
}; };
ppr.toBits = function() { p.fromBits = sjcl.bn.fromBits;
this.fullReduce();
var i=this.modOffset - 1, w=sjcl.bitArray, e = (this.exponent + 7 & -8) % this.radix || this.radix;
out = [w.partial(e, this.getLimb(i))];
for (i--; i >= 0; i--) {
out = w.concat(out, [w.partial(this.radix, this.getLimb(i))]);
}
return out;
};
p.fromBits = function(bits) {
var out = new this(), words=[], w=sjcl.bitArray, t = this.prototype,
l = Math.min(w.bitLength(bits), t.exponent + 7 & -8), e = l % t.radix || t.radix;
words[0] = w.extract(bits, 0, e);
for (; e < l; e += t.radix) {
words.unshift(w.extract(bits, e, t.radix));
}
out.limbs = words;
return out;
};
return p; return p;
} }
// a small Mersenne prime // a small Mersenne prime
p127 = pseudoMersennePrime(127, [[0,-1]]); sjcl.bn.prime = {
p127: sjcl.bn.pseudoMersennePrime(127, [[0,-1]]),
// Bernstein's prime for Curve25519 // Bernstein's prime for Curve25519
p25519 = pseudoMersennePrime(255, [[0,-19]]); p25519: sjcl.bn.pseudoMersennePrime(255, [[0,-19]]),
// NIST primes // NIST primes
p192 = pseudoMersennePrime(192, [[0,-1],[64,-1]]); p192: sjcl.bn.pseudoMersennePrime(192, [[0,-1],[64,-1]]),
p224 = pseudoMersennePrime(224, [[0,1],[96,-1]]); p224: sjcl.bn.pseudoMersennePrime(224, [[0,1],[96,-1]]),
p256 = pseudoMersennePrime(256, [[0,-1],[96,1],[192,1],[224,-1]]); p256: sjcl.bn.pseudoMersennePrime(256, [[0,-1],[96,1],[192,1],[224,-1]]),
p384 = pseudoMersennePrime(384, [[0,-1],[32,1],[96,-1],[128,-1]]); p384: sjcl.bn.pseudoMersennePrime(384, [[0,-1],[32,1],[96,-1],[128,-1]]),
p521 = pseudoMersennePrime(521, [[0,-1]]); p521: sjcl.bn.pseudoMersennePrime(521, [[0,-1]])
};
bn.random = function(modulus, paranoia) { sjcl.bn.random = function(modulus, paranoia) {
if (typeof modulus != "object") { modulus = new bn(modulus); } if (typeof modulus != "object") { modulus = new sjcl.bn(modulus); }
var words, i, l = modulus.limbs.length, m = modulus.limbs[l-1]+1, out = new bn(); var words, i, l = modulus.limbs.length, m = modulus.limbs[l-1]+1, out = new sjcl.bn();
while (true) { while (true) {
// get a sequence whose first digits make sense // get a sequence whose first digits make sense
do { do {

View File

@ -58,7 +58,8 @@
/* do the encryption */ /* do the encryption */
p.ct = sjcl.mode[p.mode].encrypt(prp, plaintext, p.iv, p.adata, p.tag); p.ct = sjcl.mode[p.mode].encrypt(prp, plaintext, p.iv, p.adata, p.tag);
return j.encode(j._subtract(p, j.defaults)); //return j.encode(j._subtract(p, j.defaults));
return j.encode(p);
}, },
/** Simple decryption function. /** Simple decryption function.
@ -122,7 +123,7 @@
if (!i.match(/^[a-z0-9]+$/i)) { if (!i.match(/^[a-z0-9]+$/i)) {
throw new sjcl.exception.invalid("json encode: invalid property name"); throw new sjcl.exception.invalid("json encode: invalid property name");
} }
out += comma + i + ':'; out += comma + "'" + i + "':";
comma = ','; comma = ',';
switch (typeof obj[i]) { switch (typeof obj[i]) {
@ -160,13 +161,13 @@
} }
var a = str.replace(/^\{|\}$/g, '').split(/,/), out={}, i, m; var a = str.replace(/^\{|\}$/g, '').split(/,/), out={}, i, m;
for (i=0; i<a.length; i++) { for (i=0; i<a.length; i++) {
if (!(m=a[i].match(/^([a-z][a-z0-9]*):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i))) { if (!(m=a[i].match(/^(?:(["']?)([a-z][a-z0-9]*)\1):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i))) {
throw new sjcl.exception.invalid("json decode: this isn't json!"); throw new sjcl.exception.invalid("json decode: this isn't json!");
} }
if (m[2]) { if (m[3]) {
out[m[1]] = parseInt(m[2],10); out[m[2]] = parseInt(m[3],10);
} else { } else {
out[m[1]] = m[1].match(/^(ct|salt|iv)$/) ? sjcl.codec.base64.toBits(m[3]) : unescape(m[3]); out[m[2]] = m[2].match(/^(ct|salt|iv)$/) ? sjcl.codec.base64.toBits(m[4]) : unescape(m[4]);
} }
} }
return out; return out;
@ -196,7 +197,6 @@
/** Remove all elements of minus from plus. Does not modify plus. /** Remove all elements of minus from plus. Does not modify plus.
* @private * @private
*/
_subtract: function (plus, minus) { _subtract: function (plus, minus) {
var out = {}, i; var out = {}, i;
@ -208,6 +208,7 @@
return out; return out;
}, },
*/
/** Return only the specified elements of src. /** Return only the specified elements of src.
* @private * @private

View File

@ -1,7 +1,3 @@
if (window.sjcl == undefined) {
window.sjcl = {};
}
sjcl.ecc = {}; sjcl.ecc = {};
/** /**
@ -145,7 +141,7 @@ sjcl.ecc.pointJac.prototype = {
return new sjcl.ecc.point(this.curve); return new sjcl.ecc.point(this.curve);
} }
var zi = this.z.inverse(), zi2 = zi.square(); var zi = this.z.inverse(), zi2 = zi.square();
return new sjcl.ecc.point(this.curve, this.x.mul(zi2), this.y.mul(zi2.mul(zi))); return new sjcl.ecc.point(this.curve, this.x.mul(zi2).fullReduce(), this.y.mul(zi2.mul(zi)).fullReduce());
}, },
/** /**
@ -160,7 +156,7 @@ sjcl.ecc.pointJac.prototype = {
} else if (k.limbs !== undefined) { } else if (k.limbs !== undefined) {
k = k.normalize().limbs; k = k.normalize().limbs;
} }
var i, j, out = this, multiples, aff2; var i, j, out = new sjcl.ecc.point(this.curve).toJac(), multiples, aff2;
if (affine === undefined) { if (affine === undefined) {
affine = this.toAffine(); affine = this.toAffine();
@ -177,7 +173,7 @@ sjcl.ecc.pointJac.prototype = {
multiples = affine.multiples; multiples = affine.multiples;
for (i=k.length-1; i>=0; i--) { for (i=k.length-1; i>=0; i--) {
for (j=bn.prototype.radix-4; j>=0; j-=4) { for (j=sjcl.bn.prototype.radix-4; j>=0; j-=4) {
out = out.doubl().doubl().doubl().doubl().add(multiples[k[i]>>j & 0xF]); out = out.doubl().doubl().doubl().doubl().add(multiples[k[i]>>j & 0xF]);
} }
} }
@ -221,46 +217,44 @@ sjcl.ecc.curve.prototype.fromBits = function (bits) {
return p; return p;
}; };
sjcl.ecc.p192curve = new sjcl.ecc.curve( sjcl.ecc.curves = {
p192, c192: new sjcl.ecc.curve(
sjcl.bn.prime.p192,
"0x662107c8eb94364e4b2dd7ce", "0x662107c8eb94364e4b2dd7ce",
-3, -3,
"0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
"0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
"0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"); "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"),
sjcl.ecc.p224curve = new sjcl.ecc.curve( c224: new sjcl.ecc.curve(
p224, sjcl.bn.prime.p224,
"0xe95c1f470fc1ec22d6baa3a3d5c4", "0xe95c1f470fc1ec22d6baa3a3d5c4",
-3, -3,
"0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
"0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
"0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"); "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"),
sjcl.ecc.p256curve = new sjcl.ecc.curve( c256: new sjcl.ecc.curve(
p256, sjcl.bn.prime.p256,
"0x4319055358e8617b0c46353d039cdaae", "0x4319055358e8617b0c46353d039cdaae",
-3, -3,
"0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
"0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"); "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"),
sjcl.ecc.p384curve = new sjcl.ecc.curve( c384: new sjcl.ecc.curve(
p384, sjcl.bn.prime.p384,
"0x389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68c", "0x389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68c",
-3, -3,
"0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef", "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef",
"0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
"0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f"); "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f")
sjcl.ecc.curves = {
192: sjcl.ecc.p192curve,
224: sjcl.ecc.p224curve,
256: sjcl.ecc.p256curve,
384: sjcl.ecc.p384curve
}; };
sjcl.ecc.elGamal = {
/* Diffie-Hellman-like public-key system */
sjcl.ecc._dh = function(cn) {
sjcl.ecc[cn] = {
publicKey: function(curve, point) { publicKey: function(curve, point) {
this._curve = curve; this._curve = curve;
if (point instanceof Array) { if (point instanceof Array) {
@ -269,6 +263,7 @@ sjcl.ecc.elGamal = {
this._point = point; this._point = point;
} }
}, },
secretKey: function(curve, exponent) { secretKey: function(curve, exponent) {
this._curve = curve; this._curve = curve;
this._exponent = exponent; this._exponent = exponent;
@ -276,20 +271,23 @@ sjcl.ecc.elGamal = {
generateKeys: function(curve, paranoia) { generateKeys: function(curve, paranoia) {
if (typeof curve == "number") { if (typeof curve == "number") {
curve = sjcl.ecc.curves[curve]; curve = sjcl.ecc.curves['c'+curve];
if (curve === undefined) { if (curve === undefined) {
throw new sjcl.exception.invalid("no such curve"); throw new sjcl.exception.invalid("no such curve");
} }
} }
var sec = bn.random(curve.r, paranoia), pub = curve.G.mult(sec); var sec = sjcl.bn.random(curve.r, paranoia), pub = curve.G.mult(sec);
return { pub: new sjcl.ecc.elGamal.publicKey(curve, pub), return { pub: new sjcl.ecc[cn].publicKey(curve, pub),
sec: new sjcl.ecc.elGamal.secretKey(curve, sec) }; sec: new sjcl.ecc[cn].secretKey(curve, sec) };
} }
};
}; };
sjcl.ecc._dh("elGamal");
sjcl.ecc.elGamal.publicKey.prototype = { sjcl.ecc.elGamal.publicKey.prototype = {
kem: function(paranoia) { kem: function(paranoia) {
var sec = bn.random(this._curve.r, paranoia), var sec = sjcl.bn.random(this._curve.r, paranoia),
tag = this._curve.G.mult(sec).toBits(), tag = this._curve.G.mult(sec).toBits(),
key = sjcl.hash.sha256.hash(this._point.mult(sec).toBits()); key = sjcl.hash.sha256.hash(this._point.mult(sec).toBits());
return { key: key, tag: tag }; return { key: key, tag: tag };
@ -302,5 +300,35 @@ sjcl.ecc.elGamal.secretKey.prototype = {
} }
}; };
sjcl.ecc._dh("dsa");
sjcl.ecc.dsa.secretKey.prototype = {
sign: function(hash, paranoia) {
var R = this._curve.r,
l = R.bitLength(),
k = kkkk = sjcl.bn.random(R.sub(1), paranoia).add(1),
r = this._curve.G.mult(k).x.mod(R),
s = sjcl.bn.fromBits(hash).add(r.mul(this._exponent)).inverseMod(R).mul(kkkk).mod(R);
return sjcl.bitArray.concat(r.toBits(l), s.toBits(l));
}
};
sjcl.ecc.dsa.publicKey.prototype = {
verify: function(hash, rs) {
var w = sjcl.bitArray,
R = this._curve.r,
l = R.bitLength(),
r = sjcl.bn.fromBits(w.bitSlice(rs,0,l)),
s = sjcl.bn.fromBits(w.bitSlice(rs,l,2*l)),
hG = sjcl.bn.fromBits(hash).mul(s).mod(R),
hA = r.mul(s).mod(R),
jG = this._curve.G.toJac(),
r2 = jG.mult(hG, this._curve.G).add(this._point.mult(hA)).toAffine().x,
corrupt = sjcl.exception.corrupt;
if (r.equals(0) || s.equals(0) || r.greaterEquals(R) || s.greaterEquals(R) || !r2.equals(r)) {
throw (new corrupt("signature didn't check out"));
}
return true;
}
}

View File

@ -50,7 +50,8 @@ sjcl.mode.ocb2 = {
/* Encrypt a non-final block */ /* Encrypt a non-final block */
bi = plaintext.slice(i,i+4); bi = plaintext.slice(i,i+4);
checksum = xor(checksum, bi); checksum = xor(checksum, bi);
output = output.concat(xor(delta,prp.encrypt(xor(delta, bi)))); bi = xor(delta,prp.encrypt(xor(delta, bi)));
output.splice(i,0,bi[0],bi[1],bi[2],bi[3]);
delta = times2(delta); delta = times2(delta);
} }
@ -105,7 +106,7 @@ sjcl.mode.ocb2 = {
/* Decrypt a non-final block */ /* Decrypt a non-final block */
bi = xor(delta, prp.decrypt(xor(delta, ciphertext.slice(i,i+4)))); bi = xor(delta, prp.decrypt(xor(delta, ciphertext.slice(i,i+4))));
checksum = xor(checksum, bi); checksum = xor(checksum, bi);
output = output.concat(bi); output.splice(i,0,bi[0],bi[1],bi[2],bi[3]);
delta = times2(delta); delta = times2(delta);
} }

101
sjcl.js
View File

@ -1,39 +1,68 @@
"use strict";var sjcl={cipher:{},hash:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a}}}; "use strict";var sjcl={cipher:{},hash:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"GENERATOR NOT READY: "+this.message};this.message=a}}};
sjcl.cipher.aes=function(a){this.h[0][0][0]||this.w();var b,c,d,e,f=this.h[0][4],g=this.h[1];b=a.length;var h=1;if(b!==4&&b!==6&&b!==8)throw new sjcl.exception.invalid("invalid aes key size");this.a=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(a%b===0||b===8&&a%b===4){c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255];if(a%b===0){c=c<<8^c>>>24^h<<24;h=h<<1^(h>>7)*283}}d[a]=d[a-b]^c}for(b=0;a;b++,a--){c=d[b&3?a:a-4];e[b]=a<=4||b<4?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^ sjcl.cipher.aes=function(a){this.l[0][0][0]||this.F();var b,c,d,e,f=this.l[0][4],g=this.l[1];b=a.length;var h=1;if(b!==4&&b!==6&&b!==8)throw new sjcl.exception.invalid("invalid aes key size");this.c=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(a%b===0||b===8&&a%b===4){c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255];if(a%b===0){c=c<<8^c>>>24^h<<24;h=h<<1^(h>>7)*283}}d[a]=d[a-b]^c}for(b=0;a;b++,a--){c=d[b&3?a:a-4];e[b]=a<=4||b<4?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^
g[3][f[c&255]]}}; g[3][f[c&255]]}};
sjcl.cipher.aes.prototype={encrypt:function(a){return this.H(a,0)},decrypt:function(a){return this.H(a,1)},h:[[[],[],[],[],[]],[[],[],[],[],[]]],w:function(){var a=this.h[0],b=this.h[1],c=a[4],d=b[4],e,f,g,h=[],i=[],k,j,l,m;for(e=0;e<0x100;e++)i[(h[e]=e<<1^(e>>7)*283)^e]=e;for(f=g=0;!c[f];f^=k||1,g=i[g]||1){l=g^g<<1^g<<2^g<<3^g<<4;l=l>>8^l&255^99;c[f]=l;d[l]=f;j=h[e=h[k=h[f]]];m=j*0x1010101^e*0x10001^k*0x101^f*0x1010100;j=h[l]*0x101^l*0x1010100;for(e=0;e<4;e++){a[e][f]=j=j<<24^j>>>8;b[e][l]=m=m<<24^m>>>8}}for(e= sjcl.cipher.aes.prototype={encrypt:function(a){return this.O(a,0)},decrypt:function(a){return this.O(a,1)},l:[[[],[],[],[],[]],[[],[],[],[],[]]],F:function(){var a=this.l[0],b=this.l[1],c=a[4],d=b[4],e,f,g,h=[],j=[],n,l,m,o;for(e=0;e<0x100;e++)j[(h[e]=e<<1^(e>>7)*283)^e]=e;for(f=g=0;!c[f];f^=n||1,g=j[g]||1){m=g^g<<1^g<<2^g<<3^g<<4;m=m>>8^m&255^99;c[f]=m;d[m]=f;l=h[e=h[n=h[f]]];o=l*0x1010101^e*0x10001^n*0x101^f*0x1010100;l=h[m]*0x101^m*0x1010100;for(e=0;e<4;e++){a[e][f]=l=l<<24^l>>>8;b[e][m]=o=o<<24^o>>>8}}for(e=
0;e<5;e++){a[e]=a[e].slice(0);b[e]=b[e].slice(0)}},H:function(a,b){if(a.length!==4)throw new sjcl.exception.invalid("invalid aes block size");var c=this.a[b],d=a[0]^c[0],e=a[b?3:1]^c[1],f=a[2]^c[2];a=a[b?1:3]^c[3];var g,h,i,k=c.length/4-2,j,l=4,m=[0,0,0,0];g=this.h[b];var n=g[0],o=g[1],p=g[2],q=g[3],r=g[4];for(j=0;j<k;j++){g=n[d>>>24]^o[e>>16&255]^p[f>>8&255]^q[a&255]^c[l];h=n[e>>>24]^o[f>>16&255]^p[a>>8&255]^q[d&255]^c[l+1];i=n[f>>>24]^o[a>>16&255]^p[d>>8&255]^q[e&255]^c[l+2];a=n[a>>>24]^o[d>>16& 0;e<5;e++){a[e]=a[e].slice(0);b[e]=b[e].slice(0)}},O:function(a,b){if(a.length!==4)throw new sjcl.exception.invalid("invalid aes block size");var c=this.c[b],d=a[0]^c[0],e=a[b?3:1]^c[1],f=a[2]^c[2];a=a[b?1:3]^c[3];var g,h,j,n=c.length/4-2,l,m=4,o=[0,0,0,0];g=this.l[b];var q=g[0],r=g[1],s=g[2],t=g[3],u=g[4];for(l=0;l<n;l++){g=q[d>>>24]^r[e>>16&255]^s[f>>8&255]^t[a&255]^c[m];h=q[e>>>24]^r[f>>16&255]^s[a>>8&255]^t[d&255]^c[m+1];j=q[f>>>24]^r[a>>16&255]^s[d>>8&255]^t[e&255]^c[m+2];a=q[a>>>24]^r[d>>16&
255]^p[e>>8&255]^q[f&255]^c[l+3];l+=4;d=g;e=h;f=i}for(j=0;j<4;j++){m[b?3&-j:j]=r[d>>>24]<<24^r[e>>16&255]<<16^r[f>>8&255]<<8^r[a&255]^c[l++];g=d;d=e;e=f;f=a;a=g}return m}}; 255]^s[e>>8&255]^t[f&255]^c[m+3];m+=4;d=g;e=h;f=j}for(l=0;l<4;l++){o[b?3&-l:l]=u[d>>>24]<<24^u[e>>16&255]<<16^u[f>>8&255]<<8^u[a&255]^c[m++];g=d;d=e;e=f;f=a;a=g}return o}};
sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.P(a.slice(b/32),32-(b&31)).slice(1);return c===undefined?a:sjcl.bitArray.clamp(a,c-b)},concat:function(a,b){if(a.length===0||b.length===0)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return d===32?a.concat(b):sjcl.bitArray.P(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;if(b===0)return 0;return(b-1)*32+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(a.length*32<b)return a;a=a.slice(0,Math.ceil(b/ sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.Z(a.slice(b/32),32-(b&31)).slice(1);return c===undefined?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=-b-c&31;return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<<c)-1},concat:function(a,b){if(a.length===0||b.length===0)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return d===32?a.concat(b):sjcl.bitArray.Z(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;if(b===0)return 0;
32));var c=a.length;b&=31;if(c>0&&b)a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1);return a},partial:function(a,b,c){if(a===32)return b;return(c?b|0:b<<32-a)+a*0x10000000000},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d<a.length;d++)c|=a[d]^b[d];return c===0},P:function(a,b,c,d){var e;e=0;if(d===undefined)d=[];for(;b>=32;b-=32){d.push(c);c=0}if(b===0)return d.concat(a); return(b-1)*32+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(a.length*32<b)return a;a=a.slice(0,Math.ceil(b/32));var c=a.length;b&=31;if(c>0&&b)a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1);return a},partial:function(a,b,c){if(a===32)return b;return(c?b|0:b<<32-a)+a*0x10000000000},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d<a.length;d++)c|=a[d]^b[d];
for(e=0;e<a.length;e++){d.push(c|a[e]>>>b);c=a[e]<<32-b}e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,b+a>32?c:d.pop(),1));return d},k:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]}}; return c===0},Z:function(a,b,c,d){var e;e=0;if(d===undefined)d=[];for(;b>=32;b-=32){d.push(c);c=0}if(b===0)return d.concat(a);for(e=0;e<a.length;e++){d.push(c|a[e]>>>b);c=a[e]<<32-b}e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,b+a>32?c:d.pop(),1));return d},o:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]}};
sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++){if((d&3)===0)e=a[d/4];b+=String.fromCharCode(e>>>24);e<<=8}return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++){d=d<<8|a.charCodeAt(c);if((c&3)===3){b.push(d);d=0}}c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}}; sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++){if((d&3)===0)e=a[d/4];b+=String.fromCharCode(e>>>24);e<<=8}return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++){d=d<<8|a.charCodeAt(c);if((c&3)===3){b.push(d);d=0}}c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}};
sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a+="00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,d*4)}}; sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a+="00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,d*4)}};
sjcl.codec.base64={D:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b){var c="",d,e=0,f=sjcl.codec.base64.D,g=0,h=sjcl.bitArray.bitLength(a);for(d=0;c.length*6<h;){c+=f.charAt((g^a[d]>>>e)>>>26);if(e<6){g=a[d]<<6-e;e+=26;d++}else{g<<=6;e-=6}}for(;c.length&3&&!b;)c+="=";return c},toBits:function(a){a=a.replace(/\s|=/g,"");var b=[],c,d=0,e=sjcl.codec.base64.D,f=0,g;for(c=0;c<a.length;c++){g=e.indexOf(a.charAt(c));if(g<0)throw new sjcl.exception.invalid("this isn't base64!"); sjcl.codec.base64={L:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b){var c="",d,e=0,f=sjcl.codec.base64.L,g=0,h=sjcl.bitArray.bitLength(a);for(d=0;c.length*6<h;){c+=f.charAt((g^a[d]>>>e)>>>26);if(e<6){g=a[d]<<6-e;e+=26;d++}else{g<<=6;e-=6}}for(;c.length&3&&!b;)c+="=";return c},toBits:function(a){a=a.replace(/\s|=/g,"");var b=[],c,d=0,e=sjcl.codec.base64.L,f=0,g;for(c=0;c<a.length;c++){g=e.indexOf(a.charAt(c));if(g<0)throw new sjcl.exception.invalid("this isn't base64!");
if(d>26){d-=26;b.push(f^g>>>d);f=g<<32-d}else{d+=6;f^=g<<32-d}}d&56&&b.push(sjcl.bitArray.partial(d&56,f,1));return b}};sjcl.hash.sha256=function(a){this.a[0]||this.w();if(a){this.n=a.n.slice(0);this.i=a.i.slice(0);this.e=a.e}else this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()}; if(d>26){d-=26;b.push(f^g>>>d);f=g<<32-d}else{d+=6;f^=g<<32-d}}d&56&&b.push(sjcl.bitArray.partial(d&56,f,1));return b}};sjcl.hash.sha256=function(a){this.c[0]||this.F();if(a){this.s=a.s.slice(0);this.m=a.m.slice(0);this.i=a.i}else this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()};
sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.n=this.N.slice(0);this.i=[];this.e=0;return this},update:function(a){if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);var b,c=this.i=sjcl.bitArray.concat(this.i,a);b=this.e;a=this.e=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)this.C(c.splice(0,16));return this},finalize:function(){var a,b=this.i,c=this.n;b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.e/ sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.s=this.W.slice(0);this.m=[];this.i=0;return this},update:function(a){if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);var b,c=this.m=sjcl.bitArray.concat(this.m,a);b=this.i;a=this.i=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)this.K(c.splice(0,16));return this},finalize:function(){var a,b=this.m,c=this.s;b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.i/
4294967296));for(b.push(this.e|0);b.length;)this.C(b.splice(0,16));this.reset();return c},N:[],a:[],w:function(){function a(e){return(e-Math.floor(e))*0x100000000|0}var b=0,c=2,d;a:for(;b<64;c++){for(d=2;d*d<=c;d++)if(c%d===0)continue a;if(b<8)this.N[b]=a(Math.pow(c,0.5));this.a[b]=a(Math.pow(c,1/3));b++}},C:function(a){var b,c,d=a.slice(0),e=this.n,f=this.a,g=e[0],h=e[1],i=e[2],k=e[3],j=e[4],l=e[5],m=e[6],n=e[7];for(a=0;a<64;a++){if(a<16)b=d[a];else{b=d[a+1&15];c=d[a+14&15];b=d[a&15]=(b>>>7^b>>>18^ 4294967296));for(b.push(this.i|0);b.length;)this.K(b.splice(0,16));this.reset();return c},W:[],c:[],F:function(){function a(e){return(e-Math.floor(e))*0x100000000|0}var b=0,c=2,d;a:for(;b<64;c++){for(d=2;d*d<=c;d++)if(c%d===0)continue a;if(b<8)this.W[b]=a(Math.pow(c,0.5));this.c[b]=a(Math.pow(c,1/3));b++}},K:function(a){var b,c,d=a.slice(0),e=this.s,f=this.c,g=e[0],h=e[1],j=e[2],n=e[3],l=e[4],m=e[5],o=e[6],q=e[7];for(a=0;a<64;a++){if(a<16)b=d[a];else{b=d[a+1&15];c=d[a+14&15];b=d[a&15]=(b>>>7^b>>>18^
b>>>3^b<<25^b<<14)+(c>>>17^c>>>19^c>>>10^c<<15^c<<13)+d[a&15]+d[a+9&15]|0}b=b+n+(j>>>6^j>>>11^j>>>25^j<<26^j<<21^j<<7)+(m^j&(l^m))+f[a];n=m;m=l;l=j;j=k+b|0;k=i;i=h;h=g;g=b+(h&i^k&(h^i))+(h>>>2^h>>>13^h>>>22^h<<30^h<<19^h<<10)|0}e[0]=e[0]+g|0;e[1]=e[1]+h|0;e[2]=e[2]+i|0;e[3]=e[3]+k|0;e[4]=e[4]+j|0;e[5]=e[5]+l|0;e[6]=e[6]+m|0;e[7]=e[7]+n|0}}; b>>>3^b<<25^b<<14)+(c>>>17^c>>>19^c>>>10^c<<15^c<<13)+d[a&15]+d[a+9&15]|0}b=b+q+(l>>>6^l>>>11^l>>>25^l<<26^l<<21^l<<7)+(o^l&(m^o))+f[a];q=o;o=m;m=l;l=n+b|0;n=j;j=h;h=g;g=b+(h&j^n&(h^j))+(h>>>2^h>>>13^h>>>22^h<<30^h<<19^h<<10)|0}e[0]=e[0]+g|0;e[1]=e[1]+h|0;e[2]=e[2]+j|0;e[3]=e[3]+n|0;e[4]=e[4]+l|0;e[5]=e[5]+m|0;e[6]=e[6]+o|0;e[7]=e[7]+q|0}};
sjcl.mode.ccm={name:"ccm",encrypt:function(a,b,c,d,e){var f,g=b.slice(0),h=sjcl.bitArray,i=h.bitLength(c)/8,k=h.bitLength(g)/8;e=e||64;d=d||[];if(i<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;f<4&&k>>>8*f;f++);if(f<15-i)f=15-i;c=h.clamp(c,8*(15-f));b=sjcl.mode.ccm.G(a,b,c,d,e,f);g=sjcl.mode.ccm.I(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),i=f.clamp(b,h-e),k=f.bitSlice(b, sjcl.mode.ccm={name:"ccm",encrypt:function(a,b,c,d,e){var f,g=b.slice(0),h=sjcl.bitArray,j=h.bitLength(c)/8,n=h.bitLength(g)/8;e=e||64;d=d||[];if(j<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;f<4&&n>>>8*f;f++);if(f<15-j)f=15-j;c=h.clamp(c,8*(15-f));b=sjcl.mode.ccm.N(a,b,c,d,e,f);g=sjcl.mode.ccm.P(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),j=f.clamp(b,h-e),n=f.bitSlice(b,
h-e);h=(h-e)/8;if(g<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;b<4&&h>>>8*b;b++);if(b<15-g)b=15-g;c=f.clamp(c,8*(15-b));i=sjcl.mode.ccm.I(a,i,c,k,e,b);a=sjcl.mode.ccm.G(a,i.data,c,d,e,b);if(!f.equal(i.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");return i.data},G:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,i=h.k;e/=8;if(e%2||e<4||e>16)throw new sjcl.exception.invalid("ccm: invalid tag length");if(d.length>0xffffffff||b.length>0xffffffff)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data"); h-e);h=(h-e)/8;if(g<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;b<4&&h>>>8*b;b++);if(b<15-g)b=15-g;c=f.clamp(c,8*(15-b));j=sjcl.mode.ccm.P(a,j,c,n,e,b);a=sjcl.mode.ccm.N(a,j.data,c,d,e,b);if(!f.equal(j.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");return j.data},N:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,j=h.o;e/=8;if(e%2||e<4||e>16)throw new sjcl.exception.invalid("ccm: invalid tag length");if(d.length>0xffffffff||b.length>0xffffffff)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");
f=[h.partial(8,(d.length?64:0)|e-2<<2|f-1)];f=h.concat(f,c);f[3]|=h.bitLength(b)/8;f=a.encrypt(f);if(d.length){c=h.bitLength(d)/8;if(c<=65279)g=[h.partial(16,c)];else if(c<=0xffffffff)g=h.concat([h.partial(16,65534)],[c]);g=h.concat(g,d);for(d=0;d<g.length;d+=4)f=a.encrypt(i(f,g.slice(d,d+4)))}for(d=0;d<b.length;d+=4)f=a.encrypt(i(f,b.slice(d,d+4)));return h.clamp(f,e*8)},I:function(a,b,c,d,e,f){var g,h=sjcl.bitArray;g=h.k;var i=b.length,k=h.bitLength(b);c=h.concat([h.partial(8,f-1)],c).concat([0, f=[h.partial(8,(d.length?64:0)|e-2<<2|f-1)];f=h.concat(f,c);f[3]|=h.bitLength(b)/8;f=a.encrypt(f);if(d.length){c=h.bitLength(d)/8;if(c<=65279)g=[h.partial(16,c)];else if(c<=0xffffffff)g=h.concat([h.partial(16,65534)],[c]);g=h.concat(g,d);for(d=0;d<g.length;d+=4)f=a.encrypt(j(f,g.slice(d,d+4)))}for(d=0;d<b.length;d+=4)f=a.encrypt(j(f,b.slice(d,d+4)));return h.clamp(f,e*8)},P:function(a,b,c,d,e,f){var g,h=sjcl.bitArray;g=h.o;var j=b.length,n=h.bitLength(b);c=h.concat([h.partial(8,f-1)],c).concat([0,
0,0]).slice(0,4);d=h.bitSlice(g(d,a.encrypt(c)),0,e);if(!i)return{tag:d,data:[]};for(g=0;g<i;g+=4){c[3]++;e=a.encrypt(c);b[g]^=e[0];b[g+1]^=e[1];b[g+2]^=e[2];b[g+3]^=e[3]}return{tag:d,data:h.clamp(b,k)}}}; 0,0]).slice(0,4);d=h.bitSlice(g(d,a.encrypt(c)),0,e);if(!j)return{tag:d,data:[]};for(g=0;g<j;g+=4){c[3]++;e=a.encrypt(c);b[g]^=e[0];b[g+1]^=e[1];b[g+2]^=e[2];b[g+3]^=e[3]}return{tag:d,data:h.clamp(b,n)}}};
sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.A,i=sjcl.bitArray,k=i.k,j=[0,0,0,0];c=h(a.encrypt(c));var l,m=[];d=d||[];e=e||64;for(g=0;g+4<b.length;g+=4){l=b.slice(g,g+4);j=k(j,l);m=m.concat(k(c,a.encrypt(k(c,l))));c=h(c)}l=b.slice(g);b=i.bitLength(l);g=a.encrypt(k(c,[0,0,0,b]));l=i.clamp(k(l,g),b);j=k(j,k(l,g));j=a.encrypt(k(j,k(c,h(c))));if(d.length)j=k(j,f?d:sjcl.mode.ocb2.pmac(a, sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.I,j=sjcl.bitArray,n=j.o,l=[0,0,0,0];c=h(a.encrypt(c));var m,o=[];d=d||[];e=e||64;for(g=0;g+4<b.length;g+=4){m=b.slice(g,g+4);l=n(l,m);m=n(c,a.encrypt(n(c,m)));o.splice(g,0,m[0],m[1],m[2],m[3]);c=h(c)}m=b.slice(g);b=j.bitLength(m);g=a.encrypt(n(c,[0,0,0,b]));m=j.clamp(n(m,g),b);l=n(l,n(m,g));l=a.encrypt(n(l,n(c,h(c))));if(d.length)l=
d));return m.concat(i.concat(l,i.clamp(j,e)))},decrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");e=e||64;var g=sjcl.mode.ocb2.A,h=sjcl.bitArray,i=h.k,k=[0,0,0,0],j=g(a.encrypt(c)),l,m,n=sjcl.bitArray.bitLength(b)-e,o=[];d=d||[];for(c=0;c+4<n/32;c+=4){l=i(j,a.decrypt(i(j,b.slice(c,c+4))));k=i(k,l);o=o.concat(l);j=g(j)}m=n-c*32;l=a.encrypt(i(j,[0,0,0,m]));l=i(l,h.clamp(b.slice(c),m));k=i(k,l);k=a.encrypt(i(k,i(j,g(j))));if(d.length)k= n(l,f?d:sjcl.mode.ocb2.pmac(a,d));return o.concat(j.concat(m,j.clamp(l,e)))},decrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");e=e||64;var g=sjcl.mode.ocb2.I,h=sjcl.bitArray,j=h.o,n=[0,0,0,0],l=g(a.encrypt(c)),m,o,q=sjcl.bitArray.bitLength(b)-e,r=[];d=d||[];for(c=0;c+4<q/32;c+=4){m=j(l,a.decrypt(j(l,b.slice(c,c+4))));n=j(n,m);r.splice(c,0,m[0],m[1],m[2],m[3]);l=g(l)}o=q-c*32;m=a.encrypt(j(l,[0,0,0,o]));m=j(m,h.clamp(b.slice(c),
i(k,f?d:sjcl.mode.ocb2.pmac(a,d));if(!h.equal(h.clamp(k,e),h.bitSlice(b,n)))throw new sjcl.exception.corrupt("ocb: tag doesn't match");return o.concat(h.clamp(l,m))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.A,e=sjcl.bitArray,f=e.k,g=[0,0,0,0],h=a.encrypt([0,0,0,0]);h=f(h,d(d(h)));for(c=0;c+4<b.length;c+=4){h=d(h);g=f(g,a.encrypt(f(h,b.slice(c,c+4))))}b=b.slice(c);if(e.bitLength(b)<128){h=f(h,d(h));b=e.concat(b,[2147483648|0])}g=f(g,b);return a.encrypt(f(d(f(h,d(h))),g))},A:function(a){return[a[0]<< o));n=j(n,m);n=a.encrypt(j(n,j(l,g(l))));if(d.length)n=j(n,f?d:sjcl.mode.ocb2.pmac(a,d));if(!h.equal(h.clamp(n,e),h.bitSlice(b,q)))throw new sjcl.exception.corrupt("ocb: tag doesn't match");return r.concat(h.clamp(m,o))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.I,e=sjcl.bitArray,f=e.o,g=[0,0,0,0],h=a.encrypt([0,0,0,0]);h=f(h,d(d(h)));for(c=0;c+4<b.length;c+=4){h=d(h);g=f(g,a.encrypt(f(h,b.slice(c,c+4))))}b=b.slice(c);if(e.bitLength(b)<128){h=f(h,d(h));b=e.concat(b,[2147483648|0])}g=f(g,b);return a.encrypt(f(d(f(h,
1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^(a[0]>>>31)*135]}};sjcl.misc.hmac=function(a,b){this.M=b=b||sjcl.hash.sha256;var c=[[],[]],d=b.prototype.blockSize/32;this.l=[new b,new b];if(a.length>d)a=b.hash(a);for(b=0;b<d;b++){c[0][b]=a[b]^909522486;c[1][b]=a[b]^1549556828}this.l[0].update(c[0]);this.l[1].update(c[1])};sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a,b){a=(new this.M(this.l[0])).update(a,b).finalize();return(new this.M(this.l[1])).update(a).finalize()}; d(h))),g))},I:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^(a[0]>>>31)*135]}};sjcl.misc.hmac=function(a,b){this.V=b=b||sjcl.hash.sha256;var c=[[],[]],d=b.prototype.blockSize/32;this.p=[new b,new b];if(a.length>d)a=b.hash(a);for(b=0;b<d;b++){c[0][b]=a[b]^909522486;c[1][b]=a[b]^1549556828}this.p[0].update(c[0]);this.p[1].update(c[1])};sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a,b){a=(new this.V(this.p[0])).update(a,b).finalize();return(new this.V(this.p[1])).update(a).finalize()};
sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E3;if(d<0||c<0)throw sjcl.exception.invalid("invalid params to pbkdf2");if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,i,k=[],j=sjcl.bitArray;for(i=1;32*k.length<(d||1);i++){e=f=a.encrypt(j.concat(b,[i]));for(g=1;g<c;g++){f=a.encrypt(f);for(h=0;h<f.length;h++)e[h]^=f[h]}k=k.concat(e)}if(d)k=j.clamp(k,d);return k}; sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E3;if(d<0||c<0)throw sjcl.exception.invalid("invalid params to pbkdf2");if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,j,n=[],l=sjcl.bitArray;for(j=1;32*n.length<(d||1);j++){e=f=a.encrypt(l.concat(b,[j]));for(g=1;g<c;g++){f=a.encrypt(f);for(h=0;h<f.length;h++)e[h]^=f[h]}n=n.concat(e)}if(d)n=l.clamp(n,d);return n};
sjcl.random={randomWords:function(a,b){var c=[];b=this.isReady(b);var d;if(b===0)throw new sjcl.exception.notready("generator isn't seeded");else b&2&&this.U(!(b&1));for(b=0;b<a;b+=4){(b+1)%0x10000===0&&this.L();d=this.u();c.push(d[0],d[1],d[2],d[3])}this.L();return c.slice(0,a)},setDefaultParanoia:function(a){this.t=a},addEntropy:function(a,b,c){c=c||"user";var d,e,f=(new Date).valueOf(),g=this.q[c],h=this.isReady();d=this.F[c];if(d===undefined)d=this.F[c]=this.R++;if(g===undefined)g=this.q[c]=0;this.q[c]= sjcl.random={randomWords:function(a,b){var c=[];b=this.isReady(b);var d;if(b===0)throw new sjcl.exception.notReady("generator isn't seeded");else b&2&&this.ea(!(b&1));for(b=0;b<a;b+=4){(b+1)%0x10000===0&&this.U();d=this.D();c.push(d[0],d[1],d[2],d[3])}this.U();return c.slice(0,a)},setDefaultParanoia:function(a){this.C=a},addEntropy:function(a,b,c){c=c||"user";var d,e,f=(new Date).valueOf(),g=this.w[c],h=this.isReady();d=this.M[c];if(d===undefined)d=this.M[c]=this.ba++;if(g===undefined)g=this.w[c]=0;
(this.q[c]+1)%this.b.length;switch(typeof a){case "number":break;case "object":if(b===undefined)for(c=b=0;c<a.length;c++)for(e=a[c];e>0;){b++;e>>>=1}this.b[g].update([d,this.J++,2,b,f,a.length].concat(a));break;case "string":if(b===undefined)b=a.length;this.b[g].update([d,this.J++,3,b,f,a.length]);this.b[g].update(a);break;default:throw new sjcl.exception.bug("random: addEntropy only supports number, array or string");}this.j[g]+=b;this.f+=b;if(h===0){this.isReady()!==0&&this.K("seeded",Math.max(this.g, this.w[c]=(this.w[c]+1)%this.f.length;switch(typeof a){case "number":break;case "object":if(b===undefined)for(c=b=0;c<a.length;c++)for(e=a[c];e>0;){b++;e>>>=1}this.f[g].update([d,this.R++,2,b,f,a.length].concat(a));break;case "string":if(b===undefined)b=a.length;this.f[g].update([d,this.R++,3,b,f,a.length]);this.f[g].update(a);break;default:throw new sjcl.exception.bug("random: addEntropy only supports number, array or string");}this.n[g]+=b;this.j+=b;if(h===0){this.isReady()!==0&&this.T("seeded",
this.f));this.K("progress",this.getProgress())}},isReady:function(a){a=this.B[a!==undefined?a:this.t];return this.g&&this.g>=a?this.j[0]>80&&(new Date).valueOf()>this.O?3:1:this.f>=a?2:0},getProgress:function(a){a=this.B[a?a:this.t];return this.g>=a?1["0"]:this.f>a?1["0"]:this.f/a},startCollectors:function(){if(!this.m){if(window.addEventListener){window.addEventListener("load",this.o,false);window.addEventListener("mousemove",this.p,false)}else if(document.attachEvent){document.attachEvent("onload", Math.max(this.k,this.j));this.T("progress",this.getProgress())}},isReady:function(a){a=this.J[a!==undefined?a:this.C];return this.k&&this.k>=a?this.n[0]>80&&(new Date).valueOf()>this.X?3:1:this.j>=a?2:0},getProgress:function(a){a=this.J[a?a:this.C];return this.k>=a?1["0"]:this.j>a?1["0"]:this.j/a},startCollectors:function(){if(!this.q){if(window.addEventListener){window.addEventListener("load",this.t,false);window.addEventListener("mousemove",this.u,false)}else if(document.attachEvent){document.attachEvent("onload",
this.o);document.attachEvent("onmousemove",this.p)}else throw new sjcl.exception.bug("can't attach event");this.m=true}},stopCollectors:function(){if(this.m){if(window.removeEventListener){window.removeEventListener("load",this.o);window.removeEventListener("mousemove",this.p)}else if(window.detachEvent){window.detachEvent("onload",this.o);window.detachEvent("onmousemove",this.p)}this.m=false}},addEventListener:function(a,b){this.r[a][this.Q++]=b},removeEventListener:function(a,b){var c;a=this.r[a]; this.t);document.attachEvent("onmousemove",this.u)}else throw new sjcl.exception.bug("can't attach event");this.q=true}},stopCollectors:function(){if(this.q){if(window.removeEventListener){window.removeEventListener("load",this.t);window.removeEventListener("mousemove",this.u)}else if(window.detachEvent){window.detachEvent("onload",this.t);window.detachEvent("onmousemove",this.u)}this.q=false}},addEventListener:function(a,b){this.A[a][this.aa++]=b},removeEventListener:function(a,b){var c;a=this.A[a];
var d=[];for(c in a)a.hasOwnProperty[c]&&a[c]===b&&d.push(c);for(b=0;b<d.length;b++){c=d[b];delete a[c]}},b:[new sjcl.hash.sha256],j:[0],z:0,q:{},J:0,F:{},R:0,g:0,f:0,O:0,a:[0,0,0,0,0,0,0,0],d:[0,0,0,0],s:undefined,t:6,m:false,r:{progress:{},seeded:{}},Q:0,B:[0,48,64,96,128,192,0x100,384,512,768,1024],u:function(){for(var a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}return this.s.encrypt(this.d)},L:function(){this.a=this.u().concat(this.u());this.s=new sjcl.cipher.aes(this.a)},T:function(a){this.a= var d=[];for(c in a)a.hasOwnProperty[c]&&a[c]===b&&d.push(c);for(b=0;b<d.length;b++){c=d[b];delete a[c]}},f:[new sjcl.hash.sha256],n:[0],H:0,w:{},R:0,M:{},ba:0,k:0,j:0,X:0,c:[0,0,0,0,0,0,0,0],h:[0,0,0,0],B:undefined,C:6,q:false,A:{progress:{},seeded:{}},aa:0,J:[0,48,64,96,128,192,0x100,384,512,768,1024],D:function(){for(var a=0;a<4;a++){this.h[a]=this.h[a]+1|0;if(this.h[a])break}return this.B.encrypt(this.h)},U:function(){this.c=this.D().concat(this.D());this.B=new sjcl.cipher.aes(this.c)},da:function(a){this.c=
sjcl.hash.sha256.hash(this.a.concat(a));this.s=new sjcl.cipher.aes(this.a);for(a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}},U:function(a){var b=[],c=0,d;this.O=b[0]=(new Date).valueOf()+3E4;for(d=0;d<16;d++)b.push(Math.random()*0x100000000|0);for(d=0;d<this.b.length;d++){b=b.concat(this.b[d].finalize());c+=this.j[d];this.j[d]=0;if(!a&&this.z&1<<d)break}if(this.z>=1<<this.b.length){this.b.push(new sjcl.hash.sha256);this.j.push(0)}this.f-=c;if(c>this.g)this.g=c;this.z++;this.T(b)},p:function(a){sjcl.random.addEntropy([a.x|| sjcl.hash.sha256.hash(this.c.concat(a));this.B=new sjcl.cipher.aes(this.c);for(a=0;a<4;a++){this.h[a]=this.h[a]+1|0;if(this.h[a])break}},ea:function(a){var b=[],c=0,d;this.X=b[0]=(new Date).valueOf()+3E4;for(d=0;d<16;d++)b.push(Math.random()*0x100000000|0);for(d=0;d<this.f.length;d++){b=b.concat(this.f[d].finalize());c+=this.n[d];this.n[d]=0;if(!a&&this.H&1<<d)break}if(this.H>=1<<this.f.length){this.f.push(new sjcl.hash.sha256);this.n.push(0)}this.j-=c;if(c>this.k)this.k=c;this.H++;this.da(b)},u:function(a){sjcl.random.addEntropy([a.x||
a.clientX||a.offsetX,a.y||a.clientY||a.offsetY],2,"mouse")},o:function(){sjcl.random.addEntropy(new Date,2,"loadtime")},K:function(a,b){var c;a=sjcl.random.r[a];var d=[];for(c in a)a.hasOwnProperty(c)&&d.push(a[c]);for(c=0;c<d.length;c++)d[c](b)}}; a.clientX||a.offsetX,a.y||a.clientY||a.offsetY],2,"mouse")},t:function(){sjcl.random.addEntropy(new Date,2,"loadtime")},T:function(a,b){var c;a=sjcl.random.A[a];var d=[];for(c in a)a.hasOwnProperty(c)&&d.push(a[c]);for(c=0;c<d.length;c++)d[c](b)}};
sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},encrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.c({iv:sjcl.random.randomWords(4,0)},e.defaults);e.c(f,c);if(typeof f.salt==="string")f.salt=sjcl.codec.base64.toBits(f.salt);if(typeof f.iv==="string")f.iv=sjcl.codec.base64.toBits(f.iv);if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||typeof a==="string"&&f.iter<=100||f.ts!==64&&f.ts!==96&&f.ts!==128||f.ks!==128&&f.ks!==192&&f.ks!==0x100||f.iv.length<2||f.iv.length> sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},encrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.g({iv:sjcl.random.randomWords(4,0)},e.defaults);e.g(f,c);if(typeof f.salt==="string")f.salt=sjcl.codec.base64.toBits(f.salt);if(typeof f.iv==="string")f.iv=sjcl.codec.base64.toBits(f.iv);if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||typeof a==="string"&&f.iter<=100||f.ts!==64&&f.ts!==96&&f.ts!==128||f.ks!==128&&f.ks!==192&&f.ks!==0x100||f.iv.length<2||f.iv.length>
4)throw new sjcl.exception.invalid("json encrypt: invalid parameters");if(typeof a==="string"){c=sjcl.misc.cachedPbkdf2(a,f);a=c.key.slice(0,f.ks/32);f.salt=c.salt}if(typeof b==="string")b=sjcl.codec.utf8String.toBits(b);c=new sjcl.cipher[f.cipher](a);e.c(d,f);d.key=a;f.ct=sjcl.mode[f.mode].encrypt(c,b,f.iv,f.adata,f.tag);return e.encode(e.V(f,e.defaults))},decrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.c(e.c(e.c({},e.defaults),e.decode(b)),c,true);if(typeof b.salt==="string")b.salt= 4)throw new sjcl.exception.invalid("json encrypt: invalid parameters");if(typeof a==="string"){c=sjcl.misc.cachedPbkdf2(a,f);a=c.key.slice(0,f.ks/32);f.salt=c.salt}if(typeof b==="string")b=sjcl.codec.utf8String.toBits(b);c=new sjcl.cipher[f.cipher](a);e.g(d,f);d.key=a;f.ct=sjcl.mode[f.mode].encrypt(c,b,f.iv,f.adata,f.tag);return e.encode(f)},decrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.g(e.g(e.g({},e.defaults),e.decode(b)),c,true);if(typeof b.salt==="string")b.salt=sjcl.codec.base64.toBits(b.salt);
sjcl.codec.base64.toBits(b.salt);if(typeof b.iv==="string")b.iv=sjcl.codec.base64.toBits(b.iv);if(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||typeof a==="string"&&b.iter<=100||b.ts!==64&&b.ts!==96&&b.ts!==128||b.ks!==128&&b.ks!==192&&b.ks!==0x100||!b.iv||b.iv.length<2||b.iv.length>4)throw new sjcl.exception.invalid("json decrypt: invalid parameters");if(typeof a==="string"){c=sjcl.misc.cachedPbkdf2(a,b);a=c.key.slice(0,b.ks/32);b.salt=c.salt}c=new sjcl.cipher[b.cipher](a);c=sjcl.mode[b.mode].decrypt(c, if(typeof b.iv==="string")b.iv=sjcl.codec.base64.toBits(b.iv);if(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||typeof a==="string"&&b.iter<=100||b.ts!==64&&b.ts!==96&&b.ts!==128||b.ks!==128&&b.ks!==192&&b.ks!==0x100||!b.iv||b.iv.length<2||b.iv.length>4)throw new sjcl.exception.invalid("json decrypt: invalid parameters");if(typeof a==="string"){c=sjcl.misc.cachedPbkdf2(a,b);a=c.key.slice(0,b.ks/32);b.salt=c.salt}c=new sjcl.cipher[b.cipher](a);c=sjcl.mode[b.mode].decrypt(c,b.ct,b.iv,b.adata,b.tag);e.g(d,
b.ct,b.iv,b.adata,b.tag);e.c(d,b);d.key=a;return sjcl.codec.utf8String.fromBits(c)},encode:function(a){var b,c="{",d="";for(b in a)if(a.hasOwnProperty(b)){if(!b.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");c+=d+b+":";d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+sjcl.codec.base64.fromBits(a[b],1)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type"); b);d.key=a;return sjcl.codec.utf8String.fromBits(c)},encode:function(a){var b,c="{",d="";for(b in a)if(a.hasOwnProperty(b)){if(!b.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");c+=d+"'"+b+"':";d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+sjcl.codec.base64.fromBits(a[b],1)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type");}}return c+"}"},
}}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++){if(!(d=a[c].match(/^([a-z][a-z0-9]*):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");b[d[1]]=d[2]?parseInt(d[2],10):d[1].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.toBits(d[3]):unescape(d[3])}return b},c:function(a,b,c){if(a=== decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++){if(!(d=a[c].match(/^(?:(["']?)([a-z][a-z0-9]*)\1):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");b[d[2]]=d[3]?parseInt(d[3],10):d[2].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.toBits(d[4]):unescape(d[4])}return b},g:function(a,b,c){if(a===
undefined)a={};if(b===undefined)return a;var d;for(d in b)if(b.hasOwnProperty(d)){if(c&&a[d]!==undefined&&a[d]!==b[d])throw new sjcl.exception.invalid("required parameter overridden");a[d]=b[d]}return a},V:function(a,b){var c={},d;for(d in a)if(a.hasOwnProperty(d)&&a[d]!==b[d])c[d]=a[d];return c},W:function(a,b){var c={},d;for(d=0;d<b.length;d++)if(a[b[d]]!==undefined)c[b[d]]=a[b[d]];return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.S={}; undefined)a={};if(b===undefined)return a;var d;for(d in b)if(b.hasOwnProperty(d)){if(c&&a[d]!==undefined&&a[d]!==b[d])throw new sjcl.exception.invalid("required parameter overridden");a[d]=b[d]}return a},fa:function(a,b){var c={},d;for(d=0;d<b.length;d++)if(a[b[d]]!==undefined)c[b[d]]=a[b[d]];return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.ca={};
sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.S,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=b.salt===undefined?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}}; sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.ca,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=b.salt===undefined?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}};sjcl.bn=function(a){this.initWith(a)};
sjcl.bn.prototype={radix:24,maxMul:8,d:sjcl.bn,copy:function(){return new this.d(this)},initWith:function(a){var b=0,c;switch(typeof a){case "object":this.limbs=a.limbs.slice(0);break;case "number":this.limbs=[a];this.normalize();break;case "string":a=a.replace(/^0x/,"");this.limbs=[];c=this.radix/4;for(b=0;b<a.length;b+=c)this.limbs.push(parseInt(a.substring(Math.max(a.length-b-c,0),a.length-b),16));break;default:this.limbs=[0]}return this},equals:function(a){if(typeof a=="number")a=new this.d(a);
var b=0,c;this.fullReduce();a.fullReduce();for(c=0;c<this.limbs.length||c<a.limbs.length;c++)b|=this.getLimb(c)^a.getLimb(c);return b===0},getLimb:function(a){return a>=this.limbs.length?0:this.limbs[a]},greaterEquals:function(a){if(typeof a=="number")a=new this.d(a);var b=0,c=0,d,e,f;for(d=Math.max(this.limbs.length,a.limbs.length)-1;d>=0;d--){e=this.getLimb(d);f=a.getLimb(d);c|=f-e&~b;b|=e-f&~c}return(c|~b)>>>31},toString:function(){this.fullReduce();var a="",b,c,d=this.limbs;for(b=0;b<this.limbs.length;b++){for(c=
d[b].toString(16);b<this.limbs.length-1&&c.length<6;)c="0"+c;a=c+a}return"0x"+a},addM:function(a){if(typeof a!=="object")a=new this.d(a);var b=this.limbs,c=a.limbs;for(a=b.length;a<c.length;a++)b[a]=0;for(a=0;a<c.length;a++)b[a]+=c[a];return this},doubleM:function(){var a,b=0,c,d=this.radix,e=this.radixMask,f=this.limbs;for(a=0;a<f.length;a++){c=f[a];c=c+c+b;f[a]=c&e;b=c>>d}b&&f.push(b);return this},halveM:function(){var a,b=0,c,d=this.radix,e=this.limbs;for(a=e.length-1;a>=0;a--){c=e[a];e[a]=c+b>>
1;b=(c&1)<<d}e[e.length-1]||e.pop();return this},subM:function(a){if(typeof a!=="object")a=new this.d(a);var b=this.limbs,c=a.limbs;for(a=b.length;a<c.length;a++)b[a]=0;for(a=0;a<c.length;a++)b[a]-=c[a];return this},mod:function(a){a=(new sjcl.bn(a)).normalize();for(var b=(new sjcl.bn(this)).normalize(),c=0;b.greaterEquals(a);c++)a.doubleM();for(;c>0;c--){a.halveM();b.greaterEquals(a)&&b.subM(a).normalize()}return b.trim()},inverseMod:function(a){var b=new sjcl.bn(1),c=new sjcl.bn(0),d=new sjcl.bn(this),
e=new sjcl.bn(a),f,g=1;if(!(a.limbs[0]&1))throw new sjcl.exception.invalid("inverseMod: p must be odd");do{if(d.limbs[0]&1){if(!d.greaterEquals(e)){f=d;d=e;e=f;f=b;b=c;c=f}d.subM(e);d.normalize();b.greaterEquals(c)||b.addM(a);b.subM(c)}d.halveM();b.limbs[0]&1&&b.addM(a);b.normalize();b.halveM();for(f=g=0;f<d.limbs.length;f++)g|=d.limbs[f]}while(g);if(!e.equals(1))throw new sjcl.exception.invalid("inverseMod: p and x must be relatively prime");return c},add:function(a){return this.copy().addM(a)},
sub:function(a){return this.copy().subM(a)},mul:function(a){if(typeof a=="number")a=new this.d(a);var b,c=this.limbs,d=a.limbs,e=c.length,f=d.length,g=new this.d,h=g.limbs,j,n=this.maxMul;for(b=0;b<this.limbs.length+a.limbs.length+1;b++)h[b]=0;for(b=0;b<e;b++){j=c[b];for(a=0;a<f;a++)h[b+a]+=j*d[a];if(!--n){n=this.maxMul;g.cnormalize()}}return g.cnormalize().reduce()},square:function(){return this.mul(this)},power:function(a){if(typeof a=="number")a=[a];else if(a.limbs!==undefined)a=a.normalize().limbs;
var b,c=new this.d(1),d=this;for(i=0;i<a.length;i++)for(b=0;b<this.radix;b++){if(a[i]&1<<b)c=c.mul(d);d=d.square()}return c},trim:function(){var a=this.limbs,b;do b=a.pop();while(a.length&&b==0);a.push(b);return this},reduce:function(){return this},fullReduce:function(){return this.normalize()},normalize:function(){var a=0,b,c=this.ipv,d,e=this.limbs,f=e.length,g=this.radixMask;for(b=0;b<f||a!==0&&a!==-1;b++){a=(e[b]||0)+a;d=e[b]=a&g;a=(a-d)*c}if(a==-1)e[b-1]-=this.placeVal;return this},cnormalize:function(){var a=
0,b,c=this.ipv,d,e=this.limbs,f=e.length,g=this.radixMask;for(b=0;b<f-1;b++){a=e[b]+a;d=e[b]=a&g;a=(a-d)*c}e[b]+=a;return this},toBits:function(a){this.fullReduce();a=a||this.exponent||this.limbs.length*this.radix;var b=Math.floor((a-1)/24),c=sjcl.bitArray;out=[c.partial((a+7&-8)%this.radix||this.radix,this.getLimb(b))];for(b--;b>=0;b--)out=c.concat(out,[c.partial(this.radix,this.getLimb(b))]);return out},bitLength:function(){this.fullReduce();for(var a=this.radix*(this.limbs.length-1),b=this.limbs[this.limbs.length-
1];b;b>>=1)a++;return a+7&-8}};sjcl.bn.fromBits=function(a){var b=new this,c=[],d=sjcl.bitArray,e=this.prototype,f=Math.min(this.bitLength||0x100000000,d.bitLength(a)),g=f%e.radix||e.radix;for(c[0]=d.extract(a,0,g);g<f;g+=e.radix)c.unshift(d.extract(a,g,e.radix));b.limbs=c;return b};sjcl.bn.prototype.ipv=1/(sjcl.bn.prototype.placeVal=Math.pow(2,sjcl.bn.prototype.radix));sjcl.bn.prototype.radixMask=(1<<sjcl.bn.prototype.radix)-1;
sjcl.bn.pseudoMersennePrime=function(a,b){function c(g){this.initWith(g)}var d=c.prototype=new sjcl.bn,e,f;e=d.modOffset=Math.ceil(f=a/d.radix);d.exponent=a;d.offset=[];d.factor=[];d.minOffset=e;d.fullMask=0;d.fullOffset=[];d.fullFactor=[];d.modulus=c.modulus=new sjcl.bn(Math.pow(2,a));d.fullMask=0|-Math.pow(2,a%d.radix);for(e=0;e<b.length;e++){d.offset[e]=Math.floor(b[e][0]/d.radix-f);d.fullOffset[e]=Math.ceil(b[e][0]/d.radix-f);d.factor[e]=b[e][1]*Math.pow(0.5,a-b[e][0]+d.offset[e]*d.radix);d.fullFactor[e]=
b[e][1]*Math.pow(0.5,a-b[e][0]+d.fullOffset[e]*d.radix);d.modulus.addM(new sjcl.bn(Math.pow(2,b[e][0])*b[e][1]));d.minOffset=Math.min(d.minOffset,-d.offset[e])}d.d=c;d.modulus.cnormalize();d.reduce=function(){var g,h,j,n=this.modOffset,l=this.limbs,m=this.offset,o=this.offset.length,q=this.factor,r;for(g=this.minOffset;l.length>n;){j=l.pop();r=l.length;for(h=0;h<o;h++)l[r+m[h]]-=q[h]*j;g--;if(g==0){l.push(0);this.cnormalize();g=this.minOffset}}this.cnormalize();return this};d.$=d.fullMask==-1?d.reduce:
function(){var g=this.limbs,h=g.length-1,j;this.reduce();if(h==this.modOffset-1){j=g[h]&this.fullMask;g[h]-=j;for(k=0;k<this.fullOffset.length;k++)g[h+this.fullOffset[k]]-=this.fullFactor[k]*j;this.normalize()}};d.fullReduce=function(){var g,h;this.$();this.addM(this.modulus);this.addM(this.modulus);this.normalize();this.$();for(h=this.limbs.length;h<this.modOffset;h++)this.limbs[h]=0;g=this.greaterEquals(this.modulus);for(h=0;h<this.limbs.length;h++)this.limbs[h]-=this.modulus.limbs[h]*g;this.cnormalize();
return this};d.inverse=function(){return this.power(this.modulus.sub(2))};c.fromBits=sjcl.bn.fromBits;return c};
sjcl.bn.prime={p127:sjcl.bn.pseudoMersennePrime(127,[[0,-1]]),p25519:sjcl.bn.pseudoMersennePrime(255,[[0,-19]]),p192:sjcl.bn.pseudoMersennePrime(192,[[0,-1],[64,-1]]),p224:sjcl.bn.pseudoMersennePrime(224,[[0,1],[96,-1]]),p256:sjcl.bn.pseudoMersennePrime(0x100,[[0,-1],[96,1],[192,1],[224,-1]]),p384:sjcl.bn.pseudoMersennePrime(384,[[0,-1],[32,1],[96,-1],[128,-1]]),p521:sjcl.bn.pseudoMersennePrime(521,[[0,-1]])};
sjcl.bn.random=function(a,b){if(typeof a!="object")a=new sjcl.bn(a);for(var c,d,e=a.limbs.length,f=a.limbs[e-1]+1,g=new sjcl.bn;;){do{c=sjcl.random.randomWords(e,b);if(c[e-1]<0)c[e-1]+=0x100000000}while(Math.floor(c[e-1]/f)==Math.floor(0x100000000/f));c[e-1]%=f;for(d=0;d<e-1;d++)c[d]&=a.radixMask;g.limbs=c;if(!g.greaterEquals(a))return g}};sjcl.ecc={};sjcl.ecc.point=function(a,b,c){if(b===undefined)this.isIdentity=true;else{this.x=b;this.y=c;this.isIdentity=false}this.curve=a};
sjcl.ecc.point.prototype={toJac:function(){return new sjcl.ecc.pointJac(this.curve,this.x,this.y,new this.curve.field(1))},mult:function(a){return this.toJac().mult(a,this).toAffine()},isValid:function(){return this.y.square().equals(this.curve.b.add(this.x.mul(this.curve.a.add(this.x.square()))))},toBits:function(){return sjcl.bitArray.concat(this.x.toBits(),this.y.toBits())}};
sjcl.ecc.pointJac=function(a,b,c,d){if(b===undefined)this.isIdentity=true;else{this.x=b;this.y=c;this.z=d;this.isIdentity=false}this.curve=a};
sjcl.ecc.pointJac.prototype={add:function(a){if(this.curve!==a.curve)throw"sjcl['ecc']['add'](): Points must be on the same curve to add them!";if(this.isIdentity)return a.toJac();else if(a.isIdentity)return this;var b=this.z.square(),c=a.x.mul(b).subM(this.x);if(c.equals(0))return this.y.equals(a.y.mul(b.mul(this.z)))?this.doubl():new sjcl.ecc.pointJac(this.curve);b=a.y.mul(b.mul(this.z)).subM(this.y);var d=c.square();a=b.square();var e=c.square().mul(c).addM(this.x.add(this.x).mul(d));a=a.subM(e);
b=this.x.mul(d).subM(a).mul(b);d=this.y.mul(c.square().mul(c));b=b.subM(d);c=this.z.mul(c);c=new sjcl.ecc.pointJac(this.curve,a,b,c);if(!c.isValid())throw"FOOOOOOOO";return c},doubl:function(){if(this.isIdentity)return this;var a=this.y.square(),b=a.mul(this.x.mul(4)),c=a.square().mul(8);a=this.z.square();var d=this.x.sub(a).mul(3).mul(this.x.add(a));a=d.square().subM(b).subM(b);b=b.sub(a).mul(d).subM(c);c=this.y.add(this.y).mul(this.z);return new sjcl.ecc.pointJac(this.curve,a,b,c)},toAffine:function(){if(this.isIdentity||
this.z.equals(0))return new sjcl.ecc.point(this.curve);var a=this.z.inverse(),b=a.square();return new sjcl.ecc.point(this.curve,this.x.mul(b).fullReduce(),this.y.mul(b.mul(a)).fullReduce())},mult:function(a,b){if(typeof a=="number")a=[a];else if(a.limbs!==undefined)a=a.normalize().limbs;var c,d,e=(new sjcl.ecc.point(this.curve)).toJac();if(b===undefined)b=this.toAffine();if(b.multiples===undefined){d=this.doubl();b.multiples=[new sjcl.ecc.point(this.curve),b,d.toAffine()];for(c=3;c<16;c++){d=d.add(b);
b.multiples[c]=d.toAffine()}}b=b.multiples;for(c=a.length-1;c>=0;c--)for(d=sjcl.bn.prototype.radix-4;d>=0;d-=4)e=e.doubl().doubl().doubl().doubl().add(b[a[c]>>d&15]);return e},isValid:function(){var a=this.z.square(),b=a.square();a=b.mul(a);return this.y.square().equals(this.curve.b.mul(a).add(this.x.mul(this.curve.a.mul(b).add(this.x.square()))))}};
sjcl.ecc.curve=function(a,b,c,d,e,f){this.field=a;this.r=a.prototype.modulus.sub(b);this.a=new a(c);this.b=new a(d);this.G=new sjcl.ecc.point(this,new a(e),new a(f))};sjcl.ecc.curve.prototype.fromBits=function(a){var b=sjcl.bitArray,c=this.field.prototype.exponent+7&-8;p=new sjcl.ecc.point(this,this.field.fromBits(b.bitSlice(a,0,c)),this.field.fromBits(b.bitSlice(a,c,2*c)));if(!p.isValid())throw new sjcl.exception.corrupt("not on the curve!");return p};
sjcl.ecc.curves={c192:new sjcl.ecc.curve(sjcl.bn.prime.p192,"0x662107c8eb94364e4b2dd7ce",-3,"0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1","0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012","0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"),c224:new sjcl.ecc.curve(sjcl.bn.prime.p224,"0xe95c1f470fc1ec22d6baa3a3d5c4",-3,"0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4","0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21","0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"),
c256:new sjcl.ecc.curve(sjcl.bn.prime.p256,"0x4319055358e8617b0c46353d039cdaae",-3,"0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b","0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"),c384:new sjcl.ecc.curve(sjcl.bn.prime.p384,"0x389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68c",-3,"0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef","0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
"0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f")};
sjcl.ecc.Q=function(a){sjcl.ecc[a]={publicKey:function(b,c){this.e=b;this.Y=c instanceof Array?b.fromBits(c):c},secretKey:function(b,c){this.e=b;this.S=c},generateKeys:function(b,c){if(typeof b=="number"){b=sjcl.ecc.curves["c"+b];if(b===undefined)throw new sjcl.exception.invalid("no such curve");}c=sjcl.bn.random(b.r,c);var d=b.G.mult(c);return{pub:new sjcl.ecc[a].publicKey(b,d),sec:new sjcl.ecc[a].secretKey(b,c)}}}};sjcl.ecc.Q("elGamal");
sjcl.ecc.elGamal.publicKey.prototype={kem:function(a){a=sjcl.bn.random(this.e.r,a);var b=this.e.G.mult(a).toBits();return{key:sjcl.hash.sha256.hash(this.Y.mult(a).toBits()),tag:b}}};sjcl.ecc.elGamal.secretKey.prototype={unkem:function(a){return sjcl.hash.sha256.hash(this.e.fromBits(a).mult(this.S).toBits())}};sjcl.ecc.Q("dsa");
sjcl.ecc.dsa.secretKey.prototype={sign:function(a,b){var c=this.e.r,d=c.bitLength();b=this.e.G.mult(kkkk=sjcl.bn.random(c.sub(1),b).add(1)).x.mod(c);a=sjcl.bn.fromBits(a).add(b.mul(this.S)).inverseMod(c).mul(kkkk).mod(c);return sjcl.bitArray.concat(b.toBits(d),a.toBits(d))}};
sjcl.ecc.dsa.publicKey.prototype={verify:function(a,b){var c=sjcl.bitArray,d=this.e.r,e=d.bitLength(),f=sjcl.bn.fromBits(c.bitSlice(b,0,e));b=sjcl.bn.fromBits(c.bitSlice(b,e,2*e));a=sjcl.bn.fromBits(a).mul(b).mod(d);c=f.mul(b).mod(d);a=this.e.G.toJac().mult(a,this.e.G).add(this.Y.mult(c)).toAffine().x;c=sjcl.exception.corrupt;if(f.equals(0)||b.equals(0)||f.greaterEquals(d)||b.greaterEquals(d)||!a.equals(f))throw new c("signature didn't check out");return true}};