/* r=x^n using XTR method on traces of FP12s */ public FP4 Xtr_Pow(BIG n) { FP4 a = new FP4(3); FP4 b = new FP4(this); FP4 c = new FP4(b); c.Xtr_D(); FP4 t = new FP4(0); FP4 r = new FP4(0); n.Norm(); int par = n.Parity(); BIG v = new BIG(n); v.FShr(1); if (par == 0) { v.Dec(1); v.Norm(); } int nb = v.NBits(); for (int i = nb - 1; i >= 0; i--) { if (v.Bit(i) != 1) { t.Copy(b); Conj(); c.Conj(); b.Xtr_A(a, this, c); Conj(); c.Copy(t); c.Xtr_D(); a.Xtr_D(); } else { t.Copy(a); t.Conj(); a.Copy(b); a.Xtr_D(); b.Xtr_A(c, this, t); c.Xtr_D(); } } if (par == 0) { r.Copy(c); } else { r.Copy(b); } r.Reduce(); return(r); }
/* 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); }
/* trace function */ public FP4 Trace() { FP4 t = new FP4(0); t.Copy(a); t.IMul(3); t.Reduce(); return(t); }
/* 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"); }
/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */ public FP4 Xtr_Pow2(FP4 ck, FP4 ckml, FP4 ckm2l, BIG a, BIG b) { a.Norm(); b.Norm(); BIG e = new BIG(a); BIG d = new BIG(b); BIG w = new BIG(0); FP4 cu = new FP4(ck); // can probably be passed in w/o copying FP4 cv = new FP4(this); FP4 cumv = new FP4(ckml); FP4 cum2v = new FP4(ckm2l); FP4 r = new FP4(0); FP4 t = new FP4(0); int f2 = 0; while (d.Parity() == 0 && e.Parity() == 0) { d.FShr(1); e.FShr(1); f2++; } while (BIG.Comp(d, e) != 0) { if (BIG.Comp(d, e) > 0) { w.Copy(e); w.IMul(4); w.Norm(); if (BIG.Comp(d, w) <= 0) { w.Copy(d); d.Copy(e); e.RSub(w); e.Norm(); t.Copy(cv); t.Xtr_A(cu, cumv, cum2v); cum2v.Copy(cumv); cum2v.Conj(); cumv.Copy(cv); cv.Copy(cu); cu.Copy(t); } else if (d.Parity() == 0) { d.FShr(1); r.Copy(cum2v); r.Conj(); t.Copy(cumv); t.Xtr_A(cu, cv, r); cum2v.Copy(cumv); cum2v.Xtr_D(); cumv.Copy(t); cu.Xtr_D(); } else if (e.Parity() == 1) { d.Sub(e); d.Norm(); d.FShr(1); t.Copy(cv); t.Xtr_A(cu, cumv, cum2v); cu.Xtr_D(); cum2v.Copy(cv); cum2v.Xtr_D(); cum2v.Conj(); cv.Copy(t); } else { w.Copy(d); d.Copy(e); d.FShr(1); e.Copy(w); t.Copy(cumv); t.Xtr_D(); cumv.Copy(cum2v); cumv.Conj(); cum2v.Copy(t); cum2v.Conj(); t.Copy(cv); t.Xtr_D(); cv.Copy(cu); cu.Copy(t); } } if (BIG.Comp(d, e) < 0) { w.Copy(d); w.IMul(4); w.Norm(); if (BIG.Comp(e, w) <= 0) { e.Sub(d); e.Norm(); t.Copy(cv); t.Xtr_A(cu, cumv, cum2v); cum2v.Copy(cumv); cumv.Copy(cu); cu.Copy(t); } else if (e.Parity() == 0) { w.Copy(d); d.Copy(e); d.FShr(1); e.Copy(w); t.Copy(cumv); t.Xtr_D(); cumv.Copy(cum2v); cumv.Conj(); cum2v.Copy(t); cum2v.Conj(); t.Copy(cv); t.Xtr_D(); cv.Copy(cu); cu.Copy(t); } else if (d.Parity() == 1) { w.Copy(e); e.Copy(d); w.Sub(d); w.Norm(); d.Copy(w); d.FShr(1); t.Copy(cv); t.Xtr_A(cu, cumv, cum2v); cumv.Conj(); cum2v.Copy(cu); cum2v.Xtr_D(); cum2v.Conj(); cu.Copy(cv); cu.Xtr_D(); cv.Copy(t); } else { d.FShr(1); r.Copy(cum2v); r.Conj(); t.Copy(cumv); t.Xtr_A(cu, cv, r); cum2v.Copy(cumv); cum2v.Xtr_D(); cumv.Copy(t); cu.Xtr_D(); } } } r.Copy(cv); r.Xtr_A(cu, cumv, cum2v); for (int i = 0; i < f2; i++) { r.Xtr_D(); } r = r.Xtr_Pow(d); return(r); }
/* 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"); }
/* 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"); }
/* copy this=x */ public void Copy(FP12 x) { a.Copy(x.a); b.Copy(x.b); c.Copy(x.c); }