Пример #1
0
/* this=this^e */
    public FP12 pow(BIG e)
    {
        norm();
        e.norm();
        FP12 w = new FP12(this);
        BIG  z = new BIG(e);
        FP12 r = new FP12(1);

        while (true)
        {
            int bt = z.parity();
            z.fshr(1);
            if (bt == 1)
            {
                r.mul(w);
            }
            if (z.iszilch())
            {
                break;
            }
            w.usqr();
        }
        r.reduce();
        return(r);
    }
Пример #2
0
/* return this^e mod m */
    public virtual BIG powmod(BIG e, BIG m)
    {
        int bt;

        norm();
        e.norm();
        BIG a = new BIG(1);
        BIG z = new BIG(e);
        BIG s = new BIG(this);

        while (true)
        {
            bt = z.parity();
            z.fshr(1);
            if (bt == 1)
            {
                a = modmul(a, s, m);
            }
            if (z.iszilch())
            {
                break;
            }
            s = modsqr(s, m);
        }
        return(a);
    }
Пример #3
0
/* return this^e mod Modulus */
    public FP pow(BIG e)
    {
        int bt;
        FP  r = new FP(1);

        e.norm();
        x.norm();
        FP m = new FP(this);

        while (true)
        {
            bt = e.parity();
            e.fshr(1);
            if (bt == 1)
            {
                r.mul(m);
            }
            if (e.iszilch())
            {
                break;
            }
            m.sqr();
        }
        r.x.mod(p);
        return(r);
    }
Пример #4
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);
    }
Пример #5
0
/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
    public virtual int jacobi(BIG p)
    {
        int n8, k, m = 0;
        BIG t     = new BIG(0);
        BIG x     = new BIG(0);
        BIG n     = new BIG(0);
        BIG zilch = new BIG(0);
        BIG one   = new BIG(1);

        if (p.parity() == 0 || comp(this, zilch) == 0 || comp(p, one) <= 0)
        {
            return(0);
        }
        norm();
        x.copy(this);
        n.copy(p);
        x.mod(p);

        while (comp(n, one) > 0)
        {
            if (comp(x, zilch) == 0)
            {
                return(0);
            }
            n8 = n.lastbits(3);
            k  = 0;
            while (x.parity() == 0)
            {
                k++;
                x.shr(1);
            }
            if (k % 2 == 1)
            {
                m += (n8 * n8 - 1) / 8;
            }
            m += (n8 - 1) * (x.lastbits(2) - 1) / 4;
            t.copy(n);
            t.mod(x);
            n.copy(x);
            x.copy(t);
            m %= 2;
        }
        if (m == 0)
        {
            return(1);
        }
        else
        {
            return(-1);
        }
    }
Пример #6
0
/* this/=2 mod Modulus */
    public void div2()
    {
        x.norm();
        if (x.parity() == 0)
        {
            x.fshr(1);
        }
        else
        {
            x.add(p);
            x.norm();
            x.fshr(1);
        }
    }
Пример #7
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);
    }
Пример #8
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);
    }
Пример #9
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);
        }
    }
Пример #10
0
/* P*=e */
    public ECP2 mul(BIG e)
    {
/* fixed size windows */
        int  i, b, nb, m, s, ns;
        BIG  mt = new BIG();
        BIG  t  = new BIG();
        ECP2 P  = new ECP2();
        ECP2 Q  = new ECP2();
        ECP2 C  = new ECP2();

        ECP2[]  W = new ECP2[8];
        sbyte[] w = new sbyte[1 + (ROM.NLEN * ROM.BASEBITS + 3) / 4];

        if (is_infinity())
        {
            return(new ECP2());
        }

        affine();

/* precompute table */
        Q.copy(this);
        Q.dbl();
        W[0] = new ECP2();
        W[0].copy(this);

        for (i = 1; i < 8; i++)
        {
            W[i] = new ECP2();
            W[i].copy(W[i - 1]);
            W[i].add(Q);
        }

/* convert the table to affine */

        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);
        P.affine();
        return(P);
    }
Пример #11
0
/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
    public FP4 xtr_pow2(FP4 ck, FP4 ckml, FP4 ckm2l, BIG a, BIG b)
    {
        a.norm();
        b.norm();
        BIG e = new BIG(a);
        BIG d = new BIG(b);
        BIG w = new BIG(0);

        FP4 cu    = new FP4(ck);      // can probably be passed in w/o copying
        FP4 cv    = new FP4(this);
        FP4 cumv  = new FP4(ckml);
        FP4 cum2v = new FP4(ckm2l);
        FP4 r     = new FP4(0);
        FP4 t     = new FP4(0);

        int f2 = 0;

        while (d.parity() == 0 && e.parity() == 0)
        {
            d.fshr(1);
            e.fshr(1);
            f2++;
        }

        while (BIG.comp(d, e) != 0)
        {
            if (BIG.comp(d, e) > 0)
            {
                w.copy(e);
                w.imul(4);
                w.norm();
                if (BIG.comp(d, w) <= 0)
                {
                    w.copy(d);
                    d.copy(e);
                    e.rsub(w);
                    e.norm();

                    t.copy(cv);
                    t.xtr_A(cu, cumv, cum2v);
                    cum2v.copy(cumv);
                    cum2v.conj();
                    cumv.copy(cv);
                    cv.copy(cu);
                    cu.copy(t);
                }
                else if (d.parity() == 0)
                {
                    d.fshr(1);
                    r.copy(cum2v);
                    r.conj();
                    t.copy(cumv);
                    t.xtr_A(cu, cv, r);
                    cum2v.copy(cumv);
                    cum2v.xtr_D();
                    cumv.copy(t);
                    cu.xtr_D();
                }
                else if (e.parity() == 1)
                {
                    d.sub(e);
                    d.norm();
                    d.fshr(1);
                    t.copy(cv);
                    t.xtr_A(cu, cumv, cum2v);
                    cu.xtr_D();
                    cum2v.copy(cv);
                    cum2v.xtr_D();
                    cum2v.conj();
                    cv.copy(t);
                }
                else
                {
                    w.copy(d);
                    d.copy(e);
                    d.fshr(1);
                    e.copy(w);
                    t.copy(cumv);
                    t.xtr_D();
                    cumv.copy(cum2v);
                    cumv.conj();
                    cum2v.copy(t);
                    cum2v.conj();
                    t.copy(cv);
                    t.xtr_D();
                    cv.copy(cu);
                    cu.copy(t);
                }
            }
            if (BIG.comp(d, e) < 0)
            {
                w.copy(d);
                w.imul(4);
                w.norm();
                if (BIG.comp(e, w) <= 0)
                {
                    e.sub(d);
                    e.norm();
                    t.copy(cv);
                    t.xtr_A(cu, cumv, cum2v);
                    cum2v.copy(cumv);
                    cumv.copy(cu);
                    cu.copy(t);
                }
                else if (e.parity() == 0)
                {
                    w.copy(d);
                    d.copy(e);
                    d.fshr(1);
                    e.copy(w);
                    t.copy(cumv);
                    t.xtr_D();
                    cumv.copy(cum2v);
                    cumv.conj();
                    cum2v.copy(t);
                    cum2v.conj();
                    t.copy(cv);
                    t.xtr_D();
                    cv.copy(cu);
                    cu.copy(t);
                }
                else if (d.parity() == 1)
                {
                    w.copy(e);
                    e.copy(d);
                    w.sub(d);
                    w.norm();
                    d.copy(w);
                    d.fshr(1);
                    t.copy(cv);
                    t.xtr_A(cu, cumv, cum2v);
                    cumv.conj();
                    cum2v.copy(cu);
                    cum2v.xtr_D();
                    cum2v.conj();
                    cu.copy(cv);
                    cu.xtr_D();
                    cv.copy(t);
                }
                else
                {
                    d.fshr(1);
                    r.copy(cum2v);
                    r.conj();
                    t.copy(cumv);
                    t.xtr_A(cu, cv, r);
                    cum2v.copy(cumv);
                    cum2v.xtr_D();
                    cumv.copy(t);
                    cu.xtr_D();
                }
            }
        }
        r.copy(cv);
        r.xtr_A(cu, cumv, cum2v);
        for (int i = 0; i < f2; i++)
        {
            r.xtr_D();
        }
        r = r.xtr_pow(d);
        return(r);
    }