http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/js/AES.js ---------------------------------------------------------------------- diff --git a/js/AES.js b/js/AES.js deleted file mode 100755 index 39f8aa6..0000000 --- a/js/AES.js +++ /dev/null @@ -1,424 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -var AES = function() { - this.mode=0; - this.fkey=[]; - this.rkey=[]; - this.f=[]; -}; - -AES.prototype={ -/* reset cipher */ - reset:function(m,iv) - { /* reset mode, or reset iv */ - var i; - this.mode=m; - for (i=0;i<16;i++) - this.f[i]=0; - if (this.mode!=this.ECB && iv!==null) - for (i=0;i<16;i++) - this.f[i]=iv[i]; - }, - - getreg:function() - { - var ir=[]; - for (var i=0;i<16;i++) ir[i]=this.f[i]; - return ir; - }, - -/* Initialise cipher */ - init: function(m,key,iv) - { /* Key=16 bytes */ - /* Key Scheduler. Create expanded encryption key */ - var i,j,k,N,nk; - var CipherKey= []; - var b=[]; - nk=4; - this.reset(m,iv); - N=44; - - for (i=j=0;i<nk;i++,j+=4) - { - for (k=0;k<4;k++) b[k]=key[j+k]; - CipherKey[i]=AES.pack(b); - } - for (i=0;i<nk;i++) this.fkey[i]=CipherKey[i]; - for (j=nk,k=0;j<N;j+=nk,k++) - { - this.fkey[j]=this.fkey[j-nk]^AES.SubByte(AES.ROTL24(this.fkey[j-1]))^(ROM.rco[k])&0xff; - for (i=1;i<nk && (i+j)<N;i++) - this.fkey[i+j]=this.fkey[i+j-nk]^this.fkey[i+j-1]; - } - - /* now for the expanded decrypt key in reverse order */ - - for (j=0;j<4;j++) this.rkey[j+N-4]=this.fkey[j]; - for (i=4;i<N-4;i+=4) - { - k=N-4-i; - for (j=0;j<4;j++) this.rkey[k+j]=AES.InvMixCol(this.fkey[i+j]); - } - for (j=N-4;j<N;j++) this.rkey[j-N+4]=this.fkey[j]; - }, - -/* Encrypt a single block */ - ecb_encrypt: function(buff) - { - var i,j,k; - var t; - var b=[]; - var p=[]; - var q=[]; - - for (i=j=0;i<4;i++,j+=4) - { - for (k=0;k<4;k++) b[k]=buff[j+k]; - p[i]=AES.pack(b); - p[i]^=this.fkey[i]; - } - - k=4; - -/* State alternates between p and q */ - for (i=1;i<10;i++) - { - q[0]=this.fkey[k]^ROM.ftable[p[0]&0xff]^ - AES.ROTL8(ROM.ftable[(p[1]>>>8)&0xff])^ - AES.ROTL16(ROM.ftable[(p[2]>>>16)&0xff])^ - AES.ROTL24(ROM.ftable[(p[3]>>>24)&0xff]); - q[1]=this.fkey[k+1]^ROM.ftable[p[1]&0xff]^ - AES.ROTL8(ROM.ftable[(p[2]>>>8)&0xff])^ - AES.ROTL16(ROM.ftable[(p[3]>>>16)&0xff])^ - AES.ROTL24(ROM.ftable[(p[0]>>>24)&0xff]); - q[2]=this.fkey[k+2]^ROM.ftable[p[2]&0xff]^ - AES.ROTL8(ROM.ftable[(p[3]>>>8)&0xff])^ - AES.ROTL16(ROM.ftable[(p[0]>>>16)&0xff])^ - AES.ROTL24(ROM.ftable[(p[1]>>>24)&0xff]); - q[3]=this.fkey[k+3]^ROM.ftable[p[3]&0xff]^ - AES.ROTL8(ROM.ftable[(p[0]>>>8)&0xff])^ - AES.ROTL16(ROM.ftable[(p[1]>>>16)&0xff])^ - AES.ROTL24(ROM.ftable[(p[2]>>>24)&0xff]); - - k+=4; - for (j=0;j<4;j++) - { - t=p[j]; p[j]=q[j]; q[j]=t; - } - } - -/* Last Round */ - - q[0]=this.fkey[k]^(ROM.fbsub[p[0]&0xff]&0xff)^ - AES.ROTL8(ROM.fbsub[(p[1]>>>8)&0xff]&0xff)^ - AES.ROTL16(ROM.fbsub[(p[2]>>>16)&0xff]&0xff)^ - AES.ROTL24(ROM.fbsub[(p[3]>>>24)&0xff]&0xff); - - q[1]=this.fkey[k+1]^(ROM.fbsub[p[1]&0xff]&0xff)^ - AES.ROTL8(ROM.fbsub[(p[2]>>>8)&0xff]&0xff)^ - AES.ROTL16(ROM.fbsub[(p[3]>>>16)&0xff]&0xff)^ - AES.ROTL24(ROM.fbsub[(p[0]>>>24)&0xff]&0xff); - - q[2]=this.fkey[k+2]^(ROM.fbsub[p[2]&0xff]&0xff)^ - AES.ROTL8(ROM.fbsub[(p[3]>>>8)&0xff]&0xff)^ - AES.ROTL16(ROM.fbsub[(p[0]>>>16)&0xff]&0xff)^ - AES.ROTL24(ROM.fbsub[(p[1]>>>24)&0xff]&0xff); - - q[3]=this.fkey[k+3]^(ROM.fbsub[(p[3])&0xff]&0xff)^ - AES.ROTL8(ROM.fbsub[(p[0]>>>8)&0xff]&0xff)^ - AES.ROTL16(ROM.fbsub[(p[1]>>>16)&0xff]&0xff)^ - AES.ROTL24(ROM.fbsub[(p[2]>>>24)&0xff]&0xff); - - for (i=j=0;i<4;i++,j+=4) - { - b=AES.unpack(q[i]); - for (k=0;k<4;k++) buff[j+k]=b[k]; - } - }, - -/* Decrypt a single block */ - ecb_decrypt: function(buff) - { - var i,j,k; - var t; - var b=[]; - var p=[]; - var q=[]; - - for (i=j=0;i<4;i++,j+=4) - { - for (k=0;k<4;k++) b[k]=buff[j+k]; - p[i]=AES.pack(b); - p[i]^=this.rkey[i]; - } - - k=4; - -/* State alternates between p and q */ - for (i=1;i<10;i++) - { - q[0]=this.rkey[k]^ROM.rtable[p[0]&0xff]^ - AES.ROTL8(ROM.rtable[(p[3]>>>8)&0xff])^ - AES.ROTL16(ROM.rtable[(p[2]>>>16)&0xff])^ - AES.ROTL24(ROM.rtable[(p[1]>>>24)&0xff]); - q[1]=this.rkey[k+1]^ROM.rtable[p[1]&0xff]^ - AES.ROTL8(ROM.rtable[(p[0]>>>8)&0xff])^ - AES.ROTL16(ROM.rtable[(p[3]>>>16)&0xff])^ - AES.ROTL24(ROM.rtable[(p[2]>>>24)&0xff]); - q[2]=this.rkey[k+2]^ROM.rtable[p[2]&0xff]^ - AES.ROTL8(ROM.rtable[(p[1]>>>8)&0xff])^ - AES.ROTL16(ROM.rtable[(p[0]>>>16)&0xff])^ - AES.ROTL24(ROM.rtable[(p[3]>>>24)&0xff]); - q[3]=this.rkey[k+3]^ROM.rtable[p[3]&0xff]^ - AES.ROTL8(ROM.rtable[(p[2]>>>8)&0xff])^ - AES.ROTL16(ROM.rtable[(p[1]>>>16)&0xff])^ - AES.ROTL24(ROM.rtable[(p[0]>>>24)&0xff]); - - k+=4; - for (j=0;j<4;j++) - { - t=p[j]; p[j]=q[j]; q[j]=t; - } - } - -/* Last Round */ - - q[0]=this.rkey[k]^(ROM.rbsub[p[0]&0xff]&0xff)^ - AES.ROTL8(ROM.rbsub[(p[3]>>>8)&0xff]&0xff)^ - AES.ROTL16(ROM.rbsub[(p[2]>>>16)&0xff]&0xff)^ - AES.ROTL24(ROM.rbsub[(p[1]>>>24)&0xff]&0xff); - q[1]=this.rkey[k+1]^(ROM.rbsub[p[1]&0xff]&0xff)^ - AES.ROTL8(ROM.rbsub[(p[0]>>>8)&0xff]&0xff)^ - AES.ROTL16(ROM.rbsub[(p[3]>>>16)&0xff]&0xff)^ - AES.ROTL24(ROM.rbsub[(p[2]>>>24)&0xff]&0xff); - q[2]=this.rkey[k+2]^(ROM.rbsub[p[2]&0xff]&0xff)^ - AES.ROTL8(ROM.rbsub[(p[1]>>>8)&0xff]&0xff)^ - AES.ROTL16(ROM.rbsub[(p[0]>>>16)&0xff]&0xff)^ - AES.ROTL24(ROM.rbsub[(p[3]>>>24)&0xff]&0xff); - q[3]=this.rkey[k+3]^(ROM.rbsub[p[3]&0xff]&0xff)^ - AES.ROTL8(ROM.rbsub[(p[2]>>>8)&0xff]&0xff)^ - AES.ROTL16(ROM.rbsub[(p[1]>>>16)&0xff]&0xff)^ - AES.ROTL24(ROM.rbsub[(p[0]>>>24)&0xff]&0xff); - - for (i=j=0;i<4;i++,j+=4) - { - b=AES.unpack(q[i]); - for (k=0;k<4;k++) buff[j+k]=b[k]; - } - - }, - -/* Encrypt using selected mode of operation */ - encrypt: function(buff) - { - var j,bytes; - var st=[]; - var fell_off; - -// Supported Modes of Operation - - fell_off=0; - - switch (this.mode) - { - case ROM.ECB: - this.ecb_encrypt(buff); - return 0; - case ROM.CBC: - for (j=0;j<16;j++) buff[j]^=this.f[j]; - this.ecb_encrypt(buff); - for (j=0;j<16;j++) this.f[j]=buff[j]; - return 0; - - case ROM.CFB1: - case ROM.CFB2: - case ROM.CFB4: - bytes=this.mode-ROM.CFB1+1; - for (j=0;j<bytes;j++) fell_off=(fell_off<<8)|this.f[j]; - for (j=0;j<16;j++) st[j]=this.f[j]; - for (j=bytes;j<16;j++) this.f[j-bytes]=this.f[j]; - this.ecb_encrypt(st); - for (j=0;j<bytes;j++) - { - buff[j]^=st[j]; - this.f[16-bytes+j]=buff[j]; - } - return fell_off; - - case ROM.OFB1: - case ROM.OFB2: - case ROM.OFB4: - case ROM.OFB8: - case ROM.OFB16: - - bytes=this.mode-ROM.OFB1+1; - this.ecb_encrypt(this.f); - for (j=0;j<bytes;j++) buff[j]^=this.f[j]; - return 0; - - default: - return 0; - } - }, - -/* Decrypt using selected mode of operation */ - decrypt: function(buff) - { - var j,bytes; - var st=[]; - var fell_off; - - // Supported modes of operation - fell_off=0; - switch (this.mode) - { - case ROM.ECB: - this.ecb_decrypt(buff); - return 0; - case ROM.CBC: - for (j=0;j<16;j++) - { - st[j]=this.f[j]; - this.f[j]=buff[j]; - } - this.ecb_decrypt(buff); - for (j=0;j<16;j++) - { - buff[j]^=st[j]; - st[j]=0; - } - return 0; - case ROM.CFB1: - case ROM.CFB2: - case ROM.CFB4: - bytes=this.mode-ROM.CFB1+1; - for (j=0;j<bytes;j++) fell_off=(fell_off<<8)|this.f[j]; - for (j=0;j<16;j++) st[j]=this.f[j]; - for (j=bytes;j<16;j++) this.f[j-bytes]=this.f[j]; - this.ecb_encrypt(st); - for (j=0;j<bytes;j++) - { - this.f[16-bytes+j]=buff[j]; - buff[j]^=st[j]; - } - return fell_off; - case ROM.OFB1: - case ROM.OFB2: - case ROM.OFB4: - case ROM.OFB8: - case ROM.OFB16: - bytes=this.mode-ROM.OFB1+1; - this.ecb_encrypt(this.f); - for (j=0;j<bytes;j++) buff[j]^=this.f[j]; - return 0; - - - default: - return 0; - } - }, - -/* Clean up and delete left-overs */ - end: function() - { // clean up - var i; - for (i=0;i<44;i++) - this.fkey[i]=this.rkey[i]=0; - for (i=0;i<16;i++) - this.f[i]=0; - } - -}; - -AES.ROTL8=function(x) -{ - return (((x)<<8)|((x)>>>24)); -}; - -AES.ROTL16=function(x) -{ - return (((x)<<16)|((x)>>>16)); -}; - -AES.ROTL24=function(x) -{ - return (((x)<<24)|((x)>>>8)); -}; - -AES.pack= function(b) -{ /* pack 4 bytes into a 32-bit Word */ - return (((b[3])&0xff)<<24)|((b[2]&0xff)<<16)|((b[1]&0xff)<<8)|(b[0]&0xff); -}; - -AES.unpack=function(a) -{ /* unpack bytes from a word */ - var b=[]; - b[0]=(a&0xff); - b[1]=((a>>>8)&0xff); - b[2]=((a>>>16)&0xff); - b[3]=((a>>>24)&0xff); - return b; -}; - -AES.bmul=function(x,y) -{ /* x.y= AntiLog(Log(x) + Log(y)) */ - - var ix=(x&0xff); - var iy=(y&0xff); - var lx=(ROM.ltab[ix])&0xff; - var ly=(ROM.ltab[iy])&0xff; - if (x!==0 && y!==0) return ROM.ptab[(lx+ly)%255]; - else return 0; -}; - -// if (x && y) - -AES.SubByte=function(a) -{ - var b=AES.unpack(a); - b[0]=ROM.fbsub[b[0]&0xff]; - b[1]=ROM.fbsub[b[1]&0xff]; - b[2]=ROM.fbsub[b[2]&0xff]; - b[3]=ROM.fbsub[b[3]&0xff]; - return AES.pack(b); -}; - -AES.product=function(x,y) -{ /* dot product of two 4-byte arrays */ - var xb=AES.unpack(x); - var yb=AES.unpack(y); - return (AES.bmul(xb[0],yb[0])^AES.bmul(xb[1],yb[1])^AES.bmul(xb[2],yb[2])^AES.bmul(xb[3],yb[3]))&0xff; -}; - -AES.InvMixCol=function(x) -{ /* matrix Multiplication */ - var y,m; - var b=[]; - m=AES.pack(ROM.InCo); - b[3]=AES.product(m,x); - m=AES.ROTL24(m); - b[2]=AES.product(m,x); - m=AES.ROTL24(m); - b[1]=AES.product(m,x); - m=AES.ROTL24(m); - b[0]=AES.product(m,x); - y=AES.pack(b); - return y; -};
http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/js/BIG.js ---------------------------------------------------------------------- diff --git a/js/BIG.js b/js/BIG.js deleted file mode 100755 index 4b34100..0000000 --- a/js/BIG.js +++ /dev/null @@ -1,953 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* AMCL BIG number class */ - -/* General purpose Constructor */ -var BIG = function(x) { - this.w=new Array(ROM.NLEN); - switch (typeof(x)) - { - case "object": - this.copy(x); - break; - case "number": - this.zero(); - this.w[0]=x; - break; - default: - this.zero(); - } -}; - -BIG.prototype={ -/* set to zero */ - zero: function() - { - for (var i=0;i<ROM.NLEN;i++) this.w[i]=0; - return this; - }, -/* set to one */ - one: function() - { - this.w[0]=1; - for (var i=1;i<ROM.NLEN;i++) this.w[i]=0; - return this; - }, - - get: function(i) - { - return this.w[i]; - }, - - set: function(i,x) - { - this.w[i]=x; - }, -/* test for zero */ - iszilch: function() - { - for (var i=0;i<ROM.NLEN;i++) - if (this.w[i]!==0) return false; - return true; - }, -/* test for unity */ - isunity: function() - { - for (var i=1;i<ROM.NLEN;i++) - if (this.w[i]!==0) return false; - if (this.w[0]!=1) return false; - return true; - }, - -/* Conditional swap of two bigs depending on d using XOR - no branches */ - cswap: function(b,d) - { - var i; - var t,c=d; - c=~(c-1); - - for (i=0;i<ROM.NLEN;i++) - { - t=c&(this.w[i]^b.w[i]); - this.w[i]^=t; - b.w[i]^=t; - } - }, - -/* Conditional move of big depending on d using XOR - no branches */ - cmove: function(b,d) - { - var i; - var t,c=d; - c=~(c-1); - - for (i=0;i<ROM.NLEN;i++) - { - this.w[i]^=(this.w[i]^b.w[i])&c; - } - }, - -/* copy from another BIG */ - copy: function(y) - { - for (var i=0;i<ROM.NLEN;i++) - this.w[i]=y.w[i]; - return this; - }, -/* copy from bottom half of DBIG */ - hcopy: function(y) - { - for (var i=0;i<ROM.NLEN;i++) - this.w[i]=y.w[i]; - return this; - }, -/* copy from ROM */ - rcopy: function(y) - { - for (var i=0;i<ROM.NLEN;i++) - this.w[i]=y[i]; - return this; - }, - - xortop: function(x) - { - this.w[ROM.NLEN-1]^=x; - }, - - ortop: function(x) - { - this.w[ROM.NLEN-1]|=x; - }, - -/* normalise BIG - force all digits < 2^BASEBITS */ - norm: function() - { - var d,carry=0; - for (var i=0;i<ROM.NLEN-1;i++) - { - d=this.w[i]+carry; - this.w[i]=d&ROM.MASK; - carry=d>>ROM.BASEBITS; - } - this.w[ROM.NLEN-1]=(this.w[ROM.NLEN-1]+carry); - - return (this.w[ROM.NLEN-1]>>((8*ROM.MODBYTES)%ROM.BASEBITS)); - - }, -/* quick shift right by less than a word */ - fshr: function(k) - { - var r=this.w[0]&((1<<k)-1); /* shifted out part */ - for (var i=0;i<ROM.NLEN-1;i++) - this.w[i]=(this.w[i]>>k)|((this.w[i+1]<<(ROM.BASEBITS-k))&ROM.MASK); - this.w[ROM.NLEN-1]=this.w[ROM.NLEN-1]>>k; - return r; - }, -/* General shift right by k bits */ - shr: function(k) - { - var n=k%ROM.BASEBITS; - var m=Math.floor(k/ROM.BASEBITS); - for (var i=0;i<ROM.NLEN-m-1;i++) - this.w[i]=(this.w[m+i]>>n)|((this.w[m+i+1]<<(ROM.BASEBITS-n))&ROM.MASK); - this.w[ROM.NLEN-m-1]=this.w[ROM.NLEN-1]>>n; - for (i=ROM.NLEN-m;i<ROM.NLEN;i++) this.w[i]=0; - return this; - }, -/* quick shift left by less than a word */ - fshl: function(k) - { - this.w[ROM.NLEN-1]=((this.w[ROM.NLEN-1]<<k))|(this.w[ROM.NLEN-2]>>(ROM.BASEBITS-k)); - for (var i=ROM.NLEN-2;i>0;i--) - this.w[i]=((this.w[i]<<k)&ROM.MASK)|(this.w[i-1]>>(ROM.BASEBITS-k)); - this.w[0]=(this.w[0]<<k)&ROM.MASK; - - return (this.w[ROM.NLEN-1]>>((8*ROM.MODBYTES)%ROM.BASEBITS)); /* return excess - only used in FF.java */ - }, -/* General shift left by k bits */ - shl: function(k) - { - var i,n=k%ROM.BASEBITS; - var m=Math.floor(k/ROM.BASEBITS); - - this.w[ROM.NLEN-1]=((this.w[ROM.NLEN-1-m]<<n))|(this.w[ROM.NLEN-m-2]>>(ROM.BASEBITS-n)); - for (i=ROM.NLEN-2;i>m;i--) - this.w[i]=((this.w[i-m]<<n)&ROM.MASK)|(this.w[i-m-1]>>(ROM.BASEBITS-n)); - this.w[m]=(this.w[0]<<n)&ROM.MASK; - for (i=0;i<m;i++) this.w[i]=0; - return this; - }, -/* return length in bits */ - nbits: function() - { - var bts,k=ROM.NLEN-1; - var c; - this.norm(); - while (k>=0 && this.w[k]===0) k--; - if (k<0) return 0; - bts=ROM.BASEBITS*k; - c=this.w[k]; - while (c!==0) {c=Math.floor(c/2); bts++;} - return bts; - }, -/* convert this to string */ - toString: function() - { - var b; - var s=""; - var len=this.nbits(); - if (len%4===0) len=Math.floor(len/4); - else {len=Math.floor(len/4); len++;} - if (len<ROM.MODBYTES*2) len=ROM.MODBYTES*2; - for (var i=len-1;i>=0;i--) - { - b=new BIG(0); - b.copy(this); - b.shr(i*4); - s+=(b.w[0]&15).toString(16); - } - return s; - }, -/* this+=y */ - add: function(y) - { - for (var i=0;i<ROM.NLEN;i++) this.w[i]+=y.w[i]; - return this; - }, -/* return this+x */ - plus: function(x) - { - var s=new BIG(0); - for (var i=0;i<ROM.NLEN;i++) - s.w[i]=this.w[i]+x.w[i]; - return s; - }, -/* this+=i, where i is int */ - inc: function(i) - { - this.norm(); - this.w[0]+=i; - return this; - }, -/* this-=y */ - sub: function(y) - { - for (var i=0;i<ROM.NLEN;i++) this.w[i]-=y.w[i]; - return this; - }, - -/* reverse subtract this=x-this */ - rsub: function(x) - { - for (var i=0;i<ROM.NLEN;i++) - this.w[i]=x.w[i]-this.w[i]; - return this; - }, -/* this-=i, where i is int */ - dec: function(i) - { - this.norm(); - this.w[0]-=i; - return this; - }, -/* return this-x */ - minus: function(x) { - var d=new BIG(0); - for (var i=0;i<ROM.NLEN;i++) - d.w[i]=this.w[i]-x.w[i]; - return d; - }, -/* multiply by small integer */ - imul: function(c) - { - for (var i=0;i<ROM.NLEN;i++) this.w[i]*=c; - return this; - }, -/* convert this BIG to byte array */ - tobytearray: function(b,n) - { - this.norm(); - var c=new BIG(0); - c.copy(this); - - for (var i=ROM.MODBYTES-1;i>=0;i--) - { - b[i+n]=c.w[0]&0xff; - c.fshr(8); - } - return this; - }, -/* convert this to byte array */ - toBytes: function(b) - { - this.tobytearray(b,0); - }, - -/* set this[i]+=x*y+c, and return high part */ - muladd: function(x,y,c,i) - { - var prod=x*y+c+this.w[i]; - this.w[i]=prod&ROM.MASK; - return ((prod-this.w[i])*ROM.MODINV); - }, -/* multiply by larger int */ - pmul: function(c) - { - var ak,carry=0; - this.norm(); - for (var i=0;i<ROM.NLEN;i++) - { - ak=this.w[i]; - this.w[i]=0; - carry=this.muladd(ak,c,carry,i); - } - return carry; - }, -/* multiply by still larger int - results requires a DBIG */ - pxmul: function(c) - { - var m=new DBIG(0); - var carry=0; - for (var j=0;j<ROM.NLEN;j++) - carry=m.muladd(this.w[j],c,carry,j); - m.w[ROM.NLEN]=carry; - return m; - }, -/* divide by 4 */ - div3: function() - { - var ak,base,carry=0; - this.norm(); - base=(1<<ROM.BASEBITS); - for (var i=ROM.NLEN-1;i>=0;i--) - { - ak=(carry*base+this.w[i]); - this.w[i]=Math.floor(ak/3); - carry=ak%3; - } - return carry; - }, - -/* set x = x mod 2^m */ - mod2m: function(m) - { - var i,wd,bt; - var msk; - wd=Math.floor(m/ROM.BASEBITS); - bt=m%ROM.BASEBITS; - msk=(1<<bt)-1; - this.w[wd]&=msk; - for (i=wd+1;i<ROM.NLEN;i++) this.w[i]=0; - }, - -/* a=1/a mod 2^256. This is very fast! */ - invmod2m: function() - { - var U=new BIG(0); - var b=new BIG(0); - var c=new BIG(0); - - U.inc(BIG.invmod256(this.lastbits(8))); - - for (var i=8;i<256;i<<=1) - { - b.copy(this); b.mod2m(i); - var t1=BIG.smul(U,b); t1.shr(i); - c.copy(this); c.shr(i); c.mod2m(i); - - var t2=BIG.smul(U,c); t2.mod2m(i); - t1.add(t2); - b=BIG.smul(t1,U); t1.copy(b); - t1.mod2m(i); - - t2.one(); t2.shl(i); t1.rsub(t2); t1.norm(); - t1.shl(i); - U.add(t1); - } - this.copy(U); - }, - -/* reduce this mod m */ - mod: function(m) - { - var k=0; - - this.norm(); - if (BIG.comp(this,m)<0) return; - do - { - m.fshl(1); - k++; - } while (BIG.comp(this,m)>=0); - - while (k>0) - { - m.fshr(1); - if (BIG.comp(this,m)>=0) - { - this.sub(m); - this.norm(); - } - k--; - } - }, -/* this/=m */ - div: function(m) - { - var k=0; - this.norm(); - var e=new BIG(1); - var b=new BIG(0); - b.copy(this); - this.zero(); - - while (BIG.comp(b,m)>=0) - { - e.fshl(1); - m.fshl(1); - k++; - } - - while (k>0) - { - m.fshr(1); - e.fshr(1); - if (BIG.comp(b,m)>=0) - { - this.add(e); - this.norm(); - b.sub(m); - b.norm(); - } - k--; - } - }, -/* return parity of this */ - parity: function() - { - return this.w[0]%2; - }, -/* return n-th bit of this */ - bit: function(n) - { - if ((this.w[Math.floor(n/ROM.BASEBITS)]&(1<<(n%ROM.BASEBITS)))>0) return 1; - else return 0; - }, -/* return last n bits of this */ - lastbits: function(n) - { - var msk=(1<<n)-1; - this.norm(); - return (this.w[0])&msk; - }, -/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */ - jacobi: function(p) - { - var n8,k,m=0; - var t=new BIG(0); - var x=new BIG(0); - var n=new BIG(0); - var zilch=new BIG(0); - var one=new BIG(1); - if (p.parity()===0 || BIG.comp(this,zilch)===0 || BIG.comp(p,one)<=0) return 0; - this.norm(); - x.copy(this); - n.copy(p); - x.mod(p); - - while (BIG.comp(n,one)>0) - { - if (BIG.comp(x,zilch)===0) return 0; - n8=n.lastbits(3); - k=0; - while (x.parity()===0) - { - k++; - x.shr(1); - } - if (k%2==1) m+=(n8*n8-1)/8; - m+=(n8-1)*(x.lastbits(2)-1)/4; - t.copy(n); - t.mod(x); - n.copy(x); - x.copy(t); - m%=2; - - } - if (m===0) return 1; - else return -1; - }, -/* this=1/this mod p. Binary method */ - invmodp: function(p) - { - this.mod(p); - var u=new BIG(0); - u.copy(this); - var v=new BIG(0); - v.copy(p); - var x1=new BIG(1); - var x2=new BIG(0); - var t=new BIG(0); - var one=new BIG(1); - - while (BIG.comp(u,one)!==0 && BIG.comp(v,one)!==0) - { - while (u.parity()===0) - { - u.shr(1); - if (x1.parity()!==0) - { - x1.add(p); - x1.norm(); - } - x1.shr(1); - } - while (v.parity()===0) - { - v.shr(1); - if (x2.parity()!==0) - { - x2.add(p); - x2.norm(); - } - x2.shr(1); - } - if (BIG.comp(u,v)>=0) - { - u.sub(v); - u.norm(); - if (BIG.comp(x1,x2)>=0) x1.sub(x2); - else - { - t.copy(p); - t.sub(x2); - x1.add(t); - } - x1.norm(); - } - else - { - v.sub(u); - v.norm(); - if (BIG.comp(x2,x1)>=0) x2.sub(x1); - else - { - t.copy(p); - t.sub(x1); - x2.add(t); - } - x2.norm(); - } - } - if (BIG.comp(u,one)===0) this.copy(x1); - else this.copy(x2); - }, -/* return this^e mod m */ - powmod:function(e,m) - { - var bt; - this.norm(); - e.norm(); - var a=new BIG(1); - var z=new BIG(0); - z.copy(e); - var s=new BIG(0); - s.copy(this); - var i=0; - while (true) - { - i++; - bt=z.parity(); - z.fshr(1); - if (bt==1) a=BIG.modmul(a,s,m); -//ROM.debug=false; - if (z.iszilch()) break; - s=BIG.modsqr(s,m); - } - return a; - } - -}; -/* convert from byte array to BIG */ -BIG.frombytearray=function(b,n) -{ - var m=new BIG(0); - - for (var i=0;i<ROM.MODBYTES;i++) - { - m.fshl(8); m.w[0]+=b[i+n]&0xff; - //m.inc(b[i]&0xff); - } - return m; -}; - -BIG.fromBytes=function(b) -{ - return BIG.frombytearray(b,0); -}; - -/* return a*b where product fits a BIG */ -BIG.smul=function(a,b) -{ - var carry; - var c=new BIG(0); - for (var i=0;i<ROM.NLEN;i++) - { - carry=0; - for (var j=0;j<ROM.NLEN;j++) - if (i+j<ROM.NLEN) carry=c.muladd(a.w[i],b.w[j],carry,i+j); - } - return c; -}; -/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ -BIG.comp=function(a,b) -{ - for (var i=ROM.NLEN-1;i>=0;i--) - { - if (a.w[i]==b.w[i]) continue; - if (a.w[i]>b.w[i]) return 1; - else return -1; - } - return 0; -}; - -/* get 8*MODBYTES size random number */ -BIG.random=function(rng) -{ - var m=new BIG(0); - var i,b,j=0,r=0; - -/* generate random BIG */ - for (i=0;i<8*ROM.MODBYTES;i++) - { - if (j===0) r=rng.getByte(); - else r>>=1; - - b=r&1; - m.shl(1); m.w[0]+=b;// m.inc(b); - j++; j&=7; - } - return m; -}; - -/* Create random BIG in portable way, one bit at a time */ -BIG.randomnum=function(q,rng) -{ - var d=new DBIG(0); - var i,b,j=0,r=0; - for (i=0;i<2*ROM.MODBITS;i++) - { - if (j===0) r=rng.getByte(); - else r>>=1; - - b=r&1; - d.shl(1); d.w[0]+=b; - j++; j&=7; - } - - var m=d.mod(q); - - return m; -}; - -/* return NAF value as +/- 1, 3 or 5. x and x3 should be normed. -nbs is number of bits processed, and nzs is number of trailing 0s detected */ -BIG.nafbits=function(x,x3,i) -{ - var n=[]; - var nb=x3.bit(i)-x.bit(i); - var j; - n[1]=1; - n[0]=0; - if (nb===0) {n[0]=0; return n;} - if (i===0) {n[0]=nb; return n;} - if (nb>0) n[0]=1; - else n[0]=(-1); - - for (j=i-1;j>0;j--) - { - n[1]++; - n[0]*=2; - nb=x3.bit(j)-x.bit(j); - if (nb>0) n[0]+=1; - if (nb<0) n[0]-=1; - if (n[0]>5 || n[0]<-5) break; - } - - if (n[0]%2!==0 && j!==0) - { /* backtrack */ - if (nb>0) n[0]=(n[0]-1)/2; - if (nb<0) n[0]=(n[0]+1)/2; - n[1]--; - } - while (n[0]%2===0) - { /* remove trailing zeros */ - n[0]/=2; - n[2]++; - n[1]--; - } - return n; -}; - -/* return a*b as DBIG */ -BIG.mul=function(a,b) -{ - var n,c=new DBIG(0); - a.norm(); - b.norm(); - - c.w[0]=a.w[0]*b.w[0]; - c.w[1]=a.w[1]*b.w[0]+a.w[0]*b.w[1]; - c.w[2]=a.w[2]*b.w[0]+a.w[1]*b.w[1]+a.w[0]*b.w[2]; - c.w[3]=a.w[3]*b.w[0]+a.w[2]*b.w[1]+a.w[1]*b.w[2]+a.w[0]*b.w[3]; - c.w[4]=a.w[4]*b.w[0]+a.w[3]*b.w[1]+a.w[2]*b.w[2]+a.w[1]*b.w[3]+a.w[0]*b.w[4]; - c.w[5]=a.w[5]*b.w[0]+a.w[4]*b.w[1]+a.w[3]*b.w[2]+a.w[2]*b.w[3]+a.w[1]*b.w[4]+a.w[0]*b.w[5]; - c.w[6]=a.w[6]*b.w[0]+a.w[5]*b.w[1]+a.w[4]*b.w[2]+a.w[3]*b.w[3]+a.w[2]*b.w[4]+a.w[1]*b.w[5]+a.w[0]*b.w[6]; - c.w[7]=a.w[7]*b.w[0]+a.w[6]*b.w[1]+a.w[5]*b.w[2]+a.w[4]*b.w[3]+a.w[3]*b.w[4]+a.w[2]*b.w[5]+a.w[1]*b.w[6]+a.w[0]*b.w[7]; - c.w[8]=a.w[8]*b.w[0]+a.w[7]*b.w[1]+a.w[6]*b.w[2]+a.w[5]*b.w[3]+a.w[4]*b.w[4]+a.w[3]*b.w[5]+a.w[2]*b.w[6]+a.w[1]*b.w[7]+a.w[0]*b.w[8]; - c.w[9]=a.w[9]*b.w[0]+a.w[8]*b.w[1]+a.w[7]*b.w[2]+a.w[6]*b.w[3]+a.w[5]*b.w[4]+a.w[4]*b.w[5]+a.w[3]*b.w[6]+a.w[2]*b.w[7]+a.w[1]*b.w[8]+a.w[0]*b.w[9]; - c.w[10]=a.w[10]*b.w[0]+a.w[9]*b.w[1]+a.w[8]*b.w[2]+a.w[7]*b.w[3]+a.w[6]*b.w[4]+a.w[5]*b.w[5]+a.w[4]*b.w[6]+a.w[3]*b.w[7]+a.w[2]*b.w[8]+a.w[1]*b.w[9]+a.w[0]*b.w[10]; - - c.w[11]=a.w[10]*b.w[1]+a.w[9]*b.w[2]+a.w[8]*b.w[3]+a.w[7]*b.w[4]+a.w[6]*b.w[5]+a.w[5]*b.w[6]+a.w[4]*b.w[7]+a.w[3]*b.w[8]+a.w[2]*b.w[9]+a.w[1]*b.w[10]; - c.w[12]= a.w[10]*b.w[2]+a.w[9]*b.w[3]+a.w[8]*b.w[4]+a.w[7]*b.w[5]+a.w[6]*b.w[6]+a.w[5]*b.w[7]+a.w[4]*b.w[8]+a.w[3]*b.w[9]+a.w[2]*b.w[10]; - c.w[13]= a.w[10]*b.w[3]+a.w[9]*b.w[4]+a.w[8]*b.w[5]+a.w[7]*b.w[6]+a.w[6]*b.w[7]+a.w[5]*b.w[8]+a.w[4]*b.w[9]+a.w[3]*b.w[10]; - c.w[14]= a.w[10]*b.w[4]+a.w[9]*b.w[5]+a.w[8]*b.w[6]+a.w[7]*b.w[7]+a.w[6]*b.w[8]+a.w[5]*b.w[9]+a.w[4]*b.w[10]; - c.w[15]= a.w[10]*b.w[5]+a.w[9]*b.w[6]+a.w[8]*b.w[7]+a.w[7]*b.w[8]+a.w[6]*b.w[9]+a.w[5]*b.w[10]; - c.w[16]= a.w[10]*b.w[6]+a.w[9]*b.w[7]+a.w[8]*b.w[8]+a.w[7]*b.w[9]+a.w[6]*b.w[10]; - c.w[17]= a.w[10]*b.w[7]+a.w[9]*b.w[8]+a.w[8]*b.w[9]+a.w[7]*b.w[10]; - c.w[18]= a.w[10]*b.w[8]+a.w[9]*b.w[9]+a.w[8]*b.w[10]; - c.w[19]= a.w[10]*b.w[9]+a.w[9]*b.w[10]; - c.w[20]= a.w[10]*b.w[10]; -// for (var j=9;j<ROM.NLEN;j++) -// { -// t=0; for (var i=0;i<=j;i++) t+=a.w[j-i]*b.w[i]; -// c.w[j]=t; -// } -// for (var j=ROM.NLEN;j<ROM.DNLEN-2;j++) -// { -// t=0; for (var i=j-ROM.NLEN+1;i<ROM.NLEN;i++) t+=a.w[j-i]*b.w[i]; -// c.w[j]=t; -// } -// t=a.w[ROM.NLEN-1]*b.w[ROM.NLEN-1]; -// c.w[ROM.DNLEN-2]=t; - var co=0; - for (var i=0;i<ROM.DNLEN-1;i++) - { - n=c.w[i]+co; - c.w[i]=n&ROM.MASK; - co=(n-c.w[i])*ROM.MODINV; - } - c.w[ROM.DNLEN-1]=co; - - return c; -}; - -/* return a^2 as DBIG */ -BIG.sqr=function(a) -{ - var n,c=new DBIG(0); - a.norm(); - - c.w[0]=a.w[0]*a.w[0]; - c.w[1]=2*(a.w[1]*a.w[0]); - c.w[2]=2*(a.w[2]*a.w[0])+a.w[1]*a.w[1]; - c.w[3]=2*(a.w[3]*a.w[0]+a.w[2]*a.w[1]); - c.w[4]=2*(a.w[4]*a.w[0]+a.w[3]*a.w[1])+a.w[2]*a.w[2]; - c.w[5]=2*(a.w[5]*a.w[0]+a.w[4]*a.w[1]+a.w[3]*a.w[2]); - c.w[6]=2*(a.w[6]*a.w[0]+a.w[5]*a.w[1]+a.w[4]*a.w[2])+a.w[3]*a.w[3]; - c.w[7]=2*(a.w[7]*a.w[0]+a.w[6]*a.w[1]+a.w[5]*a.w[2]+a.w[4]*a.w[3]); - c.w[8]=2*(a.w[8]*a.w[0]+a.w[7]*a.w[1]+a.w[6]*a.w[2]+a.w[5]*a.w[3])+a.w[4]*a.w[4]; - c.w[9]=2*(a.w[9]*a.w[0]+a.w[8]*a.w[1]+a.w[7]*a.w[2]+a.w[6]*a.w[3]+a.w[5]*a.w[4]); - c.w[10]=2*(a.w[10]*a.w[0]+a.w[9]*a.w[1]+a.w[8]*a.w[2]+a.w[7]*a.w[3]+a.w[6]*a.w[4])+a.w[5]*a.w[5]; - - c.w[11]=2*(a.w[10]*a.w[1]+a.w[9]*a.w[2]+a.w[8]*a.w[3]+a.w[7]*a.w[4]+a.w[6]*a.w[5]); - c.w[12]=2*(a.w[10]*a.w[2]+a.w[9]*a.w[3]+a.w[8]*a.w[4]+a.w[7]*a.w[5])+a.w[6]*a.w[6]; - c.w[13]=2*(a.w[10]*a.w[3]+a.w[9]*a.w[4]+a.w[8]*a.w[5]+a.w[7]*a.w[6]); - c.w[14]=2*(a.w[10]*a.w[4]+a.w[9]*a.w[5]+a.w[8]*a.w[6])+a.w[7]*a.w[7]; - c.w[15]=2*(a.w[10]*a.w[5]+a.w[9]*a.w[6]+a.w[8]*a.w[7]); - c.w[16]=2*(a.w[10]*a.w[6]+a.w[9]*a.w[7])+a.w[8]*a.w[8]; - c.w[17]=2*(a.w[10]*a.w[7]+a.w[9]*a.w[8]); - c.w[18]=2*(a.w[10]*a.w[8])+a.w[9]*a.w[9]; - c.w[19]=2*(a.w[10]*a.w[9]); - c.w[20]= a.w[10]*a.w[10]; -/* - c.w[0]=a.w[0]*a.w[0]; - t=a.w[1]*a.w[0]; t+=t; c.w[1]=t; - for (j=2;j<ROM.NLEN-1;j+=2) - { - t=a.w[j]*a.w[0]; for (var i=1;i<(j+1)>>1;i++) t+=a.w[j-i]*a.w[i]; t+=t; t+=a.w[j>>1]*a.w[j>>1]; - c.w[j]=t; - t=a.w[j+1]*a.w[0]; for (var i=1;i<(j+2)>>1;i++) t+=a.w[j+1-i]*a.w[i]; t+=t; - c.w[j+1]=t; - } - j=ROM.NLEN-1; - t=a.w[j]*a.w[0]; for (var i=1;i<(j+1)>>1;i++) t+=a.w[j-i]*a.w[i]; t+=t; t+=a.w[j>>1]*a.w[j>>1]; - c.w[j]=t; - - j=ROM.NLEN; - t=a.w[ROM.NLEN-1]*a.w[j-ROM.NLEN+1]; for (var i=j-ROM.NLEN+2;i<(j+1)>>1;i++) t+=a.w[j-i]*a.w[i]; t+=t; - c.w[j]=t; - for (j=ROM.NLEN+1;j<ROM.DNLEN-2;j+=2) - { - t=a.w[ROM.NLEN-1]*a.w[j-ROM.NLEN+1]; for (var i=j-ROM.NLEN+2;i<(j+1)>>1;i++) t+=a.w[j-i]*a.w[i]; t+=t; t+=a.w[j>>1]*a.w[j>>1]; - c.w[j]=t; - t=a.w[ROM.NLEN-1]*a.w[j-ROM.NLEN+2]; for (var i=j-ROM.NLEN+3;i<(j+2)>>1;i++) t+=a.w[j+1-i]*a.w[i]; t+=t; - c.w[j+1]=t; - } - - t=a.w[ROM.NLEN-1]*a.w[ROM.NLEN-1]; - c.w[ROM.DNLEN-2]=t; -*/ - var co=0; - for (var i=0;i<ROM.DNLEN-1;i++) - { - n=c.w[i]+co; - c.w[i]=n&ROM.MASK; - co=(n-c.w[i])*ROM.MODINV; - } - c.w[ROM.DNLEN-1]=co; - - return c; -}; - -/* reduce a DBIG to a BIG using a "special" modulus */ -BIG.mod=function(d) -{ - var i,j,b=new BIG(0); - if (ROM.MODTYPE==ROM.PSEUDO_MERSENNE) - { - var v,tw; - var t=d.split(ROM.MODBITS); - b.hcopy(d); - - v=t.pmul(ROM.MConst); - tw=t.w[ROM.NLEN-1]; - t.w[ROM.NLEN-1]&=ROM.TMASK; - t.inc(ROM.MConst*((tw>>ROM.TBITS)+(v<<(ROM.BASEBITS-ROM.TBITS)))); - b.add(t); - } - - if (ROM.MODTYPE==ROM.MONTGOMERY_FRIENDLY) - { - for (i=0;i<ROM.NLEN;i++) - d.w[ROM.NLEN+i]+=d.muladd(d.w[i],ROM.MConst-1,d.w[i],ROM.NLEN+i-1); - for (i=0;i<ROM.NLEN;i++) - b.w[i]=d.w[ROM.NLEN+i]; - } - - if (ROM.MODTYPE==ROM.NOT_SPECIAL) - { - var md=new BIG(0); - md.rcopy(ROM.Modulus); - var sum; - - sum=d.w[0]; - for (j=0;j<ROM.NLEN;j++) - { - for (i=0;i<j;i++) sum+=d.w[i]*md.w[j-i]; - d.w[j]=((sum&ROM.MASK)*ROM.MConst)&ROM.MASK; sum+=d.w[j]*md.w[0]; - sum=d.w[j+1]+(sum*ROM.MODINV); - } - for (j=ROM.NLEN;j<ROM.DNLEN-2;j++) - { - for (i=j-ROM.NLEN+1;i<ROM.NLEN;i++) sum+=d.w[i]*md.w[j-i]; - d.w[j]=sum&ROM.MASK; - sum=d.w[j+1]+((sum-d.w[j])*ROM.MODINV); - } - - sum+=d.w[ROM.NLEN-1]*md.w[ROM.NLEN-1]; - d.w[ROM.DNLEN-2]=sum&ROM.MASK; - sum=d.w[ROM.DNLEN-1]+((sum-d.w[ROM.DNLEN-2])*ROM.MODINV); - d.w[ROM.DNLEN-1]=sum&ROM.MASK; - - for (i=0;i<ROM.NLEN;i++) - b.w[i]=d.w[ROM.NLEN+i]; - } - b.norm(); - return b; -}; - -/* return a*b mod m */ -BIG.modmul=function(a,b,m) -{ - a.mod(m); - b.mod(m); - var d=BIG.mul(a,b); - return d.mod(m); -}; - -/* return a^2 mod m */ -BIG.modsqr=function(a,m) -{ - a.mod(m); - var d=BIG.sqr(a); - return d.mod(m); -}; - -/* return -a mod m */ -BIG.modneg=function(a,m) -{ - a.mod(m); - return m.minus(a); -}; - -/* calculate Field Excess */ -BIG.EXCESS=function(a) -{ - return ((a.w[ROM.NLEN-1]&ROM.OMASK)>>(ROM.MODBITS%ROM.BASEBITS)); -}; - -/* Arazi and Qi inversion mod 256 */ -BIG.invmod256=function(a) -{ - var U,t1,t2,b,c; - t1=0; - c=(a>>1)&1; - t1+=c; - t1&=1; - t1=2-t1; - t1<<=1; - U=t1+1; - -// i=2 - b=a&3; - t1=U*b; t1>>=2; - c=(a>>2)&3; - t2=(U*c)&3; - t1+=t2; - t1*=U; t1&=3; - t1=4-t1; - t1<<=2; - U+=t1; - -// i=4 - b=a&15; - t1=U*b; t1>>=4; - c=(a>>4)&15; - t2=(U*c)&15; - t1+=t2; - t1*=U; t1&=15; - t1=16-t1; - t1<<=4; - U+=t1; - - return U; -}; - http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/js/DBIG.js ---------------------------------------------------------------------- diff --git a/js/DBIG.js b/js/DBIG.js deleted file mode 100755 index 7523743..0000000 --- a/js/DBIG.js +++ /dev/null @@ -1,248 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* AMCL double length DBIG number class */ - -/* constructor */ -var DBIG = function(x) { - this.w=[]; - this.zero(); - this.w[0]=x; -}; - -DBIG.prototype={ - -/* set this=0 */ - zero: function() - { - for (var i=0;i<ROM.DNLEN;i++) this.w[i]=0; - return this; - }, - -/* set this=b */ - copy: function(b) - { - for (var i=0;i<ROM.DNLEN;i++) this.w[i]=b.w[i]; - return this; - }, - - -/* copy from BIG */ - hcopy: function(b) - { - var i; - for (i=0;i<ROM.NLEN;i++) this.w[i]=b.w[i]; - for (i=ROM.NLEN;i<ROM.DNLEN;i++) this.w[i]=0; - return this; - }, - -/* normalise this */ - norm: function() - { - var d,carry=0; - for (var i=0;i<ROM.DNLEN-1;i++) - { - d=this.w[i]+carry; - this.w[i]=d&ROM.MASK; - carry=d>>ROM.BASEBITS; - } - this.w[ROM.DNLEN-1]=(this.w[ROM.DNLEN-1]+carry); - return this; - }, - -/* set this[i]+=x*y+c, and return high part */ - muladd: function(x,y,c,i) - { - var prod=x*y+c+this.w[i]; - this.w[i]=prod&ROM.MASK; - return ((prod-this.w[i])*ROM.MODINV); - }, - -/* shift this right by k bits */ - shr: function(k) - { - var i,n=k%ROM.BASEBITS; - var m=Math.floor(k/ROM.BASEBITS); - for (i=0;i<ROM.DNLEN-m-1;i++) - this.w[i]=(this.w[m+i]>>n)|((this.w[m+i+1]<<(ROM.BASEBITS-n))&ROM.MASK); - this.w[ROM.DNLEN-m-1]=this.w[ROM.DNLEN-1]>>n; - for (i=ROM.DNLEN-m;i<ROM.DNLEN;i++) this.w[i]=0; - return this; - }, - -/* shift this left by k bits */ - shl: function(k) - { - var i,n=k%ROM.BASEBITS; - var m=Math.floor(k/ROM.BASEBITS); - - this.w[ROM.DNLEN-1]=((this.w[ROM.DNLEN-1-m]<<n))|(this.w[ROM.DNLEN-m-2]>>(ROM.BASEBITS-n)); - for (i=ROM.DNLEN-2;i>m;i--) - this.w[i]=((this.w[i-m]<<n)&ROM.MASK)|(this.w[i-m-1]>>(ROM.BASEBITS-n)); - this.w[m]=(this.w[0]<<n)&ROM.MASK; - for (i=0;i<m;i++) this.w[i]=0; - return this; - }, - -/* this+=x */ - add: function(x) - { - for (var i=0;i<ROM.DNLEN;i++) - this.w[i]+=x.w[i]; - }, - -/* this-=x */ - sub: function(x) - { - for (var i=0;i<ROM.DNLEN;i++) - this.w[i]-=x.w[i]; - }, - -/* return number of bits in this */ - nbits: function() - { - var bts,k=ROM.DNLEN-1; - var c; - this.norm(); - while (k>=0 && this.w[k]===0) k--; - if (k<0) return 0; - bts=ROM.BASEBITS*k; - c=this.w[k]; - while (c!==0) {c=Math.floor(c/2); bts++;} - return bts; - }, - -/* convert this to string */ - toString: function() - { - - var b; - var s=""; - var len=this.nbits(); - if (len%4===0) len=Math.floor(len/4); - else {len=Math.floor(len/4); len++;} - - for (var i=len-1;i>=0;i--) - { - b=new DBIG(0); - b.copy(this); - b.shr(i*4); - s+=(b.w[0]&15).toString(16); - } - return s; - }, - -/* reduces this DBIG mod a BIG, and returns the BIG */ - mod: function(c) - { - var k=0; - this.norm(); - var m=new DBIG(0); - m.hcopy(c); - var r=new BIG(0); - r.hcopy(this); - - if (DBIG.comp(this,m)<0) return r; - - do - { - m.shl(1); - k++; - } - while (DBIG.comp(this,m)>=0); - - while (k>0) - { - m.shr(1); - if (DBIG.comp(this,m)>=0) - { - this.sub(m); - this.norm(); - } - k--; - } - - r.hcopy(this); - return r; - }, - -/* this/=c */ - div: function(c) - { - var k=0; - var m=new DBIG(0); m.hcopy(c); - var a=new BIG(0); - var e=new BIG(1); - this.norm(); - - while (DBIG.comp(this,m)>=0) - { - e.fshl(1); - m.shl(1); - k++; - } - - while (k>0) - { - m.shr(1); - e.shr(1); - if (DBIG.comp(this,m)>0) - { - a.add(e); - a.norm(); - this.sub(m); - this.norm(); - } - k--; - } - return a; - }, - -/* split this DBIG at position n, return higher half, keep lower half */ - split: function(n) - { - var t=new BIG(0); - var nw,m=n%ROM.BASEBITS; - var carry=this.w[ROM.DNLEN-1]<<(ROM.BASEBITS-m); - - - for (var i=ROM.DNLEN-2;i>=ROM.NLEN-1;i--) - { - nw=(this.w[i]>>m)|carry; - carry=(this.w[i]<<(ROM.BASEBITS-m))&ROM.MASK; - t.w[i-ROM.NLEN+1]=nw; - } - this.w[ROM.NLEN-1]&=((1<<m)-1); - - return t; - } - -}; - -/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ -DBIG.comp=function(a,b) -{ - for (var i=ROM.DNLEN-1;i>=0;i--) - { - if (a.w[i]==b.w[i]) continue; - if (a.w[i]>b.w[i]) return 1; - else return -1; - } - return 0; -}; http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/js/ECDH.js ---------------------------------------------------------------------- diff --git a/js/ECDH.js b/js/ECDH.js deleted file mode 100755 index 35b1479..0000000 --- a/js/ECDH.js +++ /dev/null @@ -1,537 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -var ECDH = { - - INVALID_PUBLIC_KEY:-2, - ERROR:-3, - INVALID:-4, - EFS:ROM.MODBYTES, - EGS:ROM.MODBYTES, - EAS:16, - EBS:16, - - /* Convert Integer to n-byte array */ - inttobytes: function(n,len) - { - var i; - var b=[]; - - for (i=0;i<len;i++) b[i]=0; - i=len; - while (n>0 && i>0) - { - i--; - b[i]=(n&0xff); - n=Math.floor(n/256); - } - return b; - }, - - bytestostring: function(b) - { - var s=""; - var len=b.length; - var ch; - - for (var i=0;i<len;i++) - { - ch=b[i]; - s+=((ch>>>4)&15).toString(16); - s+=(ch&15).toString(16); - - } - return s; - }, - - stringtobytes: function(s) - { - var b=[]; - for (var i=0;i<s.length;i++) - b.push(s.charCodeAt(i)); - return b; - }, - - - KDF1: function(Z,olen) - { -/* NOTE: the parameter olen is the length of the output K in bytes */ - var H=new HASH(); - var i,hlen=32; - var K=[]; - - var B=[]; - var counter,cthreshold,k=0; - - for (i=0;i<K.length;i++) K[i]=0; // redundant? - - cthreshold=Math.floor(olen/hlen); if (olen%hlen!==0) cthreshold++; - - for (counter=0;counter<cthreshold;counter++) - { - H.process_array(Z); if (counter>0) H.process_num(counter); - B=H.hash(); - if (k+hlen>olen) for (i=0;i<olen%hlen;i++) K[k++]=B[i]; - else for (i=0;i<hlen;i++) K[k++]=B[i]; - } - return K; - }, - - KDF2: function(Z,P,olen) - { -/* NOTE: the parameter olen is the length of the output k in bytes */ - var H=new HASH(); - var i,hlen=32; - var K=[]; - - var B=[]; - var counter,cthreshold,k=0; - - for (i=0;i<K.length;i++) K[i]=0; // redundant? - - cthreshold=Math.floor(olen/hlen); if (olen%hlen!==0) cthreshold++; - - for (counter=1;counter<=cthreshold;counter++) - { - H.process_array(Z); H.process_num(counter); H.process_array(P); - B=H.hash(); - if (k+hlen>olen) for (i=0;i<olen%hlen;i++) K[k++]=B[i]; - else for (i=0;i<hlen;i++) K[k++]=B[i]; - } - return K; - }, - -/* Password based Key Derivation Function */ -/* Input password p, salt s, and repeat count */ -/* Output key of length olen */ - - PBKDF2: function(Pass,Salt,rep,olen) - { - var i,j,k,d,opt; - d=Math.floor(olen/32); if (olen%32!==0) d++; - var F=new Array(this.EFS); - var U=[]; - var S=[]; - - var K=[]; - opt=0; - - for (i=1;i<=d;i++) - { - for (j=0;j<Salt.length;j++) S[j]=Salt[j]; - var N=this.inttobytes(i,4); - for (j=0;j<4;j++) S[Salt.length+j]=N[j]; - this.HMAC(S,Pass,F); - for (j=0;j<this.EFS;j++) U[j]=F[j]; - for (j=2;j<=rep;j++) - { - this.HMAC(U,Pass,U); - for (k=0;k<this.EFS;k++) F[k]^=U[k]; - } - for (j=0;j<this.EFS;j++) K[opt++]=F[j]; - } - var key=[]; - for (i=0;i<olen;i++) key[i]=K[i]; - return key; - }, - - HMAC: function(M,K,tag) - { - /* Input is from an octet m * - * olen is requested output length in bytes. k is the key * - * The output is the calculated tag */ - var i,b; - var B=[]; - var K0=new Array(64); - var olen=tag.length; - - b=K0.length; - if (olen<4 || olen>32) return 0; - - for (i=0;i<b;i++) K0[i]=0; - - var H=new HASH(); - - if (K.length > b) - { - H.process_array(K); B=H.hash(); - for (i=0;i<32;i++) K0[i]=B[i]; - } - else - for (i=0;i<K.length;i++) K0[i]=K[i]; - - for (i=0;i<b;i++) K0[i]^=0x36; - H.process_array(K0); H.process_array(M); B=H.hash(); - - for (i=0;i<b;i++) K0[i]^=0x6a; - H.process_array(K0); H.process_array(B); B=H.hash(); - - for (i=0;i<olen;i++) tag[i]=B[i]; - - return 1; - }, - -/* AES encryption/decryption */ - - AES_CBC_IV0_ENCRYPT: function(K,M) - { /* AES CBC encryption, with Null IV and key K */ - /* Input is from an octet string M, output is to an octet string C */ - /* Input is padded as necessary to make up a full final block */ - var a=new AES(); - var fin; - var i,j,ipt,opt; - var buff=[]; - /*var clen=16+(Math.floor(M.length/16))*16;*/ - - var C=[]; - var padlen; - - a.init(ROM.CBC,K,null); - - ipt=opt=0; - fin=false; - for(;;) - { - for (i=0;i<16;i++) - { - if (ipt<M.length) buff[i]=M[ipt++]; - else {fin=true; break;} - } - if (fin) break; - a.encrypt(buff); - for (i=0;i<16;i++) - C[opt++]=buff[i]; - } - -/* last block, filled up to i-th index */ - - padlen=16-i; - for (j=i;j<16;j++) buff[j]=padlen; - a.encrypt(buff); - for (i=0;i<16;i++) - C[opt++]=buff[i]; - a.end(); - return C; - }, - - AES_CBC_IV0_DECRYPT: function(K,C) - { /* padding is removed */ - var a=new AES(); - var i,ipt,opt,ch; - var buff=[]; - var MM=[]; - var fin,bad; - var padlen; - ipt=opt=0; - - a.init(ROM.CBC,K,null); - - if (C.length===0) return []; - ch=C[ipt++]; - - fin=false; - - for(;;) - { - for (i=0;i<16;i++) - { - buff[i]=ch; - if (ipt>=C.length) {fin=true; break;} - else ch=C[ipt++]; - } - a.decrypt(buff); - if (fin) break; - for (i=0;i<16;i++) - MM[opt++]=buff[i]; - } - - a.end(); - bad=false; - padlen=buff[15]; - if (i!=15 || padlen<1 || padlen>16) bad=true; - if (padlen>=2 && padlen<=16) - for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true; - - if (!bad) for (i=0;i<16-padlen;i++) - MM[opt++]=buff[i]; - - var M=[]; - if (bad) return M; - - for (i=0;i<opt;i++) M[i]=MM[i]; - return M; - }, - - KEY_PAIR_GENERATE: function(RNG,S,W) - { - var r,gx,gy,s; - var G,WP; - var res=0; - var T=[]; - G=new ECP(0); - - gx=new BIG(0); gx.rcopy(ROM.CURVE_Gx); - - if (ROM.CURVETYPE!=ROM.MOMTGOMERY) - { - gy=new BIG(0); gy.rcopy(ROM.CURVE_Gy); - G.setxy(gx,gy); - } - else G.setx(gx); - - r=new BIG(0); r.rcopy(ROM.CURVE_Order); - - if (RNG===null) - { - s=BIG.fromBytes(S); - } - else - { - s=BIG.randomnum(r,RNG); - - s.toBytes(T); - for (var i=0;i<this.EGS;i++) S[i]=T[i]; - } - - WP=G.mul(s); - WP.toBytes(W); - - return res; - }, - - PUBLIC_KEY_VALIDATE: function(full,W) - { - var r; - var WP=ECP.fromBytes(W); - var res=0; - - r=new BIG(0); r.rcopy(ROM.CURVE_Order); - - if (WP.is_infinity()) res=this.INVALID_PUBLIC_KEY; - - if (res===0 && full) - { - WP=WP.mul(r); - if (!WP.is_infinity()) res=this.INVALID_PUBLIC_KEY; - } - return res; - }, - - ECPSVDP_DH: function(S,WD,Z) - { - var r,s; - var W; - var res=0; - var T=[]; - - s=BIG.fromBytes(S); - - W=ECP.fromBytes(WD); - if (W.is_infinity()) res=this.ERROR; - - if (res===0) - { - r=new BIG(0); r.rcopy(ROM.CURVE_Order); - s.mod(r); - W=W.mul(s); - if (W.is_infinity()) res=this.ERROR; - else - { - W.getX().toBytes(T); - for (var i=0;i<this.EFS;i++) Z[i]=T[i]; - } - } - return res; - }, - - ECPSP_DSA: function(RNG,S,F,C,D) - { - var T=[]; - var i,gx,gy,r,s,f,c,d,u,vx; - var G,V; - - var H=new HASH(); - H.process_array(F); - var B=H.hash(); - - gx=new BIG(0); gx.rcopy(ROM.CURVE_Gx); - gy=new BIG(0); gy.rcopy(ROM.CURVE_Gy); - - G=new ECP(0); - G.setxy(gx,gy); - r=new BIG(0); r.rcopy(ROM.CURVE_Order); - - s=BIG.fromBytes(S); - f=BIG.fromBytes(B); - - c=new BIG(0); - d=new BIG(0); - V=new ECP(); - - do { - u=BIG.randomnum(r,RNG); - - V.copy(G); - V=V.mul(u); - vx=V.getX(); - c.copy(vx); - c.mod(r); - if (c.iszilch()) continue; - u.invmodp(r); - d=BIG.modmul(s,c,r); - d.add(f); - d=BIG.modmul(u,d,r); - } while (d.iszilch()); - - c.toBytes(T); - for (i=0;i<this.EFS;i++) C[i]=T[i]; - d.toBytes(T); - for (i=0;i<this.EFS;i++) D[i]=T[i]; - return 0; - }, - - ECPVP_DSA: function(W,F,C,D) - { - var B=[]; - var r,gx,gy,f,c,d,h2; - var res=0; - var G,WP,P; - - var H=new HASH(); - H.process_array(F); - B=H.hash(); - - gx=new BIG(0); gx.rcopy(ROM.CURVE_Gx); - gy=new BIG(0); gy.rcopy(ROM.CURVE_Gy); - - G=new ECP(0); - G.setxy(gx,gy); - r=new BIG(0); r.rcopy(ROM.CURVE_Order); - - c=BIG.fromBytes(C); - d=BIG.fromBytes(D); - f=BIG.fromBytes(B); - - if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) - res=this.INVALID; - - if (res===0) - { - d.invmodp(r); - f=BIG.modmul(f,d,r); - h2=BIG.modmul(c,d,r); - - WP=ECP.fromBytes(W); - if (WP.is_infinity()) res=this.ERROR; - else - { - P=new ECP(); - P.copy(WP); - P=P.mul2(h2,G,f); - if (P.is_infinity()) res=this.INVALID; - else - { - d=P.getX(); - d.mod(r); - if (BIG.comp(d,c)!==0) res=this.INVALID; - } - } - } - - return res; - }, - - ECIES_ENCRYPT: function(P1,P2,RNG,W,M,V,T) - { - var i; - - var Z=[]; - var VZ=[]; - var K1=[]; - var K2=[]; - var U=[]; - var C=[]; - - if (this.KEY_PAIR_GENERATE(RNG,U,V)!==0) return C; - if (this.ECPSVDP_DH(U,W,Z)!==0) return C; - - for (i=0;i<2*this.EFS+1;i++) VZ[i]=V[i]; - for (i=0;i<this.EFS;i++) VZ[2*this.EFS+1+i]=Z[i]; - - - var K=this.KDF2(VZ,P1,EFS); - - for (i=0;i<this.EAS;i++) {K1[i]=K[i]; K2[i]=K[this.EAS+i];} - - C=this.AES_CBC_IV0_ENCRYPT(K1,M); - - var L2=this.inttobytes(P2.length,8); - - var AC=[]; - for (i=0;i<C.length;i++) AC[i]=C[i]; - for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i]; - for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i]; - - this.HMAC(AC,K2,T); - - return C; - }, - - ECIES_DECRYPT: function(P1,P2,V,C,T,U) - { - - var i; - - var Z=[]; - var VZ=[]; - var K1=[]; - var K2=[]; - var TAG=new Array(T.length); - var M=[]; - - if (this.ECPSVDP_DH(U,V,Z)!==0) return M; - - for (i=0;i<2*this.EFS+1;i++) VZ[i]=V[i]; - for (i=0;i<this.EFS;i++) VZ[2*this.EFS+1+i]=Z[i]; - - var K=this.KDF2(VZ,P1,this.EFS); - - for (i=0;i<this.EAS;i++) {K1[i]=K[i]; K2[i]=K[this.EAS+i];} - - M=this.AES_CBC_IV0_DECRYPT(K1,C); - - if (M.length===0) return M; - - var L2=this.inttobytes(P2.length,8); - - var AC=[]; - - for (i=0;i<C.length;i++) AC[i]=C[i]; - for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i]; - for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i]; - - this.HMAC(AC,K2,TAG); - - var same=true; - for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false; - if (!same) return []; - - return M; - } -}; http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/js/ECP.js ---------------------------------------------------------------------- diff --git a/js/ECP.js b/js/ECP.js deleted file mode 100755 index e9625a5..0000000 --- a/js/ECP.js +++ /dev/null @@ -1,898 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* Elliptic Curve Point class */ - -/* Constructor */ -var ECP = function() -{ - this.x=new FP(0); - this.y=new FP(1); - this.z=new FP(1); - this.INF=true; -}; - -ECP.prototype={ -/* test this=O point-at-infinity */ - is_infinity: function() - { - if (ROM.CURVETYPE==ROM.EDWARDS) - { - this.x.reduce(); this.y.reduce(); this.z.reduce(); - return (this.x.iszilch() && this.y.equals(this.z)); - } - else return this.INF; - }, - - -/* conditional swap of this and Q dependant on d */ - cswap: function(Q,d) - { - this.x.cswap(Q.x,d); - if (ROM.CURVETYPE!=ROM.MONTGOMERY) this.y.cswap(Q.y,d); - this.z.cswap(Q.z,d); - if (ROM.CURVETYPE!=ROM.EDWARDS) - { - var bd=(d!==0)?true:false; - bd=bd&(this.INF^Q.INF); - this.INF^=bd; - Q.INF^=bd; - } - }, - -/* conditional move of Q to P dependant on d */ - cmove: function(Q,d) - { - this.x.cmove(Q.x,d); - if (ROM.CURVETYPE!=ROM.MONTGOMERY) this.y.cmove(Q.y,d); - this.z.cmove(Q.z,d); - if (ROM.CURVETYPE!=ROM.EDWARDS) - { - var bd=(d!==0)?true:false; - this.INF^=(this.INF^Q.INF)&bd; - } - }, - -/* Constant time select from pre-computed table */ - select: function(W,b) - { - var MP=new ECP(); - var m=b>>31; - var babs=(b^m)-m; - - babs=(babs-1)/2; - - this.cmove(W[0],ECP.teq(babs,0)); // conditional move - this.cmove(W[1],ECP.teq(babs,1)); - this.cmove(W[2],ECP.teq(babs,2)); - this.cmove(W[3],ECP.teq(babs,3)); - this.cmove(W[4],ECP.teq(babs,4)); - this.cmove(W[5],ECP.teq(babs,5)); - this.cmove(W[6],ECP.teq(babs,6)); - this.cmove(W[7],ECP.teq(babs,7)); - - MP.copy(this); - MP.neg(); - this.cmove(MP,(m&1)); - }, - -/* Test P == Q */ - - equals: function(Q) - { - if (this.is_infinity() && Q.is_infinity()) return true; - if (this.is_infinity() || Q.is_infinity()) return false; - if (ROM.CURVETYPE==ROM.WEIERSTRASS) - { - var zs2=new FP(0); zs2.copy(this.z); zs2.sqr(); - var zo2=new FP(0); zo2.copy(Q.z); zo2.sqr(); - var zs3=new FP(0); zs3.copy(zs2); zs3.mul(this.z); - var zo3=new FP(0); zo3.copy(zo2); zo3.mul(Q.z); - zs2.mul(Q.x); - zo2.mul(this.x); - if (!zs2.equals(zo2)) return false; - zs3.mul(Q.y); - zo3.mul(this.y); - if (!zs3.equals(zo3)) return false; - } - else - { - var a=new FP(0); - var b=new FP(0); - a.copy(this.x); a.mul(Q.z); a.reduce(); - b.copy(Q.x); b.mul(this.z); b.reduce(); - if (!a.equals(b)) return false; - if (ROM.CURVETYPE==ROM.EDWARDS) - { - a.copy(this.y); a.mul(Q.z); a.reduce(); - b.copy(Q.y); b.mul(this.z); b.reduce(); - if (!a.equals(b)) return false; - } - } - return true; - }, -/* copy this=P */ - copy: function(P) - { - this.x.copy(P.x); - if (ROM.CURVETYPE!=ROM.MONTGOMERY) this.y.copy(P.y); - this.z.copy(P.z); - this.INF=P.INF; - }, -/* this=-this */ - neg: function() - { - if (this.is_infinity()) return; - if (ROM.CURVETYPE==ROM.WEIERSTRASS) - { - this.y.neg(); this.y.norm(); - } - if (ROM.CURVETYPE==ROM.EDWARDS) - { - this.x.neg(); this.x.norm(); - } - return; - }, -/* set this=O */ - inf: function() - { - this.INF=true; - this.x.zero(); - this.y=new FP(1); - this.z=new FP(1); - }, -/* set this=(x,y) where x and y are BIGs */ - setxy: function(ix,iy) - { - this.x=new FP(0); this.x.bcopy(ix); - this.y=new FP(0); this.y.bcopy(iy); - this.z=new FP(1); - var rhs=ECP.RHS(this.x); - if (ROM.CURVETYPE==ROM.MONTGOMERY) - { - if (rhs.jacobi()==1) this.INF=false; - else this.inf(); - } - else - { - var y2=new FP(0); y2.copy(this.y); - y2.sqr(); - if (y2.equals(rhs)) this.INF=false; - else this.inf(); - } - }, -/* set this=x, where x is BIG, y is derived from sign s */ - setxi: function(ix,s) - { - this.x=new FP(0); this.x.bcopy(ix); - var rhs=ECP.RHS(this.x); - this.z=new FP(1); - if (rhs.jacobi()==1) - { - var ny=rhs.sqrt(); - if (ny.redc().parity()!=s) ny.neg(); - this.y=ny; - this.INF=false; - } - else this.inf(); - }, -/* set this=x, y calcuated from curve equation */ - setx: function(ix) - { - this.x=new FP(0); this.x.bcopy(ix); - var rhs=ECP.RHS(this.x); - this.z=new FP(1); - if (rhs.jacobi()==1) - { - if (ROM.CURVETYPE!=ROM.MONTGOMERY) this.y=rhs.sqrt(); - this.INF=false; - } - else this.INF=true; - }, -/* set this to affine - from (x,y,z) to (x,y) */ - affine: function() - { - if (this.is_infinity()) return; - var one=new FP(1); - if (this.z.equals(one)) return; - this.z.inverse(); - if (ROM.CURVETYPE==ROM.WEIERSTRASS) - { - var z2=new FP(0); z2.copy(this.z); - z2.sqr(); - this.x.mul(z2); this.x.reduce(); - this.y.mul(z2); - this.y.mul(this.z); this.y.reduce(); - this.z=one; - } - if (ROM.CURVETYPE==ROM.EDWARDS) - { - this.x.mul(this.z); this.x.reduce(); - this.y.mul(this.z); this.y.reduce(); - this.z=one; - } - if (ROM.CURVETYPE==ROM.MONTGOMERY) - { - this.x.mul(this.z); this.x.reduce(); - this.z=one; - } - }, -/* extract x as BIG */ - getX: function() - { - this.affine(); - return this.x.redc(); - }, -/* extract y as BIG */ - getY: function() - { - this.affine(); - return this.y.redc(); - }, - -/* get sign of Y */ - getS: function() - { - this.affine(); - var y=this.getY(); - return y.parity(); - }, -/* extract x as FP */ - getx: function() - { - return this.x; - }, -/* extract y as FP */ - gety: function() - { - return this.y; - }, -/* extract z as FP */ - getz: function() - { - return this.z; - }, -/* convert to byte array */ - toBytes: function(b) - { - var i,t=[]; - if (ROM.CURVETYPE!=ROM.MONTGOMERY) b[0]=0x04; - else b[0]=0x02; - - this.affine(); - this.x.redc().toBytes(t); - for (i=0;i<ROM.MODBYTES;i++) b[i+1]=t[i]; - if (ROM.CURVETYPE!=ROM.MONTGOMERY) - { - this.y.redc().toBytes(t); - for (i=0;i<ROM.MODBYTES;i++) b[i+ROM.MODBYTES+1]=t[i]; - } - }, -/* convert to hex string */ - toString: function() - { - if (this.is_infinity()) return "infinity"; - this.affine(); - if (ROM.CURVETYPE==ROM.MONTGOMERY) return "("+this.x.redc().toString()+")"; - else return "("+this.x.redc().toString()+","+this.y.redc().toString()+")"; - }, - -/* this+=this */ - dbl: function() - { - if (ROM.CURVETYPE==ROM.WEIERSTRASS) - { - if (this.INF) return; - if (this.y.iszilch()) - { - this.inf(); - return; - } - - var w1=new FP(0); w1.copy(this.x); - var w6=new FP(0); w6.copy(this.z); - var w2=new FP(0); - var w3=new FP(0); w3.copy(this.x); - var w8=new FP(0); w8.copy(this.x); - - if (ROM.CURVE_A==-3) - { - w6.sqr(); - w1.copy(w6); - w1.neg(); - w3.add(w1); - w8.add(w6); - w3.mul(w8); - w8.copy(w3); - w8.imul(3); - } - else - { - w1.sqr(); - w8.copy(w1); - w8.imul(3); - } - - w2.copy(this.y); w2.sqr(); - w3.copy(this.x); w3.mul(w2); - w3.imul(4); - w1.copy(w3); w1.neg(); - - this.x.copy(w8); this.x.sqr(); - this.x.add(w1); - this.x.add(w1); - this.x.norm(); - - this.z.mul(this.y); - this.z.add(this.z); - - w2.add(w2); - w2.sqr(); - w2.add(w2); - w3.sub(this.x); - this.y.copy(w8); this.y.mul(w3); - this.y.sub(w2); - this.y.norm(); - this.z.norm(); - } - if (ROM.CURVETYPE==ROM.EDWARDS) - { - var C=new FP(0); C.copy(this.x); - var D=new FP(0); D.copy(this.y); - var H=new FP(0); H.copy(this.z); - var J=new FP(0); - - this.x.mul(this.y); this.x.add(this.x); - C.sqr(); - D.sqr(); - if (ROM.CURVE_A==-1) C.neg(); - this.y.copy(C); this.y.add(D); - H.sqr(); H.add(H); - this.z.copy(this.y); - J.copy(this.y); J.sub(H); - this.x.mul(J); - C.sub(D); - this.y.mul(C); - this.z.mul(J); - - this.x.norm(); - this.y.norm(); - this.z.norm(); - } - if (ROM.CURVETYPE==ROM.MONTGOMERY) - { - var A=new FP(0); A.copy(this.x); - var B=new FP(0); B.copy(this.x); - var AA=new FP(0); - var BB=new FP(0); - var C=new FP(0); - - if (this.INF) return; - - A.add(this.z); - AA.copy(A); AA.sqr(); - B.sub(this.z); - BB.copy(B); BB.sqr(); - C.copy(AA); C.sub(BB); - - this.x.copy(AA); this.x.mul(BB); - - A.copy(C); A.imul((ROM.CURVE_A+2)>>2); - - BB.add(A); - this.z.copy(BB); this.z.mul(C); - this.x.norm(); - this.z.norm(); - } - return; - }, - -/* this+=Q */ - add: function(Q) - { - if (ROM.CURVETYPE==ROM.WEIERSTRASS) - { - if (this.INF) - { - this.copy(Q); - return; - } - if (Q.INF) return; - - var aff=false; - var one=new FP(1); - if (Q.z.equals(one)) aff=true; - - var A,C; - var B=new FP(this.z); - var D=new FP(this.z); - if (!aff) - { - A=new FP(Q.z); - C=new FP(Q.z); - - A.sqr(); B.sqr(); - C.mul(A); D.mul(B); - - A.mul(this.x); - C.mul(this.y); - } - else - { - A=new FP(this.x); - C=new FP(this.y); - - B.sqr(); - D.mul(B); - } - - B.mul(Q.x); B.sub(A); - D.mul(Q.y); D.sub(C); - - if (B.iszilch()) - { - if (D.iszilch()) - { - this.dbl(); - return; - } - else - { - this.INF=true; - return; - } - } - - if (!aff) this.z.mul(Q.z); - this.z.mul(B); - - var e=new FP(B); e.sqr(); - B.mul(e); - A.mul(e); - - e.copy(A); - e.add(A); e.add(B); - this.x.copy(D); this.x.sqr(); this.x.sub(e); - - A.sub(this.x); - this.y.copy(A); this.y.mul(D); - C.mul(B); this.y.sub(C); - - this.x.norm(); - this.y.norm(); - this.z.norm(); - - } - if (ROM.CURVETYPE==ROM.EDWARDS) - { - var b=new FP(0); b.rcopy(ROM.CURVE_B); - var A=new FP(0); A.copy(this.z); - var B=new FP(0); - var C=new FP(0); C.copy(this.x); - var D=new FP(0); D.copy(this.y); - var E=new FP(0); - var F=new FP(0); - var G=new FP(0); - - A.mul(Q.z); - B.copy(A); B.sqr(); - C.mul(Q.x); - D.mul(Q.y); - - E.copy(C); E.mul(D); E.mul(b); - F.copy(B); F.sub(E); - G.copy(B); G.add(E); - C.add(D); - - if (ROM.CURVE_A==1) - { - E.copy(D); D.sub(C); - } - - B.copy(this.x); B.add(this.y); - D.copy(Q.x); D.add(Q.y); - B.mul(D); - B.sub(C); - B.mul(F); - this.x.copy(A); this.x.mul(B); - - if (ROM.CURVE_A==1) - { - C.copy(E); C.mul(G); - } - if (ROM.CURVE_A==-1) - { - C.mul(G); - } - this.y.copy(A); this.y.mul(C); - this.z.copy(F); this.z.mul(G); - this.x.norm(); this.y.norm(); this.z.norm(); - } - return; - }, - -/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */ - dadd: function(Q,W) - { - var A=new FP(0); A.copy(this.x); - var B=new FP(0); B.copy(this.x); - var C=new FP(0); C.copy(Q.x); - var D=new FP(0); D.copy(Q.x); - var DA=new FP(0); - var CB=new FP(0); - - A.add(this.z); - B.sub(this.z); - - C.add(Q.z); - D.sub(Q.z); - - DA.copy(D); DA.mul(A); - CB.copy(C); CB.mul(B); - - A.copy(DA); A.add(CB); A.sqr(); - B.copy(DA); B.sub(CB); B.sqr(); - - this.x.copy(A); - this.z.copy(W.x); this.z.mul(B); - - if (this.z.iszilch()) this.inf(); - else this.INF=false; - - this.x.norm(); - }, - -/* this-=Q */ - sub: function(Q) { - Q.neg(); - this.add(Q); - Q.neg(); - }, - -/* constant time multiply by small integer of length bts - use ladder */ - pinmul: function(e,bts) { - if (ROM.CURVETYPE==ROM.MONTGOMERY) - return this.mul(new BIG(e)); - else - { - var nb,i,b; - var P=new ECP(); - var R0=new ECP(); - var R1=new ECP(); R1.copy(this); - - for (i=bts-1;i>=0;i--) - { - b=(e>>i)&1; - P.copy(R1); - P.add(R0); - R0.cswap(R1,b); - R1.copy(P); - R0.dbl(); - R0.cswap(R1,b); - } - P.copy(R0); - P.affine(); - return P; - } - }, - -/* return e.this - SPA immune, using Ladder */ - - mul: function(e) - { - if (e.iszilch() || this.is_infinity()) return new ECP(); - var P=new ECP(); - if (ROM.CURVETYPE==ROM.MONTGOMERY) - { /* use ladder */ - var nb,i,b; - var D=new ECP(); - var R0=new ECP(); R0.copy(this); - var R1=new ECP(); R1.copy(this); - R1.dbl(); - D.copy(this); D.affine(); - nb=e.nbits(); - for (i=nb-2;i>=0;i--) - { - b=e.bit(i); - P.copy(R1); - P.dadd(R0,D); - - R0.cswap(R1,b); - R1.copy(P); - R0.dbl(); - R0.cswap(R1,b); - } - P.copy(R0); - } - else - { -// fixed size windows - var i,b,nb,m,s,ns; - var mt=new BIG(); - var t=new BIG(); - var Q=new ECP(); - var C=new ECP(); - var W=[]; - var w=[]; - - this.affine(); - -// precompute table - Q.copy(this); - Q.dbl(); - W[0]=new ECP(); - W[0].copy(this); - - for (i=1;i<8;i++) - { - W[i]=new ECP(); - W[i].copy(W[i-1]); - W[i].add(Q); - } - -// convert the table to affine - if (ROM.CURVETYPE==ROM.WEIERSTRASS) - ECP.multiaffine(8,W); - -// make exponent odd - add 2P if even, P if odd - t.copy(e); - s=t.parity(); - t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm(); - t.cmove(mt,s); - Q.cmove(this,ns); - C.copy(Q); - - nb=1+Math.floor((t.nbits()+3)/4); - -// convert exponent to signed 4-bit window - for (i=0;i<nb;i++) - { - w[i]=(t.lastbits(5)-16); - t.dec(w[i]); t.norm(); - t.fshr(4); - } - w[nb]=t.lastbits(5); - - P.copy(W[Math.floor((w[nb]-1)/2)]); - for (i=nb-1;i>=0;i--) - { - Q.select(W,w[i]); - P.dbl(); - P.dbl(); - P.dbl(); - P.dbl(); - P.add(Q); - } - P.sub(C); - } - P.affine(); - return P; - }, - -/* Return e.this+f.Q */ - - mul2: function(e,Q,f) { - var te=new BIG(); - var tf=new BIG(); - var mt=new BIG(); - var S=new ECP(); - var T=new ECP(); - var C=new ECP(); - var W=[]; - var w=[]; - var i,s,ns,nb; - var a,b; - - this.affine(); - Q.affine(); - - te.copy(e); - tf.copy(f); - -// precompute table - W[1]=new ECP(); W[1].copy(this); W[1].sub(Q); - W[2]=new ECP(); W[2].copy(this); W[2].add(Q); - S.copy(Q); S.dbl(); - W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S); - W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S); - T.copy(this); T.dbl(); - W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T); - W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T); - W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S); - W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S); - -// convert the table to affine - if (ROM.CURVETYPE==ROM.WEIERSTRASS) - ECP.multiaffine(8,W); - -// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction - - s=te.parity(); - te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm(); - te.cmove(mt,s); - T.cmove(this,ns); - C.copy(T); - - s=tf.parity(); - tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm(); - tf.cmove(mt,s); - S.cmove(Q,ns); - C.add(S); - - mt.copy(te); mt.add(tf); mt.norm(); - nb=1+Math.floor((mt.nbits()+1)/2); - -// convert exponent to signed 2-bit window - for (i=0;i<nb;i++) - { - a=(te.lastbits(3)-4); - te.dec(a); te.norm(); - te.fshr(2); - b=(tf.lastbits(3)-4); - tf.dec(b); tf.norm(); - tf.fshr(2); - w[i]=(4*a+b); - } - w[nb]=(4*te.lastbits(3)+tf.lastbits(3)); - S.copy(W[Math.floor((w[nb]-1)/2)]); - - for (i=nb-1;i>=0;i--) - { - T.select(W,w[i]); - S.dbl(); - S.dbl(); - S.add(T); - } - S.sub(C); /* apply correction */ - S.affine(); - return S; - } - -}; - -ECP.multiaffine=function(m,P) -{ - var i; - var t1=new FP(0); - var t2=new FP(0); - var work=[]; - - for (i=0;i<m;i++) - work[i]=new FP(0); - - work[0].one(); - work[1].copy(P[0].z); - - for (i=2;i<m;i++) - { - work[i].copy(work[i-1]); - work[i].mul(P[i-1].z); - } - - t1.copy(work[m-1]); - t1.mul(P[m-1].z); - t1.inverse(); - t2.copy(P[m-1].z); - work[m-1].mul(t1); - - for (i=m-2;;i--) - { - if (i==0) - { - work[0].copy(t1); - work[0].mul(t2); - break; - } - work[i].mul(t2); - work[i].mul(t1); - t2.mul(P[i].z); - } -/* now work[] contains inverses of all Z coordinates */ - - for (i=0;i<m;i++) - { - P[i].z.one(); - t1.copy(work[i]); - t1.sqr(); - P[i].x.mul(t1); - t1.mul(work[i]); - P[i].y.mul(t1); - } -}; - -/* return 1 if b==c, no branching */ -ECP.teq=function(b,c) -{ - var x=b^c; - x-=1; // if x=0, x now -1 - return ((x>>31)&1); -}; - -/* convert from byte array to ECP */ -ECP.fromBytes= function(b) -{ - var i,t=[]; - var P=new ECP(); - var p=new BIG(0); p.rcopy(ROM.Modulus); - - for (i=0;i<ROM.MODBYTES;i++) t[i]=b[i+1]; - var px=BIG.fromBytes(t); - if (BIG.comp(px,p)>=0) return P; - - if (b[0]==0x04) - { - for (i=0;i<ROM.MODBYTES;i++) t[i]=b[i+ROM.MODBYTES+1]; - var py=BIG.fromBytes(t); - if (BIG.comp(py,p)>=0) return P; - P.setxy(px,py); - return P; - } - else - { - P.setx(px); - return P; - } -}; - -/* Calculate RHS of curve equation */ -ECP.RHS= function(x) -{ - x.norm(); - var r=new FP(0); r.copy(x); - r.sqr(); - - if (ROM.CURVETYPE==ROM.WEIERSTRASS) - { // x^3+Ax+B - var b=new FP(0); b.rcopy(ROM.CURVE_B); - r.mul(x); - if (ROM.CURVE_A==-3) - { - var cx=new FP(0); cx.copy(x); - cx.imul(3); - cx.neg(); cx.norm(); - r.add(cx); - } - r.add(b); - } - if (ROM.CURVETYPE==ROM.EDWARDS) - { // (Ax^2-1)/(Bx^2-1) - var b=new FP(0); b.rcopy(ROM.CURVE_B); - - var one=new FP(1); - b.mul(r); - b.sub(one); - if (ROM.CURVE_A==-1) r.neg(); - r.sub(one); - - b.inverse(); - - r.mul(b); - } - if (ROM.CURVETYPE==ROM.MONTGOMERY) - { // x^3+Ax^2+x - var x3=new FP(0); - x3.copy(r); - x3.mul(x); - r.imul(ROM.CURVE_A); - r.add(x3); - r.add(x); - } - r.reduce(); - return r; -}; http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/js/ECP2.js ---------------------------------------------------------------------- diff --git a/js/ECP2.js b/js/ECP2.js deleted file mode 100755 index 4c310ab..0000000 --- a/js/ECP2.js +++ /dev/null @@ -1,604 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* AMCL Weierstrass elliptic curve functions over FP2 */ - -/* Constructor, set this=O */ -var ECP2=function() -{ - this.x=new FP2(0); - this.y=new FP2(1); - this.z=new FP2(1); - this.INF=true; -}; - -ECP2.prototype={ -/* Test this=O? */ - is_infinity: function() - { - return this.INF; - }, -/* copy this=P */ - copy: function(P) - { - this.x.copy(P.x); - this.y.copy(P.y); - this.z.copy(P.z); - this.INF=P.INF; - }, -/* set this=O */ - inf: function() - { - this.INF=true; - this.x.zero(); - this.y.zero(); - this.z.zero(); - }, - -/* conditional move of Q to P dependant on d */ - cmove: function(Q,d) - { - this.x.cmove(Q.x,d); - this.y.cmove(Q.y,d); - this.z.cmove(Q.z,d); - - var bd=(d!==0)?true:false; - this.INF^=(this.INF^Q.INF)&bd; - }, - -/* Constant time select from pre-computed table */ - select: function(W,b) - { - var MP=new ECP2(); - var m=b>>31; - var babs=(b^m)-m; - - babs=(babs-1)/2; - - this.cmove(W[0],ECP2.teq(babs,0)); // conditional move - this.cmove(W[1],ECP2.teq(babs,1)); - this.cmove(W[2],ECP2.teq(babs,2)); - this.cmove(W[3],ECP2.teq(babs,3)); - this.cmove(W[4],ECP2.teq(babs,4)); - this.cmove(W[5],ECP2.teq(babs,5)); - this.cmove(W[6],ECP2.teq(babs,6)); - this.cmove(W[7],ECP2.teq(babs,7)); - - MP.copy(this); - MP.neg(); - this.cmove(MP,(m&1)); - }, - -/* Test P == Q */ - - equals: function(Q) { - if (this.is_infinity() && Q.is_infinity()) return true; - if (this.is_infinity() || Q.is_infinity()) return false; - - var zs2=new FP2(this.z); /*zs2.copy(this.z);*/ zs2.sqr(); - var zo2=new FP2(Q.z); /*zo2.copy(Q.z);*/ zo2.sqr(); - var zs3=new FP2(zs2); /*zs3.copy(zs2);*/ zs3.mul(this.z); - var zo3=new FP2(zo2); /*zo3.copy(zo2);*/ zo3.mul(Q.z); - zs2.mul(Q.x); - zo2.mul(this.x); - if (!zs2.equals(zo2)) return false; - zs3.mul(Q.y); - zo3.mul(this.y); - if (!zs3.equals(zo3)) return false; - - return true; - }, -/* set this=-this */ - neg: function() - { - if (this.is_infinity()) return; - this.y.neg(); this.y.norm(); - return; - }, -/* convert this to affine, from (x,y,z) to (x,y) */ - affine: function() - { - if (this.is_infinity()) return; - var one=new FP2(1); - if (this.z.equals(one)) return; - this.z.inverse(); - - var z2=new FP2(this.z); //z2.copy(this.z); - z2.sqr(); - this.x.mul(z2); this.x.reduce(); - this.y.mul(z2); - this.y.mul(this.z); this.y.reduce(); - this.z=one; - }, -/* extract affine x as FP2 */ - getX: function() - { - this.affine(); - return this.x; - }, -/* extract affine y as FP2 */ - getY: function() - { - this.affine(); - return this.y; - }, -/* extract projective x */ - getx: function() - { - return this.x; - }, -/* extract projective y */ - gety: function() - { - return this.y; - }, -/* extract projective z */ - getz: function() - { - return this.z; - }, -/* convert this to byte array */ - toBytes: function(b) - { - var i,t=[]; - this.affine(); - this.x.getA().toBytes(t); - for (i=0;i<ROM.MODBYTES;i++) - b[i]=t[i]; - this.x.getB().toBytes(t); - for (i=0;i<ROM.MODBYTES;i++) - b[i+ROM.MODBYTES]=t[i]; - - this.y.getA().toBytes(t); - for (i=0;i<ROM.MODBYTES;i++) - b[i+2*ROM.MODBYTES]=t[i]; - this.y.getB().toBytes(t); - for (i=0;i<ROM.MODBYTES;i++) - b[i+3*ROM.MODBYTES]=t[i]; - }, -/* convert this to hex string */ - toString: function() - { - if (this.is_infinity()) return "infinity"; - this.affine(); - return "("+this.x.toString()+","+this.y.toString()+")"; - }, -/* set this=(x,y) */ - setxy: function(ix,iy) - { - this.x.copy(ix); - this.y.copy(iy); - this.z.one(); - - var rhs=ECP2.RHS(this.x); - - var y2=new FP2(this.y); //y2.copy(this.y); - y2.sqr(); - if (y2.equals(rhs)) this.INF=false; - else this.inf(); - }, - -/* set this=(x,.) */ - setx: function(ix) - { - this.x.copy(ix); - this.z.one(); - - var rhs=ECP2.RHS(this.x); - - if (rhs.sqrt()) - { - this.y.copy(rhs); - this.INF=false; - } - else this.inf(); - }, - -/* set this*=q, where q is Modulus, using Frobenius */ - frob: function(X) - { - if (this.INF) return; - var X2=new FP2(X); //X2.copy(X); - X2.sqr(); - this.x.conj(); - this.y.conj(); - this.z.conj(); - this.z.reduce(); - this.x.mul(X2); - this.y.mul(X2); - this.y.mul(X); - }, -/* this+=this */ - dbl: function() - { - if (this.INF) return -1; - if (this.y.iszilch()) - { - this.inf(); - return -1; - } - - var w1=new FP2(this.x); //w1.copy(this.x); - var w2=new FP2(0); - var w3=new FP2(this.x); //w3.copy(this.x); - var w8=new FP2(this.x); //w8.copy(this.x); - - w1.sqr(); - w8.copy(w1); - w8.imul(3); - - w2.copy(this.y); w2.sqr(); - w3.copy(this.x); w3.mul(w2); - w3.imul(4); - w1.copy(w3); w1.neg(); - - - this.x.copy(w8); this.x.sqr(); - this.x.add(w1); - this.x.add(w1); - this.x.norm(); - - this.z.mul(this.y); - this.z.add(this.z); - - w2.add(w2); - w2.sqr(); - w2.add(w2); - w3.sub(this.x); - this.y.copy(w8); this.y.mul(w3); - this.y.sub(w2); - this.y.norm(); - this.z.norm(); - - return 1; - }, -/* this+=Q - return 0 for add, 1 for double, -1 for O */ -/* this+=Q */ - add: function(Q) - { - if (this.INF) - { - this.copy(Q); - return -1; - } - if (Q.INF) return -1; - - var aff=false; - - if (Q.z.isunity()) aff=true; - - var A,C; - var B=new FP2(this.z); - var D=new FP2(this.z); - if (!aff) - { - A=new FP2(Q.z); - C=new FP2(Q.z); - - A.sqr(); B.sqr(); - C.mul(A); D.mul(B); - - A.mul(this.x); - C.mul(this.y); - } - else - { - A=new FP2(this.x); - C=new FP2(this.y); - - B.sqr(); - D.mul(B); - } - - B.mul(Q.x); B.sub(A); - D.mul(Q.y); D.sub(C); - - if (B.iszilch()) - { - if (D.iszilch()) - { - this.dbl(); - return 1; - } - else - { - this.INF=true; - return -1; - } - } - - if (!aff) this.z.mul(Q.z); - this.z.mul(B); - - var e=new FP2(B); e.sqr(); - B.mul(e); - A.mul(e); - - e.copy(A); - e.add(A); e.add(B); - this.x.copy(D); this.x.sqr(); this.x.sub(e); - - A.sub(this.x); - this.y.copy(A); this.y.mul(D); - C.mul(B); this.y.sub(C); - - this.x.norm(); - this.y.norm(); - this.z.norm(); - return 0; - }, -/* this-=Q */ - sub: function(Q) - { - Q.neg(); - var D=this.add(Q); - Q.neg(); - return D; - }, - -/* P*=e */ - mul: function(e) - { -/* fixed size windows */ - var i,b,nb,m,s,ns; - var mt=new BIG(); - var t=new BIG(); - var C=new ECP2(); - var P=new ECP2(); - var Q=new ECP2(); - var W=[]; - var w=[]; - - if (this.is_infinity()) return new ECP2(); - - this.affine(); - -// precompute table - Q.copy(this); - Q.dbl(); - W[0]=new ECP2(); - W[0].copy(this); - - for (i=1;i<8;i++) - { - W[i]=new ECP2(); - W[i].copy(W[i-1]); - W[i].add(Q); - } - -// convert the table to affine - - ECP2.multiaffine(8,W); - -// make exponent odd - add 2P if even, P if odd - t.copy(e); - s=t.parity(); - t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm(); - t.cmove(mt,s); - Q.cmove(this,ns); - C.copy(Q); - - nb=1+Math.floor((t.nbits()+3)/4); - -// convert exponent to signed 4-bit window - for (i=0;i<nb;i++) - { - w[i]=(t.lastbits(5)-16); - t.dec(w[i]); t.norm(); - t.fshr(4); - } - w[nb]=t.lastbits(5); - - P.copy(W[Math.floor((w[nb]-1)/2)]); - for (i=nb-1;i>=0;i--) - { - Q.select(W,w[i]); - P.dbl(); - P.dbl(); - P.dbl(); - P.dbl(); - P.add(Q); - } - P.sub(C); - P.affine(); - return P; - } -}; - -/* convert from byte array to point */ -ECP2.fromBytes=function(b) -{ - var i,t=[]; - var ra,rb; - - for (i=0;i<ROM.MODBYTES;i++) t[i]=b[i]; - ra=BIG.fromBytes(t); - for (i=0;i<ROM.MODBYTES;i++) t[i]=b[i+ROM.MODBYTES]; - rb=BIG.fromBytes(t); - - var rx=new FP2(ra,rb); //rx.bset(ra,rb); - - for (i=0;i<ROM.MODBYTES;i++) t[i]=b[i+2*ROM.MODBYTES]; - ra=BIG.fromBytes(t); - for (i=0;i<ROM.MODBYTES;i++) t[i]=b[i+3*ROM.MODBYTES]; - rb=BIG.fromBytes(t); - - var ry=new FP2(ra,rb); //ry.bset(ra,rb); - - var P=new ECP2(); - P.setxy(rx,ry); - return P; -}; - -/* Calculate RHS of curve equation x^3+B */ -ECP2.RHS=function(x) -{ - x.norm(); - var r=new FP2(x); //r.copy(x); - r.sqr(); - - var c=new BIG(0); c.rcopy(ROM.CURVE_B); - var b=new FP2(c); //b.bseta(c); - b.div_ip(); - r.mul(x); - r.add(b); - - r.reduce(); - return r; -}; - -/* normalises m-array of ECP2 points. Requires work vector of m FP2s */ - -ECP2.multiaffine=function(m,P) -{ - var i; - var t1=new FP2(0); - var t2=new FP2(0); - var work=[]; - - work[0]=new FP2(1); - work[1]=new FP2(P[0].z); - for (i=2;i<m;i++) - { - work[i]=new FP2(work[i-1]); - work[i].mul(P[i-1].z); - } - - t1.copy(work[m-1]); t1.mul(P[m-1].z); - - t1.inverse(); - - t2.copy(P[m-1].z); - work[m-1].mul(t1); - - for (i=m-2;;i--) - { - if (i==0) - { - work[0].copy(t1); - work[0].mul(t2); - break; - } - work[i].mul(t2); - work[i].mul(t1); - t2.mul(P[i].z); - } -/* now work[] contains inverses of all Z coordinates */ - - for (i=0;i<m;i++) - { - P[i].z.one(); - t1.copy(work[i]); t1.sqr(); - P[i].x.mul(t1); - t1.mul(work[i]); - P[i].y.mul(t1); - } -}; - -/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */ -ECP2.mul4=function(Q,u) -{ - var i,j,nb; - var a=[]; - var T=new ECP2(); - var C=new ECP2(); - var P=new ECP2(); - var W=[]; - var mt=new BIG(); - var t=[]; - var w=[]; - - for (i=0;i<4;i++) - { - t[i]=new BIG(u[i]); - Q[i].affine(); - } - -/* precompute table */ - - W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]); - W[1]=new ECP2(); W[1].copy(W[0]); - W[2]=new ECP2(); W[2].copy(W[0]); - W[3]=new ECP2(); W[3].copy(W[0]); - W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]); - W[5]=new ECP2(); W[5].copy(W[4]); - W[6]=new ECP2(); W[6].copy(W[4]); - W[7]=new ECP2(); W[7].copy(W[4]); - T.copy(Q[2]); T.sub(Q[3]); - W[1].sub(T); - W[2].add(T); - W[5].sub(T); - W[6].add(T); - T.copy(Q[2]); T.add(Q[3]); - W[0].sub(T); - W[3].add(T); - W[4].sub(T); - W[7].add(T); - - ECP2.multiaffine(8,W); - -/* if multiplier is even add 1 to multiplier, and add P to correction */ - mt.zero(); C.inf(); - for (i=0;i<4;i++) - { - if (t[i].parity()==0) - { - t[i].inc(1); t[i].norm(); - C.add(Q[i]); - } - mt.add(t[i]); mt.norm(); - } - - nb=1+mt.nbits(); - -/* convert exponent to signed 1-bit window */ - for (j=0;j<nb;j++) - { - for (i=0;i<4;i++) - { - a[i]=(t[i].lastbits(2)-2); - t[i].dec(a[i]); t[i].norm(); - t[i].fshr(1); - } - w[j]=(8*a[0]+4*a[1]+2*a[2]+a[3]); - } - w[nb]=(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2)); - - P.copy(W[Math.floor((w[nb]-1)/2)]); - - for (i=nb-1;i>=0;i--) - { - T.select(W,w[i]); - P.dbl(); - P.add(T); - } - P.sub(C); /* apply correction */ - - P.affine(); - return P; -}; - -/* return 1 if b==c, no branching */ -ECP2.teq=function(b,c) -{ - var x=b^c; - x-=1; // if x=0, x now -1 - return ((x>>31)&1); -}; -
