Пример #1
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;
         *      } */

        /* return sqrt(this) mod Modulus */
        public FP Sqrt()
        {
            Reduce();
            BIG b = new BIG(ROM.Modulus);

            if (MOD8 == 5)
            {
                b.Dec(5);
                b.Norm();
                b.Shr(3);
                FP i = new FP(this);
                i.x.Shl(1);
                FP v = i.Pow(b);
                i.Mul(v);
                i.Mul(v);
                i.x.Dec(1);
                FP r = new FP(this);
                r.Mul(v);
                r.Mul(i);
                r.Reduce();
                return(r);
            }
            else
            {
                b.Inc(1);
                b.Norm();
                b.Shr(2);
                return(Pow(b));
            }
        }
Пример #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
        /* this=1/this mod Modulus */
        public void Inverse()
        {
            /*
             *              BIG r=redc();
             *              r.invmodp(p);
             *              x.copy(r);
             *              nres();
             */
            BIG m2 = new BIG(ROM.Modulus);

            m2.Dec(2);
            m2.Norm();
            Copy(Pow(m2));
        }
Пример #5
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);
        }
Пример #6
0
        /* this=this^e */
        /* Note this is simple square and multiply, so not side-channel safe */
        public FP12 Pow(BIG e)
        {
            Norm();
            e.Norm();
            BIG e3 = new BIG(e);

            e3.PMul(3);
            e3.Norm();

            FP12 w = new FP12(this);

            int nb = e3.NBits();

            for (int i = nb - 2; i >= 1; i--)
            {
                w.USqr();
                int bt = e3.Bit(i) - e.Bit(i);
                if (bt == 1)
                {
                    w.mul(this);
                }
                if (bt == -1)
                {
                    Conj();
                    w.mul(this);
                    Conj();
                }
            }
            w.Reduce();
            return(w);


            /*
             *              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; */
        }
Пример #7
0
        /* this*=y */
        /* Now uses Lazy reduction */
        public void Mul(FP2 y)
        {
            if ((long)(a.XES + b.XES) * (y.a.XES + y.b.XES) > (long)FP.FEXCESS)
            {
                if (a.XES > 1)
                {
                    a.Reduce();
                }
                if (b.XES > 1)
                {
                    b.Reduce();
                }
            }

            DBIG pR = new DBIG(0);
            BIG  C  = new BIG(a.x);
            BIG  D  = new BIG(y.a.x);

            pR.UCopy(new BIG(ROM.Modulus));

            DBIG A = BIG.Mul(a.x, y.a.x);
            DBIG B = BIG.Mul(b.x, y.b.x);

            C.Add(b.x);
            C.Norm();
            D.Add(y.b.x);
            D.Norm();

            DBIG E = BIG.Mul(C, D);
            DBIG F = new DBIG(A);

            F.Add(B);
            B.RSub(pR);

            A.Add(B);
            A.Norm();
            E.Sub(F);
            E.Norm();

            a.x.Copy(FP.Mod(A));
            a.XES = 3;
            b.x.Copy(FP.Mod(E));
            b.XES = 2;
        }
Пример #8
0
        /* return this/c */
        public virtual BIG Div(BIG c)
        {
            int  d, k = 0;
            DBIG m  = new DBIG(c);
            DBIG dr = new DBIG(0);
            BIG  r  = new BIG(0);
            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);

                dr.Copy(this);
                dr.Sub(m);
                dr.Norm();
                d = (int)(1 - ((dr.w[BIG.DNLEN - 1] >> (BIG.CHUNK - 1)) & 1));
                CMove(dr, d);
                r.Copy(a);
                r.Add(e);
                r.Norm();
                a.CMove(r, d);
                k--;
            }
            return(a);
        }
Пример #9
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);
        }
Пример #10
0
        /* Optimal R-ate double pairing e(P,Q).e(R,S) */
        public static FP12 Ate2(ECP2 P1, ECP Q1, ECP2 R1, ECP S1)
        {
            FP2  f;
            BIG  x = new BIG(ROM.CURVE_Bnx);
            BIG  n = new BIG(x);
            ECP2 K = new ECP2();
            FP12 lv;
            int  bt;

            ECP2 P = new ECP2(P1);
            ECP  Q = new ECP(Q1);

            P.Affine();
            Q.Affine();

            ECP2 R = new ECP2(R1);
            ECP  S = new ECP(S1);

            R.Affine();
            S.Affine();

            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                f = new FP2(new BIG(ROM.Fra), new BIG(ROM.Frb));
                if (ECP.SEXTIC_TWIST == ECP.M_TYPE)
                {
                    f.Inverse();
                    f.Norm();
                }

                n.PMul(6);
                if (ECP.SIGN_OF_X == ECP.POSITIVEX)
                {
                    n.Inc(2);
                }
                else
                {
                    n.Dec(2);
                }
            }
            else
            {
                n.Copy(x);
            }

            n.Norm();

            BIG n3 = new BIG(n);

            n3.PMul(3);
            n3.Norm();

            FP Qx = new FP(Q.GetX());
            FP Qy = new FP(Q.GetY());
            FP Sx = new FP(S.GetX());
            FP Sy = new FP(S.GetY());

            ECP2 A = new ECP2();
            ECP2 B = new ECP2();
            FP12 r = new FP12(1);

            A.Copy(P);
            B.Copy(R);

            ECP2 MP = new ECP2();

            MP.Copy(P);
            MP.Neg();
            ECP2 MR = new ECP2();

            MR.Copy(R);
            MR.Neg();


            int nb = n3.NBits();

            for (int i = nb - 2; i >= 1; i--)
            {
                r.Sqr();
                lv = Line(A, A, Qx, Qy);
                r.SMul(lv, ECP.SEXTIC_TWIST);

                lv = Line(B, B, Sx, Sy);
                r.SMul(lv, ECP.SEXTIC_TWIST);

                bt = n3.Bit(i) - n.Bit(i); // bt=n.bit(i);
                if (bt == 1)
                {
                    lv = Line(A, P, Qx, Qy);
                    r.SMul(lv, ECP.SEXTIC_TWIST);
                    lv = Line(B, R, Sx, Sy);
                    r.SMul(lv, ECP.SEXTIC_TWIST);
                }

                if (bt == -1)
                {
                    //P.neg();
                    lv = Line(A, MP, Qx, Qy);
                    r.SMul(lv, ECP.SEXTIC_TWIST);
                    //P.neg();
                    //R.neg();
                    lv = Line(B, MR, Sx, Sy);
                    r.SMul(lv, ECP.SEXTIC_TWIST);
                    //R.neg();
                }
            }

            if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
            {
                r.Conj();
            }

            /* R-ate fixup required for BN curves */
            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    //	r.conj();
                    A.Neg();
                    B.Neg();
                }

                K.Copy(P);
                K.Frob(f);

                lv = Line(A, K, Qx, Qy);
                r.SMul(lv, ECP.SEXTIC_TWIST);
                K.Frob(f);
                K.Neg();
                lv = Line(A, K, Qx, Qy);
                r.SMul(lv, ECP.SEXTIC_TWIST);
                K.Copy(R);
                K.Frob(f);
                lv = Line(B, K, Sx, Sy);
                r.SMul(lv, ECP.SEXTIC_TWIST);
                K.Frob(f);
                K.Neg();
                lv = Line(B, K, Sx, Sy);
                r.SMul(lv, ECP.SEXTIC_TWIST);
            }

            return(r);
        }
Пример #11
0
        /// <summary>
        ///************** 64-bit specific *********************** </summary>

        /* reduce a DBIG to a BIG using the appropriate form of the modulus */
        public static BIG Mod(DBIG d)
        {
            if (MODTYPE == PSEUDO_MERSENNE)
            {
                BIG  b;
                long v, tw;
                BIG  t = d.Split(MODBITS);
                b = new BIG(d);

                v = t.PMul(unchecked ((int)ROM.MConst));

                t.Add(b);
                t.Norm();

                tw = t.w[BIG.NLEN - 1];
                t.w[BIG.NLEN - 1] &= FP.TMASK;
                t.w[0]            += (ROM.MConst * ((tw >> TBITS) + (v << (BIG.BASEBITS - TBITS))));

                t.Norm();
                return(t);
            }
            if (FP.MODTYPE == MONTGOMERY_FRIENDLY)
            {
                BIG    b;
                long[] cr = new long[2];
                for (int i = 0; i < BIG.NLEN; i++)
                {
                    cr = BIG.MulAdd(d.w[i], ROM.MConst - 1, d.w[i], d.w[BIG.NLEN + i - 1]);
                    d.w[BIG.NLEN + i]    += cr[0];
                    d.w[BIG.NLEN + i - 1] = cr[1];
                }

                b = new BIG(0);
                for (int i = 0; i < BIG.NLEN; i++)
                {
                    b.w[i] = d.w[BIG.NLEN + i];
                }
                b.Norm();
                return(b);
            }
            if (MODTYPE == GENERALISED_MERSENNE)
            {             // GoldiLocks Only
                BIG b;
                BIG t = d.Split(MODBITS);
                b = new BIG(d);
                b.Add(t);
                DBIG dd = new DBIG(t);
                dd.Shl(MODBITS / 2);

                BIG tt = dd.Split(MODBITS);
                BIG lo = new BIG(dd);
                b.Add(tt);
                b.Add(lo);
                b.Norm();
                tt.Shl(MODBITS / 2);
                b.Add(tt);

                long carry = b.w[BIG.NLEN - 1] >> TBITS;
                b.w[BIG.NLEN - 1] &= FP.TMASK;
                b.w[0]            += carry;

                b.w[224 / BIG.BASEBITS] += carry << (224 % BIG.BASEBITS);
                b.Norm();
                return(b);
            }
            if (MODTYPE == NOT_SPECIAL)
            {
                return(BIG.Monty(new BIG(ROM.Modulus), ROM.MConst, d));
            }

            return(new BIG(0));
        }
Пример #12
0
 /* normalise this */
 public void Norm()
 {
     x.Norm();
 }