Exemplo n.º 1
0
 private static void _MulNumber(ref BigInt C, ref BigInt B, ulong A)
 {
     if (B == 0)
     {
         C = new BigInt(B.Size, 0);
     }
     else if (A == 0)
     {
         C = new BigInt(B.Size, 0);
     }
     else if (A == 1)
     {
         C = B;
     }
     else if (A == 2)
     {
         C = B.Clone();
         C.ShiftLeft(1);
     }
     else if (A == 8)
     {
         C = B.Clone();          // C = B
         C.ShiftLeft(2);         // C = C * 4
         C.ShiftLeft(1);         // C = C * 2
     }
     else if (A == 10)
     {
         C = B.Clone();          // C = B
         C.ShiftLeft(2);         // C = C * 4
         C = C + B;              // C = C + B
         C.ShiftLeft(1);         // C = C * 2
     }
     else if (A == 16)
     {
         C = B.Clone();          // C = B
         C.ShiftLeft(2);         // C = C * 4
         C.ShiftLeft(2);         // C = C * 4
     }
     else
     {
         BigInt A1 = new BigInt(B.Size, A);
         _Mul(ref C, ref B, ref A1, B.Sign);
     }
 }
Exemplo n.º 2
0
        private static void _MulCell(ref BigInt C, ref BigInt B1, ulong A)
        {
            BigInt B1C = B1.Clone(); // C = B

            while (A > 1)
            {
                if (A % 16 == 0)
                {
                    B1C.ShiftLeft(2);         // C = C * 4
                    B1C.ShiftLeft(2);         // C = C * 4
                    A = A / 16;
                }
                else if (A % 10 == 0)
                {
                    B1C.ShiftLeft(2);         // C = C * 4
                    B1C = B1C + B1;           // C = C + B
                    B1C.ShiftLeft(1);         // C = C * 2
                    A = A / 10;
                }
                else if (A % 2 == 0)
                {
                    B1C = B1.Clone();
                    B1C.ShiftLeft(1);
                    A = A / 2;
                }
                else
                {
                    // A is not a multiple of 2, 10 or 16
                    BigInt C1 = new BigInt(B1C.Size, 0);
                    BigInt A1 = new BigInt(B1C.Size, A);
                    _Mul(ref C1, ref B1C, ref A1, B1C.Sign);
                    B1C = C1.Clone();
                    break;
                }
            }

            C = B1C.Clone();
        }
Exemplo n.º 3
0
        public static BigInt operator %(BigInt B1, BigInt B2)
        {
            B2 = (BigInt)B1.SameSize(B2);
            BigInt B2Copy = B2.Clone();
            BigInt Q      = new BigInt(B2Copy.Size, 0);
            BigInt R      = new BigInt(B2Copy.Size, 0);

            switch (B1.LookAtSign(B2Copy))
            {
            case signt2.pp:
                _Divmod(ref Q, ref R, ref B1, ref B2Copy, signt.positive);
                break;

            case signt2.np:
                _Divmod(ref Q, ref R, ref B1, ref B2Copy, signt.negative);
                break;

            case signt2.pn:
                _Divmod(ref Q, ref R, ref B1, ref B2Copy, signt.negative);
                break;

            case signt2.nn:
                _Divmod(ref Q, ref R, ref B1, ref B2Copy, signt.positive);
                break;

            default:
                throw new Exception("Could not determine the sign of the result value.");
            }

            if (B1.Sign == signt.negative && R != 0)
            {
                BigInt RCopy = R.Clone();
                RCopy.Sign  = signt.negative;
                B2Copy.Sign = signt.positive;

                RCopy = RCopy + B2Copy;
                while (!(RCopy >= 0 && RCopy.Sign == signt.positive))
                {
                    RCopy = RCopy + B2Copy;
                }
                R      = RCopy.Clone();
                R.Sign = signt.positive;
            }
            return(R);
        }
Exemplo n.º 4
0
        private static void _DivCellMod(ref BigInt Q, ref BigInt R, BigInt B, uint DefaultBase, signt ResultSign)
        {
            uint[] Result    = new uint[B.Size];
            short  ResultPos = 0;

            // First copy the Dividend (B) to the Remainder R
            B.Reduce();
            R = B.Clone();

            short Pos      = (short)(R.Spart - 1);
            ulong Dividend = R.Value[Pos];

            if (Dividend >= DefaultBase)
            {
                ulong LocalQuotient = Dividend / DefaultBase;
                Result[ResultPos++] = (uint)LocalQuotient;
                R.Value[Pos]        = (uint)(Dividend % DefaultBase);
            }
            Pos--;

            while (Pos >= 0)
            {
                Dividend = ((ulong)R.Value[Pos + 1] << CELL_SIZE) + (ulong)R.Value[Pos];
                ulong LocalQuotient = Dividend / DefaultBase;
                Result[ResultPos++] = (uint)LocalQuotient;

                R.Value[Pos + 1] = 0;
                R.Value[Pos--]   = (uint)(Dividend % DefaultBase);
            }

            Q.Spart = ResultPos;
            int j = 0;

            for (int i = Q.Spart - 1; i >= 0; i--, j++)
            {
                Q.Value[j] = Result[i];
            }
            for (; j < B.Size; j++)
            {
                Q.Value[j] = 0;
            }
            Q.Sign = ResultSign;
            Q.Reduce();
            R.Reduce();
        }
Exemplo n.º 5
0
        public static BigInt GetNextBlumPrime(BigInt Start, bool IsP = true, int Rounds = 20)
        {
            BigInt PNext = Start.Clone();

            if (!IsP)
            {
                PNext = PNext + (PNext / 4) + 2;
            }

            //int PBitsCount = Start.BitsCount();
            if (PNext.Even())
            {
                PNext.Value[0] |= 0x01;
            }
            if (!PNext.IsProbablePrime(Rounds) || PNext % 4 != 3 || PNext == Start)
            {
                do
                {
                    PNext += 2;
                }while (!PNext.IsProbablePrime(Rounds) || PNext % 4 != 3);
            }

            return(PNext);
        }
Exemplo n.º 6
0
        private static void _MulKara(ref BigInt C, ref BigInt B1, ref BigInt B2, signt ResultSign)
        {
            short B1Spart = B1.Spart;
            short B2Spart = B2.Spart;

            B1.Reduce();
            B2.Reduce();
            B2 = (BigInt)B1.SameSize(B2);
            C.Resize((short)(2 * B1.Spart + 1));

            if (B1.Spart <= SPART_LIMIT || ((B1Spart < SPART_LIMIT && (B2Spart - B1Spart) > SPART_LIMIT) || (B2Spart < SPART_LIMIT && (B1Spart - B2Spart) > SPART_LIMIT)))
            {
                _Mul(ref C, ref B1, ref B2, ResultSign);
            }
            else
            {
                B1.Reduce();
                B2.Reduce();
                short Part = B1.Spart < B2.Spart ? (short)(B1.Spart / 2) : (short)(B2.Spart / 2);

                //short PartCopy = Part;
                //while (PartCopy != 0 && PartCopy < (B1.Spart < B2.Spart ? B1.Spart : B2.Spart) && CELL_SIZE % PartCopy != 0)
                //{
                //    PartCopy++;
                //}
                //if (PartCopy != 0 && CELL_SIZE % PartCopy == 0)
                //{
                //    Part = PartCopy;
                //}
                //else
                //{
                //    PartCopy = Part;
                //    while (PartCopy > 0 && CELL_SIZE % PartCopy != 0)
                //    {
                //        PartCopy--;
                //    }
                //    Part = PartCopy;
                //}

                B2 = (BigInt)B1.SameSize(B2);

                BigInt D = new BigInt(B1.Size, 0), E = new BigInt(B1.Size, 0);
                BigInt F = new BigInt(B1.Size, 0), G = new BigInt(B1.Size, 0);
                BigInt Z0 = new BigInt(B1.Size, 0), Z1 = new BigInt(B1.Size, 0), Z2 = new BigInt(B1.Size, 0);
                // C  := Z2 * (Base ^ (2 * Part)) + (Z1 - Z2 - Z0) * (Base ^ Part) + Z0
                B1.Split(ref D, ref E, Part);
                B2.Split(ref F, ref G, Part);
                // K = D + E
                // L = F + G
                BigInt K = D + E;
                BigInt L = F + G;
                // Z0 := E*G
                // Z1 := K*L
                // Z2 := D*F
                _MulKara(ref Z0, ref E, ref G, ResultSign);
                _MulKara(ref Z1, ref K, ref L, ResultSign);
                _MulKara(ref Z2, ref D, ref F, ResultSign);
                Z0.Reduce();
                Z1.Reduce();
                Z2.Reduce();

                // Z2Copy = Z2 * (Base ^ (2 * Part))
                BigInt Z2Copy = Z2.Clone();
                for (int i = 0; i < 2 * Part; i++)
                {
                    // Z2 * Base
                    // Base = 2 ^ CELL_SIZE
                    Z2Copy.ShiftLeft(CELL_SIZE);
                }

                // (Z1 - Z2 - Z0) * (Base ^ Part)
                BigInt ZDiff = Z1 - Z2 - Z0;
                for (int i = 0; i < Part; i++)
                {
                    // ZDiff * Base
                    // Base = 2 ^ CELL_SIZE
                    ZDiff.ShiftLeft(CELL_SIZE);
                }

                C = Z2Copy + ZDiff + Z0;

                C.Reduce();
            }
        }
Exemplo n.º 7
0
        private string ToString(uint DefaultBase, bool Fill = true, OutputFormat OutType = OutputFormat.hex)
        {
            if (DefaultBase < 2 || DefaultBase > 16)
            {
                throw new ArgumentOutOfRangeException("Provided argument DefaultBase is out of range.");
            }

            string HString = "0123456789ABCDEF";
            string Result  = "";

            BigInt B         = this.Clone();
            BigInt Quotient  = new BigInt(this.Size, 0);
            BigInt Remainder = new BigInt(this.Size, 0);

            if (B.Spart == 1 && B.Value[0] == 0)
            {
                Result = "0";
            }
            else
            {
                while (B.Spart > 1 || (B.Spart == 1 && B.Value[0] != 0))
                {
                    _DivCellMod(ref Quotient, ref Remainder, B, DefaultBase, B.Sign);

                    if (Remainder.Value[0] < 10)
                    {
                        Result = Remainder.Value[0] + Result;
                    }
                    else
                    {
                        Result = HString[(int)(Remainder.Value[0])] + Result;
                    }

                    B = Quotient.Clone();
                }
            }

            // Fill the result with 000... based on size
            if (Fill)
            {
                int ResultSize = this.Size / 4 - Result.Length;
                while (ResultSize > 0)
                {
                    Result = "0" + Result;
                    ResultSize--;
                }
            }
            else if (Result.Length == 0)
            {
                Result = "0";
            }

            if (DefaultBase == 8)
            {
                Result = this.Sign == signt.positive ? $"+0o{Result}" : $"-0o{Result}";
            }
            else if (DefaultBase == 10)
            {
                Result = this.Sign == signt.positive ? $"+{Result}" : $"-{Result}";
            }
            else if (DefaultBase == 16)
            {
                Result = this.Sign == signt.positive ? $"+0x{Result}" : $"-0x{Result}";
            }

            return(Result);
        }