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

public final class PAIR192 {

//	public static final boolean GT_STRONG=false;


/* Line function */
	public static FP24 line(ECP4 A,ECP4 B,FP Qx,FP Qy)
	{
		FP8 a,b,c;                            
		if (A==B)
		{ // Doubling
			FP4 XX=new FP4(A.getx());  //X
			FP4 YY=new FP4(A.gety());  //Y
			FP4 ZZ=new FP4(A.getz());  //Z
			FP4 YZ=new FP4(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.qmul(Qy);               //-2YZ.Ys

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

			int sb=3*ROM.CURVE_B_I;
			ZZ.imul(sb); 	
			
			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.D_TYPE)
			{
				ZZ.div_2i();
			}
			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.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 FP8(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.D_TYPE)
			{			
				b=new FP8(XX);             // L(0,1) | L(0,0) | L(1,0)
				c=new FP8();
			}
			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
			{
				b=new FP8();
				c=new FP8(XX); c.times_i();
			}
			A.dbl();
		}
		else
		{ // Addition - assume B is affine

			FP4 X1=new FP4(A.getx());    // X1
			FP4 Y1=new FP4(A.gety());    // Y1
			FP4 T1=new FP4(A.getz());    // Z1
			FP4 T2=new FP4(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.qmul(Qy);            // X1=(X1-Z1.X2).Ys

			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.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.qmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs

			a=new FP8(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.D_TYPE)
			{
				b=new FP8(Y1);
				c=new FP8();
			}
			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
			{
				b=new FP8();
				c=new FP8(Y1); c.times_i();
			}
			A.add(B);
		}
		FP24 r=new FP24(a,b,c);
		r.settype(FP24.SPARSER);
		return r;
	}

/* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
	public static int lbits(BIG n3,BIG n)
	{
		n.copy(new BIG(ROM.CURVE_Bnx));
		n3.copy(n);
		n3.pmul(3);
		n3.norm();
		return n3.nbits();
	}

/* prepare for multi-pairing */
	public static FP24[] initmp()
	{
		FP24[] r=new FP24[CONFIG_CURVE.ATE_BITS];
		for (int i=CONFIG_CURVE.ATE_BITS-1; i>=0; i--)
			r[i]=new FP24(1);
		return r;
	}

/* basic Miller loop */
	public static FP24 miller(FP24[] r)
	{
		FP24 res=new FP24(1);
		for (int i=CONFIG_CURVE.ATE_BITS-1; i>=1; i--)
		{
			res.sqr();
			res.ssmul(r[i]); 
		}

		if (CONFIG_CURVE.SIGN_OF_X==CONFIG_CURVE.NEGATIVEX)
			res.conj();
		res.ssmul(r[0]);

		return res;
	}

/* Accumulate another set of line functions for n-pairing */
	public static void another(FP24[] r,ECP4 P1,ECP Q1)
	{
		FP2 f;
		BIG n=new BIG(0);
		BIG n3=new BIG(0);
		FP24 lv,lv2;
		int bt;

// P is needed in affine form for line function, Q for (Qx,Qy) extraction
		ECP4 P=new ECP4(P1);
		ECP Q=new ECP(Q1);

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

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

		ECP4 A=new ECP4();
		A.copy(P);

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

		int nb=lbits(n3,n);

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

			bt=n3.bit(i)-n.bit(i); 
			if (bt==1)
			{
				lv2=line(A,P,Qx,Qy);
				lv.smul(lv2);
			}
			if (bt==-1)
			{
				lv2=line(A,MP,Qx,Qy);
				lv.smul(lv2);
			}
			r[i].ssmul(lv);
		}

	}

/* Optimal R-ate pairing */
	public static FP24 ate(ECP4 P1,ECP Q1)
	{
		FP2 f;
		BIG n=new BIG(0);
		BIG n3=new BIG(0);
		FP24 lv,lv2;
		int bt;
		
		ECP4 P=new ECP4(P1);
		ECP Q=new ECP(Q1);

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

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

		ECP4 A=new ECP4();
		FP24 r=new FP24(1);
		A.copy(P);

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

		int nb=lbits(n3,n);

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

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

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

		return r;
	}

/* Optimal R-ate double pairing e(P,Q).e(R,S) */
	public static FP24 ate2(ECP4 P1,ECP Q1,ECP4 R1,ECP S1)
	{
		FP2 f;
		BIG n=new BIG(0);
		BIG n3=new BIG(0);
		FP24 lv,lv2;
		int bt;

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

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

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

		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());

		ECP4 A=new ECP4();
		ECP4 B=new ECP4();
		FP24 r=new FP24(1);

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

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


		int nb=lbits(n3,n);

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

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

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

		return r;
	}

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

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

		r.mul(lv);
		lv.copy(r);
		r.frob(f,4);
		r.mul(lv);
		if (r.isunity())
		{
			r.zero();
			return r;
		}
		FP24 t0,t1,t2,t3,t4,t5,t6,t7;
/* Hard part of final exp */	
// Ghamman & Fouotsa Method

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

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

		if (CONFIG_CURVE.SIGN_OF_X==CONFIG_CURVE.NEGATIVEX) {
			t1.conj();
		}
		t3=new FP24(t1); t3.conj();
		t2.mul(t3);
		t2.mul(r);

		t3=t2.pow(x);
		t4=t3.pow(x);
		t5=t4.pow(x);

		if (CONFIG_CURVE.SIGN_OF_X==CONFIG_CURVE.NEGATIVEX) {
			t3.conj(); t5.conj();
		}

		t3.frob(f,6); t4.frob(f,5);
		t3.mul(t4);

		t6=t5.pow(x);
		if (CONFIG_CURVE.SIGN_OF_X==CONFIG_CURVE.NEGATIVEX) {
			t6.conj();
		}

		t5.frob(f,4);
		t3.mul(t5);

		t0=new FP24(t2); t0.conj();
		t6.mul(t0);

		t5.copy(t6);
		t5.frob(f,3);

		t3.mul(t5);
		t5=t6.pow(x);
		t6=t5.pow(x);

		if (CONFIG_CURVE.SIGN_OF_X==CONFIG_CURVE.NEGATIVEX) {
			t5.conj();
		}

		t0.copy(t5);
		t0.frob(f,2);
		t3.mul(t0);
		t0.copy(t6);
		t0.frob(f,1);

		t3.mul(t0);
		t5=t6.pow(x);

		if (CONFIG_CURVE.SIGN_OF_X==CONFIG_CURVE.NEGATIVEX) {
			t5.conj();
		}
		t2.frob(f,7);

		t5.mul(t7);
		t3.mul(t2);
		t3.mul(t5);

		r.mul(t3);

		r.reduce();
		return r;
	}

/* GLV method */
	public static BIG[] glv(BIG e)
	{
		BIG[] u=new BIG[2];
// -(x^4).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);
		u[0]=new BIG(e);
		u[0].mod(x);
		u[1]=new BIG(e);
		u[1].div(x);
		u[1].rsub(q);

		return u;
	}

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

		BIG q=new BIG(ROM.CURVE_Order);
		BIG x=new BIG(ROM.CURVE_Bnx);
		BIG w=new BIG(e);
		for (int i=0;i<7;i++)
		{
			u[i]=new BIG(w);
			u[i].mod(x);
			w.div(x);
		}
		u[7]=new BIG(w);
		if (CONFIG_CURVE.SIGN_OF_X==CONFIG_CURVE.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));
		}

		return u;
	}	

/* Multiply P by e in group G1 */
	public static ECP G1mul(ECP P,BIG e)
	{
		ECP R;
		if (CONFIG_CURVE.USE_GLV)
		{
			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 ECP4 G2mul(ECP4 P,BIG e)
	{
		ECP4 R;
		if (CONFIG_CURVE.USE_GS_G2)
		{
			ECP4[] Q=new ECP4[8];
			FP2[] F=ECP4.frob_constants();

			BIG q=new BIG(ROM.CURVE_Order);
			BIG[] u=gs(e);

			BIG t=new BIG(0);
			int i,np,nn;

			Q[0]=new ECP4(); Q[0].copy(P);
			for (i=1;i<8;i++)
			{
				Q[i]=new ECP4(); Q[i].copy(Q[i-1]);
				Q[i].frob(F,1);
			}
			for (i=0;i<8;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();
			}

			R=ECP4.mul8(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 FP8.java */
	public static FP24 GTpow(FP24 d,BIG e)
	{
		FP24 r;
		if (CONFIG_CURVE.USE_GS_GT)
		{
			FP24[] g=new FP24[8];
			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 FP24(d);
			for (i=1;i<8;i++)
			{
				g[i]=new FP24(); g[i].copy(g[i-1]);
				g[i].frob(f,1);
			}
			for (i=0;i<8;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=FP24.pow8(g,u);
		}
		else
		{
			r=d.pow(e);
		}
		return r;
	}

}

