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

package org.apache.milagro.amcl.BLS48;

public final class PAIR256 {

	public static final boolean USE_GLV =true;
	public static final boolean USE_GS_G2 =true;
	public static final boolean USE_GS_GT =true;	
	public static final boolean GT_STRONG=false;


/* Line function */
	public static FP48 line(ECP8 A,ECP8 B,FP Qx,FP Qy)
	{
//System.out.println("Into line");
		FP16 a,b,c;                            // Edits here
//		c=new FP16(0);
		if (A==B)
		{ // Doubling
			FP8 XX=new FP8(A.getx());  //X
			FP8 YY=new FP8(A.gety());  //Y
			FP8 ZZ=new FP8(A.getz());  //Z
			FP8 YZ=new FP8(YY);        //Y 
			YZ.mul(ZZ);                //YZ
			XX.sqr();	               //X^2
			YY.sqr();	               //Y^2
			ZZ.sqr();			       //Z^2
			
			YZ.imul(4);
			YZ.neg(); YZ.norm();       //-2YZ
			YZ.tmul(Qy);               //-2YZ.Ys

			XX.imul(6);                //3X^2
			XX.tmul(Qx);               //3X^2.Xs

			int sb=3*ROM.CURVE_B_I;
			ZZ.imul(sb); 	
			
			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
			{
				ZZ.div_2i();
			}
			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
			{
				ZZ.times_i();
				ZZ.add(ZZ);
				YZ.times_i();
				YZ.norm();
			}
			
			ZZ.norm(); // 3b.Z^2 

			YY.add(YY);
			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2

			a=new FP16(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
			{			
				b=new FP16(XX);             // L(0,1) | L(0,0) | L(1,0)
				c=new FP16(0);
			}
			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
			{
				b=new FP16(0);
				c=new FP16(XX); c.times_i();
			}
			A.dbl();
		}
		else
		{ // Addition - assume B is affine

			FP8 X1=new FP8(A.getx());    // X1
			FP8 Y1=new FP8(A.gety());    // Y1
			FP8 T1=new FP8(A.getz());    // Z1
			FP8 T2=new FP8(A.getz());    // Z1
			
			T1.mul(B.gety());    // T1=Z1.Y2 
			T2.mul(B.getx());    // T2=Z1.X2

			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2

			T1.copy(X1);            // T1=X1-Z1.X2
			X1.tmul(Qy);            // X1=(X1-Z1.X2).Ys

			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
			{
				X1.times_i();
				X1.norm();
			}

			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2

			T2.copy(Y1);            // T2=Y1-Z1.Y2
			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
			Y1.tmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs

			a=new FP16(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
			{
				b=new FP16(Y1);
				c=new FP16(0);
			}
			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
			{
				b=new FP16(0);
				c=new FP16(Y1); c.times_i();
			}
			A.add(B);
		}
//System.out.println("Out of line");
		return new FP48(a,b,c);
	}

/* Optimal R-ate pairing */
	public static FP48 ate(ECP8 P1,ECP Q1)
	{
		FP2 f;
		BIG x=new BIG(ROM.CURVE_Bnx);
		BIG n=new BIG(x);
		FP48 lv;
		int bt;
		
		ECP8 P=new ECP8(P1);
		ECP Q=new ECP(Q1);

		P.affine();
		Q.affine();


		BIG n3=new BIG(n);
		n3.pmul(3);
		n3.norm();

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

		ECP8 A=new ECP8();
		FP48 r=new FP48(1);
		A.copy(P);

		ECP8 MP=new ECP8();
		MP.copy(P); MP.neg();

		int nb=n3.nbits();

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

			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
			if (bt==1)
			{
				lv=line(A,P,Qx,Qy);
				r.smul(lv,ECP.SEXTIC_TWIST);
			}
			if (bt==-1)
			{
				//P.neg();
				lv=line(A,MP,Qx,Qy);
				r.smul(lv,ECP.SEXTIC_TWIST);
				//P.neg();
			}
		}

		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
		{
			r.conj();
		}

		return r;
	}

/* Optimal R-ate double pairing e(P,Q).e(R,S) */
	public static FP48 ate2(ECP8 P1,ECP Q1,ECP8 R1,ECP S1)
	{
		FP2 f;
		BIG x=new BIG(ROM.CURVE_Bnx);
		BIG n=new BIG(x);
		FP48 lv;
		int bt;

		ECP8 P=new ECP8(P1);
		ECP Q=new ECP(Q1);

		P.affine();
		Q.affine();

		ECP8 R=new ECP8(R1);
		ECP S=new ECP(S1);

		R.affine();
		S.affine();

		BIG n3=new BIG(n);
		n3.pmul(3);
		n3.norm();

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

		ECP8 A=new ECP8();
		ECP8 B=new ECP8();
		FP48 r=new FP48(1);

		A.copy(P);
		B.copy(R);

		ECP8 MP=new ECP8();
		MP.copy(P); MP.neg();
		ECP8 MR=new ECP8();
		MR.copy(R); MR.neg();


		int nb=n3.nbits();

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

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

			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
			if (bt==1)
			{
				lv=line(A,P,Qx,Qy);
				r.smul(lv,ECP.SEXTIC_TWIST);
				lv=line(B,R,Sx,Sy);
				r.smul(lv,ECP.SEXTIC_TWIST);
			}
			if (bt==-1)
			{
				//P.neg(); 
				lv=line(A,MP,Qx,Qy);
				r.smul(lv,ECP.SEXTIC_TWIST);
				//P.neg(); 
				//R.neg();
				lv=line(B,MR,Sx,Sy);
				r.smul(lv,ECP.SEXTIC_TWIST);
				//R.neg();
			}
		}

		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
		{
			r.conj();
		}

		return r;
	}

/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
	public static FP48 fexp(FP48 m)
	{
		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
		BIG x=new BIG(ROM.CURVE_Bnx);
		FP48 r=new FP48(m);

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

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

		FP48 t0,t1,t2,t3,t4,t5,t6,t7;
/* Hard part of final exp */	
// Ghamman & Fouotsa Method

		t7=new FP48(r); t7.usqr();
		t1=t7.pow(x);

		x.fshr(1);
		t2=t1.pow(x);
		x.fshl(1);

		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3=new FP48(t1); t3.conj();
		t2.mul(t3);
		t2.mul(r);

		r.mul(t7);

		t1=t2.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}
		t3.copy(t1);
		t3.frob(f,14);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,13);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,12);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,11);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,10);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,9);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,8);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t2); t3.conj();
		t1.mul(t3);
		t3.copy(t1);
		t3.frob(f,7);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,6);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,5);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,4);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,3);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,2);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}

		t3.copy(t1);
		t3.frob(f,1);
		r.mul(t3);
		t1=t1.pow(x);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
			t1.conj();
		}
	
		r.mul(t1);
		t2.frob(f,15);
		r.mul(t2);

		r.reduce();
		return r;
	}

/* GLV method */
	public static BIG[] glv(BIG e)
	{
		BIG[] u=new BIG[2];
// -(x^8).P = (Beta.x,y)
		BIG q=new BIG(ROM.CURVE_Order);
		BIG x=new BIG(ROM.CURVE_Bnx);
		BIG x2=BIG.smul(x,x);
		x=BIG.smul(x2,x2);
		x2=BIG.smul(x,x);
		u[0]=new BIG(e);
		u[0].mod(x2);
		u[1]=new BIG(e);
		u[1].div(x2);
		u[1].rsub(q);

		return u;
	}

/* Galbraith & Scott Method */
	public static BIG[] gs(BIG e)
	{
		BIG[] u=new BIG[16];

		BIG q=new BIG(ROM.CURVE_Order);
		BIG x=new BIG(ROM.CURVE_Bnx);
		BIG w=new BIG(e);
		for (int i=0;i<15;i++)
		{
			u[i]=new BIG(w);
			u[i].mod(x);
			w.div(x);
		}
		u[15]=new BIG(w);
		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
		{
			u[1].copy(BIG.modneg(u[1],q));
			u[3].copy(BIG.modneg(u[3],q));
			u[5].copy(BIG.modneg(u[5],q));
			u[7].copy(BIG.modneg(u[7],q));
			u[9].copy(BIG.modneg(u[9],q));
			u[11].copy(BIG.modneg(u[11],q));
			u[13].copy(BIG.modneg(u[13],q));
			u[15].copy(BIG.modneg(u[15],q));
		}

		return u;
	}	

/* Multiply P by e in group G1 */
	public static ECP G1mul(ECP P,BIG e)
	{
		ECP R;
		if (USE_GLV)
		{
			//P.affine();
			R=new ECP();
			R.copy(P);
			int i,np,nn;
			ECP Q=new ECP(); 
			Q.copy(P); Q.affine();
			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();
			}
			u[0].norm();
			u[1].norm();
			R=R.mul2(u[0],Q,u[1]);
			
		}
		else
		{
			R=P.mul(e);
		}
		return R;
	}

/* Multiply P by e in group G2 */
	public static ECP8 G2mul(ECP8 P,BIG e)
	{
		ECP8 R;
		if (USE_GS_G2)
		{
			ECP8[] Q=new ECP8[16];
			FP2[] F=ECP8.frob_constants();

			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 ECP8(); Q[0].copy(P);
			for (i=1;i<16;i++)
			{
				Q[i]=new ECP8(); Q[i].copy(Q[i-1]);
				Q[i].frob(F,1);
			}
			for (i=0;i<16;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();
				}
				u[i].norm();
				//Q[i].affine();
			}

			R=ECP8.mul16(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 FP16.java */
	public static FP48 GTpow(FP48 d,BIG e)
	{
		FP48 r;
		if (USE_GS_GT)
		{
			FP48[] g=new FP48[16];
			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
			BIG q=new BIG(ROM.CURVE_Order);
			BIG t=new BIG(0);
			int i,np,nn;
			BIG[] u=gs(e);

			g[0]=new FP48(d);
			for (i=1;i<16;i++)
			{
				g[i]=new FP48(0); g[i].copy(g[i-1]);
				g[i].frob(f,1);
			}
			for (i=0;i<16;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();
				}
				u[i].norm();
			}
			r=FP48.pow16(g,u);
		}
		else
		{
			r=d.pow(e);
		}
		return r;
	}


}

