Пример #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
/* 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);
    }
Пример #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
    /* 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);
    }
Пример #5
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);
    }
Пример #6
0
/* return NAF value as +/- 1, 3 or 5. x and x3 should be normed.
 * nbs is number of bits processed, and nzs is number of trailing 0s detected */
    public static int[] nafbits(BIG x, BIG x3, int i)
    {
        int[] n  = new int[3];
        int   nb = x3.bit(i) - x.bit(i);
        int   j;

        n[1] = 1;
        n[0] = 0;
        if (nb == 0)
        {
            n[0] = 0;
            return(n);
        }
        if (i == 0)
        {
            n[0] = nb;
            return(n);
        }
        if (nb > 0)
        {
            n[0] = 1;
        }
        else
        {
            n[0] = (-1);
        }

        for (j = i - 1; j > 0; j--)
        {
            n[1]++;
            n[0] *= 2;
            nb    = x3.bit(j) - x.bit(j);
            if (nb > 0)
            {
                n[0] += 1;
            }
            if (nb < 0)
            {
                n[0] -= 1;
            }
            if (n[0] > 5 || n[0] < -5)
            {
                break;
            }
        }

        if (n[0] % 2 != 0 && j != 0)
        {         // backtrack
            if (nb > 0)
            {
                n[0] = (n[0] - 1) / 2;
            }
            if (nb < 0)
            {
                n[0] = (n[0] + 1) / 2;
            }
            n[1]--;
        }
        while (n[0] % 2 == 0)
        {         // remove trailing zeros
            n[0] /= 2;
            n[2]++;
            n[1]--;
        }
        return(n);
    }