Пример #1
0
        /* return number of bits */
        public virtual int NBits()
        {
            BIG  t = new BIG(this);
            int  bts, k = NLEN - 1;
            long c;

            t.Norm();
            while (k >= 0 && t.w[k] == 0)
            {
                k--;
            }

            if (k < 0)
            {
                return(0);
            }

            bts = BASEBITS * k;
            c   = t.w[k];
            while (c != 0)
            {
                c /= 2;
                bts++;
            }

            return(bts);
        }
Пример #2
0
        /* reduce this mod m */
        public virtual void Mod(BIG m1)
        {
            int k = 0;
            BIG r = new BIG(0);
            BIG m = new BIG(m1);

            Norm();
            if (Comp(this, m) < 0)
            {
                return;
            }

            do
            {
                m.FShl(1);
                k++;
            } while (Comp(this, m) >= 0);

            while (k > 0)
            {
                m.FShr(1);

                r.Copy(this);
                r.Sub(m);
                r.Norm();
                CMove(r, (int)(1 - ((r.w[NLEN - 1] >> (CHUNK - 1)) & 1)));
                k--;
            }
        }
Пример #3
0
        /* return this^e mod m */
        public virtual BIG PowMod(BIG e1, BIG m)
        {
            BIG e = new BIG(e1);
            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);
        }
Пример #4
0
        /* a=1/a mod 2^256. This is very fast! */
        public virtual void InvMod2m()
        {
            int i;
            BIG U = new BIG(0);
            BIG b = new BIG(0);
            BIG c = new BIG(0);

            U.Inc(InvMod256(LastBits(8)));

            for (i = 8; i < BIGBITS; i <<= 1)
            {
                U.Norm();
                b.Copy(this);
                b.Mod2m(i);
                BIG t1 = SMul(U, b);
                t1.Shr(i);

                c.Copy(this);
                c.Shr(i);
                c.Mod2m(i);
                BIG t2 = SMul(U, c);
                t2.Mod2m(i);

                t1.Add(t2);
                t1.Norm();
                b = SMul(t1, U);
                t1.Copy(b);
                t1.Mod2m(i);

                t2.One();
                t2.Shl(i);
                t1.RSub(t2);
                t1.Norm();

                t1.Shl(i);
                U.Add(t1);
            }

            U.Mod2m(BIGBITS);
            Copy(U);
            Norm();
        }
Пример #5
0
        /* convert this BIG to byte array */
        public virtual void ToByteArray(sbyte[] b, int n)
        {
            BIG c = new BIG(this);

            c.Norm();

            for (int i = MODBYTES - 1; i >= 0; i--)
            {
                b[i + n] = (sbyte)c.w[0];
                c.FShr(8);
            }
        }
Пример #6
0
        /* divide this by m */
        public virtual void Div(BIG m1)
        {
            int d, k = 0;

            Norm();
            BIG e = new BIG(1);
            BIG m = new BIG(m1);
            BIG b = new BIG(this);
            BIG r = new BIG(0);

            Zero();

            while (Comp(b, m) >= 0)
            {
                e.FShl(1);
                m.FShl(1);
                k++;
            }

            while (k > 0)
            {
                m.FShr(1);
                e.FShr(1);

                r.Copy(b);
                r.Sub(m);
                r.Norm();
                d = (int)(1 - ((r.w[NLEN - 1] >> (CHUNK - 1)) & 1));
                b.CMove(r, d);
                r.Copy(this);
                r.Add(e);
                r.Norm();
                CMove(r, d);
                k--;
            }
        }
Пример #7
0
        internal static BIG Monty(BIG md, long MC, DBIG d)
        {
            BIG  b;
            long m, carry;

            long[] cr = new long[2];
            for (int i = 0; i < NLEN; i++)
            {
                if (MC == -1)
                {
                    m = -d.w[i] & BMASK;
                }
                else
                {
                    if (MC == 1)
                    {
                        m = d.w[i];
                    }
                    else
                    {
                        m = (MC * d.w[i]) & BMASK;
                    }
                }

                carry = 0;
                for (int j = 0; j < NLEN; j++)
                {
                    cr         = MulAdd(m, md.w[j], carry, d.w[i + j]);
                    carry      = cr[0];
                    d.w[i + j] = cr[1];
                }

                d.w[NLEN + i] += carry;
            }

            b = new BIG(0);
            for (int i = 0; i < NLEN; i++)
            {
                b.w[i] = d.w[NLEN + i];
            }

            b.Norm();
            return(b);
        }
Пример #8
0
        /* Map byte string to curve point */
        public static ECP MapIt(sbyte[] h)
        {
            BIG q = new BIG(ROM.Modulus);
            BIG x = BIG.FromBytes(h);

            x.Mod(q);
            ECP P;

            while (true)
            {
                while (true)
                {
                    if (CURVETYPE != MONTGOMERY)
                    {
                        P = new ECP(x, 0);
                    }
                    else
                    {
                        P = new ECP(x);
                    }

                    x.Inc(1);
                    x.Norm();
                    if (!P.IsInfinity())
                    {
                        break;
                    }
                }

                P.Cfp();
                if (!P.IsInfinity())
                {
                    break;
                }
            }

            return(P);
        }
Пример #9
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 + (BIG.NLEN * BIG.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);

            // 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);
        }
Пример #10
0
        /* return e.this */

        public ECP Mul(BIG e)
        {
            if (e.IsZilch() || IsInfinity())
            {
                return(new ECP());
            }

            ECP P = new ECP();

            if (CURVETYPE == 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, nb, 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 + (BIG.NLEN * BIG.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);
                }

                // 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);
        }
Пример #11
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.FShr(1);
                    if (x1.Parity() != 0)
                    {
                        x1.Add(p);
                        x1.Norm();
                    }

                    x1.FShr(1);
                }

                while (v.Parity() == 0)
                {
                    v.FShr(1);
                    if (x2.Parity() != 0)
                    {
                        x2.Add(p);
                        x2.Norm();
                    }

                    x2.FShr(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);
            }
        }
Пример #12
0
        /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */

        /*
         *      public static ECP2 mul4(ECP2[] Q,BIG[] u)
         *      {
         *              int i,j,nb;
         *              int[] a=new int[4];
         *              ECP2 T=new ECP2();
         *              ECP2 C=new ECP2();
         *              ECP2 P=new ECP2();
         *              ECP2[] W=new ECP2[8];
         *
         *              BIG mt=new BIG();
         *              BIG[] t=new BIG[4];
         *
         *              byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
         *
         *              for (i=0;i<4;i++)
         *              {
         *                      t[i]=new BIG(u[i]);
         *                      Q[i].affine();
         *              }
         *
         * // precompute table
         *
         *              W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]);
         *
         *              W[1]=new ECP2(); W[1].copy(W[0]);
         *              W[2]=new ECP2(); W[2].copy(W[0]);
         *              W[3]=new ECP2(); W[3].copy(W[0]);
         *              W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]);
         *              W[5]=new ECP2(); W[5].copy(W[4]);
         *              W[6]=new ECP2(); W[6].copy(W[4]);
         *              W[7]=new ECP2(); W[7].copy(W[4]);
         *              T.copy(Q[2]); T.sub(Q[3]);
         *              W[1].sub(T);
         *              W[2].add(T);
         *              W[5].sub(T);
         *              W[6].add(T);
         *              T.copy(Q[2]); T.add(Q[3]);
         *              W[0].sub(T);
         *              W[3].add(T);
         *              W[4].sub(T);
         *              W[7].add(T);
         *
         * // if multiplier is even add 1 to multiplier, and add P to correction
         *              mt.zero(); C.inf();
         *              for (i=0;i<4;i++)
         *              {
         *                      if (t[i].parity()==0)
         *                      {
         *                              t[i].inc(1); t[i].norm();
         *                              C.add(Q[i]);
         *                      }
         *                      mt.add(t[i]); mt.norm();
         *              }
         *
         *              nb=1+mt.nbits();
         *
         * // convert exponent to signed 1-bit window
         *              for (j=0;j<nb;j++)
         *              {
         *                      for (i=0;i<4;i++)
         *                      {
         *                              a[i]=(byte)(t[i].lastbits(2)-2);
         *                              t[i].dec(a[i]); t[i].norm();
         *                              t[i].fshr(1);
         *                      }
         *                      w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
         *              }
         *              w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
         *
         *              P.copy(W[(w[nb]-1)/2]);
         *              for (i=nb-1;i>=0;i--)
         *              {
         *                      T.select(W,w[i]);
         *                      P.dbl();
         *                      P.add(T);
         *              }
         *              P.sub(C); // apply correction
         *
         *              P.affine();
         *              return P;
         *      }
         */

        /* needed for SOK */
        public static ECP2 MapIt(sbyte[] h)
        {
            BIG  q   = new BIG(ROM.Modulus);
            BIG  x   = BIG.FromBytes(h);
            BIG  one = new BIG(1);
            FP2  X;
            ECP2 Q;

            x.Mod(q);
            while (true)
            {
                X = new FP2(one, x);
                Q = new ECP2(X);
                if (!Q.IsInfinity())
                {
                    break;
                }
                x.Inc(1);
                x.Norm();
            }

            BIG Fra = new BIG(ROM.Fra);
            BIG Frb = new BIG(ROM.Frb);

            X = new FP2(Fra, Frb);

            if (ECP.SEXTIC_TWIST == ECP.M_TYPE)
            {
                X.Inverse();
                X.Norm();
            }

            x = new BIG(ROM.CURVE_Bnx);

            /* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */

            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                ECP2 T, K;

                T = new ECP2();
                T.Copy(Q);
                T = T.Mul(x);

                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    T.Neg();
                }
                K = new ECP2();
                K.Copy(T);
                K.Dbl();
                K.Add(T);                 //K.affine();

                K.Frob(X);
                Q.Frob(X);
                Q.Frob(X);
                Q.Frob(X);
                Q.Add(T);
                Q.Add(K);
                T.Frob(X);
                T.Frob(X);
                Q.Add(T);
            }

            /* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
            /* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */

            if (ECP.CURVE_PAIRING_TYPE == ECP.BLS)
            {
                //	ECP2 xQ,x2Q;
                //	xQ=new ECP2();
                //	x2Q=new ECP2();

                ECP2 xQ  = Q.Mul(x);
                ECP2 x2Q = xQ.Mul(x);

                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    xQ.Neg();
                }

                x2Q.Sub(xQ);
                x2Q.Sub(Q);

                xQ.Sub(Q);
                xQ.Frob(X);

                Q.Dbl();
                Q.Frob(X);
                Q.Frob(X);

                Q.Add(x2Q);
                Q.Add(xQ);
            }
            Q.Affine();
            return(Q);
        }
Пример #13
0
        /* P*=e */
        public ECP2 Mul(BIG e)
        {
            /* fixed size windows */
            int  i, nb, 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 + (BIG.NLEN * BIG.BASEBITS + 3) / 4];

            if (IsInfinity())
            {
                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);
            }

            /* 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);
        }