/*
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 Fp^12 functions */
/* FP12 elements are of the form a+i.b+i^2.c */

package org.apache.milagro.amcl.FP256BN;

public final class FP12 {
	private final FP4 a;
	private final FP4 b;
	private final FP4 c;
/* reduce all components of this mod Modulus */
	public void reduce()
	{
		a.reduce();
		b.reduce();
		c.reduce();
	}
/* normalise all components of this */
	public void norm()
	{
		a.norm();
		b.norm();
		c.norm();
	}
/* test x==0 ? */
	public boolean iszilch() {
		//reduce();
		return (a.iszilch() && b.iszilch() && c.iszilch());
	}

	public void cmove(FP12 g,int d)
	{
		a.cmove(g.a,d);
		b.cmove(g.b,d);
		c.cmove(g.c,d);		
	}


/* 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(FP12 g[],int b)
	{
		int m=b>>31;
		int babs=(b^m)-m;

		babs=(babs-1)/2;

		cmove(g[0],teq(babs,0));  // conditional move
		cmove(g[1],teq(babs,1));
		cmove(g[2],teq(babs,2));
		cmove(g[3],teq(babs,3));
		cmove(g[4],teq(babs,4));
		cmove(g[5],teq(babs,5));
		cmove(g[6],teq(babs,6));
		cmove(g[7],teq(babs,7));
 
		FP12 invf=new FP12(this); 
		invf.conj();
		cmove(invf,(int)(m&1));
	}


/* test x==1 ? */
	public boolean isunity() {
		FP4 one=new FP4(1);
		return (a.equals(one) && b.iszilch() && c.iszilch());
	}
/* return 1 if x==y, else 0 */
	public boolean equals(FP12 x)
	{
		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
	}
/* extract a from this */
	public FP4 geta()
	{
		return a;
	}
/* extract b */
	public FP4 getb()
	{
		return b;
	}
/* extract c */
	public FP4 getc()
	{
		return c;
	}
/* copy this=x */
	public void copy(FP12 x)
	{
		a.copy(x.a);
		b.copy(x.b);
		c.copy(x.c);
	}
/* set this=1 */
	public void one()
	{
		a.one();
		b.zero();
		c.zero();
	}
/* this=conj(this) */
	public void conj()
	{
		a.conj();
		b.nconj();
		c.conj();
	}
/* Constructors */
	public FP12(FP4 d)
	{
		a=new FP4(d);
		b=new FP4(0);
		c=new FP4(0);
	}

	public FP12(int d)
	{
		a=new FP4(d);
		b=new FP4(0);
		c=new FP4(0);
	}

	public FP12(FP4 d,FP4 e,FP4 f)
	{
		a=new FP4(d);
		b=new FP4(e);
		c=new FP4(f);
	}

	public FP12(FP12 x)
	{
		a=new FP4(x.a);
		b=new FP4(x.b);
		c=new FP4(x.c);
	}

/* Granger-Scott Unitary Squaring */
	public void usqr()
	{
//System.out.println("Into usqr");
		FP4 A=new FP4(a);
		FP4 B=new FP4(c);
		FP4 C=new FP4(b);
		FP4 D=new FP4(0);

		a.sqr();
		D.copy(a); D.add(a);
		a.add(D);

		a.norm();
		A.nconj();

		A.add(A);
		a.add(A);
		B.sqr();
		B.times_i();

		D.copy(B); D.add(B);
		B.add(D);
		B.norm();

		C.sqr();
		D.copy(C); D.add(C);
		C.add(D);
		C.norm();

		b.conj();
		b.add(b);
		c.nconj();

		c.add(c);
		b.add(B);
		c.add(C);
//System.out.println("Out of usqr 1");
		reduce();
//System.out.println("Out of usqr 2");
	}

/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
	public void sqr()
	{
//System.out.println("Into sqr");
		FP4 A=new FP4(a);
		FP4 B=new FP4(b);
		FP4 C=new FP4(c);
		FP4 D=new FP4(a);

		A.sqr();
		B.mul(c);
		B.add(B);
	B.norm();
		C.sqr();
		D.mul(b);
		D.add(D);

		c.add(a);
		c.add(b);
	c.norm();
		c.sqr();

		a.copy(A);

		A.add(B);
		A.norm();
		A.add(C);
		A.add(D);
		A.norm();

		A.neg();
		B.times_i();
		C.times_i();

		a.add(B);

		b.copy(C); b.add(D);
		c.add(A);
//System.out.println("Out of sqr");
		norm();
	}

/* FP12 full multiplication this=this*y */
	public void mul(FP12 y)
	{
//System.out.println("Into mul");
		FP4 z0=new FP4(a);
		FP4 z1=new FP4(0);
		FP4 z2=new FP4(b);
		FP4 z3=new FP4(0);
		FP4 t0=new FP4(a);
		FP4 t1=new FP4(y.a);

		z0.mul(y.a);
		z2.mul(y.b);

		t0.add(b);
		t1.add(y.b);

	t0.norm();
	t1.norm();

		z1.copy(t0); z1.mul(t1);
		t0.copy(b); t0.add(c);

		t1.copy(y.b); t1.add(y.c);

	t0.norm();
	t1.norm();

		z3.copy(t0); z3.mul(t1);

		t0.copy(z0); t0.neg();
		t1.copy(z2); t1.neg();

		z1.add(t0);
		//z1.norm();
		b.copy(z1); b.add(t1);

		z3.add(t1);
		z2.add(t0);

		t0.copy(a); t0.add(c);
		t1.copy(y.a); t1.add(y.c);

t0.norm();
t1.norm();
	
		t0.mul(t1);
		z2.add(t0);

		t0.copy(c); t0.mul(y.c);
		t1.copy(t0); t1.neg();

//		z2.norm();
//		z3.norm();
//		b.norm();

		c.copy(z2); c.add(t1);
		z3.add(t1);
		t0.times_i();
		b.add(t0);
	z3.norm();
		z3.times_i();
		a.copy(z0); a.add(z3);
		norm();
//System.out.println("Out of mul");
	}

/* Special case of multiplication arises from special form of ATE pairing line function */
	public void smul(FP12 y,int type)
	{
//System.out.println("Into smul");

		if (type==ECP.D_TYPE)
		{
			FP4 z0=new FP4(a);
			FP4 z2=new FP4(b);
			FP4 z3=new FP4(b);
			FP4 t0=new FP4(0);
			FP4 t1=new FP4(y.a);
			z0.mul(y.a);
			z2.pmul(y.b.real());
			b.add(a);
			t1.real().add(y.b.real());

			t1.norm();
			b.norm();
			b.mul(t1);
			z3.add(c);
			z3.norm();
			z3.pmul(y.b.real());

			t0.copy(z0); t0.neg();
			t1.copy(z2); t1.neg();

			b.add(t0);

			b.add(t1);
			z3.add(t1);
			z2.add(t0);

			t0.copy(a); t0.add(c);
			t0.norm();
			z3.norm();
			t0.mul(y.a);
			c.copy(z2); c.add(t0);

			z3.times_i();
			a.copy(z0); a.add(z3);
		}
		if (type==ECP.M_TYPE)
		{
			FP4 z0=new FP4(a);
			FP4 z1=new FP4(0);
			FP4 z2=new FP4(0);
			FP4 z3=new FP4(0);
			FP4 t0=new FP4(a);
			FP4 t1=new FP4(0);
		
			z0.mul(y.a);
			t0.add(b);
			t0.norm();

			z1.copy(t0); z1.mul(y.a);
			t0.copy(b); t0.add(c);
			t0.norm();

			z3.copy(t0); //z3.mul(y.c);
			z3.pmul(y.c.getb());
			z3.times_i();

			t0.copy(z0); t0.neg();

			z1.add(t0);
			b.copy(z1); 
			z2.copy(t0);

			t0.copy(a); t0.add(c);
			t1.copy(y.a); t1.add(y.c);

			t0.norm();
			t1.norm();
	
			t0.mul(t1);
			z2.add(t0);

			t0.copy(c); 
			
			t0.pmul(y.c.getb());
			t0.times_i();

			t1.copy(t0); t1.neg();

			c.copy(z2); c.add(t1);
			z3.add(t1);
			t0.times_i();
			b.add(t0);
			z3.norm();
			z3.times_i();
			a.copy(z0); a.add(z3);
		}
		norm();
//System.out.println("Out of smul");
	}

/* this=1/this */
	public void inverse()
	{
		FP4 f0=new FP4(a);
		FP4 f1=new FP4(b);
		FP4 f2=new FP4(a);
		FP4 f3=new FP4(0);

		norm();
		f0.sqr();
		f1.mul(c);
		f1.times_i();
		f0.sub(f1);
	f0.norm();

		f1.copy(c); f1.sqr();
		f1.times_i();
		f2.mul(b);
		f1.sub(f2);
	f1.norm();

		f2.copy(b); f2.sqr();
		f3.copy(a); f3.mul(c);
		f2.sub(f3);
	f2.norm();

		f3.copy(b); f3.mul(f2);
		f3.times_i();
		a.mul(f0);
		f3.add(a);
		c.mul(f1);
		c.times_i();

		f3.add(c);
	f3.norm();
		f3.inverse();
		a.copy(f0); a.mul(f3);
		b.copy(f1); b.mul(f3);
		c.copy(f2); c.mul(f3);
	}

/* this=this^p using Frobenius */
	public void frob(FP2 f)
	{
		FP2 f2=new FP2(f);
		FP2 f3=new FP2(f);

		f2.sqr();
		f3.mul(f2);

		a.frob(f3);
		b.frob(f3);
		c.frob(f3);

		b.pmul(f);
		c.pmul(f2);
	}

/* trace function */
	public FP4 trace()
	{
		FP4 t=new FP4(0);
		t.copy(a);
		t.imul(3);
		t.reduce();
		return t;
	}

/* convert from byte array to FP12 */
	public static FP12 fromBytes(byte[] w)
	{
		BIG a,b;
		FP2 c,d;
		FP4 e,f,g;
		byte[] t=new byte[BIG.MODBYTES];

		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
		a=BIG.fromBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
		b=BIG.fromBytes(t);
		c=new FP2(a,b);

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

		e=new FP4(c,d);


		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
		a=BIG.fromBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
		b=BIG.fromBytes(t);
		c=new FP2(a,b);

		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
		a=BIG.fromBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
		b=BIG.fromBytes(t);
		d=new FP2(a,b);

		f=new FP4(c,d);


		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
		a=BIG.fromBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
		b=BIG.fromBytes(t);
		c=new FP2(a,b);

		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
		a=BIG.fromBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
		b=BIG.fromBytes(t);
		d=new FP2(a,b);

		g=new FP4(c,d);

		return new FP12(e,f,g);
	}

/* convert this to byte array */
	public void toBytes(byte[] w)
	{
		byte[] t=new byte[BIG.MODBYTES];
		a.geta().getA().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
		a.geta().getB().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
		a.getb().getA().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
		a.getb().getB().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];

		b.geta().getA().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
		b.geta().getB().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
		b.getb().getA().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
		b.getb().getB().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];

		c.geta().getA().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
		c.geta().getB().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
		c.getb().getA().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
		c.getb().getB().toBytes(t);
		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
	}

/* convert to hex string */
	public String toString() 
	{
		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
	}

/* this=this^e */ 
/* Note this is simple square and multiply, so not side-channel safe */
	public FP12 pow(BIG e)
	{
		norm();
		e.norm();
		BIG e3=new BIG(e);
		e3.pmul(3);
		e3.norm();

		FP12 w=new FP12(this);

		int nb=e3.nbits();
		for (int i=nb-2;i>=1;i--)
		{
			w.usqr();
			int bt=e3.bit(i)-e.bit(i);
			if (bt==1)
				w.mul(this);
			if (bt==-1)
			{
				conj(); w.mul(this); conj();
			}
		}
		w.reduce();
		return w;


/*
		BIG z=new BIG(e);
		FP12 r=new FP12(1);

		while (true)
		{
			int bt=z.parity();
			z.fshr(1);
			if (bt==1) r.mul(w);
			if (z.iszilch()) break;
			w.usqr();
		}
		r.reduce();
		return r; */
	}

/* constant time powering by small integer of max length bts */
	public void pinpow(int e,int bts)
	{
		int i,b;
		FP12 [] R=new FP12[2];
		R[0]=new FP12(1);
		R[1]=new FP12(this);
		for (i=bts-1;i>=0;i--)
		{
			b=(e>>i)&1;
			R[1-b].mul(R[b]);
			R[b].usqr();
		}
		this.copy(R[0]);
	}

	public FP4 compow(BIG e,BIG r)
	{
		FP12 g1=new FP12(0);
		FP12 g2=new FP12(0);
		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
		BIG q=new BIG(ROM.Modulus);

		BIG m=new BIG(q);
		m.mod(r);

		BIG a=new BIG(e);
		a.mod(m);

		BIG b=new BIG(e);
		b.div(m);

		g1.copy(this);
		g2.copy(this);

		FP4 c=g1.trace();

		if (b.iszilch())
		{
			c=c.xtr_pow(e);
			return c;
		}

		g2.frob(f);
		FP4 cp=g2.trace();
		g1.conj();
		g2.mul(g1);
		FP4 cpm1=g2.trace();
		g2.mul(g1);
		FP4 cpm2=g2.trace();

		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);

		return c;
	}

/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
// 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 FP12 pow4(FP12[] q,BIG[] u)
	{
		int i,j,nb,pb;
		FP12 [] g=new FP12[8];
		FP12 r=new FP12(1);
		FP12 p=new FP12(0);
		BIG [] t=new BIG[4];
		BIG mt=new BIG(0);
		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();
		}
		g[0]=new FP12(q[0]);  // q[0]
		g[1]=new FP12(g[0]); g[1].mul(q[1]); // q[0].q[1]
		g[2]=new FP12(g[0]); g[2].mul(q[2]); // q[0].q[2]
		g[3]=new FP12(g[1]); g[3].mul(q[2]); // q[0].q[1].q[2]
		g[4]=new FP12(q[0]); g[4].mul(q[3]); // q[0].q[3]
		g[5]=new FP12(g[1]); g[5].mul(q[3]); // q[0].q[1].q[3]
		g[6]=new FP12(g[2]); g[6].mul(q[3]); // q[0].q[2].q[3]
		g[7]=new FP12(g[3]); g[7].mul(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(g,(int)(2*w[nb-1]+1)); 
        for (i=nb-2;i>=0;i--) {
            p.usqr();
            r.select(g,(int)(2*w[i]+s[i]));
            p.mul(r);
        }

    // apply correction
        r.copy(q[0]); r.conj();   
        r.mul(p);
        p.cmove(r,pb);

 		p.reduce();
		return p;
	}              

/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
/* Timing attack secure, but not cache attack secure */
/*
	public static FP12 pow4(FP12[] q,BIG[] u)
	{
		int i,j,nb,m;
		int[] a=new int[4];
		FP12 [] g=new FP12[8];
		FP12 [] s=new FP12[2];
		FP12 c=new FP12(1);
		FP12 p=new FP12(0);
		BIG [] t=new BIG[4];
		BIG mt=new BIG(0);
		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];

		for (i=0;i<4;i++)
			t[i]=new BIG(u[i]);

		s[0]=new FP12(0);
		s[1]=new FP12(0);

		g[0]=new FP12(q[0]); s[0].copy(q[1]); s[0].conj(); g[0].mul(s[0]);
		g[1]=new FP12(g[0]);
		g[2]=new FP12(g[0]);
		g[3]=new FP12(g[0]);
		g[4]=new FP12(q[0]); g[4].mul(q[1]);
		g[5]=new FP12(g[4]);
		g[6]=new FP12(g[4]);
		g[7]=new FP12(g[4]);

		s[1].copy(q[2]); s[0].copy(q[3]); s[0].conj(); s[1].mul(s[0]);
		s[0].copy(s[1]); s[0].conj(); g[1].mul(s[0]);
		g[2].mul(s[1]);
		g[5].mul(s[0]);
		g[6].mul(s[1]);
		s[1].copy(q[2]); s[1].mul(q[3]);
		s[0].copy(s[1]); s[0].conj(); g[0].mul(s[0]);
		g[3].mul(s[1]);
		g[4].mul(s[0]);
		g[7].mul(s[1]);

// if power is even add 1 to power, and add q to correction 

		for (i=0;i<4;i++)
		{
			if (t[i].parity()==0)
			{
				t[i].inc(1); t[i].norm();
				c.mul(q[i]);
			}
			mt.add(t[i]); mt.norm();
		}
		c.conj();
		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]=(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(g[(w[nb]-1)/2]);  

		for (i=nb-1;i>=0;i--)
		{
			m=w[i]>>7;
			j=(w[i]^m)-m;  // j=abs(w[i]) 
			j=(j-1)/2;
			s[0].copy(g[j]); s[1].copy(g[j]); s[1].conj();
			p.usqr();
			p.mul(s[m&1]);
		}
		p.mul(c);  // apply correction 
		p.reduce();
		return p;
	}
*/
/*
	public static void main(String[] args) {
		BIG p=new BIG(ROM.Modulus);
		FP2 w0,w1;
		BIG a=new BIG(0);
		BIG b=new BIG(0);
		
		a.zero(); b.zero(); a.inc(1); b.inc(2);
		w0=new FP2(a,b);
		a.zero(); b.zero(); a.inc(3); b.inc(4);
		w1=new FP2(a,b);
		FP4 t0=new FP4(w0,w1);

		a.zero(); b.zero(); a.inc(5); b.inc(6);
		w0=new FP2(a,b);
		a.zero(); b.zero(); a.inc(7); b.inc(8);
		w1=new FP2(a,b);
		FP4 t1=new FP4(w0,w1);

		a.zero(); b.zero(); a.inc(9); b.inc(10);
		w0=new FP2(a,b);
		a.zero(); b.zero(); a.inc(11); b.inc(12);
		w1=new FP2(a,b);
		FP4 t2=new FP4(w0,w1);

		FP12 w=new FP12(t0,t1,t2);
		FP12 t=new FP12(w);

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

		a=new BIG(ROM_ZZZ.CURVE_Fra);
		b=new BIG(ROM_ZZZ.CURVE_Frb);

		FP2 f=new FP2(a,b);

		w.frob(f);
		System.out.println("w= "+w.toString());

		w=t.pow(p);

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

		w.inverse();

		System.out.println("1/w= "+w.toString());

		w.inverse();

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

		t.copy(w);
		w.conj();
		t.inverse();
		w.mul(t);

		System.out.println("w^(p^6-1)= "+w.toString());

		t.copy(w);
		w.frob(f);
		w.frob(f);
		w.mul(t);

		System.out.println("w^(p^6-1)(p^2+1)= "+w.toString());

		t.copy(w);

		t.inverse();
		w.conj();

		System.out.println("w= "+w.toString());
		System.out.println("t= "+t.toString());
	} */
}
