/*
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 BN Curve Pairing functions */

public final class PAIR {

/* Line function */
	public static FP12 line(ECP2 A,ECP2 B,FP Qx,FP Qy)
	{
		ECP2 P=new ECP2();

		FP4 a,b,c;
		P.copy(A);
		FP2 ZZ=new FP2(P.getz());
		ZZ.sqr();
		int D;
		if (A==B) D=A.dbl(); /* Check this return value in amcl_ec2.c */
		else D=A.add(B);
		if (D<0)
			return new FP12(1);
		FP2 Z3=new FP2(A.getz());
		c=new FP4(0);
		if (D==0)
		{ /* Addition */
			FP2 X=new FP2(B.getx());
			FP2 Y=new FP2(B.gety());
			FP2 T=new FP2(P.getz());
			T.mul(Y);
			ZZ.mul(T);

			FP2 NY=new FP2(P.gety()); NY.neg();
			ZZ.add(NY);
			Z3.pmul(Qy);
			T.mul(P.getx());
			X.mul(NY);
			T.add(X);
			a=new FP4(Z3,T);
			ZZ.neg();
			ZZ.pmul(Qx);
			b=new FP4(ZZ);
		}
		else
		{ /* Doubling */
			FP2 X=new FP2(P.getx());
			FP2 Y=new FP2(P.gety());
			FP2 T=new FP2(P.getx());
			T.sqr();
			T.imul(3);

			Y.sqr();
			Y.add(Y);
			Z3.mul(ZZ);
			Z3.pmul(Qy);

			X.mul(T);
			X.sub(Y);
			a=new FP4(Z3,X);
			T.neg();
			ZZ.mul(T);
			ZZ.pmul(Qx);
			b=new FP4(ZZ);
		}
		return new FP12(a,b,c);
	}

/* Optimal R-ate pairing */
	public static FP12 ate(ECP2 P,ECP Q)
	{
		FP2 f=new FP2(new BIG(ROM.CURVE_Fra),new BIG(ROM.CURVE_Frb));
		BIG x=new BIG(ROM.CURVE_Bnx);
		BIG n=new BIG(x);
		ECP2 K=new ECP2();
		FP12 lv;
		n.pmul(6); n.dec(2); n.norm();
		P.affine();
		Q.affine();
		FP Qx=new FP(Q.getx());
		FP Qy=new FP(Q.gety());

		ECP2 A=new ECP2();
		FP12 r=new FP12(1);

		A.copy(P);
		int nb=n.nbits();

		for (int i=nb-2;i>=1;i--)
		{
			lv=line(A,A,Qx,Qy);
			r.smul(lv);

			if (n.bit(i)==1)
			{
				lv=line(A,P,Qx,Qy);

				r.smul(lv);
			}
			r.sqr();
		}

		lv=line(A,A,Qx,Qy);
		r.smul(lv);

/* R-ate fixup */

		r.conj();

		K.copy(P);
		K.frob(f);
		A.neg();
		lv=line(A,K,Qx,Qy);
		r.smul(lv);
		K.frob(f);
		K.neg();
		lv=line(A,K,Qx,Qy);
		r.smul(lv);

		return r;
	}

/* Optimal R-ate double pairing e(P,Q).e(R,S) */
	public static FP12 ate2(ECP2 P,ECP Q,ECP2 R,ECP S)
	{
		FP2 f=new FP2(new BIG(ROM.CURVE_Fra),new BIG(ROM.CURVE_Frb));
		BIG x=new BIG(ROM.CURVE_Bnx);
		BIG n=new BIG(x);
		ECP2 K=new ECP2();
		FP12 lv;
		n.pmul(6); n.dec(2); n.norm();
		P.affine();
		Q.affine();
		R.affine();
		S.affine();

		FP Qx=new FP(Q.getx());
		FP Qy=new FP(Q.gety());
		FP Sx=new FP(S.getx());
		FP Sy=new FP(S.gety());

		ECP2 A=new ECP2();
		ECP2 B=new ECP2();
		FP12 r=new FP12(1);

		A.copy(P);
		B.copy(R);
		int nb=n.nbits();

		for (int i=nb-2;i>=1;i--)
		{
			lv=line(A,A,Qx,Qy);
			r.smul(lv);
			lv=line(B,B,Sx,Sy);
			r.smul(lv);

			if (n.bit(i)==1)
			{
				lv=line(A,P,Qx,Qy);
				r.smul(lv);
				lv=line(B,R,Sx,Sy);
				r.smul(lv);
			}
			r.sqr();
		}

		lv=line(A,A,Qx,Qy);
		r.smul(lv);

		lv=line(B,B,Sx,Sy);
		r.smul(lv);

/* R-ate fixup */
		r.conj();

		K.copy(P);
		K.frob(f);
		A.neg();
		lv=line(A,K,Qx,Qy);
		r.smul(lv);
		K.frob(f);
		K.neg();
		lv=line(A,K,Qx,Qy);
		r.smul(lv);

		K.copy(R);
		K.frob(f);
		B.neg();
		lv=line(B,K,Sx,Sy);
		r.smul(lv);
		K.frob(f);
		K.neg();
		lv=line(B,K,Sx,Sy);
		r.smul(lv);

		return r;
	}

/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
	public static FP12 fexp(FP12 m)
	{
		FP2 f=new FP2(new BIG(ROM.CURVE_Fra),new BIG(ROM.CURVE_Frb));
		BIG x=new BIG(ROM.CURVE_Bnx);
		FP12 r=new FP12(m);
		FP12 x0,x1,x2,x3,x4,x5;

/* Easy part of final exp */
		FP12 lv=new FP12(r);
		lv.inverse();
		r.conj();

		r.mul(lv);
		lv.copy(r);
		r.frob(f);
		r.frob(f);
		r.mul(lv);
/* Hard part of final exp */
		lv.copy(r);
		lv.frob(f);
		x0=new FP12(lv);
		x0.frob(f);
		lv.mul(r);
		x0.mul(lv);
		x0.frob(f);
		x1=new FP12(r);
		x1.conj();
		x4=r.pow(x);

		x3=new FP12(x4);
		x3.frob(f);

		x2=x4.pow(x);

		x5=new FP12(x2); x5.conj();
		lv=x2.pow(x);

		x2.frob(f);
		r.copy(x2); r.conj();

		x4.mul(r);
		x2.frob(f);

		r.copy(lv);
		r.frob(f);
		lv.mul(r);

		lv.usqr();
		lv.mul(x4);
		lv.mul(x5);
		r.copy(x3);
		r.mul(x5);
		r.mul(lv);
		lv.mul(x2);
		r.usqr();
		r.mul(lv);
		r.usqr();
		lv.copy(r);
		lv.mul(x1);
		r.mul(x0);
		lv.usqr();
		r.mul(lv);
		r.reduce();
		return r;
	}

/* GLV method */
	public static BIG[] glv(BIG e)
	{
		int i,j;
		BIG t=new BIG(0);
		BIG q=new BIG(ROM.CURVE_Order);
		BIG[] u=new BIG[2];
		BIG[] v=new BIG[2];
		for (i=0;i<2;i++)
		{
			t.copy(new BIG(ROM.CURVE_W[i]));  // why not just t=new BIG(ROM.CURVE_W[i]);
			DBIG d=BIG.mul(t,e);
			v[i]=new BIG(d.div(q));
			u[i]=new BIG(0);
		}
		u[0].copy(e);
		for (i=0;i<2;i++)
			for (j=0;j<2;j++)
			{
				t.copy(new BIG(ROM.CURVE_SB[j][i]));
				t.copy(BIG.modmul(v[j],t,q));
				u[i].add(q);
				u[i].sub(t);
				u[i].mod(q);
			}
		return u;
	}

/* Galbraith & Scott Method */
	public static BIG[] gs(BIG e)
	{
		int i,j;
		BIG t=new BIG(0);
		BIG q=new BIG(ROM.CURVE_Order);
		BIG[] u=new BIG[4];
		BIG[] v=new BIG[4];
		for (i=0;i<4;i++)
		{
			t.copy(new BIG(ROM.CURVE_WB[i]));
			DBIG d=BIG.mul(t,e);
			v[i]=new BIG(d.div(q));
			u[i]=new BIG(0);
		}
		u[0].copy(e);
		for (i=0;i<4;i++)
			for (j=0;j<4;j++)
			{
				t.copy(new BIG(ROM.CURVE_BB[j][i]));
				t.copy(BIG.modmul(v[j],t,q));
				u[i].add(q);
				u[i].sub(t);
				u[i].mod(q);
			}
		return u;
	}

/* Multiply P by e in group G1 */
	public static ECP G1mul(ECP P,BIG e)
	{
		ECP R;
		if (ROM.USE_GLV)
		{
			P.affine();
			R=new ECP();
			R.copy(P);
			int i,np,nn;
			ECP Q=new ECP();
			Q.copy(P);
			BIG q=new BIG(ROM.CURVE_Order);
			FP cru=new FP(new BIG(ROM.CURVE_Cru));
			BIG t=new BIG(0);
			BIG[] u=glv(e);
			Q.getx().mul(cru);

			np=u[0].nbits();
			t.copy(BIG.modneg(u[0],q));
			nn=t.nbits();
			if (nn<np)
			{
				u[0].copy(t);
				R.neg();
			}

			np=u[1].nbits();
			t.copy(BIG.modneg(u[1],q));
			nn=t.nbits();
			if (nn<np)
			{
				u[1].copy(t);
				Q.neg();
			}

			R=R.mul2(u[0],Q,u[1]);

		}
		else
		{
			R=P.mul(e);
		}
		return R;
	}

/* Multiply P by e in group G2 */
	public static ECP2 G2mul(ECP2 P,BIG e)
	{
		ECP2 R;
		if (ROM.USE_GS_G2)
		{
			ECP2[] Q=new ECP2[4];
			FP2 f=new FP2(new BIG(ROM.CURVE_Fra),new BIG(ROM.CURVE_Frb));
			BIG q=new BIG(ROM.CURVE_Order);
			BIG[] u=gs(e);

			BIG t=new BIG(0);
			int i,np,nn;
			P.affine();
			Q[0]=new ECP2(); Q[0].copy(P);
			for (i=1;i<4;i++)
			{
				Q[i]=new ECP2(); Q[i].copy(Q[i-1]);
				Q[i].frob(f);
			}
			for (i=0;i<4;i++)
			{
				np=u[i].nbits();
				t.copy(BIG.modneg(u[i],q));
				nn=t.nbits();
				if (nn<np)
				{
					u[i].copy(t);
					Q[i].neg();
				}
			}
			R=ECP2.mul4(Q,u);

		}
		else
		{
			R=P.mul(e);
		}
		return R;
	}

/* f=f^e */
/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
	public static FP12 GTpow(FP12 d,BIG e)
	{
		FP12 r;
		if (ROM.USE_GS_GT)
		{
			FP12[] g=new FP12[4];
			FP2 f=new FP2(new BIG(ROM.CURVE_Fra),new BIG(ROM.CURVE_Frb));
			BIG q=new BIG(ROM.CURVE_Order);
			BIG t=new BIG(0);
			int i,np,nn;
			BIG[] u=gs(e);

			g[0]=new FP12(d);
			for (i=1;i<4;i++)
			{
				g[i]=new FP12(0); g[i].copy(g[i-1]);
				g[i].frob(f);
			}
			for (i=0;i<4;i++)
			{
				np=u[i].nbits();
				t.copy(BIG.modneg(u[i],q));
				nn=t.nbits();
				if (nn<np)
				{
					u[i].copy(t);
					g[i].conj();
				}
			}
			r=FP12.pow4(g,u);
		}
		else
		{
			r=d.pow(e);
		}
		return r;
	}

/* test group membership */
/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
	public static boolean GTmember(FP12 m)
	{
		if (m.isunity()) return false;
		FP12 r=new FP12(m);
		r.conj();
		r.mul(m);
		if (!r.isunity()) return false;

		FP2 f=new FP2(new BIG(ROM.CURVE_Fra),new BIG(ROM.CURVE_Frb));

		r.copy(m); r.frob(f); r.frob(f);
		FP12 w=new FP12(r); w.frob(f); w.frob(f);
		w.mul(m);
		if (!ROM.GT_STRONG)
		{
			if (!w.equals(r)) return false;
			BIG x=new BIG(ROM.CURVE_Bnx);
			r.copy(m); w=r.pow(x); w=w.pow(x);
			r.copy(w); r.sqr(); r.mul(w); r.sqr();
			w.copy(m); w.frob(f);
		}
		return w.equals(r);
	}

	public static void main(String[] args) {
		ECP Q=new ECP(new BIG(ROM.CURVE_Gx),new BIG(ROM.CURVE_Gy));
		ECP2 P=new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));

		BIG r=new BIG(ROM.CURVE_Order);
		BIG xa=new BIG(ROM.CURVE_Pxa);

		System.out.println("P= "+P.toString());
		System.out.println("Q= "+Q.toString());

		BIG m=new BIG(17);

		FP12 e=ate(P,Q);
		System.out.println("\ne= "+e.toString());

		e=fexp(e);
	//	e=GTpow(e,m);

		System.out.println("\ne= "+e.toString());

		BIG [] GLV=glv(r);

		System.out.println("GLV[0]= "+GLV[0].toString());
		System.out.println("GLV[0]= "+GLV[1].toString());

		ECP G=new ECP(); G.copy(Q);
		ECP2 R=new ECP2(); R.copy(P);


		e=ate(R,Q);
		e=fexp(e);

		e=GTpow(e,xa);
		System.out.println("\ne= "+e.toString());


		R=G2mul(R,xa);
		e=ate(R,G);
		e=fexp(e);

		System.out.println("\ne= "+e.toString());

		G=G1mul(G,xa);
		e=ate(P,G);
		e=fexp(e);
		System.out.println("\ne= "+e.toString());
	}
}

