Пример #1
0
/* this+=b */
    public void add(FP b)
    {
        x.add(b.x);
        if (BIG.EXCESS(x) + 2 >= ROM.FEXCESS)
        {
            reduce();
        }
    }
Пример #2
0
/* reduces this DBIG mod a DBIG in place */

/*	public void mod(DBIG m)
 *      {
 *              int k=0;
 *              if (comp(this,m)<0) return;
 *
 *              do
 *              {
 *                      m.shl(1);
 *                      k++;
 *              }
 *              while (comp(this,m)>=0);
 *
 *              while (k>0)
 *              {
 *                      m.shr(1);
 *                      if (comp(this,m)>=0)
 *                      {
 *                              sub(m);
 *                              norm();
 *                      }
 *                      k--;
 *              }
 *              return;
 *
 *      }*/

/* return this/c */
    public virtual BIG div(BIG c)
    {
        int  k = 0;
        DBIG m = new DBIG(c);
        BIG  a = new BIG(0);
        BIG  e = new BIG(1);

        norm();

        while (comp(this, m) >= 0)
        {
            e.fshl(1);
            m.shl(1);
            k++;
        }

        while (k > 0)
        {
            m.shr(1);
            e.shr(1);
            if (comp(this, m) > 0)
            {
                a.add(e);
                a.norm();
                sub(m);
                norm();
            }
            k--;
        }
        return(a);
    }
Пример #3
0
/* a=1/a mod 2^256. This is very fast! */
    public virtual void invmod2m()
    {
        int i;
        BIG U = new BIG(0);
        BIG b = new BIG(0);
        BIG c = new BIG(0);

        U.inc(invmod256(lastbits(8)));

        for (i = 8; i < 256; i <<= 1)
        {
            b.copy(this);
            b.mod2m(i);
            BIG t1 = BIG.smul(U, b);
            t1.shr(i);
            c.copy(this);
            c.shr(i);
            c.mod2m(i);

            BIG t2 = BIG.smul(U, c);
            t2.mod2m(i);
            t1.add(t2);
            b = BIG.smul(t1, U);
            t1.copy(b);
            t1.mod2m(i);

            t2.one();
            t2.shl(i);
            t1.rsub(t2);
            t1.norm();
            t1.shl(i);
            U.add(t1);
        }
        this.copy(U);
    }
Пример #4
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);
    }
Пример #5
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);
    }
Пример #6
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);
    }
Пример #7
0
/* reduce a DBIG to a BIG using the appropriate form of the modulus */
    public static BIG mod(DBIG d)
    {
        BIG b;

        if (ROM.MODTYPE == ROM.PSEUDO_MERSENNE)
        {
            long v, tw;
            BIG  t = d.Split(ROM.MODBITS);
            b = new BIG(d);
            unchecked
            {
                v = t.pmul((int)ROM.MConst);
            }
            tw = t.w[ROM.NLEN - 1];
            t.w[ROM.NLEN - 1] &= ROM.TMASK;
            t.w[0]            += (ROM.MConst * ((tw >> ROM.TBITS) + (v << (ROM.BASEBITS - ROM.TBITS))));

            b.add(t);
            b.norm();
        }
        if (ROM.MODTYPE == ROM.MONTGOMERY_FRIENDLY)
        {
            for (int i = 0; i < ROM.NLEN; i++)
            {
                d.w[ROM.NLEN + i] += d.muladd(d.w[i], ROM.MConst - 1, d.w[i], ROM.NLEN + i - 1);
            }

            b = new BIG(0);

            for (int i = 0; i < ROM.NLEN; i++)
            {
                b.w[i] = d.w[ROM.NLEN + i];
            }
            b.norm();
        }

        if (ROM.MODTYPE == ROM.NOT_SPECIAL)
        {
            BIG  md = new BIG(ROM.Modulus);
            long m, carry;
            for (int i = 0; i < ROM.NLEN; i++)
            {
                if (ROM.MConst == -1)
                {
                    m = (-d.w[i]) & ROM.MASK;
                }
                else
                {
                    if (ROM.MConst == 1)
                    {
                        m = d.w[i];
                    }
                    else
                    {
                        m = (ROM.MConst * d.w[i]) & ROM.MASK;
                    }
                }

                carry = 0;
                for (int j = 0; j < ROM.NLEN; j++)
                {
                    carry = d.muladd(m, md.w[j], carry, i + j);
                }
                d.w[ROM.NLEN + i] += carry;
            }

            b = new BIG(0);
            for (int i = 0; i < ROM.NLEN; i++)
            {
                b.w[i] = d.w[ROM.NLEN + i];
            }
            b.norm();
        }

        return(b);
    }
Пример #8
0
/* this=1/this mod p. Binary method */
    public virtual void invmodp(BIG p)
    {
        mod(p);
        BIG u = new BIG(this);

        BIG v   = new BIG(p);
        BIG x1  = new BIG(1);
        BIG x2  = new BIG(0);
        BIG t   = new BIG(0);
        BIG one = new BIG(1);

        while (comp(u, one) != 0 && comp(v, one) != 0)
        {
            while (u.parity() == 0)
            {
                u.shr(1);
                if (x1.parity() != 0)
                {
                    x1.add(p);
                    x1.norm();
                }
                x1.shr(1);
            }
            while (v.parity() == 0)
            {
                v.shr(1);
                if (x2.parity() != 0)
                {
                    x2.add(p);
                    x2.norm();
                }
                x2.shr(1);
            }
            if (comp(u, v) >= 0)
            {
                u.sub(v);
                u.norm();
                if (comp(x1, x2) >= 0)
                {
                    x1.sub(x2);
                }
                else
                {
                    t.copy(p);
                    t.sub(x2);
                    x1.add(t);
                }
                x1.norm();
            }
            else
            {
                v.sub(u);
                v.norm();
                if (comp(x2, x1) >= 0)
                {
                    x2.sub(x1);
                }
                else
                {
                    t.copy(p);
                    t.sub(x1);
                    x2.add(t);
                }
                x2.norm();
            }
        }
        if (comp(u, one) == 0)
        {
            copy(x1);
        }
        else
        {
            copy(x2);
        }
    }
Пример #9
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);
    }
Пример #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);
    }