Esempio n. 1
0
/* constant time multiply by small integer of length bts - use ladder */
    public ECP pinmul(int e, int bts)
    {
        if (ROM.CURVETYPE == ROM.MONTGOMERY)
        {
            return(this.mul(new BIG(e)));
        }
        else
        {
            int nb, i, b;
            ECP P  = new ECP();
            ECP R0 = new ECP();
            ECP R1 = new ECP();
            R1.copy(this);

            for (i = bts - 1; i >= 0; i--)
            {
                b = (e >> i) & 1;
                P.copy(R1);
                P.add(R0);
                R0.cswap(R1, b);
                R1.copy(P);
                R0.dbl();
                R0.cswap(R1, b);
            }
            P.copy(R0);
            P.affine();
            return(P);
        }
    }
Esempio n. 2
0
/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
    public static int ECPVP_DSA(sbyte[] W, sbyte[] F, sbyte[] C, sbyte[] D)
    {
        BIG r, gx, gy, f, c, d, h2;
        int res = 0;
        ECP G, WP, P;

        HASH H = new HASH();

        H.process_array(F);
        sbyte[] B = H.hash();

        gx = new BIG(ROM.CURVE_Gx);
        gy = new BIG(ROM.CURVE_Gy);

        G = new ECP(gx, gy);
        r = new BIG(ROM.CURVE_Order);

        c = BIG.fromBytes(C);
        d = BIG.fromBytes(D);
        f = BIG.fromBytes(B);

        if (c.iszilch() || BIG.comp(c, r) >= 0 || d.iszilch() || BIG.comp(d, r) >= 0)
        {
            res = INVALID;
        }

        if (res == 0)
        {
            d.invmodp(r);
            f.copy(BIG.modmul(f, d, r));
            h2 = BIG.modmul(c, d, r);

            WP = ECP.fromBytes(W);
            if (WP.is_infinity())
            {
                res = ERROR;
            }
            else
            {
                P = new ECP();
                P.copy(WP);
                P = P.mul2(h2, G, f);
                if (P.is_infinity())
                {
                    res = INVALID;
                }
                else
                {
                    d = P.X;
                    d.mod(r);
                    if (BIG.comp(d, c) != 0)
                    {
                        res = INVALID;
                    }
                }
            }
        }

        return(res);
    }
Esempio n. 3
0
/* IEEE ECDSA Signature, C and D are signature on F using private key S */
    public static int ECPSP_DSA(RAND RNG, sbyte[] S, sbyte[] F, sbyte[] C, sbyte[] D)
    {
        sbyte[] T = new sbyte[EFS];
        BIG     gx, gy, r, s, f, c, d, u, vx;
        ECP     G, V;

        HASH H = new HASH();

        H.process_array(F);
        sbyte[] B = H.hash();

        gx = new BIG(ROM.CURVE_Gx);
        gy = new BIG(ROM.CURVE_Gy);

        G = new ECP(gx, gy);
        r = new BIG(ROM.CURVE_Order);

        s = BIG.fromBytes(S);
        f = BIG.fromBytes(B);

        c = new BIG(0);
        d = new BIG(0);
        V = new ECP();

        do
        {
            u = BIG.randomnum(r, RNG);

            V.copy(G);
            V  = V.mul(u);
            vx = V.X;
            c.copy(vx);
            c.mod(r);
            if (c.iszilch())
            {
                continue;
            }
            u.invmodp(r);
            d.copy(BIG.modmul(s, c, r));
            d.add(f);
            d.copy(BIG.modmul(u, d, r));
        } while (d.iszilch());

        c.toBytes(T);
        for (int i = 0; i < EFS; i++)
        {
            C[i] = T[i];
        }
        d.toBytes(T);
        for (int i = 0; i < EFS; i++)
        {
            D[i] = T[i];
        }
        return(0);
    }
Esempio n. 4
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);
    }
Esempio n. 5
0
/* Constant time select from pre-computed table */
    private void select(ECP[] W, int b)
    {
        ECP MP   = new ECP();
        int m    = b >> 31;
        int babs = (b ^ m) - m;

        babs = (babs - 1) / 2;

        cmove(W[0], teq(babs, 0));       // conditional move
        cmove(W[1], teq(babs, 1));
        cmove(W[2], teq(babs, 2));
        cmove(W[3], teq(babs, 3));
        cmove(W[4], teq(babs, 4));
        cmove(W[5], teq(babs, 5));
        cmove(W[6], teq(babs, 6));
        cmove(W[7], teq(babs, 7));

        MP.copy(this);
        MP.neg();
        cmove(MP, (int)(m & 1));
    }
Esempio n. 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);
    }
Esempio n. 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);
    }