示例#1
0
/* 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);
    }
示例#2
0
/* 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));
    }
示例#3
0
/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
/* Timing attack secure, but not cache attack secure */

    public static FP12 pow4(FP12[] q, BIG[] u)
    {
        int i, j, nb, m;

        int[]  a = new int[4];
        FP12[] g = new FP12[8];
        FP12[] s = new FP12[2];
        FP12   c = new FP12(1);
        FP12   p = new FP12(0);

        BIG[] t  = new BIG[4];
        BIG   mt = new BIG(0);

        sbyte[] w = new sbyte[ROM.NLEN * ROM.BASEBITS + 1];

        for (i = 0; i < 4; i++)
        {
            t[i] = new BIG(u[i]);
        }

        s[0] = new FP12(0);
        s[1] = new FP12(0);

        g[0] = new FP12(q[0]);
        s[0].copy(q[1]);
        s[0].conj();
        g[0].mul(s[0]);
        g[1] = new FP12(g[0]);
        g[2] = new FP12(g[0]);
        g[3] = new FP12(g[0]);
        g[4] = new FP12(q[0]);
        g[4].mul(q[1]);
        g[5] = new FP12(g[4]);
        g[6] = new FP12(g[4]);
        g[7] = new FP12(g[4]);

        s[1].copy(q[2]);
        s[0].copy(q[3]);
        s[0].conj();
        s[1].mul(s[0]);
        s[0].copy(s[1]);
        s[0].conj();
        g[1].mul(s[0]);
        g[2].mul(s[1]);
        g[5].mul(s[0]);
        g[6].mul(s[1]);
        s[1].copy(q[2]);
        s[1].mul(q[3]);
        s[0].copy(s[1]);
        s[0].conj();
        g[0].mul(s[0]);
        g[3].mul(s[1]);
        g[4].mul(s[0]);
        g[7].mul(s[1]);

/* if power is even add 1 to power, and add q to correction */

        for (i = 0; i < 4; i++)
        {
            if (t[i].parity() == 0)
            {
                t[i].inc(1);
                t[i].norm();
                c.mul(q[i]);
            }
            mt.add(t[i]);
            mt.norm();
        }
        c.conj();
        nb = 1 + mt.nbits();

/* convert exponent to signed 1-bit window */
        for (j = 0; j < nb; j++)
        {
            for (i = 0; i < 4; i++)
            {
                a[i] = (t[i].lastbits(2) - 2);
                t[i].dec(a[i]);
                t[i].norm();
                t[i].fshr(1);
            }
            w[j] = (sbyte)(8 * a[0] + 4 * a[1] + 2 * a[2] + a[3]);
        }
        w[nb] = (sbyte)(8 * t[0].lastbits(2) + 4 * t[1].lastbits(2) + 2 * t[2].lastbits(2) + t[3].lastbits(2));
        p.copy(g[(w[nb] - 1) / 2]);

        for (i = nb - 1; i >= 0; i--)
        {
            m = w[i] >> 7;
            j = (w[i] ^ m) - m;             // j=abs(w[i])
            j = (j - 1) / 2;
            s[0].copy(g[j]);
            s[1].copy(g[j]);
            s[1].conj();
            p.usqr();
            p.mul(s[m & 1]);
        }
        p.mul(c);         // apply correction
        p.reduce();
        return(p);
    }
示例#4
0
/* calculate common key on client side */
/* wCID = w.(A+AT) */
    public static int CLIENT_KEY(sbyte[] G1, sbyte[] G2, int pin, sbyte[] R, sbyte[] X, sbyte[] wCID, sbyte[] CK)
    {
        HASH H = new HASH();

        sbyte[] t = new sbyte[EFS];

        FP12 g1 = FP12.fromBytes(G1);
        FP12 g2 = FP12.fromBytes(G2);
        BIG  z  = BIG.fromBytes(R);
        BIG  x  = BIG.fromBytes(X);

        ECP W = ECP.fromBytes(wCID);

        if (W.is_infinity())
        {
            return(INVALID_POINT);
        }

        W = PAIR.G1mul(W, x);

        FP2 f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb));
        BIG r = new BIG(ROM.CURVE_Order);
        BIG q = new BIG(ROM.Modulus);

        BIG m = new BIG(q);

        m.mod(r);

        BIG a = new BIG(z);

        a.mod(m);

        BIG b = new BIG(z);

        b.div(m);

        g2.pinpow(pin, PBLEN);
        g1.mul(g2);

        FP4 c = g1.trace();

        g2.copy(g1);
        g2.frob(f);
        FP4 cp = g2.trace();

        g1.conj();
        g2.mul(g1);
        FP4 cpm1 = g2.trace();

        g2.mul(g1);
        FP4 cpm2 = g2.trace();

        c = c.xtr_pow2(cp, cpm1, cpm2, a, b);

        c.geta().A.toBytes(t);
        H.process_array(t);
        c.geta().B.toBytes(t);
        H.process_array(t);
        c.getb().A.toBytes(t);
        H.process_array(t);
        c.getb().B.toBytes(t);
        H.process_array(t);

        W.X.toBytes(t);
        H.process_array(t);
        W.Y.toBytes(t);
        H.process_array(t);

        t = H.hash();
        for (int i = 0; i < PAS; i++)
        {
            CK[i] = t[i];
        }

        return(0);
    }
示例#5
0
/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
    public static FP12 fexp(FP12 m)
    {
        FP2  f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb));
        BIG  x = new BIG(ROM.CURVE_Bnx);
        FP12 r = new FP12(m);
        FP12 x0, x1, x2, x3, x4, x5;

/* Easy part of final exp */
        FP12 lv = new FP12(r);

        lv.inverse();
        r.conj();

        r.mul(lv);
        lv.copy(r);
        r.frob(f);
        r.frob(f);
        r.mul(lv);
/* Hard part of final exp */
        lv.copy(r);
        lv.frob(f);
        x0 = new FP12(lv);
        x0.frob(f);
        lv.mul(r);
        x0.mul(lv);
        x0.frob(f);
        x1 = new FP12(r);
        x1.conj();
        x4 = r.pow(x);

        x3 = new FP12(x4);
        x3.frob(f);

        x2 = x4.pow(x);

        x5 = new FP12(x2);
        x5.conj();
        lv = x2.pow(x);

        x2.frob(f);
        r.copy(x2);
        r.conj();

        x4.mul(r);
        x2.frob(f);

        r.copy(lv);
        r.frob(f);
        lv.mul(r);

        lv.usqr();
        lv.mul(x4);
        lv.mul(x5);
        r.copy(x3);
        r.mul(x5);
        r.mul(lv);
        lv.mul(x2);
        r.usqr();
        r.mul(lv);
        r.usqr();
        lv.copy(r);
        lv.mul(x1);
        r.mul(x0);
        lv.usqr();
        r.mul(lv);
        r.reduce();
        return(r);
    }