示例#1
0
        public void AlgebraicFactorbaseBuildMethodTest()
        {
            //algebraic factorbase for n=45113, m=31 with bound B=103 and polynomial f(x)=x^3+15x^2+29x+8
            Polynomial poly = new Polynomial(new BigInteger[] { 8, 29, 15, 1 });
            AlgebraicFactorbaseBuilder builder = new AlgebraicFactorbaseBuilder(poly, new BruteforceRootFinder(), 103);
            var actual   = builder.Build();
            var expected = new List <Pair>()
            {
                new Pair(0, 2),
                new Pair(6, 7),
                new Pair(13, 17),
                new Pair(11, 23),
                new Pair(26, 29),
                new Pair(18, 31),
                new Pair(19, 41),
                new Pair(13, 43),
                new Pair(1, 53),
                new Pair(46, 61),
                new Pair(2, 67),
                new Pair(6, 67),
                new Pair(44, 67),
                new Pair(50, 73),
                new Pair(23, 79),
                new Pair(47, 79),
                new Pair(73, 79),
                new Pair(28, 89),
                new Pair(62, 89),
                new Pair(73, 89),
                new Pair(28, 97),
                new Pair(87, 101),
                new Pair(47, 103)
            };

            CollectionAssert.AreEquivalent(expected, actual.Elements);
        }
示例#2
0
文件: SNFS.cs 项目: 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);
        }