/* this=this^e */ public FP4 Pow(BIG e) { Norm(); e.Norm(); FP4 w = new FP4(this); BIG z = new BIG(e); FP4 r = new FP4(1); while (true) { int bt = z.Parity(); z.FShr(1); if (bt == 1) { r.Mul(w); } if (z.IsZilch()) { break; } w.Sqr(); } r.Reduce(); return(r); }
/* this-=x */ public void Sub(FP4 x) { FP4 m = new FP4(x); m.Neg(); Add(m); }
/* this=this^e */ public FP4 pow(BIG e) { norm(); e.norm(); FP4 w = new FP4(this); BIG z = new BIG(e); FP4 r = new FP4(1); while (true) { int bt = z.parity(); z.fshr(1); if (bt == 1) { r.mul(w); } if (z.iszilch()) { break; } w.sqr(); } r.reduce(); return(r); }
/* this-=x */ public void sub(FP4 x) { FP4 m = new FP4(x); m.neg(); add(m); }
/* this*=y */ public void mul(FP4 y) { norm(); FP2 t1 = new FP2(a); FP2 t2 = new FP2(b); FP2 t3 = new FP2(0); FP2 t4 = new FP2(b); t1.mul(y.a); t2.mul(y.b); t3.copy(y.b); t3.add(y.a); t4.add(a); t4.mul(t3); t4.sub(t1); // t4.norm(); b.copy(t4); b.sub(t2); t2.mul_ip(); a.copy(t2); a.add(t1); norm(); }
/* 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); }
/* 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); }
/* trace function */ public FP4 Trace() { FP4 t = new FP4(0); t.Copy(a); t.IMul(3); t.Reduce(); return(t); }
/* trace function */ public FP4 trace() { FP4 t = new FP4(0); t.copy(a); t.imul(3); t.reduce(); return(t); }
/* XTR xtr_d function */ public void xtr_D() { FP4 w = new FP4(this); sqr(); w.conj(); w.add(w); sub(w); reduce(); }
/* XTR xtr_d function */ public void Xtr_D() { FP4 w = new FP4(this); Sqr(); w.Conj(); w.Add(w); w.Norm(); Sub(w); Reduce(); }
/* 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]); }
/* XTR xtr_a function */ public void xtr_A(FP4 w, FP4 y, FP4 z) { FP4 r = new FP4(w); FP4 t = new FP4(w); r.sub(y); r.pmul(a); t.add(y); t.pmul(b); t.times_i(); copy(r); add(t); add(z); norm(); }
/* 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); }
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); }
/* 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"); }
/* 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); f1.copy(c); f1.sqr(); f1.times_i(); f2.mul(b); f1.sub(f2); f2.copy(b); f2.sqr(); f3.copy(a); f3.mul(c); f2.sub(f3); 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.inverse(); a.copy(f0); a.mul(f3); b.copy(f1); b.mul(f3); c.copy(f2); c.mul(f3); }
/* this*=y */ public void Mul(FP4 y) { // norm(); FP2 t1 = new FP2(a); FP2 t2 = new FP2(b); FP2 t3 = new FP2(0); FP2 t4 = new FP2(b); t1.Mul(y.a); t2.Mul(y.b); t3.Copy(y.b); t3.Add(y.a); t4.Add(a); t3.Norm(); t4.Norm(); t4.Mul(t3); t3.Copy(t1); t3.Neg(); t4.Add(t3); t4.Norm(); // t4.sub(t1); // t4.norm(); t3.Copy(t2); t3.Neg(); b.Copy(t4); b.Add(t3); // b.copy(t4); // b.sub(t2); t2.Mul_Ip(); a.Copy(t2); a.Add(t1); Norm(); }
/* XTR xtr_a function */ public void Xtr_A(FP4 w, FP4 y, FP4 z) { FP4 r = new FP4(w); FP4 t = new FP4(w); //y.norm(); r.Sub(y); r.Norm(); r.PMul(a); t.Add(y); t.Norm(); t.PMul(b); t.Times_I(); Copy(r); Add(t); Add(z); Norm(); }
/* Special case of multiplication arises from special form of ATE pairing line function */ public void smul(FP12 y) { 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()); b.mul(t1); z3.add(c); z3.pmul(y.b.real()); t0.copy(z0); t0.neg(); t1.copy(z2); t1.neg(); b.add(t0); // b.norm(); b.add(t1); z3.add(t1); z2.add(t0); t0.copy(a); t0.add(c); t0.mul(y.a); c.copy(z2); c.add(t0); z3.times_i(); a.copy(z0); a.add(z3); norm(); }
/* 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(); }
/* Granger-Scott Unitary Squaring */ public void 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); reduce(); }
/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */ public void 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); C.sqr(); D.mul(b); D.add(D); c.add(a); c.add(b); 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); norm(); }
/* test this=x? */ public bool Equals(FP4 x) { return(a.Equals(x.a) && b.Equals(x.b)); }
public void CMove(FP4 g, int d) { a.CMove(g.a, d); b.CMove(g.b, d); }
/* 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=x-this */ public void RSub(FP4 x) { Neg(); Add(x); }
/* this+=x */ public void Add(FP4 x) { a.Add(x.a); b.Add(x.b); }
/* copy this=x */ public void Copy(FP4 x) { a.Copy(x.a); b.Copy(x.b); }
public FP4(FP4 x) { a = new FP2(x.a); b = new FP2(x.b); }