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

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

/* Test this=O? */
	public boolean is_infinity() {
		return INF;
	}
/* 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.zero();
		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 zs2=new FP2(z); zs2.sqr();
		FP2 zo2=new FP2(Q.z); zo2.sqr();
		FP2 zs3=new FP2(zs2); zs3.mul(z);
		FP2 zo3=new FP2(zo2); zo3.mul(Q.z);
		zs2.mul(Q.x);
		zo2.mul(x);
		if (!zs2.equals(zo2)) return false;
		zs3.mul(Q.y);
		zo3.mul(y);
		if (!zs3.equals(zo3)) return false;

		return true;
	}
/* set this=-this */
	public void neg() {
		if (is_infinity()) return;
		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)) return;
		z.inverse();

		FP2 z2=new FP2(z);
		z2.sqr();
		x.mul(z2); x.reduce();
		y.mul(z2);
		y.mul(z);  y.reduce();
		z.copy(one);
	}
/* extract affine x as FP2 */
	public FP2 getX()
	{
		affine();
		return x;
	}
/* extract affine y as FP2 */
	public FP2 getY()
	{
		affine();
		return 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[ROM.MODBYTES];
		affine();
		x.getA().toBytes(t);
		for (int i=0;i<ROM.MODBYTES;i++)
			b[i]=t[i];
		x.getB().toBytes(t);
		for (int i=0;i<ROM.MODBYTES;i++)
			b[i+ROM.MODBYTES]=t[i];

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

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

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

		return new ECP2(rx,ry);
	}
/* convert this to hex string */
	public String toString() {
		if (is_infinity()) return "infinity";
		affine();
		return "("+x.toString()+","+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));
		b.div_ip();
		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=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;}
	}

/* this+=this */
	public int dbl() {
		if (INF) return -1;
		if (y.iszilch())
		{
			inf();
			return -1;
		}

		FP2 w1=new FP2(x);
		FP2 w2=new FP2(0);
		FP2 w3=new FP2(x);
		FP2 w8=new FP2(x);

		w1.sqr();
		w8.copy(w1);
		w8.imul(3);

		w2.copy(y); w2.sqr();
		w3.copy(x); w3.mul(w2);
		w3.imul(4);
		w1.copy(w3); w1.neg();
		w1.norm();

		x.copy(w8); x.sqr();
		x.add(w1);
		x.add(w1);
		x.norm();

		z.mul(y);
		z.add(z);

		w2.add(w2);
		w2.sqr();
		w2.add(w2);
		w3.sub(x);
		y.copy(w8); y.mul(w3);
		w2.norm();
		y.sub(w2);
		y.norm();
		z.norm();

		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;

		boolean aff=false;

		if (Q.z.isunity()) aff=true;

		FP2 A,C;
		FP2 B=new FP2(z);
		FP2 D=new FP2(z);
		if (!aff)
		{
			A=new FP2(Q.z);
			C=new FP2(Q.z);

			A.sqr(); B.sqr();
			C.mul(A); D.mul(B);

			A.mul(x);
			C.mul(y);
		}
		else
		{
			A=new FP2(x);
			C=new FP2(y);

			B.sqr();
			D.mul(B);
		}

		B.mul(Q.x); B.sub(A);
		D.mul(Q.y); D.sub(C);

		if (B.iszilch())
		{
			if (D.iszilch())
			{
				dbl();
				return 1;
			}
			else
			{
				INF=true;
				return -1;
			}
		}

		if (!aff) z.mul(Q.z);
		z.mul(B);

		FP2 e=new FP2(B); e.sqr();
		B.mul(e);
		A.mul(e);

		e.copy(A);
		e.add(A); e.add(B);
		x.copy(D); x.sqr(); x.sub(e);

		A.sub(x);
		y.copy(A); y.mul(D);
		C.mul(B); y.sub(C);

		x.norm();
		y.norm();
		z.norm();

		return 0;
	}

/* set this-=Q */
	public int sub(ECP2 Q) {
		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);
	}

/* normalises m-array of ECP2 points. Requires work vector of m FP2s */

	public static void multiaffine(int m,ECP2[] P)
	{
		int i;
		FP2 t1=new FP2(0);
		FP2 t2=new FP2(0);

		FP2[] work=new FP2[m];
		work[0]=new FP2(1);
		work[1]=new FP2(P[0].z);
		for (i=2;i<m;i++)
		{
			work[i]=new FP2(work[i-1]);
			work[i].mul(P[i-1].z);
		}

		t1.copy(work[m-1]); t1.mul(P[m-1].z);

		t1.inverse();

		t2.copy(P[m-1].z);
		work[m-1].mul(t1);

		for (i=m-2;;i--)
		{
			if (i==0)
			{
				work[0].copy(t1);
				work[0].mul(t2);
				break;
			}
			work[i].mul(t2);
			work[i].mul(t1);
			t2.mul(P[i].z);
		}
/* now work[] contains inverses of all Z coordinates */

		for (i=0;i<m;i++)
		{
			P[i].z.one();
			t1.copy(work[i]); t1.sqr();
			P[i].x.mul(t1);
			t1.mul(work[i]);
			P[i].y.mul(t1);
		}
	}

/* 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+(ROM.NLEN*ROM.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);
		}

/* convert the table to affine */

		multiaffine(8,W);

/* 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 */
	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[ROM.NLEN*ROM.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);

		multiaffine(8,W);

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

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


}
