From 2bb04bb02f715c9f16d7fcbf8106bd1ee613ca56 Mon Sep 17 00:00:00 2001 From: Mike Hamburg Date: Thu, 7 Oct 2010 19:42:19 -0700 Subject: [PATCH] shamir's trick --- core/ecc.js | 77 ++++++++++++++++++++++++++++++++++++++++++----------- sjcl.js | 39 ++++++++++++++------------- 2 files changed, 81 insertions(+), 35 deletions(-) diff --git a/core/ecc.js b/core/ecc.js index c65fb16..9e456d0 100644 --- a/core/ecc.js +++ b/core/ecc.js @@ -28,6 +28,30 @@ sjcl.ecc.point.prototype = { mult: function(k) { return this.toJac().mult(k, this).toAffine(); }, + + /** + * Multiply this point by k, added to affine2*k2, and return the answer in Jacobian coordinates. + * @param {bigInt} k The coefficient to multiply this by. + * @param {bigInt} k2 The coefficient to multiply affine2 this by. + * @param {sjcl.ecc.point} affine The other point in affine coordinates. + * @return {sjcl.ecc.pointJac} The result of the multiplication and addition, in Jacobian coordinates. + */ + mult2: function(k, k2, affine2) { + return this.toJac().mult2(k, this, k2, affine2).toAffine(); + }, + + multiples: function() { + var m, i, j; + if (this._multiples === undefined) { + j = this.toJac().doubl(); + m = this._multiples = [new sjcl.ecc.point(this.curve), this, j.toAffine()]; + for (i=3; i<16; i++) { + j = j.add(this); + m.push(j.toAffine()); + } + } + return this._multiples; + }, isValid: function() { return this.y.square().equals(this.curve.b.add(this.x.mul(this.curve.a.add(this.x.square())))); @@ -156,21 +180,8 @@ sjcl.ecc.pointJac.prototype = { } else if (k.limbs !== undefined) { k = k.normalize().limbs; } - var i, j, out = new sjcl.ecc.point(this.curve).toJac(), multiples, aff2; - if (affine === undefined) { - affine = this.toAffine(); - } - - if (affine.multiples === undefined) { - j = this.doubl(); - affine.multiples = [new sjcl.ecc.point(this.curve), affine, j.toAffine()]; - for (i=3; i<16; i++) { - j = j.add(affine); - affine.multiples[i] = j.toAffine(); - } - } - multiples = affine.multiples; + var i, j, out = new sjcl.ecc.point(this.curve).toJac(), multiples = affine.multiples(); for (i=k.length-1; i>=0; i--) { for (j=sjcl.bn.prototype.radix-4; j>=0; j-=4) { @@ -180,6 +191,41 @@ sjcl.ecc.pointJac.prototype = { return out; }, + + /** + * Multiply this point by k, added to affine2*k2, and return the answer in Jacobian coordinates. + * @param {bigInt} k The coefficient to multiply this by. + * @param {sjcl.ecc.point} affine This point in affine coordinates. + * @param {bigInt} k2 The coefficient to multiply affine2 this by. + * @param {sjcl.ecc.point} affine The other point in affine coordinates. + * @return {sjcl.ecc.pointJac} The result of the multiplication and addition, in Jacobian coordinates. + */ + mult2: function(k1, affine, k2, affine2) { + if (typeof(k1) == "number") { + k1 = [k1]; + } else if (k1.limbs !== undefined) { + k1 = k1.normalize().limbs; + } + + if (typeof(k2) == "number") { + k2 = [k2]; + } else if (k2.limbs !== undefined) { + k2 = k2.normalize().limbs; + } + + var i, j, out = new sjcl.ecc.point(this.curve).toJac(), m1 = affine.multiples(), + m2 = affine2.multiples(), l1, l2; + + for (i=Math.max(k1.length,k2.length)-1; i>=0; i--) { + l1 = k1[i] | 0; + l2 = k2[i] | 0; + for (j=sjcl.bn.prototype.radix-4; j>=0; j-=4) { + out = out.doubl().doubl().doubl().doubl().add(m1[l1>>j & 0xF]).add(m2[l2>>j & 0xF]); + } + } + + return out; + }, isValid: function() { var z2 = this.z.square(), z4 = z2.square(), z6 = z4.mul(z2); @@ -322,8 +368,7 @@ sjcl.ecc.dsa.publicKey.prototype = { 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, + r2 = this._curve.G.mult2(hG, hA, this._point).x, corrupt = sjcl.exception.corrupt; if (r.equals(0) || s.equals(0) || r.greaterEquals(R) || s.greaterEquals(R) || !r2.equals(r)) { diff --git a/sjcl.js b/sjcl.js index fe109df..6141fbf 100644 --- a/sjcl.js +++ b/sjcl.js @@ -4,9 +4,9 @@ g[3][f[c&255]]}}; 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)}},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>>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]^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.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<>>d:a[b/32|0]>>>d)&(1<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=32;b-=32){d.push(c);c=0}if(b===0)return d.concat(a);for(e=0;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]]}}; +return c===0},$: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>>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>>24);e<<=8}return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c>>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>>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;b0;){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", -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.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=1<this.k)this.k=c;this.H++;this.da(b)},u:function(a){sjcl.random.addEntropy([a.x|| +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.Y?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.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.ba++]=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=1<this.k)this.k=c;this.H++;this.ea(b)},u:function(a){sjcl.random.addEntropy([a.x|| 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 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); 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);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+"}"}, 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=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>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>> @@ -47,22 +47,23 @@ var b,c=new this.d(1),d=this;for(i=0;i=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);gn;){j=l.pop();r=l.length;for(h=0;hn;){j=l.pop();r=l.length;for(h=0;h=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}; +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=(new sjcl.ecc.point(this.curve)).toJac(),e=b.multiples();for(b=a.length-1;b>=0;b--)for(c=sjcl.bn.prototype.radix-4;c>=0;c-=4)d=d.doubl().doubl().doubl().doubl().add(e[a[b]>>c&15]);return d},mult2:function(a, +b,c,d){if(typeof a=="number")a=[a];else if(a.limbs!==undefined)a=a.normalize().limbs;if(typeof c=="number")c=[c];else if(c.limbs!==undefined)c=c.normalize().limbs;var e,f=(new sjcl.ecc.point(this.curve)).toJac();b=b.multiples();var g=d.multiples(),h,j;for(d=Math.max(a.length,c.length)-1;d>=0;d--){h=a[d]|0;j=c[d]|0;for(e=sjcl.bn.prototype.radix-4;e>=0;e-=4)f=f.doubl().doubl().doubl().doubl().add(b[h>>e&15]).add(g[j>>e&15])}return f},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.Q=function(a){sjcl.ecc[a]={publicKey:function(b,c){this.e=b;this.Z=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.Z.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}}; +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.mult2(a,c,this.Z).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}};