Esempio n. 1
0
        /// <summary>
        /// Convert ECC point to Jacobian.
        /// </summary>
        /// <param name="p">ECC point.</param>
        /// <param name="A"></param>
        /// <param name="P">Prime number.</param>
        /// <returns></returns>
        private static GXEccPoint JacobianDouble(GXEccPoint p, GXBigInteger A, GXBigInteger P)
        {
            GXBigInteger ysq = new GXBigInteger(p.y);

            ysq.Multiply(p.y);
            ysq.Mod(P);
            GXBigInteger S = new GXBigInteger(p.x);

            S.Multiply(new GXBigInteger(4));
            S.Multiply(ysq);
            S.Mod(P);
            GXBigInteger M = new GXBigInteger(p.x);

            M.Multiply(p.x);
            M.Multiply(new GXBigInteger(3));
            GXBigInteger tmp = new GXBigInteger(p.z);

            tmp.Multiply(p.z);
            tmp.Multiply(p.z);
            tmp.Multiply(p.z);
            tmp.Multiply(A);
            M.Add(tmp);
            M.Mod(P);
            //nx
            GXBigInteger nx = new GXBigInteger(M);

            nx.Multiply(M);
            tmp = new GXBigInteger(S);
            tmp.Multiply(new GXBigInteger(2));
            nx.Sub(tmp);
            nx.Mod(P);
            //ny
            GXBigInteger ny = new GXBigInteger(S);

            ny.Sub(nx);
            ny.Multiply(M);
            tmp = new GXBigInteger(ysq);
            tmp.Multiply(ysq);
            tmp.Multiply(new GXBigInteger(8));
            ny.Sub(tmp);
            ny.Mod(P);
            //nz
            GXBigInteger nz = new GXBigInteger(p.y);

            nz.Multiply(p.z);
            nz.Multiply(new GXBigInteger(2));
            nz.Mod(P);
            return(new GXEccPoint(nx, ny, nz));
        }
Esempio n. 2
0
 public void Inv(GXBigInteger value)
 {
     if (!IsZero)
     {
         GXBigInteger lm  = new GXBigInteger(1);
         GXBigInteger hm  = new GXBigInteger(0);
         GXBigInteger low = new GXBigInteger(this);
         low.Mod(value);
         GXBigInteger high = new GXBigInteger(value);
         while (!(low.IsZero || low.IsOne))
         {
             GXBigInteger r = new GXBigInteger(high);
             r.Div(low);
             GXBigInteger tmp = new GXBigInteger(lm);
             tmp.Multiply(r);
             GXBigInteger nm = new GXBigInteger(hm);
             nm.Sub(tmp);
             tmp = new GXBigInteger(low);
             tmp.Multiply(r);
             high.Sub(tmp);
             // lm, low, hm, high = nm, new, lm, low
             tmp  = low;
             low  = new GXBigInteger(high);
             high = tmp;
             hm   = new GXBigInteger(lm);
             lm   = new GXBigInteger(nm);
         }
         Data     = lm.Data;
         negative = lm.negative;
         Mod(value);
     }
 }
        public void Div(GXBigInteger value)
        {
            GXBigInteger current = new GXBigInteger(1);
            GXBigInteger denom   = new GXBigInteger(value);
            GXBigInteger tmp     = new GXBigInteger(this);
            bool         neq     = negative;

            negative = false;
            try
            {
                // while denom < this.
                while (denom.Compare(this) == -1)
                {
                    current.Lshift(1);
                    denom.Lshift(1);
                }
                //If overflow.
                if (denom.Compare(this) == 1)
                {
                    if (current.IsOne)
                    {
                        Clear();
                        return;
                    }
                    Clear();
                    current.Rshift(1);
                    denom.Rshift(1);
                    while (!current.IsZero)
                    {
                        int r = tmp.Compare(denom);
                        if (r == 1)
                        {
                            tmp.Sub(denom);
                            Add(current);
                        }
                        else if (r == 0)
                        {
                            Add(current);
                            break;
                        }
                        current.Rshift(1);
                        denom.Rshift(1);
                    }
                    current.Data = Data;
                }
            }
            finally
            {
                negative = neq;
            }
            Data    = current.Data;
            changed = true;
        }
Esempio n. 4
0
        public void Div(GXBigInteger value)
        {
            GXBigInteger current = new GXBigInteger(1);
            GXBigInteger denom   = new GXBigInteger(value);
            GXBigInteger tmp     = new GXBigInteger(this);
            bool         neq     = negative;

            negative = false;
            try
            {
                //Shift UInt32 values to make this faster.
                if (denom.Count < Count - 1)
                {
                    UInt32[] tmp2 = new UInt32[Count - denom.Count - 1];
                    //Append UInt32 values.
                    current.InsertRange(0, tmp2);
                    denom.InsertRange(0, tmp2);
                    current.changed = denom.changed = true;
                }

                // while denom < this.
                while (denom.Compare(this) == -1)
                {
                    current.Lshift(1);
                    denom.Lshift(1);
                }
                //If overflow.
                if (denom.Compare(this) == 1)
                {
                    if (current.IsOne)
                    {
                        Clear();
                        return;
                    }
                    Clear();
                    current.Rshift(1);
                    denom.Rshift(1);
                    while (!current.IsZero)
                    {
                        int r = tmp.Compare(denom);
                        if (r == 1)
                        {
                            tmp.Sub(denom);
                            Add(current);
                        }
                        else if (r == 0)
                        {
                            Add(current);
                            break;
                        }
                        current.Rshift(1);
                        denom.Rshift(1);
                    }
                    current.Data = Data;
                }
            }
            finally
            {
                negative = neq;
            }
            Data    = current.Data;
            changed = true;
        }
Esempio n. 5
0
        public void Sub(GXBigInteger value)
        {
            int c = Compare(value);

            if (c == 0)
            {
                Clear();
            }
            else if (value.negative || c == -1)
            {
                if (!value.negative && !negative)
                {
                    //If biger value is decreased from smaller value.
                    GXBigInteger tmp = new GXBigInteger(value);
                    tmp.Sub(this);
                    Clear();
                    AddRange(tmp.Data);
                    Count    = tmp.Count;
                    negative = true;
                    changed  = true;
                }
                else
                {
                    //If negative value is decreased from the value.
                    bool ret = value.negative;
                    value.negative = false;
                    try
                    {
                        Add(value);
                    }
                    finally
                    {
                        value.negative = ret;
                        negative       = !ret;
                    }
                }
            }
            else
            {
                if (!value.IsZero)
                {
                    if (IsZero)
                    {
                        negative = true;
                        Clear();
                        AddRange(value.Data);
                        Count = value.Count;
                    }
                    else
                    {
                        while (Count < value.Count)
                        {
                            Add(0);
                        }
                        byte   borrow = 0;
                        UInt64 tmp;
                        int    pos;
                        for (pos = 0; pos != value.Count; ++pos)
                        {
                            tmp       = Data[pos];
                            tmp      += 0x100000000;
                            tmp      -= value.Data[pos];
                            tmp      -= borrow;
                            Data[pos] = (UInt32)tmp;
                            borrow    = (byte)((tmp < 0x100000000) ? 1 : 0);
                        }
                        if (borrow != 0)
                        {
                            for (; pos != Count; ++pos)
                            {
                                tmp       = Data[pos];
                                tmp      += 0x100000000;
                                tmp      -= borrow;
                                Data[pos] = (UInt32)tmp;
                                borrow    = (byte)((tmp < 0x100000000) ? 1 : 0);
                                if (borrow == 0)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    changed = true;
                }
            }
        }
Esempio n. 6
0
 /// <summary>
 /// Y^2 = X^3 + A*X + B (mod p)
 /// </summary>
 /// <param name="p"></param>
 /// <param name="q"></param>
 /// <param name="A"></param>
 /// <param name="P">Prime number</param>
 private static void JacobianAdd(GXEccPoint p, GXEccPoint q, GXBigInteger A, GXBigInteger P)
 {
     if (!(p.y.IsZero || q.y.IsZero))
     {
         GXBigInteger U1 = new GXBigInteger(p.x);
         U1.Multiply(q.z);
         U1.Multiply(q.z);
         U1.Mod(P);
         GXBigInteger U2 = new GXBigInteger(p.z);
         U2.Multiply(p.z);
         U2.Multiply(q.x);
         U2.Mod(P);
         GXBigInteger S1 = new GXBigInteger(p.y);
         S1.Multiply(q.z);
         S1.Multiply(q.z);
         S1.Multiply(q.z);
         S1.Mod(P);
         GXBigInteger S2 = new GXBigInteger(q.y);
         S2.Multiply(p.z);
         S2.Multiply(p.z);
         S2.Multiply(p.z);
         S2.Mod(P);
         if (U1.Compare(U2) == 0)
         {
             if (S1.Compare(S2) != 0)
             {
                 p.x = p.y = new GXBigInteger(0);
                 p.z = new GXBigInteger(1);
             }
             else
             {
                 p.x = A;
                 p.y = P;
             }
         }
         //H
         GXBigInteger H = U2;
         H.Sub(U1);
         //R
         GXBigInteger R = S2;
         R.Sub(S1);
         GXBigInteger H2 = new GXBigInteger(H);
         H2.Multiply(H);
         H2.Mod(P);
         GXBigInteger H3 = new GXBigInteger(H);
         H3.Multiply(H2);
         H3.Mod(P);
         GXBigInteger U1H2 = new GXBigInteger(U1);
         U1H2.Multiply(H2);
         U1H2.Mod(P);
         GXBigInteger tmp = new GXBigInteger(2);
         tmp.Multiply(U1H2);
         //nx
         GXBigInteger nx = new GXBigInteger(R);
         nx.Multiply(R);
         nx.Sub(H3);
         nx.Sub(tmp);
         nx.Mod(P);
         //ny
         GXBigInteger ny = R;
         tmp = new GXBigInteger(U1H2);
         tmp.Sub(nx);
         ny.Multiply(tmp);
         tmp = new GXBigInteger(S1);
         tmp.Multiply(H3);
         ny.Sub(tmp);
         ny.Mod(P);
         //nz
         GXBigInteger nz = H;
         nz.Multiply(p.z);
         nz.Multiply(q.z);
         nz.Mod(P);
         p.x = nx;
         p.y = ny;
         p.z = nz;
     }
 }