/* 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(); }
/* 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); }
/* reduce a DBIG to a BIG using the appropriate form of the modulus */ public static BIG mod(DBIG d) { BIG b; if (ROM.MODTYPE == ROM.PSEUDO_MERSENNE) { long v, tw; BIG t = d.Split(ROM.MODBITS); b = new BIG(d); unchecked { v = t.pmul((int)ROM.MConst); } tw = t.w[ROM.NLEN - 1]; t.w[ROM.NLEN - 1] &= ROM.TMASK; t.w[0] += (ROM.MConst * ((tw >> ROM.TBITS) + (v << (ROM.BASEBITS - ROM.TBITS)))); b.add(t); b.norm(); } if (ROM.MODTYPE == ROM.MONTGOMERY_FRIENDLY) { for (int i = 0; i < ROM.NLEN; i++) { d.w[ROM.NLEN + i] += d.muladd(d.w[i], ROM.MConst - 1, d.w[i], ROM.NLEN + i - 1); } b = new BIG(0); for (int i = 0; i < ROM.NLEN; i++) { b.w[i] = d.w[ROM.NLEN + i]; } b.norm(); } if (ROM.MODTYPE == ROM.NOT_SPECIAL) { BIG md = new BIG(ROM.Modulus); long m, carry; for (int i = 0; i < ROM.NLEN; i++) { if (ROM.MConst == -1) { m = (-d.w[i]) & ROM.MASK; } else { if (ROM.MConst == 1) { m = d.w[i]; } else { m = (ROM.MConst * d.w[i]) & ROM.MASK; } } carry = 0; for (int j = 0; j < ROM.NLEN; j++) { carry = d.muladd(m, md.w[j], carry, i + j); } d.w[ROM.NLEN + i] += carry; } b = new BIG(0); for (int i = 0; i < ROM.NLEN; i++) { b.w[i] = d.w[ROM.NLEN + i]; } b.norm(); } return(b); }