예제 #1
0
 /* this/=2 mod Modulus */
 public void Div2()
 {
     if (x.Parity() == 0)
     {
         x.FShr(1);
     }
     else
     {
         x.Add(new BIG(ROM.Modulus));
         x.Norm();
         x.FShr(1);
     }
 }
예제 #2
0
        /* this=this^e */
        public FP4 Pow(BIG e)
        {
            Norm();
            e.Norm();
            FP4 w = new FP4(this);
            BIG z = new BIG(e);
            FP4 r = new FP4(1);

            while (true)
            {
                int bt = z.Parity();
                z.FShr(1);
                if (bt == 1)
                {
                    r.Mul(w);
                }
                if (z.IsZilch())
                {
                    break;
                }
                w.Sqr();
            }
            r.Reduce();
            return(r);
        }
예제 #3
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);
        }
예제 #4
0
        public FP Pow(BIG e)
        {
            sbyte[] w  = new sbyte[1 + (BIG.NLEN * BIG.BASEBITS + 3) / 4];
            FP[]    tb = new FP[16];
            BIG     t  = new BIG(e);

            t.Norm();
            int nb = 1 + (t.NBits() + 3) / 4;

            for (int i = 0; i < nb; i++)
            {
                int lsbs = t.LastBits(4);
                t.Dec(lsbs);
                t.Norm();
                w[i] = (sbyte)lsbs;
                t.FShr(4);
            }
            tb[0] = new FP(1);
            tb[1] = new FP(this);
            for (int i = 2; i < 16; i++)
            {
                tb[i] = new FP(tb[i - 1]);
                tb[i].Mul(this);
            }
            FP r = new FP(tb[w[nb - 1]]);

            for (int i = nb - 2; i >= 0; i--)
            {
                r.Sqr();
                r.Sqr();
                r.Sqr();
                r.Sqr();
                r.Mul(tb[w[i]]);
            }
            r.Reduce();
            return(r);
        }
예제 #5
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);
        }
예제 #6
0
        /* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
        public static FP12 FExp(FP12 m)
        {
            FP2  f = new FP2(new BIG(ROM.Fra), new BIG(ROM.Frb));
            BIG  x = new BIG(ROM.CURVE_Bnx);
            FP12 r = new FP12(m);

            /* Easy part of final exp */
            FP12 lv = new FP12(r);

            lv.Inverse();
            r.Conj();

            r.mul(lv);
            lv.Copy(r);
            r.Frob(f);
            r.Frob(f);
            r.mul(lv);
            /* Hard part of final exp */
            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                FP12 x0, x1, x2, x3, x4, x5;
                lv.Copy(r);
                lv.Frob(f);
                x0 = new FP12(lv);
                x0.Frob(f);
                lv.mul(r);
                x0.mul(lv);
                x0.Frob(f);
                x1 = new FP12(r);
                x1.Conj();
                x4 = r.Pow(x);
                if (ECP.SIGN_OF_X == ECP.POSITIVEX)
                {
                    x4.Conj();
                }

                x3 = new FP12(x4);
                x3.Frob(f);

                x2 = x4.Pow(x);
                if (ECP.SIGN_OF_X == ECP.POSITIVEX)
                {
                    x2.Conj();
                }

                x5 = new FP12(x2);
                x5.Conj();
                lv = x2.Pow(x);
                if (ECP.SIGN_OF_X == ECP.POSITIVEX)
                {
                    lv.Conj();
                }

                x2.Frob(f);
                r.Copy(x2);
                r.Conj();

                x4.mul(r);
                x2.Frob(f);

                r.Copy(lv);
                r.Frob(f);
                lv.mul(r);

                lv.USqr();
                lv.mul(x4);
                lv.mul(x5);
                r.Copy(x3);
                r.mul(x5);
                r.mul(lv);
                lv.mul(x2);
                r.USqr();
                r.mul(lv);
                r.USqr();
                lv.Copy(r);
                lv.mul(x1);
                r.mul(x0);
                lv.USqr();
                r.mul(lv);
                r.Reduce();
            }
            else
            {
                FP12 y0, y1, y2, y3;
                // Ghamman & Fouotsa Method
                y0 = new FP12(r);
                y0.USqr();
                y1 = y0.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y1.Conj();
                }

                x.FShr(1);
                y2 = y1.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y2.Conj();
                }

                x.FShl(1);
                y3 = new FP12(r);
                y3.Conj();
                y1.mul(y3);

                y1.Conj();
                y1.mul(y2);

                y2 = y1.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y2.Conj();
                }

                y3 = y2.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y3.Conj();
                }

                y1.Conj();
                y3.mul(y1);

                y1.Conj();
                y1.Frob(f);
                y1.Frob(f);
                y1.Frob(f);
                y2.Frob(f);
                y2.Frob(f);
                y1.mul(y2);

                y2 = y3.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y2.Conj();
                }

                y2.mul(y0);
                y2.mul(r);

                y1.mul(y2);
                y2.Copy(y3);
                y2.Frob(f);
                y1.mul(y2);
                r.Copy(y1);
                r.Reduce();
            }

            return(r);
        }