示例#1
0
    /* this =this^e mod p using side-channel resistant Montgomery Ladder, for short e */
    public void skpow(BIG e, FF p)
    {
        int i, b, n = p.length;
        FF  R0 = new FF(n);
        FF  R1 = new FF(n);
        FF  ND = p.invmod2m();

        mod(p);
        R0.one();
        R1.copy(this);
        R0.nres(p);
        R1.nres(p);

        for (i = 8 * ROM.MODBYTES - 1; i >= 0; i--)
        {
            b = e.bit(i);
            copy(R0);
            modmul(R1, p, ND);

            cswap(R0, R1, b);
            R0.modsqr(p, ND);

            R1.copy(this);
            cswap(R0, R1, b);
        }
        copy(R0);
        redc(p, ND);
    }
示例#2
0
    /* quick and dirty check for common factor with n */
    public bool cfactor(int s)
    {
        int r, n = length;
        int g;

        FF x = new FF(n);
        FF y = new FF(n);

        y.set(s);
        x.copy(this);
        x.norm();

        do
        {
            x.sub(y);
            x.norm();
            while (!x.iszilch() && x.parity() == 0)
            {
                x.shr();
            }
        } while (comp(x, y) > 0);

        g = (int)x.v[0].get(0);
        r = igcd(s, g);
        if (r > 1)
        {
            return(true);
        }
        return(false);
    }
示例#3
0
/* Set r=this mod b */
/* this is of length - 2*n */
/* r,b is of length - n */
    public FF dmod(FF b)
    {
        int k, n = b.length;
        FF  m = new FF(2 * n);
        FF  x = new FF(2 * n);
        FF  r = new FF(n);

        x.copy(this);
        x.norm();
        m.dsucopy(b);
        k = 256 * n;

        while (k > 0)
        {
            m.shr();

            if (comp(x, m) >= 0)
            {
                x.sub(m);
                x.norm();
            }
            k--;
        }

        r.copy(x);
        r.mod(b);
        return(r);
    }
示例#4
0
/* return low part of product this*y */
    public void lmul(FF y)
    {
        int n = length;
        FF  t = new FF(2 * n);
        FF  x = new FF(n);

        x.copy(this);
        karmul_lower(0, x, 0, y, 0, t, 0, n);
    }
示例#5
0
    /* U=1/a mod 2^m - Arazi & Qi */
    private FF invmod2m()
    {
        int i, n = length;

        FF b = new FF(n);
        FF c = new FF(n);
        FF U = new FF(n);

        FF t;

        U.zero();
        U.v[0].copy(v[0]);
        U.v[0].invmod2m();

        for (i = 1; i < n; i <<= 1)
        {
            b.copy(this);
            b.mod2m(i);
            t = mul(U, b);
            t.shrw(i);
            b.copy(t);
            c.copy(this);
            c.shrw(i);
            c.mod2m(i);
            c.lmul(U);
            c.mod2m(i);

            b.add(c);
            b.norm();
            b.lmul(U);
            b.mod2m(i);

            c.one();
            c.shlw(i);
            b.revsub(c);
            b.norm();
            b.shlw(i);
            U.add(b);
        }
        U.norm();
        return(U);
    }
示例#6
0
    /* double exponentiation r=x^e.y^f mod p */
    public void pow2(BIG e, FF y, BIG f, FF p)
    {
        int i, eb, fb, n = p.length;
        FF  xn = new FF(n);
        FF  yn = new FF(n);
        FF  xy = new FF(n);
        FF  ND = p.invmod2m();

        xn.copy(this);
        yn.copy(y);
        xn.nres(p);
        yn.nres(p);
        xy.copy(xn);
        xy.modmul(yn, p, ND);
        one();
        nres(p);

        for (i = 8 * ROM.MODBYTES - 1; i >= 0; i--)
        {
            eb = e.bit(i);
            fb = f.bit(i);
            modsqr(p, ND);
            if (eb == 1)
            {
                if (fb == 1)
                {
                    modmul(xy, p, ND);
                }
                else
                {
                    modmul(xn, p, ND);
                }
            }
            else
            {
                if (fb == 1)
                {
                    modmul(yn, p, ND);
                }
            }
        }
        redc(p, ND);
    }
示例#7
0
    /* raise to an integer power - right-to-left method */
    public void power(int e, FF p)
    {
        int  n  = p.length;
        FF   w  = new FF(n);
        FF   ND = p.invmod2m();
        bool f  = true;

        w.copy(this);
        w.nres(p);

        if (e == 2)
        {
            copy(w);
            modsqr(p, ND);
        }
        else
        {
            for (; ;)
            {
                if (e % 2 == 1)
                {
                    if (f)
                    {
                        copy(w);
                    }
                    else
                    {
                        modmul(w, p, ND);
                    }
                    f = false;
                }
                e >>= 1;
                if (e == 0)
                {
                    break;
                }
                w.modsqr(p, ND);
            }
        }
        redc(p, ND);
    }
示例#8
0
    /* this=this^e mod p, faster but not side channel resistant */
    public void pow(FF e, FF p)
    {
        int i, b, n = p.length;
        FF  w  = new FF(n);
        FF  ND = p.invmod2m();

        w.copy(this);
        one();
        nres(p);
        w.nres(p);
        for (i = 8 * ROM.MODBYTES * n - 1; i >= 0; i--)
        {
            modsqr(p, ND);
            b = e.v[i / 256].bit(i % 256);
            if (b == 1)
            {
                modmul(w, p, ND);
            }
        }
        redc(p, ND);
    }
示例#9
0
/* generate an RSA key pair */

    public static void KEY_PAIR(RAND rng, int e, rsa_private_key PRIV, rsa_public_key PUB)
    {     // IEEE1363 A16.11/A16.12 more or less
        int n  = PUB.n.getlen() / 2;
        FF  t  = new FF(n);
        FF  p1 = new FF(n);
        FF  q1 = new FF(n);

        for (;;)
        {
            PRIV.p.random(rng);
            while (PRIV.p.lastbits(2) != 3)
            {
                PRIV.p.inc(1);
            }
            while (!FF.prime(PRIV.p, rng))
            {
                PRIV.p.inc(4);
            }

            p1.copy(PRIV.p);
            p1.dec(1);

            if (p1.cfactor(e))
            {
                continue;
            }
            break;
        }

        for (;;)
        {
            PRIV.q.random(rng);
            while (PRIV.q.lastbits(2) != 3)
            {
                PRIV.q.inc(1);
            }
            while (!FF.prime(PRIV.q, rng))
            {
                PRIV.q.inc(4);
            }

            q1.copy(PRIV.q);
            q1.dec(1);

            if (q1.cfactor(e))
            {
                continue;
            }

            break;
        }

        PUB.n = FF.mul(PRIV.p, PRIV.q);
        PUB.e = e;

        t.copy(p1);
        t.shr();
        PRIV.dp.set(e);
        PRIV.dp.invmodp(t);
        if (PRIV.dp.parity() == 0)
        {
            PRIV.dp.add(t);
        }
        PRIV.dp.norm();

        t.copy(q1);
        t.shr();
        PRIV.dq.set(e);
        PRIV.dq.invmodp(t);
        if (PRIV.dq.parity() == 0)
        {
            PRIV.dq.add(t);
        }
        PRIV.dq.norm();

        PRIV.c.copy(PRIV.p);
        PRIV.c.invmodp(PRIV.q);

        return;
    }
示例#10
0
/* Set return=1/this mod p. Binary method - a<p on entry */

    public void invmodp(FF p)
    {
        int n = p.length;

        FF u   = new FF(n);
        FF v   = new FF(n);
        FF x1  = new FF(n);
        FF x2  = new FF(n);
        FF t   = new FF(n);
        FF one = new FF(n);

        one.one();
        u.copy(this);
        v.copy(p);
        x1.copy(one);
        x2.zero();

        // reduce n in here as well!
        while (comp(u, one) != 0 && comp(v, one) != 0)
        {
            while (u.parity() == 0)
            {
                u.shr();
                if (x1.parity() != 0)
                {
                    x1.add(p);
                    x1.norm();
                }
                x1.shr();
            }
            while (v.parity() == 0)
            {
                v.shr();
                if (x2.parity() != 0)
                {
                    x2.add(p);
                    x2.norm();
                }
                x2.shr();
            }
            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);
        }
    }
示例#11
0
    /* Miller-Rabin test for primality. Slow. */
    public static bool prime(FF p, RAND rng)
    {
        int  i, j, s = 0, n = p.length;
        bool loop;
        FF   d     = new FF(n);
        FF   x     = new FF(n);
        FF   unity = new FF(n);
        FF   nm1   = new FF(n);

        int sf = 4849845;         // 3*5*.. *19

        p.norm();

        if (p.cfactor(sf))
        {
            return(false);
        }
        unity.one();
        nm1.copy(p);
        nm1.sub(unity);
        nm1.norm();
        d.copy(nm1);

        while (d.parity() == 0)
        {
            d.shr();
            s++;
        }
        if (s == 0)
        {
            return(false);
        }
        for (i = 0; i < 10; i++)
        {
            x.randomnum(p, rng);
            x.pow(d, p);
            if (comp(x, unity) == 0 || comp(x, nm1) == 0)
            {
                continue;
            }
            loop = false;
            for (j = 1; j < s; j++)
            {
                x.power(2, p);
                if (comp(x, unity) == 0)
                {
                    return(false);
                }
                if (comp(x, nm1) == 0)
                {
                    loop = true;
                    break;
                }
            }
            if (loop)
            {
                continue;
            }
            return(false);
        }
        return(true);
    }