/* Pollards kangaroos used to return PIN error */ public static int KANGAROO(sbyte[] E, sbyte[] F) { FP12 ge = FP12.fromBytes(E); FP12 gf = FP12.fromBytes(F); int[] distance = new int[TS]; FP12 t = new FP12(gf); FP12[] table = new FP12[TS]; int i, j, m, s, dn, dm, res, steps; s = 1; for (m = 0; m < TS; m++) { distance[m] = s; table[m] = new FP12(t); s *= 2; t.usqr(); } t.one(); dn = 0; for (j = 0; j < TRAP; j++) { i = t.geta().geta().A.lastbits(8) % TS; t.mul(table[i]); dn += distance[i]; } gf.copy(t); gf.conj(); steps = 0; dm = 0; res = 0; while (dm - dn < MAXPIN) { steps++; if (steps > 4 * TRAP) { break; } i = ge.geta().geta().A.lastbits(8) % TS; ge.mul(table[i]); dm += distance[i]; if (ge.Equals(t)) { res = dm - dn; break; } if (ge.Equals(gf)) { res = dn - dm; break; } } if (steps > 4 * TRAP || dm - dn >= MAXPIN) { res = 0; } // Trap Failed - probable invalid token return(res); }
/* test group membership */ /* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */ public static bool GTmember(FP12 m) { if (m.isunity()) { return(false); } FP12 r = new FP12(m); r.conj(); r.mul(m); if (!r.isunity()) { return(false); } FP2 f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb)); r.copy(m); r.frob(f); r.frob(f); FP12 w = new FP12(r); w.frob(f); w.frob(f); w.mul(m); if (!ROM.GT_STRONG) { if (!w.Equals(r)) { return(false); } BIG x = new BIG(ROM.CURVE_Bnx); r.copy(m); w = r.pow(x); w = w.pow(x); r.copy(w); r.sqr(); r.mul(w); r.sqr(); w.copy(m); w.frob(f); } return(w.Equals(r)); }