/* this*=c mod Modulus, where c is a small int */ public void imul(int c) { norm(); bool s = false; if (c < 0) { c = -c; s = true; } long afx = (BIG.EXCESS(x) + 1) * (c + 1) + 1; if (c < ROM.NEXCESS && afx < ROM.FEXCESS) { x.imul(c); } else { if (afx < ROM.FEXCESS) { x.pmul(c); } else { DBIG d = x.pxmul(c); x.copy(d.mod(p)); } } if (s) { neg(); } norm(); }
/* 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); }