/* 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); }
/* XTR xtr_d function */ public void Xtr_D() { FP4 w = new FP4(this); Sqr(); w.Conj(); w.Add(w); w.Norm(); Sub(w); Reduce(); }
/* 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); }
/* this=conj(this) */ public void Conj() { a.Conj(); b.NConj(); c.Conj(); }