Пример #1
0
/* r=x^n using XTR method on traces of FP12s */
    public FP4 xtr_pow(BIG n)
    {
        FP4 a = new FP4(3);
        FP4 b = new FP4(this);
        FP4 c = new FP4(b);

        c.xtr_D();
        FP4 t = new FP4(0);
        FP4 r = new FP4(0);

        n.norm();
        int par = n.parity();
        BIG v   = new BIG(n);

        v.fshr(1);
        if (par == 0)
        {
            v.dec(1);
            v.norm();
        }

        int nb = v.nbits();

        for (int i = nb - 1; i >= 0; i--)
        {
            if (v.bit(i) != 1)
            {
                t.copy(b);
                conj();
                c.conj();
                b.xtr_A(a, this, c);
                conj();
                c.copy(t);
                c.xtr_D();
                a.xtr_D();
            }
            else
            {
                t.copy(a);
                t.conj();
                a.copy(b);
                a.xtr_D();
                b.xtr_A(c, this, t);
                c.xtr_D();
            }
        }
        if (par == 0)
        {
            r.copy(c);
        }
        else
        {
            r.copy(b);
        }
        r.reduce();
        return(r);
    }
Пример #2
0
/* 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);
    }
Пример #3
0
/* 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);
    }
Пример #4
0
/* 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);
    }
Пример #5
0
/* 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);
    }
Пример #6
0
/* return e.this */

    public ECP mul(BIG e)
    {
        if (e.iszilch() || is_infinity())
        {
            return(new ECP());
        }
        ECP P = new ECP();

        if (ROM.CURVETYPE == ROM.MONTGOMERY)
        {
/* use Ladder */
            int nb, i, b;
            ECP D  = new ECP();
            ECP R0 = new ECP();
            R0.copy(this);
            ECP R1 = new ECP();
            R1.copy(this);
            R1.dbl();
            D.copy(this);
            D.affine();
            nb = e.nbits();
            for (i = nb - 2; i >= 0; i--)
            {
                b = e.bit(i);
                P.copy(R1);
                P.dadd(R0, D);
                R0.cswap(R1, b);
                R1.copy(P);
                R0.dbl();
                R0.cswap(R1, b);
            }
            P.copy(R0);
        }
        else
        {
// fixed size windows
            int     i, b, nb, m, s, ns;
            BIG     mt = new BIG();
            BIG     t  = new BIG();
            ECP     Q  = new ECP();
            ECP     C  = new ECP();
            ECP[]   W  = new ECP[8];
            sbyte[] w  = new sbyte[1 + (ROM.NLEN * ROM.BASEBITS + 3) / 4];

            affine();

// precompute table
            Q.copy(this);
            Q.dbl();
            W[0] = new ECP();
            W[0].copy(this);

            for (i = 1; i < 8; i++)
            {
                W[i] = new ECP();
                W[i].copy(W[i - 1]);
                W[i].add(Q);
            }

// convert the table to affine
            if (ROM.CURVETYPE == ROM.WEIERSTRASS)
            {
                multiaffine(8, W);
            }

// make exponent odd - add 2P if even, P if odd
            t.copy(e);
            s = t.parity();
            t.inc(1);
            t.norm();
            ns = t.parity();
            mt.copy(t);
            mt.inc(1);
            mt.norm();
            t.cmove(mt, s);
            Q.cmove(this, ns);
            C.copy(Q);

            nb = 1 + (t.nbits() + 3) / 4;

// convert exponent to signed 4-bit window
            for (i = 0; i < nb; i++)
            {
                w[i] = (sbyte)(t.lastbits(5) - 16);
                t.dec(w[i]);
                t.norm();
                t.fshr(4);
            }
            w[nb] = (sbyte)t.lastbits(5);

            P.copy(W[(w[nb] - 1) / 2]);
            for (i = nb - 1; i >= 0; i--)
            {
                Q.select(W, w[i]);
                P.dbl();
                P.dbl();
                P.dbl();
                P.dbl();
                P.add(Q);
            }
            P.sub(C);             // apply correction
        }
        P.affine();
        return(P);
    }
Пример #7
0
/* Return e.this+f.Q */

    public ECP mul2(BIG e, ECP Q, BIG f)
    {
        BIG te = new BIG();
        BIG tf = new BIG();
        BIG mt = new BIG();
        ECP S  = new ECP();
        ECP T  = new ECP();
        ECP C  = new ECP();

        ECP[]   W = new ECP[8];
        sbyte[] w = new sbyte[1 + (ROM.NLEN * ROM.BASEBITS + 1) / 2];
        int     i, s, ns, nb;
        sbyte   a, b;

        affine();
        Q.affine();

        te.copy(e);
        tf.copy(f);

// precompute table
        W[1] = new ECP();
        W[1].copy(this);
        W[1].sub(Q);
        W[2] = new ECP();
        W[2].copy(this);
        W[2].add(Q);
        S.copy(Q);
        S.dbl();
        W[0] = new ECP();
        W[0].copy(W[1]);
        W[0].sub(S);
        W[3] = new ECP();
        W[3].copy(W[2]);
        W[3].add(S);
        T.copy(this);
        T.dbl();
        W[5] = new ECP();
        W[5].copy(W[1]);
        W[5].add(T);
        W[6] = new ECP();
        W[6].copy(W[2]);
        W[6].add(T);
        W[4] = new ECP();
        W[4].copy(W[5]);
        W[4].sub(S);
        W[7] = new ECP();
        W[7].copy(W[6]);
        W[7].add(S);

// convert the table to affine
        if (ROM.CURVETYPE == ROM.WEIERSTRASS)
        {
            multiaffine(8, W);
        }

// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction

        s = te.parity();
        te.inc(1);
        te.norm();
        ns = te.parity();
        mt.copy(te);
        mt.inc(1);
        mt.norm();
        te.cmove(mt, s);
        T.cmove(this, ns);
        C.copy(T);

        s = tf.parity();
        tf.inc(1);
        tf.norm();
        ns = tf.parity();
        mt.copy(tf);
        mt.inc(1);
        mt.norm();
        tf.cmove(mt, s);
        S.cmove(Q, ns);
        C.add(S);

        mt.copy(te);
        mt.add(tf);
        mt.norm();
        nb = 1 + (mt.nbits() + 1) / 2;

// convert exponent to signed 2-bit window
        for (i = 0; i < nb; i++)
        {
            a = (sbyte)(te.lastbits(3) - 4);
            te.dec(a);
            te.norm();
            te.fshr(2);
            b = (sbyte)(tf.lastbits(3) - 4);
            tf.dec(b);
            tf.norm();
            tf.fshr(2);
            w[i] = (sbyte)(4 * a + b);
        }
        w[nb] = (sbyte)(4 * te.lastbits(3) + tf.lastbits(3));
        S.copy(W[(w[nb] - 1) / 2]);

        for (i = nb - 1; i >= 0; i--)
        {
            T.select(W, w[i]);
            S.dbl();
            S.dbl();
            S.add(T);
        }
        S.sub(C);         // apply correction
        S.affine();
        return(S);
    }
Пример #8
0
/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
    public static ECP2 mul4(ECP2[] Q, BIG[] u)
    {
        int i, j, nb;

        int[] a = new int[4];
        ECP2  T = new ECP2();
        ECP2  C = new ECP2();
        ECP2  P = new ECP2();

        ECP2[] W = new ECP2[8];

        BIG mt = new BIG();

        BIG[] t = new BIG[4];

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

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

/* precompute table */

        W[0] = new ECP2();
        W[0].copy(Q[0]);
        W[0].sub(Q[1]);
        W[1] = new ECP2();
        W[1].copy(W[0]);
        W[2] = new ECP2();
        W[2].copy(W[0]);
        W[3] = new ECP2();
        W[3].copy(W[0]);
        W[4] = new ECP2();
        W[4].copy(Q[0]);
        W[4].add(Q[1]);
        W[5] = new ECP2();
        W[5].copy(W[4]);
        W[6] = new ECP2();
        W[6].copy(W[4]);
        W[7] = new ECP2();
        W[7].copy(W[4]);
        T.copy(Q[2]);
        T.sub(Q[3]);
        W[1].sub(T);
        W[2].add(T);
        W[5].sub(T);
        W[6].add(T);
        T.copy(Q[2]);
        T.add(Q[3]);
        W[0].sub(T);
        W[3].add(T);
        W[4].sub(T);
        W[7].add(T);

        multiaffine(8, W);

/* if multiplier is even add 1 to multiplier, and add P to correction */
        mt.zero();
        C.inf();
        for (i = 0; i < 4; i++)
        {
            if (t[i].parity() == 0)
            {
                t[i].inc(1);
                t[i].norm();
                C.add(Q[i]);
            }
            mt.add(t[i]);
            mt.norm();
        }

        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] = (sbyte)(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(W[(w[nb] - 1) / 2]);
        for (i = nb - 1; i >= 0; i--)
        {
            T.select(W, w[i]);
            P.dbl();
            P.add(T);
        }
        P.sub(C);         // apply correction

        P.affine();
        return(P);
    }
Пример #9
0
/* P*=e */
    public ECP2 mul(BIG e)
    {
/* fixed size windows */
        int  i, b, nb, m, s, ns;
        BIG  mt = new BIG();
        BIG  t  = new BIG();
        ECP2 P  = new ECP2();
        ECP2 Q  = new ECP2();
        ECP2 C  = new ECP2();

        ECP2[]  W = new ECP2[8];
        sbyte[] w = new sbyte[1 + (ROM.NLEN * ROM.BASEBITS + 3) / 4];

        if (is_infinity())
        {
            return(new ECP2());
        }

        affine();

/* precompute table */
        Q.copy(this);
        Q.dbl();
        W[0] = new ECP2();
        W[0].copy(this);

        for (i = 1; i < 8; i++)
        {
            W[i] = new ECP2();
            W[i].copy(W[i - 1]);
            W[i].add(Q);
        }

/* convert the table to affine */

        multiaffine(8, W);

/* make exponent odd - add 2P if even, P if odd */
        t.copy(e);
        s = t.parity();
        t.inc(1);
        t.norm();
        ns = t.parity();
        mt.copy(t);
        mt.inc(1);
        mt.norm();
        t.cmove(mt, s);
        Q.cmove(this, ns);
        C.copy(Q);

        nb = 1 + (t.nbits() + 3) / 4;
/* convert exponent to signed 4-bit window */
        for (i = 0; i < nb; i++)
        {
            w[i] = (sbyte)(t.lastbits(5) - 16);
            t.dec(w[i]);
            t.norm();
            t.fshr(4);
        }
        w[nb] = (sbyte)t.lastbits(5);

        P.copy(W[(w[nb] - 1) / 2]);
        for (i = nb - 1; i >= 0; i--)
        {
            Q.select(W, w[i]);
            P.dbl();
            P.dbl();
            P.dbl();
            P.dbl();
            P.add(Q);
        }
        P.sub(C);
        P.affine();
        return(P);
    }
Пример #10
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);
    }