コード例 #1
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);
    }
コード例 #2
0
/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
/* Note that u and v are indistinguisible from random strings */
    public static int ENCODING(RAND rng, sbyte[] E)
    {
        int rn, m, su, sv;

        sbyte[] T = new sbyte[EFS];

        for (int i = 0; i < EFS; i++)
        {
            T[i] = E[i + 1];
        }
        BIG u = BIG.fromBytes(T);

        for (int i = 0; i < EFS; i++)
        {
            T[i] = E[i + EFS + 1];
        }
        BIG v = BIG.fromBytes(T);

        ECP P = new ECP(u, v);

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

        BIG p = new BIG(ROM.Modulus);

        u = BIG.randomnum(p, rng);

        su  = rng.Byte;        //if (su<0) su=-su;
        su %= 2;

        ECP W = map(u, su);

        P.sub(W);
        sv = P.S;
        rn = unmap(v, P);
        m  = rng.Byte;        //if (m<0) m=-m;
        m %= rn;
        v.inc(m + 1);
        E[0] = (sbyte)(su + 2 * sv);
        u.toBytes(T);
        for (int i = 0; i < EFS; i++)
        {
            E[i + 1] = T[i];
        }
        v.toBytes(T);
        for (int i = 0; i < EFS; i++)
        {
            E[i + EFS + 1] = T[i];
        }

        return(0);
    }
コード例 #3
0
/* validate public key. Set full=true for fuller check */
    public static int PUBLIC_KEY_VALIDATE(bool full, sbyte[] W)
    {
        BIG r;
        ECP WP  = ECP.fromBytes(W);
        int res = 0;

        r = new BIG(ROM.CURVE_Order);

        if (WP.is_infinity())
        {
            res = INVALID_PUBLIC_KEY;
        }
        if (res == 0 && full)
        {
            WP = WP.mul(r);
            if (!WP.is_infinity())
            {
                res = INVALID_PUBLIC_KEY;
            }
        }
        return(res);
    }
コード例 #4
0
/* R=R1+R2 in group G1 */
    public static int RECOMBINE_G1(sbyte[] R1, sbyte[] R2, sbyte[] R)
    {
        ECP P = ECP.fromBytes(R1);
        ECP Q = ECP.fromBytes(R2);

        if (P.is_infinity() || Q.is_infinity())
        {
            return(INVALID_POINT);
        }

        P.add(Q);

        P.toBytes(R);
        return(0);
    }
コード例 #5
0
/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
/* maps a random u to a point on the curve */
    public static ECP map(BIG u, int cb)
    {
        ECP P;
        BIG x = new BIG(u);
        BIG p = new BIG(ROM.Modulus);

        x.mod(p);
        while (true)
        {
            P = new ECP(x, cb);
            if (!P.is_infinity())
            {
                break;
            }
            x.inc(1);
            x.norm();
        }
        return(P);
    }
コード例 #6
0
    public static ECP mapit(sbyte[] h)
    {
        BIG q = new BIG(ROM.Modulus);
        BIG x = BIG.fromBytes(h);

        x.mod(q);
        ECP P;

        while (true)
        {
            P = new ECP(x, 0);
            if (!P.is_infinity())
            {
                break;
            }
            x.inc(1);
            x.norm();
        }
        return(P);
    }
コード例 #7
0
/* Implement step 2 on client side of MPin protocol */
    public static int CLIENT_2(sbyte[] X, sbyte[] Y, sbyte[] SEC)
    {
        BIG r = new BIG(ROM.CURVE_Order);
        ECP P = ECP.fromBytes(SEC);

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

        BIG px = BIG.fromBytes(X);
        BIG py = BIG.fromBytes(Y);

        px.add(py);
        px.mod(r);
        px.rsub(r);

        PAIR.G1mul(P, px).toBytes(SEC);
        return(0);
    }
コード例 #8
0
/* Extract PIN from TOKEN for identity CID */
    public static int EXTRACT_PIN(sbyte[] CID, int pin, sbyte[] TOKEN)
    {
        ECP P = ECP.fromBytes(TOKEN);

        if (P.is_infinity())
        {
            return(INVALID_POINT);
        }
        sbyte[] h = hashit(0, CID);
        ECP     R = mapit(h);


        pin %= MAXPIN;

        R = R.pinmul(pin, PBLEN);
        P.sub(R);

        P.toBytes(TOKEN);

        return(0);
    }
コード例 #9
0
/* returns u derived from P. Random value in range 1 to return value should then be added to u */
    public static int unmap(BIG u, ECP P)
    {
        int s = P.S;
        ECP R;
        int r = 0;
        BIG x = P.X;

        u.copy(x);
        while (true)
        {
            u.dec(1);
            u.norm();
            r++;
            R = new ECP(u, s);
            if (!R.is_infinity())
            {
                break;
            }
        }
        return(r);
    }
コード例 #10
0
ファイル: ECP.cs プロジェクト: ratranqu/milagro-crypto
/* Test P == Q */
    public bool Equals(ECP Q)
    {
        if (is_infinity() && Q.is_infinity())
        {
            return(true);
        }
        if (is_infinity() || Q.is_infinity())
        {
            return(false);
        }
        if (ROM.CURVETYPE == ROM.WEIERSTRASS)
        {
            FP zs2 = new FP(z);
            zs2.sqr();
            FP zo2 = new FP(Q.z);
            zo2.sqr();
            FP zs3 = new FP(zs2);
            zs3.mul(z);
            FP zo3 = new FP(zo2);
            zo3.mul(Q.z);
            zs2.mul(Q.x);
            zo2.mul(x);
            if (!zs2.Equals(zo2))
            {
                return(false);
            }
            zs3.mul(Q.y);
            zo3.mul(y);
            if (!zs3.Equals(zo3))
            {
                return(false);
            }
        }
        else
        {
            FP a = new FP(0);
            FP b = new FP(0);
            a.copy(x);
            a.mul(Q.z);
            a.reduce();
            b.copy(Q.x);
            b.mul(z);
            b.reduce();
            if (!a.Equals(b))
            {
                return(false);
            }
            if (ROM.CURVETYPE == ROM.EDWARDS)
            {
                a.copy(y);
                a.mul(Q.z);
                a.reduce();
                b.copy(Q.y);
                b.mul(z);
                b.reduce();
                if (!a.Equals(b))
                {
                    return(false);
                }
            }
        }
        return(true);
    }
コード例 #11
0
/* calculate common key on server side */
/* Z=r.A - no time permits involved */

    public static int SERVER_KEY(sbyte[] Z, sbyte[] SST, sbyte[] W, sbyte[] xID, sbyte[] xCID, sbyte[] SK)
    {
        HASH H = new HASH();

        sbyte[] t = new sbyte[EFS];

        ECP2 sQ = ECP2.fromBytes(SST);

        if (sQ.is_infinity())
        {
            return(INVALID_POINT);
        }
        ECP R = ECP.fromBytes(Z);

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

        ECP U;

        if (xCID != null)
        {
            U = ECP.fromBytes(xCID);
        }
        else
        {
            U = ECP.fromBytes(xID);
        }
        if (U.is_infinity())
        {
            return(INVALID_POINT);
        }

        BIG w = BIG.fromBytes(W);

        U = PAIR.G1mul(U, w);
        FP12 g = PAIR.ate(sQ, R);

        g = PAIR.fexp(g);

        FP4 c = g.trace();

        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);

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

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

        return(0);
    }
コード例 #12
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);
    }