/*
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.
*/

/* MPIN API Functions */

var MPIN = {
	BAD_PARAMS:-11,
	INVALID_POINT:-14,
	WRONG_ORDER:-18,
	BAD_PIN:-19,
/* configure PIN here */
	MAXPIN:10000,  /* max PIN */
	PBLEN:14,     /* MAXPIN length in bits */
	TS:10,        /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
	TRAP:200,     /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
	EFS:ROM.MODBYTES,
	EGS:ROM.MODBYTES,
	PAS:16,

/* return time in slots since epoch */
	today: function() {
		var now=new Date();
		return Math.floor(now.getTime()/(60000*1440));  // for daily tokens
	},

	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;
	},

	comparebytes: function(a,b)
	{
		if (a.length!=b.length) return false;
		for (var i=0;i<a.length;i++)
		{
			if (a[i]!=b[i]) return false;
		}
		return true;
	},


/* Hash number (optional) and string to point on curve */

	hashit: function(n,ID)
	{
		var H=new HASH();
		if (n!==0) H.process_num(n);
		H.process_array(ID);
		return H.hash();
	},

	mapit: function(h)
	{
		var q=new BIG(0); q.rcopy(ROM.Modulus);
		var x=BIG.fromBytes(h);
		x.mod(q);
		var P=new ECP();
		while (true)
		{
			P.setxi(x,0);
			if (!P.is_infinity()) break;
			x.inc(1); x.norm();
		}
		return P;
	},

/* needed for SOK */
	mapit2: function(h)
	{
		var q=new BIG(0); q.rcopy(ROM.Modulus);
		var x=BIG.fromBytes(h);
		var one=new BIG(1);
		x.mod(q);
		var Q,T,K,X;
		while (true)
		{
			X=new FP2(one,x);
			Q=new ECP2(); Q.setx(X);
			if (!Q.is_infinity()) break;
			x.inc(1); x.norm();
		}
/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */

		var Fa=new BIG(0); Fa.rcopy(ROM.CURVE_Fra);
		var Fb=new BIG(0); Fb.rcopy(ROM.CURVE_Frb);
		X=new FP2(Fa,Fb);
		x=new BIG(0); x.rcopy(ROM.CURVE_Bnx);

		T=new ECP2(); T.copy(Q);
		T.mul(x); T.neg();
		K=new ECP2(); K.copy(T);
		K.dbl(); K.add(T); K.affine();

		K.frob(X);
		Q.frob(X); Q.frob(X); Q.frob(X);
		Q.add(T); Q.add(K);
		T.frob(X); T.frob(X);
		Q.add(T);
		Q.affine();
		return Q;

	},

/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
/* maps a random u to a point on the curve */
	map: function(u,cb)
	{
		var P=new ECP();
		var x=new BIG(u);
		var p=new BIG(0); p.rcopy(ROM.Modulus);
		x.mod(p);
		while (true)
		{
			P.setxi(x,cb);
			if (!P.is_infinity()) break;
			x.inc(1);  x.norm();
		}
		return P;
	},

/* returns u derived from P. Random value in range 1 to return value should then be added to u */
	unmap: function(u,P)
	{
		var s=P.getS();
		var R=new ECP();
		var r=0;
		var x=P.getX();
		u.copy(x);
		while (true)
		{
			u.dec(1); u.norm();
			r++;
			R.setxi(u,s); //=new ECP(u,s);
			if (!R.is_infinity()) break;
		}
		return r;
	},

/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
/* Note that u and v are indistinguisible from random strings */
	ENCODING: function(rng,E)
	{
		var i,rn,m,su,sv;
		var T=[];

		for (i=0;i<this.EFS;i++) T[i]=E[i+1];
		var u=BIG.fromBytes(T);
		for (i=0;i<this.EFS;i++) T[i]=E[i+this.EFS+1];
		var v=BIG.fromBytes(T);

		var P=new ECP(0); P.setxy(u,v);
		if (P.is_infinity()) return this.INVALID_POINT;

		var p=new BIG(0); p.rcopy(ROM.Modulus);
		u=BIG.randomnum(p,rng);

		su=rng.getByte(); if (su<0) su=-su; su%=2;

		var W=this.map(u,su);
		P.sub(W);
		sv=P.getS();
		rn=this.unmap(v,P);
		m=rng.getByte(); if (m<0) m=-m; m%=rn;
		v.inc(m+1);
		E[0]=(su+2*sv);
		u.toBytes(T);
		for (i=0;i<this.EFS;i++) E[i+1]=T[i];
		v.toBytes(T);
		for (i=0;i<this.EFS;i++) E[i+this.EFS+1]=T[i];

		return 0;
	},

	DECODING: function(D)
	{
		var i,su,sv;
		var T=[];

		if ((D[0]&0x04)!==0) return this.INVALID_POINT;

		for (i=0;i<this.EFS;i++) T[i]=D[i+1];
		var u=BIG.fromBytes(T);
		for (i=0;i<this.EFS;i++) T[i]=D[i+this.EFS+1];
		var v=BIG.fromBytes(T);

		su=D[0]&1;
		sv=(D[0]>>1)&1;
		var W=this.map(u,su);
		var P=this.map(v,sv);
		P.add(W);
		u=P.getX();
		v=P.getY();
		D[0]=0x04;
		u.toBytes(T);
		for (i=0;i<this.EFS;i++) D[i+1]=T[i];
		v.toBytes(T);
		for (i=0;i<this.EFS;i++) D[i+this.EFS+1]=T[i];

		return 0;
	},

/* R=R1+R2 in group G1 */
	RECOMBINE_G1: function(R1,R2,R)
	{
		var P=ECP.fromBytes(R1);
		var Q=ECP.fromBytes(R2);

		if (P.is_infinity() || Q.is_infinity()) return this.INVALID_POINT;

		P.add(Q);

		P.toBytes(R);
		return 0;
	},

/* W=W1+W2 in group G2 */
	RECOMBINE_G2: function(W1,W2,W)
	{
		var P=ECP2.fromBytes(W1);
		var Q=ECP2.fromBytes(W2);

		if (P.is_infinity() || Q.is_infinity()) return this.INVALID_POINT;

		P.add(Q);

		P.toBytes(W);
		return 0;
	},

	HASH_ID: function(ID)
	{
		return this.hashit(0,ID);
	},

/* create random secret S */
	RANDOM_GENERATE: function(rng,S)
	{
		var r=new BIG(0); r.rcopy(ROM.CURVE_Order);
		var s=BIG.randomnum(r,rng);

		s.toBytes(S);
		return 0;
	},

/* Extract PIN from TOKEN for identity CID */
	EXTRACT_PIN: function(CID,pin,TOKEN)
	{
		var P=ECP.fromBytes(TOKEN);
		if (P.is_infinity()) return this.INVALID_POINT;
		var h=this.hashit(0,CID);
		var R=this.mapit(h);

		pin%=this.MAXPIN;

		R=R.pinmul(pin,this.PBLEN);
		P.sub(R);

		P.toBytes(TOKEN);

		return 0;
	},

/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
	GET_SERVER_SECRET: function(S,SST)
	{

		var A=new BIG(0);
		var B=new BIG(0);
		A.rcopy(ROM.CURVE_Pxa); B.rcopy(ROM.CURVE_Pxb);
		var QX=new FP2(0); QX.bset(A,B);
		A.rcopy(ROM.CURVE_Pya); B.rcopy(ROM.CURVE_Pyb);
		var QY=new FP2(0); QY.bset(A,B);

		var Q=new ECP2();
		Q.setxy(QX,QY);

		var s=BIG.fromBytes(S);
		Q=PAIR.G2mul(Q,s);
		Q.toBytes(SST);
		return 0;
	},


/*
 W=x*H(G);
 if RNG == NULL then X is passed in
 if RNG != NULL the X is passed out
 if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
*/
	GET_G1_MULTIPLE: function(rng,type,X,G,W)
	{
		var x;
		var r=new BIG(0); r.rcopy(ROM.CURVE_Order);

		if (rng!=null)
		{
			x=BIG.randomnum(r,rng);
			x.toBytes(X);
		}
		else
		{
			x=BIG.fromBytes(X);
		}
		var P;
		if (type==0)
		{
			P=ECP.fromBytes(G);
			if (P.is_infinity()) return INVALID_POINT;
		}
		else
			P=this.mapit(G);

		PAIR.G1mul(P,x).toBytes(W);
		return 0;
	},


/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
	GET_CLIENT_SECRET: function(S,CID,CST)
	{
		return this.GET_G1_MULTIPLE(null,1,S,CID,CST);
	},

/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
	GET_CLIENT_PERMIT: function(date,S,CID,CTT)
	{
		var h=this.hashit(date,CID);
		var P=this.mapit(h);

		var s=BIG.fromBytes(S);
		P=PAIR.G1mul(P,s);
		P.toBytes(CTT);
		return 0;
	},

/* Implement step 1 on client side of MPin protocol */
	CLIENT_1: function(date,CLIENT_ID,rng,X,pin,TOKEN,SEC,xID,xCID,PERMIT)
	{
		var r=new BIG(0); r.rcopy(ROM.CURVE_Order);
	//	var q=new BIG(0); q.rcopy(ROM.Modulus);
		var x;
		if (rng!==null)
		{
			x=BIG.randomnum(r,rng);
			x.toBytes(X);
		}
		else
		{
			x=BIG.fromBytes(X);
		}
		var P,T,W;

		var h=this.hashit(0,CLIENT_ID);
		P=this.mapit(h);
		T=ECP.fromBytes(TOKEN);
		if (T.is_infinity()) return this.INVALID_POINT;

		pin%=this.MAXPIN;
		W=P.pinmul(pin,this.PBLEN);
		T.add(W);

		if (date!=0)
		{
			W=ECP.fromBytes(PERMIT);
			if (W.is_infinity()) return this.INVALID_POINT;
			T.add(W);
			h=this.hashit(date,h);
			W=this.mapit(h);
			if (xID!=null)
			{
				P=PAIR.G1mul(P,x);
				P.toBytes(xID);
				W=PAIR.G1mul(W,x);
				P.add(W);
			}
			else
			{
				P.add(W);
				P=PAIR.G1mul(P,x);
			}
			if (xCID!=null) P.toBytes(xCID);
		}
		else
		{
			if (xID!=null)
			{
				P=PAIR.G1mul(P,x);
				P.toBytes(xID);
			}
		}

		T.toBytes(SEC);
		return 0;
	},

/* Implement step 2 on client side of MPin protocol */
	CLIENT_2: function(X,Y,SEC)
	{
		var r=new BIG(0); r.rcopy(ROM.CURVE_Order);
		var P=ECP.fromBytes(SEC);
		if (P.is_infinity()) return this.INVALID_POINT;

		var px=BIG.fromBytes(X);
		var py=BIG.fromBytes(Y);
		px.add(py);
		px.mod(r);
		px.rsub(r);

		PAIR.G1mul(P,px).toBytes(SEC);
		return 0;
	},

/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
	SERVER_1: function(date,CID,HID,HTID)
	{
		var h=this.hashit(0,CID);
		var R,P=this.mapit(h);

		if (date!==0)
		{
			if (HID!=null) P.toBytes(HID);
			h=this.hashit(date,h);
			R=this.mapit(h);
			P.add(R);
			P.toBytes(HTID);
		}
		else P.toBytes(HID);
	},

/* Implement step 1 of MPin protocol on server side */
	SERVER_2: function(date,HID,HTID,Y,SST,xID,xCID,mSEC,E,F)
	{
		var A=new BIG(0);
		var B=new BIG(0);
		A.rcopy(ROM.CURVE_Pxa); B.rcopy(ROM.CURVE_Pxb);
		var QX=new FP2(0); QX.bset(A,B);
		A.rcopy(ROM.CURVE_Pya); B.rcopy(ROM.CURVE_Pyb);
		var QY=new FP2(0); QY.bset(A,B);

		var Q=new ECP2();
		Q.setxy(QX,QY);

		var sQ=ECP2.fromBytes(SST);
		if (sQ.is_infinity()) return this.INVALID_POINT;

		var R;
		if (date!==0)
			R=ECP.fromBytes(xCID);
		else
		{
			if (xID==null) return this.BAD_PARAMS;
			R=ECP.fromBytes(xID);
		}
		if (R.is_infinity()) return this.INVALID_POINT;

		var y=BIG.fromBytes(Y);
		var P;

		if (date!=0) P=ECP.fromBytes(HTID);
		else
		{
			if (HID==null) return this.BAD_PARAMS;
			P=ECP.fromBytes(HID);
		}
		if (P.is_infinity()) return this.INVALID_POINT;

		P=PAIR.G1mul(P,y);
		P.add(R);
		R=ECP.fromBytes(mSEC);
		if (R.is_infinity()) return this.INVALID_POINT;

		var g=PAIR.ate2(Q,R,sQ,P);
		g=PAIR.fexp(g);

		if (!g.isunity())
		{
			if (HID!=null && xID!=null && E!=null && F!=null)
			{
				g.toBytes(E);
				if (date!==0)
				{
					P=ECP.fromBytes(HID);
					if (P.is_infinity()) return this.INVALID_POINT;
					R=ECP.fromBytes(xID);
					if (R.is_infinity()) return this.INVALID_POINT;

					P=PAIR.G1mul(P,y);
					P.add(R);
				}
				g=PAIR.ate(Q,P);
				g=PAIR.fexp(g);

				g.toBytes(F);
			}
			return this.BAD_PIN;
		}
		return 0;
	},

/* Pollards kangaroos used to return PIN error */
	KANGAROO: function(E,F)
	{
		var ge=FP12.fromBytes(E);
		var gf=FP12.fromBytes(F);
		var distance = [];
		var t=new FP12(gf);
		var table=[];
		var i,j,m,s,dn,dm,res,steps;

		s=1;
		for (m=0;m<this.TS;m++)
		{
			distance[m]=s;
			table[m]=new FP12(t);
			s*=2;
			t.usqr();
		}
		t.one();
		dn=0;
		for (j=0;j<this.TRAP;j++)
		{
			i=t.geta().geta().getA().lastbits(8)%this.TS;
			t.mul(table[i]);
			dn+=distance[i];
		}
		gf.copy(t); gf.conj();
		steps=0; dm=0;
		res=0;
		while (dm-dn<this.MAXPIN)
		{
			steps++;
			if (steps>4*this.TRAP) break;
			i=ge.geta().geta().getA().lastbits(8)%this.TS;
			ge.mul(table[i]);
			dm+=distance[i];
			if (ge.equals(t))
			{
				res=dm-dn;
				break;
			}
			if (ge.equals(gf))
			{
				res=dn-dm;
				break;
			}

		}
		if (steps>4*this.TRAP || dm-dn>=this.MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
		return res;
	},

        /* return time  since epoch */
	GET_TIME: function() {
		var now=new Date();
		return Math.floor(now.getTime()/(1000));
	},

        /* y = H(time,xCID) */
	GET_Y: function(TimeValue,xCID,Y)
	{
		var q=new BIG(0);
                q.rcopy(ROM.CURVE_Order);
                var h=this.hashit(TimeValue,xCID);
                var y=BIG.fromBytes(h);
		y.mod(q);
                y.toBytes(Y);
                return 0;
	},

        /* One pass MPIN Client */
	CLIENT: function(date,CLIENT_ID,rng,X,pin,TOKEN,SEC,xID,xCID,PERMIT,TimeValue,Y)
	{

                var rtn=0;
                var pID;
                if (date == 0) {
                  pID = xID;
		} else {
                  pID = xCID;
                  xID = null;
		}

                rtn = this.CLIENT_1(date,CLIENT_ID,rng,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
                if (rtn != 0)
                  return rtn;

                this.GET_Y(TimeValue,pID,Y);

                rtn = this.CLIENT_2(X,Y,SEC);
                if (rtn != 0)
                  return rtn;

                return 0;
        },

        /* One pass MPIN Server */
	SERVER: function(date,HID,HTID,Y,SST,xID,xCID,mSEC,E,F,CID,TimeValue)
        {
                var rtn=0;

                this.SERVER_1(date,CID,HID,HTID);

                this.GET_Y(TimeValue,xCID,Y);

                rtn = this.SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
                if (rtn != 0)
                  return rtn;

                return 0;
        },

/* Functions to support M-Pin Full */

	PRECOMPUTE: function(TOKEN,CID,G1,G2)
	{
		var P,T;
		var g;

		T=ECP.fromBytes(TOKEN);
		if (T.is_infinity()) return INVALID_POINT;

		P=this.mapit(CID);

		var A=new BIG(0);
		var B=new BIG(0);
		A.rcopy(ROM.CURVE_Pxa); B.rcopy(ROM.CURVE_Pxb);
		var QX=new FP2(0); QX.bset(A,B);
		A.rcopy(ROM.CURVE_Pya); B.rcopy(ROM.CURVE_Pyb);
		var QY=new FP2(0); QY.bset(A,B);

		var Q=new ECP2();
		Q.setxy(QX,QY);

		g=PAIR.ate(Q,T);
		g=PAIR.fexp(g);
		g.toBytes(G1);

		g=PAIR.ate(Q,P);
		g=PAIR.fexp(g);
		g.toBytes(G2);

		return 0;
	},

/* calculate common key on client side */
/* wCID = w.(A+AT) */
	CLIENT_KEY: function(G1,G2,pin,R,X,wCID,CK)
	{
		var H=new HASH();
		var t=[];

		var g1=FP12.fromBytes(G1);
		var g2=FP12.fromBytes(G2);
		var z=BIG.fromBytes(R);
		var x=BIG.fromBytes(X);

		var W=ECP.fromBytes(wCID);
		if (W.is_infinity()) return INVALID_POINT;

		W=PAIR.G1mul(W,x);

		var fa=new BIG(0); fa.rcopy(ROM.CURVE_Fra);
		var fb=new BIG(0); fb.rcopy(ROM.CURVE_Frb);
		var f=new FP2(fa,fb); //f.bset(fa,fb);

		var r=new BIG(0); r.rcopy(ROM.CURVE_Order);
		var q=new BIG(0); q.rcopy(ROM.Modulus);

		var m=new BIG(q);
		m.mod(r);

		var a=new BIG(z);
		a.mod(m);

		var b=new BIG(z);
		b.div(m);

		g2.pinpow(pin,this.PBLEN);
		g1.mul(g2);

		var c=g1.trace();
		g2.copy(g1);
		g2.frob(f);
		var cp=g2.trace();
		g1.conj();
		g2.mul(g1);
		var cpm1=g2.trace();
		g2.mul(g1);
		var cpm2=g2.trace();

		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);

		c.geta().getA().toBytes(t);
		H.process_array(t);
		c.geta().getB().toBytes(t);
		H.process_array(t);
		c.getb().getA().toBytes(t);
		H.process_array(t);
		c.getb().getB().toBytes(t);
		H.process_array(t);

		W.getX().toBytes(t);
		H.process_array(t);
		W.getY().toBytes(t);
		H.process_array(t);

		t=H.hash();
		for (var i=0;i<this.PAS;i++) CK[i]=t[i];

		return 0;
	},

/* calculate common key on server side */
/* Z=r.A - no time permits involved */

	SERVER_KEY: function(Z,SST,W,xID,xCID,SK)
	{
		var H=new HASH();
		var t=[];

		var sQ=ECP2.fromBytes(SST);
		if (sQ.is_infinity()) return INVALID_POINT;
		var R=ECP.fromBytes(Z);
		if (R.is_infinity()) return INVALID_POINT;

		var U;
		if (xCID!=null)
			U=ECP.fromBytes(xCID);
		else
			U=ECP.fromBytes(xID);
		if (U.is_infinity()) return INVALID_POINT;

		var w=BIG.fromBytes(W);
		U=PAIR.G1mul(U,w);
		var g=PAIR.ate(sQ,R);
		g=PAIR.fexp(g);

		var c=g.trace();
		c.geta().getA().toBytes(t);
		H.process_array(t);
		c.geta().getB().toBytes(t);
		H.process_array(t);
		c.getb().getA().toBytes(t);
		H.process_array(t);
		c.getb().getB().toBytes(t);
		H.process_array(t);

		U.getX().toBytes(t);
		H.process_array(t);
		U.getY().toBytes(t);
		H.process_array(t);

		t=H.hash();
		for (var i=0;i<this.PAS;i++) SK[i]=t[i];

		return 0;
	}
};
