Esempio n. 1
0
File: Siqs.cs Progetto: zzfeed/GNFS
        private SievePolynomial GetDefaultPolynomial(BigInteger n)
        {
            var m    = new IntegerSquareRoot().Sqrt(n);
            var ainv = new Dictionary <long, long>();

            foreach (var p in _factorBase)
            {
                ainv.Add(p, 1);
            }

            var firstSln  = new Dictionary <long, long>();
            var secondSln = new Dictionary <long, long>();

            for (int i = 0; i < _factorBase.Length; i++)
            {
                var p = _factorBase[i];
                firstSln[p]  = (long)(ainv[p] * (_sqrtN[p] - m) % p);
                secondSln[p] = (long)(ainv[p] * (-_sqrtN[p] - m) % p);
            }



            return(new SievePolynomial()
            {
                A = 1,
                B = m,
                C = (m * m - n),
                FirstRoot = firstSln,
                SecondRoot = secondSln,
                InvA = ainv
            });
        }
Esempio n. 2
0
        static BigInteger TrialDivision(BigInteger n)
        {
            var sqrtN = new IntegerSquareRoot().Sqrt(n);

            if (n % 2 == 0)
            {
                return(2);
            }
            for (BigInteger i = 3; i < sqrtN; i += 2)
            {
                if (n % i == 0)
                {
                    return(i);
                }
            }
            return(1);
        }
Esempio n. 3
0
File: Siqs.cs Progetto: zzfeed/GNFS
        private void Init(BigInteger n)
        {
            if (_autoInit)
            {
                _primeBound = (long)(12 * BigInteger.Log10(n) * BigInteger.Log10(n));
                _factorBase = BuildFactorBase(n);
                _sieveBound = (_factorBase.Length) * 60;
                _kerSize    = 10;
            }
            else
            {
                _factorBase = BuildFactorBase(n);
            }
            _logp = _factorBase.Select(x => Math.Log10(x)).ToArray();
            var sqrt = new IntegerSquareRoot();

            _thresh  = BigInteger.Log10((_sieveBound * sqrt.Sqrt(2 * n)) >> 1) * 0.735;
            _partial = new Dictionary <BigInteger, int>();
            Console.WriteLine("Prime bound:" + _primeBound);
            Console.WriteLine("Sieve size:" + _sieveBound);
            Console.WriteLine("Factorbase size:" + _factorBase.Length);
        }
Esempio n. 4
0
File: SNFS.cs Progetto: zzfeed/GNFS
        public BigInteger FindFactor()
        {
            var timer = new Stopwatch();

            timer.Start();
            _polyInfo = _generator.GeneratePolynomial();
            Console.WriteLine(_number.Value());
            Console.WriteLine("f(x)=" + _polyInfo.Polynomial);
            Console.WriteLine("Root=" + _polyInfo.Root);

            var rootFinder             = new GcdRootFinder();
            var algFbBuilder           = new AlgebraicFactorbaseBuilder(_polyInfo.Polynomial, rootFinder, _algebraicPrimeBound);
            var rationalFbBuilder      = new RationalFactorbaseBuilder(_polyInfo.Root, _rationalPrimeBound);
            var quadraticCharFbBuilder = new QuadraticCharactersBuilder(_polyInfo.Polynomial, rootFinder, _algebraicPrimeBound, _quadraticCharFbSize);

            var rationalFb = rationalFbBuilder.Build();

            var quadraticCharFb = quadraticCharFbBuilder.Build();
            var algFb           = algFbBuilder.Build();
            var sieve           = new LogSieve();

            Console.WriteLine("\nRational factorbase size: " + rationalFb.Elements.Count);
            Console.WriteLine("Algebraic factorbase size: " + algFb.Elements.Count);
            Console.WriteLine("Quadratic characters factorbase size: " + quadraticCharFb.Elements.Count);
            Console.WriteLine("Init time: " + timer.Elapsed);
            timer.Reset();
            timer.Start();
            var pairs =
                sieve.Sieve(
                    (algFb.Elements.Count + rationalFb.Elements.Count + quadraticCharFb.Elements.Count + _kerDim + 1),
                    new SieveOptions(_sieveSize, -_sieveSize, algFb, rationalFb, _polyInfo.Polynomial, _polyInfo.Root));

            Console.WriteLine();
            Console.WriteLine(pairs.Count + " relations collected.");
            Console.WriteLine("Sieve time: " + timer.Elapsed);
            timer.Reset();
            timer.Start();
            var matrixBuilder = new MatrixBuilder();
            var matrix        = matrixBuilder.Build(pairs, rationalFb, algFb, quadraticCharFb, _polyInfo.Root, _polyInfo.Polynomial);
            var matrixSolver  = new GaussianEliminationOverGf2();


            //Console.WriteLine("{0}x{1} matrix builded. ",matrix.ColumnsCount,matrix.RowsCount);
            var solutions = matrixSolver.Solve(matrix);

            //  var solutions =matrix.Solve();
            Console.WriteLine();
            Console.WriteLine("Linear algebra time: " + timer.Elapsed);
            Console.WriteLine("{0} solution computed. ", solutions.Count);
            timer.Reset();
            timer.Start();


            var polyMath = new PolynomialMath(-1);
            var df       = new PolynomialDerivative().Derivative(_polyInfo.Polynomial);
            var sqrDf    = polyMath.Mul(df, df);

            var solutionsCheked = -1;

            foreach (var solution in solutions)
            {
                timer.Reset();
                timer.Start();
                var        sqr      = new Polynomial(new BigInteger[] { 1 });
                BigInteger sqrtNorm = 1;
                BigInteger x        = 1;

                for (int i = 0; i < solution.Length; i++)
                {
                    if (solution[i] == 1)
                    {
                        var tmp = new Polynomial(new BigInteger[] { pairs[i].Item1, pairs[i].Item2 });
                        x  *= pairs[i].Item1 + _polyInfo.Root * pairs[i].Item2;
                        sqr = polyMath.Rem(polyMath.Mul(tmp, sqr), _polyInfo.Polynomial);
                        var normCalculator = new FirstDegreeElementsNormCalculator(_polyInfo.Polynomial, pairs[i].Item2);
                        sqrtNorm *= normCalculator.CalculateNorm(pairs[i].Item1);
                    }
                }
                x *= sqrDf.Value(_polyInfo.Root);
                if (x < 0)
                {
                    throw new Exception();
                }
                sqr = polyMath.Rem(polyMath.Mul(sqrDf, sqr), _polyInfo.Polynomial);
                var integerSqrt = new IntegerSquareRoot();
                var sqrtX       = integerSqrt.Sqrt(x);
                if (sqrtX * sqrtX != x)
                {
                    if (sqrtX * sqrtX != x)
                    {
                        if (sqrtX * sqrtX != x)
                        {
                            throw new Exception();
                        }
                    }
                }


                var algSqrt = new AlgebraicSqrt();


                sqrtNorm = BigInteger.Abs(sqrtNorm);
                var tmpNorm = sqrtNorm;
                sqrtNorm = integerSqrt.Sqrt(BigInteger.Abs(sqrtNorm));
                timer.Stop();
                Console.WriteLine(timer.Elapsed + " Умножение");



                if (sqrtNorm * sqrtNorm != tmpNorm)
                {
                    if (sqrtNorm * sqrtNorm != tmpNorm)
                    {
                        if (sqrtNorm * sqrtNorm != tmpNorm)
                        {
                            throw new Exception();
                        }
                    }
                }
                timer.Reset();
                timer.Start();
                var sqrt = algSqrt.Sqrt(sqr, _polyInfo.Polynomial, df, sqrtNorm);
                timer.Stop();
                Console.WriteLine(timer.Elapsed + " Квадратный корень");
                if (algSqrt.DontExist)
                {
                    Console.Write("\r{0}/{1} solutions cheked. (BAD SQRT)    ", ++solutionsCheked, solutions.Count);
                    continue;
                }
                var sqrtY = sqrt.Value(_polyInfo.Root);

                var check = polyMath.Rem(polyMath.Mul(sqrt, sqrt), _polyInfo.Polynomial);
                if (check != sqr)
                {
                    var primes = new EratosthenesSieve().GetPrimes(5, 10000);
                    int i;
                    for (i = 0; i < primes.Length; i++)
                    {
                        if (!algSqrt.IsSqr(sqr, _polyInfo.Polynomial, primes[i]))
                        {
                            break;
                        }
                    }
                    if (i == primes.Length)
                    {
                        throw new Exception();
                    }
                    Console.Write("\r{0}/{1} solutions cheked. (BAD SQRT)    ", ++solutionsCheked, solutions.Count);
                    continue;
                }
                if ((sqrtY * sqrtY - sqrtX * sqrtX) % _number.Value() != 0)
                {
                    throw new Exception();
                }
                var factor = BigInteger.GreatestCommonDivisor(sqrtX - sqrtY, _number.Value());
                if (factor > 1 && factor < _number.Value())
                {
                    Console.Write("\r{0}/{1} solutions cheked                ", ++solutionsCheked, solutions.Count);
                    return(factor);
                }
                Console.Write("\r{0}/{1} solutions cheked. (BAD SOLUTION)", ++solutionsCheked, solutions.Count);
            }
            Console.Write("\r{0}/{1} solutions cheked.                ", solutionsCheked, solutions.Count);
            return(1);
        }
Esempio n. 5
0
 public void IntegerSqrt_Test(int number, object expected)
 {
     Assert.AreEqual(expected, IntegerSquareRoot.SqrtApproximation(number));
 }
Esempio n. 6
0
File: Siqs.cs Progetto: zzfeed/GNFS
        private List <SievePolynomial> GeneratePolynomials(BigInteger n)
        {
            var        result        = new List <SievePolynomial>();
            var        sqrt          = new IntegerSquareRoot();
            var        sizeBound     = sqrt.Sqrt(2 * n) / _sieveBound;
            var        primes        = new List <long>();
            BigInteger a             = 1;
            var        aFactorsBound = Math.Exp(BigInteger.Log(sizeBound) / 13);

            var indexes = new HashSet <int>();

            while (a < sizeBound && _polyIndex < _factorBase.Length)
            {
                if (_factorBase[_polyIndex] < aFactorsBound)
                {
                    _polyIndex++;
                    continue;
                }

                indexes.Add(_polyIndex);
                var p = _factorBase[_polyIndex++];
                a *= p;
                primes.Add(p);
            }
            var inv   = new ModularInverse();
            var B     = new BigInteger[primes.Count];
            var Bainv = new Dictionary <long, Dictionary <int, long> >();

            for (int i = 0; i < primes.Count; i++)
            {
                var q     = primes[i];
                var aq    = a / q;
                var gamma = _sqrtN[q] * inv.Inverse(aq, q);
                if (gamma > q / 2)
                {
                    gamma = q - gamma;
                }
                B[i] = aq * gamma;
            }
            var ainv = new Dictionary <long, long>();


            BigInteger b = 0;

            for (int i = 0; i < B.Length; i++)
            {
                b += B[i];
            }


            var firstSln  = new Dictionary <long, long>();
            var secondSln = new Dictionary <long, long>();

            for (int i = 0; i < _factorBase.Length; i++)
            {
                if (indexes.Contains(i))
                {
                    continue;
                }
                var p = _factorBase[i];
                ainv.Add(p, (long)inv.Inverse(a, p));
                Bainv[p] = new Dictionary <int, long>();
                for (int j = 0; j < primes.Count; j++)
                {
                    Bainv[p][j] = (long)(2 * B[j] * ainv[p] % p);
                }
                firstSln[p]  = (long)(ainv[p] * (_sqrtN[p] - b) % p);
                secondSln[p] = (long)(ainv[p] * (-_sqrtN[p] - b) % p);
            }

            if (primes.Count == 0)
            {
                return(null);
            }

            result.Add(new SievePolynomial()
            {
                A = a, B = b, C = (b * b - n) / a, FirstRoot = firstSln, SecondRoot = secondSln, InvA = ainv, MinFactorA = primes[0], MaxFactorA = primes[primes.Count - 1]
            });


            var polyCount = Math.Pow(2, primes.Count - 1) - 1;

            for (int i = 1; i <= polyCount; i++)
            {
                var v = 1;
                for (; (i & (0x1 << (v - 1))) == 0; v++)
                {
                }


                var tmp = (long)Math.Ceiling(i / Math.Pow(2, v));

                if (tmp % 2 == 0)
                {
                    b = b + 2 * B[v];
                }
                else
                {
                    b = b - 2 * B[v];
                }



                firstSln  = new Dictionary <long, long>();
                secondSln = new Dictionary <long, long>();

                for (var k = 0; k < _factorBase.Length; k++)
                {
                    if (indexes.Contains(k))
                    {
                        continue;
                    }
                    var p = _factorBase[k];
                    firstSln[p]  = (long)(ainv[p] * (_sqrtN[p] - b) % p);
                    secondSln[p] = (long)(ainv[p] * (-_sqrtN[p] - b) % p);
                }
                result.Add(new SievePolynomial()
                {
                    A = a, B = b, C = (b * b - n) / a, FirstRoot = firstSln, SecondRoot = secondSln, InvA = ainv, MinFactorA = primes[0], MaxFactorA = primes[primes.Count - 1]
                });
            }
            _polyIndex += 3 - primes.Count;
            return(result);
        }