/* Multiply P by e in group G1 */ public static ECP G1mul(ECP P, BIG e) { ECP R; if (ROM.USE_GLV) { P.affine(); R = new ECP(); R.copy(P); int i, np, nn; ECP Q = new ECP(); Q.copy(P); BIG q = new BIG(ROM.CURVE_Order); FP cru = new FP(new BIG(ROM.CURVE_Cru)); BIG t = new BIG(0); BIG[] u = glv(e); Q.getx().mul(cru); np = u[0].nbits(); t.copy(BIG.modneg(u[0], q)); nn = t.nbits(); if (nn < np) { u[0].copy(t); R.neg(); } np = u[1].nbits(); t.copy(BIG.modneg(u[1], q)); nn = t.nbits(); if (nn < np) { u[1].copy(t); Q.neg(); } R = R.mul2(u[0], Q, u[1]); } else { R = P.mul(e); } return(R); }
/* Multiply P by e in group G2 */ public static ECP2 G2mul(ECP2 P, BIG e) { ECP2 R; if (ROM.USE_GS_G2) { ECP2[] Q = new ECP2[4]; FP2 f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb)); BIG q = new BIG(ROM.CURVE_Order); BIG[] u = gs(e); BIG t = new BIG(0); int i, np, nn; P.affine(); Q[0] = new ECP2(); Q[0].copy(P); for (i = 1; i < 4; i++) { Q[i] = new ECP2(); Q[i].copy(Q[i - 1]); Q[i].frob(f); } for (i = 0; i < 4; i++) { np = u[i].nbits(); t.copy(BIG.modneg(u[i], q)); nn = t.nbits(); if (nn < np) { u[i].copy(t); Q[i].neg(); } } R = ECP2.mul4(Q, u); } else { R = P.mul(e); } return(R); }
/* f=f^e */ /* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */ public static FP12 GTpow(FP12 d, BIG e) { FP12 r; if (ROM.USE_GS_GT) { FP12[] g = new FP12[4]; FP2 f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb)); BIG q = new BIG(ROM.CURVE_Order); BIG t = new BIG(0); int i, np, nn; BIG[] u = gs(e); g[0] = new FP12(d); for (i = 1; i < 4; i++) { g[i] = new FP12(0); g[i].copy(g[i - 1]); g[i].frob(f); } for (i = 0; i < 4; i++) { np = u[i].nbits(); t.copy(BIG.modneg(u[i], q)); nn = t.nbits(); if (nn < np) { u[i].copy(t); g[i].conj(); } } r = FP12.pow4(g, u); } else { r = d.pow(e); } return(r); }