/* Optimal R-ate pairing */ public static FP12 ate(ECP2 P, ECP Q) { FP2 f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb)); BIG x = new BIG(ROM.CURVE_Bnx); BIG n = new BIG(x); ECP2 K = new ECP2(); FP12 lv; n.pmul(6); n.dec(2); n.norm(); P.affine(); Q.affine(); FP Qx = new FP(Q.getx()); FP Qy = new FP(Q.gety()); ECP2 A = new ECP2(); FP12 r = new FP12(1); A.copy(P); int nb = n.nbits(); for (int i = nb - 2; i >= 1; i--) { lv = line(A, A, Qx, Qy); r.smul(lv); if (n.bit(i) == 1) { lv = line(A, P, Qx, Qy); r.smul(lv); } r.sqr(); } lv = line(A, A, Qx, Qy); r.smul(lv); /* R-ate fixup */ r.conj(); K.copy(P); K.frob(f); A.neg(); lv = line(A, K, Qx, Qy); r.smul(lv); K.frob(f); K.neg(); lv = line(A, K, Qx, Qy); r.smul(lv); return(r); }
/* 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); }