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

package org.apache.milagro.amcl.BLS381;

public final class ECP2 {
	private FP2 x;
	private FP2 y;
	private FP2 z;
//	private boolean INF;

/* Constructor - set this=O */
	public ECP2() {
//		INF=true;
		x=new FP2(0);
		y=new FP2(1);
		z=new FP2(0);
	}

    public ECP2(ECP2 e) {
        this.x = new FP2(e.x);
        this.y = new FP2(e.y);
        this.z = new FP2(e.z);
    }

/* Test this=O? */
	public boolean is_infinity() {
//		if (INF) return true;                    //******
		return (x.iszilch() && z.iszilch());
	}
/* copy this=P */
	public void copy(ECP2 P)
	{
		x.copy(P.x);
		y.copy(P.y);
		z.copy(P.z);
//		INF=P.INF;
	}
/* set this=O */
	public void inf() {
//		INF=true;
		x.zero();
		y.one();
		z.zero();
	}

/* Conditional move of Q to P dependant on d */
	public void cmove(ECP2 Q,int d)
	{
		x.cmove(Q.x,d);
		y.cmove(Q.y,d);
		z.cmove(Q.z,d);

	//	boolean bd;
	//	if (d==0) bd=false;
	//	else bd=true;
	//	INF^=(INF^Q.INF)&bd;
	}

/* return 1 if b==c, no branching */
	public static int teq(int b,int c)
	{
		int x=b^c;
		x-=1;  // if x=0, x now -1
		return ((x>>31)&1);
	}

/* Constant time select from pre-computed table */
	public void select(ECP2 W[],int b)
	{
		ECP2 MP=new ECP2(); 
		int m=b>>31;
		int babs=(b^m)-m;

		babs=(babs-1)/2;

		cmove(W[0],teq(babs,0));  // conditional move
		cmove(W[1],teq(babs,1));
		cmove(W[2],teq(babs,2));
		cmove(W[3],teq(babs,3));
		cmove(W[4],teq(babs,4));
		cmove(W[5],teq(babs,5));
		cmove(W[6],teq(babs,6));
		cmove(W[7],teq(babs,7));
 
		MP.copy(this);
		MP.neg();
		cmove(MP,(int)(m&1));
	}

/* Test if P == Q */
	public boolean equals(ECP2 Q) {
//		if (is_infinity() && Q.is_infinity()) return true;
//		if (is_infinity() || Q.is_infinity()) return false;


		FP2 a=new FP2(x);                            // *****
		FP2 b=new FP2(Q.x);
		a.mul(Q.z); 
		b.mul(z); 
		if (!a.equals(b)) return false;

		a.copy(y); a.mul(Q.z); 
		b.copy(Q.y); b.mul(z); 
		if (!a.equals(b)) return false;

		return true;
	}
/* set this=-this */
	public void neg() {
//		if (is_infinity()) return;
		y.norm();
		y.neg(); y.norm();
		return;
	}
/* set to Affine - (x,y,z) to (x,y) */
	public void affine() {
		if (is_infinity()) return;
		FP2 one=new FP2(1);
		if (z.equals(one))
		{
			x.reduce();
			y.reduce();
			return;
		}
		z.inverse();

		x.mul(z); x.reduce();               // *****
		y.mul(z); y.reduce();
		z.copy(one);
	}
/* extract affine x as FP2 */
	public FP2 getX()
	{
		ECP2 W=new ECP2(this);
		W.affine();
		return W.x;
	}
/* extract affine y as FP2 */
	public FP2 getY()
	{
		ECP2 W=new ECP2(this);
		W.affine();
		return W.y;
	}
/* extract projective x */
	public FP2 getx()
	{
		return x;
	}
/* extract projective y */
	public FP2 gety()
	{
		return y;
	}
/* extract projective z */
	public FP2 getz()
	{
		return z;
	}
/* convert to byte array */
	public void toBytes(byte[] b)
	{
		byte[] t=new byte[BIG.MODBYTES];
		ECP2 W=new ECP2(this);
		W.affine();
		W.x.getA().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++)
			b[i]=t[i];
		W.x.getB().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++)
			b[i+BIG.MODBYTES]=t[i];

		W.y.getA().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++)
			b[i+2*BIG.MODBYTES]=t[i];
		W.y.getB().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++)
			b[i+3*BIG.MODBYTES]=t[i];
	}
/* convert from byte array to point */
	public static ECP2 fromBytes(byte[] b)
	{
		byte[] t=new byte[BIG.MODBYTES];
		BIG ra;
		BIG rb;

		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i];
		ra=BIG.fromBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES];
		rb=BIG.fromBytes(t);
		FP2 rx=new FP2(ra,rb);

		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+2*BIG.MODBYTES];
		ra=BIG.fromBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+3*BIG.MODBYTES];
		rb=BIG.fromBytes(t);
		FP2 ry=new FP2(ra,rb);

		return new ECP2(rx,ry);
	}
/* convert this to hex string */
	public String toString() {
		ECP2 W=new ECP2(this);	
		W.affine();
		if (W.is_infinity()) return "infinity";
		return "("+W.x.toString()+","+W.y.toString()+")";
	}

/* Calculate RHS of twisted curve equation x^3+B/i */
	public static FP2 RHS(FP2 x) {
		x.norm();
		FP2 r=new FP2(x);
		r.sqr();
		FP2 b=new FP2(new BIG(ROM.CURVE_B));

		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
		{
			b.div_ip();
		}
		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
		{
			b.norm();
			b.mul_ip();
			b.norm();
		}


		r.mul(x);
		r.add(b);

		r.reduce();
		return r;
	}

/* construct this from (x,y) - but set to O if not on curve */
	public ECP2(FP2 ix,FP2 iy) {
		x=new FP2(ix);
		y=new FP2(iy);
		z=new FP2(1);
		FP2 rhs=RHS(x);
		FP2 y2=new FP2(y);
		y2.sqr();
		if (!y2.equals(rhs)) inf();
//		if (y2.equals(rhs)) INF=false;
//		else {x.zero();INF=true;}
	}

/* construct this from x - but set to O if not on curve */
	public ECP2(FP2 ix) {
		x=new FP2(ix);
		y=new FP2(1);
		z=new FP2(1);
		FP2 rhs=RHS(x);
		if (rhs.sqrt()) 
		{
			y.copy(rhs);
			//INF=false;
		}
		else {/*x.zero();INF=true;*/ inf();}
	}

/* this+=this */
	public int dbl() {
//		if (INF) return -1;      
//System.out.println("Into dbl");
		FP2 iy=new FP2(y);
		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
		{
			iy.mul_ip(); iy.norm();
		}
		FP2 t0=new FP2(y);                  //***** Change 
		t0.sqr();            
		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
		{		
			t0.mul_ip();
		}
		FP2 t1=new FP2(iy);  
		t1.mul(z);
		FP2 t2=new FP2(z);
		t2.sqr();

		z.copy(t0);
		z.add(t0); z.norm(); 
		z.add(z); 
		z.add(z); 
		z.norm();  

		t2.imul(3*ROM.CURVE_B_I); 
		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
		{
			t2.mul_ip();
			t2.norm();
		}

		FP2 x3=new FP2(t2);
		x3.mul(z); 

		FP2 y3=new FP2(t0);   

		y3.add(t2); y3.norm();
		z.mul(t1);
		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
		t0.sub(t2); t0.norm();                           //y^2-9bz^2
		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
		t1.copy(x); t1.mul(iy);						//
		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2

		x.norm(); 
		y.copy(y3); y.norm();
//System.out.println("Out of dbl");
		return 1;
	}

/* this+=Q - return 0 for add, 1 for double, -1 for O */
	public int add(ECP2 Q) {
//		if (INF)
//		{
//			copy(Q);
//			return -1;
//		}
//		if (Q.INF) return -1;
//System.out.println("Into add");
		int b=3*ROM.CURVE_B_I;
		FP2 t0=new FP2(x);
		t0.mul(Q.x);         // x.Q.x
		FP2 t1=new FP2(y);
		t1.mul(Q.y);		 // y.Q.y

		FP2 t2=new FP2(z);
		t2.mul(Q.z);
		FP2 t3=new FP2(x);
		t3.add(y); t3.norm();          //t3=X1+Y1
		FP2 t4=new FP2(Q.x);            
		t4.add(Q.y); t4.norm();			//t4=X2+Y2
		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2

		t3.sub(t4); t3.norm(); 
		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
		{		
			t3.mul_ip();  t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
		}
		t4.copy(y);                    
		t4.add(z); t4.norm();			//t4=Y1+Z1
		FP2 x3=new FP2(Q.y);
		x3.add(Q.z); x3.norm();			//x3=Y2+Z2

		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
		x3.copy(t1);					//
		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
	
		t4.sub(x3); t4.norm(); 
		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
		{	
			t4.mul_ip(); t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
		}
		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
		FP2 y3=new FP2(Q.x);				
		y3.add(Q.z); y3.norm();				// y3=X2+Z2
		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
		y3.copy(t0);
		y3.add(t2);							// y3=X1.X2+Z1+Z2
		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1

		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
		{
			t0.mul_ip(); t0.norm(); // x.Q.x
			t1.mul_ip(); t1.norm(); // y.Q.y
		}
		x3.copy(t0); x3.add(t0); 
		t0.add(x3); t0.norm();
		t2.imul(b); 	
		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
		{
			t2.mul_ip(); t2.norm();
		}
		FP2 z3=new FP2(t1); z3.add(t2); z3.norm();
		t1.sub(t2); t1.norm(); 
		y3.imul(b); 
		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
		{
			y3.mul_ip(); 
			y3.norm();
		}
		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
		y3.mul(t0); t1.mul(z3); y3.add(t1);
		t0.mul(t3); z3.mul(t4); z3.add(t0);

		x.copy(x3); x.norm(); 
		y.copy(y3); y.norm();
		z.copy(z3); z.norm();
//System.out.println("Out of add");
		return 0;
	}

/* set this-=Q */
	public int sub(ECP2 Q) {
		ECP2 NQ=new ECP2(Q);
		NQ.neg();
		int D=add(NQ);
		//Q.neg();
		//int D=add(Q);
		//Q.neg();
		return D;
	}
/* set this*=q, where q is Modulus, using Frobenius */
	public void frob(FP2 X)
	{
//		if (INF) return;
		FP2 X2=new FP2(X);

		X2.sqr();
		x.conj();
		y.conj();
		z.conj();
		z.reduce();
		x.mul(X2);

		y.mul(X2);
		y.mul(X);
	}

/* P*=e */
	public ECP2 mul(BIG e)
	{
/* fixed size windows */
		int i,b,nb,m,s,ns;
		BIG mt=new BIG();
		BIG t=new BIG();
		ECP2 P=new ECP2();
		ECP2 Q=new ECP2();
		ECP2 C=new ECP2();
		ECP2[] W=new ECP2[8];
		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];

		if (is_infinity()) return new ECP2();

		//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);
		}

/* 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+(t.nbits()+3)/4;
/* convert exponent to signed 4-bit window */
		for (i=0;i<nb;i++)
		{
			w[i]=(byte)(t.lastbits(5)-16);
			t.dec(w[i]); t.norm();
			t.fshr(4);	
		}
		w[nb]=(byte)t.lastbits(5);
	
		P.copy(W[(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;
	}

/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
// Bos & Costello https://eprint.iacr.org/2013/458.pdf
// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
// Side channel attack secure 

	public static ECP2 mul4(ECP2[] Q,BIG[] u)
	{
		int i,j,nb,pb;
		ECP2 W=new ECP2();
		ECP2 P=new ECP2();
		ECP2[] T=new ECP2[8];

		BIG mt=new BIG();
		BIG[] t=new BIG[4];

		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];

		for (i=0;i<4;i++)
		{
			t[i]=new BIG(u[i]);
			t[i].norm();
			//Q[i].affine();
		}

        T[0] = new ECP2(); T[0].copy(Q[0]);  // Q[0]
        T[1] = new ECP2(); T[1].copy(T[0]); T[1].add(Q[1]);  // Q[0]+Q[1]
        T[2] = new ECP2(); T[2].copy(T[0]); T[2].add(Q[2]);  // Q[0]+Q[2]
        T[3] = new ECP2(); T[3].copy(T[1]); T[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
        T[4] = new ECP2(); T[4].copy(T[0]); T[4].add(Q[3]);  // Q[0]+Q[3]
        T[5] = new ECP2(); T[5].copy(T[1]); T[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
        T[6] = new ECP2(); T[6].copy(T[2]); T[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
        T[7] = new ECP2(); T[7].copy(T[3]); T[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]

    // Make it odd
        pb=1-t[0].parity();
        t[0].inc(pb);
        t[0].norm();

    // Number of bits
        mt.zero();
        for (i=0;i<4;i++) {
            mt.or(t[i]); 
        }
        nb=1+mt.nbits();

    // Sign pivot 
        s[nb-1]=1;
        for (i=0;i<nb-1;i++) {
            t[0].fshr(1);
            s[i]=(byte)(2*t[0].parity()-1);
        }

    // Recoded exponent
        for (i=0; i<nb; i++) {
            w[i]=0;
            int k=1;
            for (j=1; j<4; j++) {
                byte bt=(byte)(s[i]*t[j].parity());
                t[j].fshr(1);
                t[j].dec((int)(bt)>>1);
                t[j].norm();
                w[i]+=bt*(byte)k;
                k*=2;
            }
        } 

    // Main loop
        P.select(T,(int)(2*w[nb-1]+1));  
        for (i=nb-2;i>=0;i--) {
            P.dbl();
            W.select(T,(int)(2*w[i]+s[i]));
            P.add(W);
        }

    // apply correction
        W.copy(P);   
        W.sub(Q[0]);
        P.cmove(W,pb);   
		P.affine();
		return P;
	}        


/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
/*
	public static ECP2 mul4(ECP2[] Q,BIG[] u)
	{
		int i,j,nb;
		int[] a=new int[4];
		ECP2 T=new ECP2();
		ECP2 C=new ECP2();
		ECP2 P=new ECP2();
		ECP2[] W=new ECP2[8];

		BIG mt=new BIG();
		BIG[] t=new BIG[4];

		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];

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

// 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]=(byte)(t[i].lastbits(2)-2);
				t[i].dec(a[i]); t[i].norm(); 
				t[i].fshr(1);
			}
			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
		}
		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));

		P.copy(W[(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;
	}
*/

/* needed for SOK */
	public static ECP2 mapit(byte[] h)
	{
		BIG q=new BIG(ROM.Modulus);
		BIG x=BIG.fromBytes(h);
		BIG one=new BIG(1);
		FP2 X;
		ECP2 Q;
		x.mod(q);
		while (true)
		{
			X=new FP2(one,x);
			Q=new ECP2(X);
			if (!Q.is_infinity()) break;
			x.inc(1); x.norm();
		}

		BIG Fra=new BIG(ROM.Fra);
		BIG Frb=new BIG(ROM.Frb);
		X=new FP2(Fra,Frb);

		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
		{
			X.inverse();
			X.norm();
		}

		x=new BIG(ROM.CURVE_Bnx);

/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */

		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
		{
			ECP2 T,K;

			T=new ECP2(); T.copy(Q);
			T=T.mul(x); 
			
			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
			{
				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);

		}

/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
/* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */

		if (ECP.CURVE_PAIRING_TYPE==ECP.BLS)
		{
		//	ECP2 xQ,x2Q;
		//	xQ=new ECP2();
		//	x2Q=new ECP2();

			ECP2 xQ=Q.mul(x);
			ECP2 x2Q=xQ.mul(x);

			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
			{
				xQ.neg();
			}	

			x2Q.sub(xQ);
			x2Q.sub(Q);

			xQ.sub(Q);
			xQ.frob(X);

			Q.dbl();
			Q.frob(X);
			Q.frob(X);

			Q.add(x2Q);
			Q.add(xQ);
		}
		Q.affine();
		return Q;
	}

	public static ECP2 generator()
	{
		return 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)));
	}

/*
	public static void main(String[] args) {
		BIG r=new BIG(ROM.Modulus);

		BIG Pxa=new BIG(ROM.CURVE_Pxa);
		BIG Pxb=new BIG(ROM.CURVE_Pxb);
		BIG Pya=new BIG(ROM.CURVE_Pya);
		BIG Pyb=new BIG(ROM.CURVE_Pyb);

		BIG Fra=new BIG(ROM.CURVE_Fra);
		BIG Frb=new BIG(ROM.CURVE_Frb);

		FP2 f=new FP2(Fra,Frb);

		FP2 Px=new FP2(Pxa,Pxb);
		FP2 Py=new FP2(Pya,Pyb);

		ECP2 P=new ECP2(Px,Py);

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

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

		ECP2 Q=new ECP2(Px,Py);
		Q.frob(f);
		System.out.println("Q= "+Q.toString());
	} */


}