internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder)
 {
     if (numerator < denominator)
     {
         quotient.Clear();
         remainder.CopyFrom(numerator);
     }
     else if (numerator == denominator)
     {
         quotient.Clear();
         quotient.SetDigit(0, 1);
         remainder.Clear();
     }
     else
     {
         BigInt a = new BigInt();
         a.CopyFrom(numerator);
         BigInt num2 = new BigInt();
         num2.CopyFrom(denominator);
         uint num3 = 0;
         while (num2.Size < a.Size)
         {
             num2.Multiply(0x100);
             num3++;
         }
         if (num2 > a)
         {
             num2.Divide(0x100);
             num3--;
         }
         int num4 = 0;
         int digit = 0;
         int b = 0;
         BigInt c = new BigInt();
         quotient.Clear();
         for (int i = 0; i <= num3; i++)
         {
             num4 = (a.Size == num2.Size) ? a.GetDigit(a.Size - 1) : ((0x100 * a.GetDigit(a.Size - 1)) + a.GetDigit(a.Size - 2));
             digit = num2.GetDigit(num2.Size - 1);
             b = num4 / digit;
             if (b >= 0x100)
             {
                 b = 0xff;
             }
             Multiply(num2, b, ref c);
             while (c > a)
             {
                 b--;
                 Multiply(num2, b, ref c);
             }
             quotient.Multiply(0x100);
             Add(quotient, (byte) b, ref quotient);
             Subtract(a, c, ref a);
             num2.Divide(0x100);
         }
         remainder.CopyFrom(a);
     }
 }
 internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder)
 {
     if (numerator < denominator)
     {
         quotient.Clear();
         remainder.CopyFrom(numerator);
     }
     else if (numerator == denominator)
     {
         quotient.Clear();
         quotient.SetDigit(0, 1);
         remainder.Clear();
     }
     else
     {
         BigInt a = new BigInt();
         a.CopyFrom(numerator);
         BigInt num2 = new BigInt();
         num2.CopyFrom(denominator);
         uint num3 = 0;
         while (num2.Size < a.Size)
         {
             num2.Multiply(0x100);
             num3++;
         }
         if (num2 > a)
         {
             num2.Divide(0x100);
             num3--;
         }
         int    num4  = 0;
         int    digit = 0;
         int    b     = 0;
         BigInt c     = new BigInt();
         quotient.Clear();
         for (int i = 0; i <= num3; i++)
         {
             num4  = (a.Size == num2.Size) ? a.GetDigit(a.Size - 1) : ((0x100 * a.GetDigit(a.Size - 1)) + a.GetDigit(a.Size - 2));
             digit = num2.GetDigit(num2.Size - 1);
             b     = num4 / digit;
             if (b >= 0x100)
             {
                 b = 0xff;
             }
             Multiply(num2, b, ref c);
             while (c > a)
             {
                 b--;
                 Multiply(num2, b, ref c);
             }
             quotient.Multiply(0x100);
             Add(quotient, (byte)b, ref quotient);
             Subtract(a, c, ref a);
             num2.Divide(0x100);
         }
         remainder.CopyFrom(a);
     }
 }
示例#3
0
        private static void Multiply(BigInt a, int b, ref BigInt c)
        {
            if (b == 0)
            {
                c.Clear();
                return;
            }

            int carry = 0, product = 0;
            int size    = a.Size;
            int newSize = 0;

            for (int index = 0; index < size; index++)
            {
                product = b * a.GetDigit(index) + carry;
                carry   = product / m_base;
                c.SetDigit(index, (byte)(product % m_base), ref newSize);
            }

            if (carry != 0)
            {
                byte[] bytes = BitConverter.GetBytes(carry);
                for (int index = 0; index < bytes.Length; index++)
                {
                    c.SetDigit(size + index, bytes[index], ref newSize);
                }
            }

            c.Size = newSize;
        }
 private static void Multiply(BigInt a, int b, ref BigInt c)
 {
     if (b == 0)
     {
         c.Clear();
     }
     else
     {
         int num  = 0;
         int num2 = 0;
         int size = a.Size;
         int num4 = 0;
         for (int i = 0; i < size; i++)
         {
             num2 = (b * a.GetDigit(i)) + num;
             num  = num2 / 0x100;
             c.SetDigit(i, (byte)(num2 % 0x100), ref num4);
         }
         if (num != 0)
         {
             byte[] bytes = BitConverter.GetBytes(num);
             for (int j = 0; j < bytes.Length; j++)
             {
                 c.SetDigit(size + j, bytes[j], ref num4);
             }
         }
         c.Size = num4;
     }
 }
示例#5
0
        //
        // Integer division of one BigInt by another.
        //

        internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder)
        {
            // Avoid extra computations in special cases.

            if (numerator < denominator)
            {
                quotient.Clear();
                remainder.CopyFrom(numerator);
                return;
            }

            if (numerator == denominator)
            {
                quotient.Clear(); quotient.SetDigit(0, 1);
                remainder.Clear();
                return;
            }

            BigInt dividend = new BigInt();

            dividend.CopyFrom(numerator);
            BigInt divisor = new BigInt();

            divisor.CopyFrom(denominator);

            uint zeroCount = 0;

            // We pad the divisor with zeros until its size equals that of the dividend.
            while (divisor.Size < dividend.Size)
            {
                divisor.Multiply(m_base);
                zeroCount++;
            }

            if (divisor > dividend)
            {
                divisor.Divide(m_base);
                zeroCount--;
            }

            // Use school division techniques, make a guess for how many times
            // divisor goes into dividend, making adjustment if necessary.
            int a = 0;
            int b = 0;
            int c = 0;

            BigInt hold = new BigInt();

            quotient.Clear();
            for (int index = 0; index <= zeroCount; index++)
            {
                a = dividend.Size == divisor.Size ? dividend.GetDigit(dividend.Size - 1) :
                    m_base *dividend.GetDigit(dividend.Size - 1) + dividend.GetDigit(dividend.Size - 2);

                b = divisor.GetDigit(divisor.Size - 1);
                c = a / b;

                if (c >= m_base)
                {
                    c = 0xFF;
                }

                Multiply(divisor, c, ref hold);
                while (hold > dividend)
                {
                    c--;
                    Multiply(divisor, c, ref hold);
                }

                quotient.Multiply(m_base);
                Add(quotient, (byte)c, ref quotient);
                Subtract(dividend, hold, ref dividend);
                divisor.Divide(m_base);
            }
            remainder.CopyFrom(dividend);
        }
示例#6
0
        //
        // Integer division of one BigInt by another.
        //

        internal static void Divide (BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder) {
            // Avoid extra computations in special cases.

            if (numerator < denominator) {
                quotient.Clear();
                remainder.CopyFrom(numerator);
                return;
            }
    
            if (numerator == denominator) {
                quotient.Clear(); quotient.SetDigit(0, 1); 
                remainder.Clear();
                return;
            }

            BigInt dividend = new BigInt();
            dividend.CopyFrom(numerator);
            BigInt divisor = new BigInt();
            divisor.CopyFrom(denominator);

            uint zeroCount = 0;
            // We pad the divisor with zeros until its size equals that of the dividend.
            while (divisor.Size < dividend.Size) {
                divisor.Multiply(m_base);
                zeroCount++; 
            }

            if (divisor > dividend) {
                divisor.Divide(m_base);
                zeroCount--;
            }

            // Use school division techniques, make a guess for how many times
            // divisor goes into dividend, making adjustment if necessary.
            int a = 0;
            int b = 0;
            int c = 0;

            BigInt hold = new BigInt();
            quotient.Clear();
            for (int index = 0; index <= zeroCount; index++) {
                a = dividend.Size == divisor.Size ? dividend.GetDigit(dividend.Size - 1) :
                                                    m_base * dividend.GetDigit(dividend.Size - 1) + dividend.GetDigit(dividend.Size - 2);
                b = divisor.GetDigit(divisor.Size - 1);
                c = a / b;

                if (c >= m_base) 
                    c = 0xFF;

                Multiply(divisor, c, ref hold);
                while (hold > dividend) {
                    c--;
                    Multiply(divisor, c, ref hold);
                }

                quotient.Multiply(m_base);
                Add(quotient, (byte) c, ref quotient);
                Subtract(dividend, hold, ref dividend);
                divisor.Divide(m_base);
            }
            remainder.CopyFrom(dividend);
        }
示例#7
0
        private static void Multiply (BigInt a, int b, ref BigInt c) {
            if (b == 0) {
                c.Clear();
                return;
            }
                
            int carry = 0, product = 0;
            int size = a.Size;
            int newSize = 0;
            for (int index = 0; index < size; index++) {
                product = b * a.GetDigit(index) + carry;
                carry = product / m_base;
                c.SetDigit(index, (byte) (product % m_base), ref newSize);
            }

            if (carry != 0) {
                byte[] bytes = BitConverter.GetBytes(carry);
                for (int index = 0; index < bytes.Length; index++) {
                    c.SetDigit(size + index, bytes[index], ref newSize);
                }
            }

            c.Size = newSize;
        }
示例#8
0
 BigInt Replace(BigInt old, BigInt new_)
 {
     old.Clear();
     return new_;
 }
示例#9
0
 public BigInt ModInv(BigInt p, BigInt negP)
 {
     var u = this.Clone();
     var v = p.Clone();
     var x1 = new BigInt(1, p.Length);
     var x2 = new BigInt(0, p.Length);
     while (!u.IsOne() && !v.IsOne())
     {
         while (u.IsEven())
         {
             u.Div2Trunc();
             x1.Div2(p);
         }
         while (v.IsEven())
         {
             v.Div2Trunc();
             x2.Div2(p);
         }
         if (u >= v)
         {
             var uTmp = u;
             u = u.SubMod(v, p, negP);
             uTmp.Clear();
             var x1Tmp = x1;
             x1 = x1.SubMod(x2, p, negP);
             x1Tmp.Clear();
         }
         else
         {
             var vTmp = v;
             v = v.SubMod(u, p, negP);
             vTmp.Clear();
             var x2Tmp = x2;
             x2 = x2.SubMod(x1, p, negP);
             x2Tmp.Clear();
         }
     }
     v.Clear();
     if (u.IsOne())
     {
         u.Clear();
         x2.Clear();
         return x1;
     }
     else
     {
         u.Clear();
         x1.Clear();
         return x2;
     }
 }
示例#10
0
            public void ModP384()
            {
                var p = EllipticCurve.P384.p;
                var negP = EllipticCurve.P384.negP;

                var a = _bits;
                var t = new BigInt() { _bits = new uint[] { a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11] } };
                var s1 = new BigInt() { _bits = new uint[] { 0, 0, 0, 0, a[21], a[22], a[23], 0, 0, 0, 0, 0 } };
                var s2 = new BigInt() { _bits = new uint[] { a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23] } };
                var s3 = new BigInt() { _bits = new uint[] { a[21], a[22], a[23], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20] } };
                var s4 = new BigInt() { _bits = new uint[] { 0, a[23], 0, a[20], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19] } };
                var s5 = new BigInt() { _bits = new uint[] { 0, 0, 0, 0, a[20], a[21], a[22], a[23], 0, 0, 0, 0 } };
                var s6 = new BigInt() { _bits = new uint[] { a[20], 0, 0, a[21], a[22], a[23], 0, 0, 0, 0, 0, 0 } };
                var d1 = new BigInt() { _bits = new uint[] { a[23], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22] } };
                var d2 = new BigInt() { _bits = new uint[] { 0, a[20], a[21], a[22], a[23], 0, 0, 0, 0, 0, 0, 0 } };
                var d3 = new BigInt() { _bits = new uint[] { 0, 0, 0, a[23], a[23], 0, 0, 0, 0, 0, 0, 0 } };

                BigInt.TwosComplement(d1._bits, d1._bits);
                BigInt.AddRaw(d1._bits, p._bits, d1._bits);

                BigInt.TwosComplement(d2._bits, d2._bits);
                BigInt.AddRaw(d2._bits, s2._bits, s2._bits);

                BigInt.TwosComplement(d3._bits, d3._bits);
                BigInt.AddRaw(d3._bits, s2._bits, s2._bits);

                var res = s1;
                BigInt.AddRaw(res._bits, res._bits, res._bits);
                BigInt.AddRaw(res._bits, s5._bits, res._bits);
                BigInt.AddRaw(res._bits, s6._bits, res._bits);

                var toAdd = new BigInt[] { t, s2, s3, s4, d1 };
                foreach (var num in toAdd)
                {
                    var carry = BigInt.AddRaw(num._bits, res._bits, res._bits) == 1;
                    if (carry || res >= p)
                    {
                        BigInt.AddRaw(res._bits, negP._bits, res._bits);
                    }
                }
                s5.Clear();
                s6.Clear();
                d2.Clear();
                d3.Clear();
                foreach (var num in toAdd)
                {
                    num.Clear();
                }
                Clear();
                _bits = res._bits;
            }
 private static void Multiply(BigInt a, int b, ref BigInt c)
 {
     if (b == 0)
     {
         c.Clear();
     }
     else
     {
         int num = 0;
         int num2 = 0;
         int size = a.Size;
         int num4 = 0;
         for (int i = 0; i < size; i++)
         {
             num2 = (b * a.GetDigit(i)) + num;
             num = num2 / 0x100;
             c.SetDigit(i, (byte) (num2 % 0x100), ref num4);
         }
         if (num != 0)
         {
             byte[] bytes = BitConverter.GetBytes(num);
             for (int j = 0; j < bytes.Length; j++)
             {
                 c.SetDigit(size + j, bytes[j], ref num4);
             }
         }
         c.Size = num4;
     }
 }