Пример #1
0
        protected static bool[] GetVector(CountDictionary primeFactorizationDict, BigInteger maxValue)
        {
            int primeIndex = PrimeFactory.GetIndexFromValue(maxValue);

            bool[] result = new bool[primeIndex];

            if (primeFactorizationDict.Any())
            {
                foreach (KeyValuePair <BigInteger, BigInteger> kvp in primeFactorizationDict)
                {
                    if (kvp.Key > maxValue)
                    {
                        continue;
                    }
                    if (kvp.Key == -1)
                    {
                        continue;
                    }
                    if (kvp.Value % 2 == 0)
                    {
                        continue;
                    }

                    int index = PrimeFactory.GetIndexFromValue(kvp.Key);
                    result[index] = true;
                }
            }

            return(result);
        }
Пример #2
0
        private void PrintCurrentCounts()
        {
            int smoothRelation_CurrentTarget = _gnfs.CurrentRelationsProgress.SmoothRelations_TargetQuantity;

            int smoothRelations_CurrentCount = _gnfs.CurrentRelationsProgress.SmoothRelations.Count;
            int smoothRelation_SavedCounter  = _gnfs.CurrentRelationsProgress.SmoothRelationsCounter;

            BigInteger rationalBase_Max  = _gnfs.PrimeFactorBase.RationalFactorBaseMax;
            BigInteger algebraicBase_Max = _gnfs.PrimeFactorBase.AlgebraicFactorBaseMax;
            BigInteger quadraticBase_Max = _gnfs.PrimeFactorBase.QuadraticFactorBaseMax;

            int rationalBase_Size  = PrimeFactory.GetIndexFromValue(rationalBase_Max);
            int algebraicBase_Size = PrimeFactory.GetIndexFromValue(algebraicBase_Max);
            int quadraticBase_Size = PrimeFactory.GetIndexFromValue(quadraticBase_Max);

            int rationalFactorPair_Count  = _gnfs.RationalFactorPairCollection.Count;
            int algebraicFactorPair_Count = _gnfs.AlgebraicFactorPairCollection.Count;
            int quadraticFactorPair_Count = _gnfs.QuadraticFactorPairCollection.Count;

            int smoothRelation_RequiredBeforeMatrixStep = _gnfs.CurrentRelationsProgress.SmoothRelationsRequiredForMatrixStep;

            Logging.LogMessage();
            Logging.LogMessage($"Required smooth relations found before beginning matrix step: {smoothRelation_RequiredBeforeMatrixStep}");
            Logging.LogMessage($"Smooth relations target value: {smoothRelation_CurrentTarget}");
            Logging.LogMessage();
            Logging.LogMessage($"Smooth relations currently loaded count: {smoothRelations_CurrentCount}");
            Logging.LogMessage($"Smooth relations saved counter: {smoothRelation_SavedCounter}");
            Logging.LogMessage();
            Logging.LogMessage($"quadraticFactorPair_Count: {quadraticFactorPair_Count}");
            Logging.LogMessage($"PrimeIndxOf(quadraticBase_Max): {PrimeFactory.GetIndexFromValue(quadraticBase_Max)}");
            Logging.LogMessage();
        }
Пример #3
0
        public void LargestPrimeFactorOfTwo()
        {
            long numberToFactor = 2;
            long expected       = 2;

            long actual = PrimeFactory.GetHighestPrime(numberToFactor);

            Assert.AreEqual(expected, actual);
        }
Пример #4
0
        public GaussianMatrix(GNFS gnfs, List <Relation> rels)
        {
            _gnfs = gnfs;
            relationMatrixTuple = new List <Tuple <Relation, bool[]> >();
            eliminationStep     = false;
            freeCols            = new bool[0];
            M = new List <bool[]>();


            int maxRelationsToSelect = PrimeFactory.GetIndexFromValue(_gnfs.PrimeFactorBase.RationalFactorBaseMax) + PrimeFactory.GetIndexFromValue(_gnfs.PrimeFactorBase.AlgebraicFactorBaseMax) + _gnfs.QuadraticFactorPairCollection.Count + 3;

            relations = rels;

            List <GaussianRow> relationsAsRows = new List <GaussianRow>();

            foreach (Relation rel in relations)
            {
                GaussianRow row = new GaussianRow(_gnfs, rel);

                relationsAsRows.Add(row);
            }

            //List<GaussianRow> orderedRows = relationsAsRows.OrderBy(row1 => row1.LastIndexOfAlgebraic).ThenBy(row2 => row2.LastIndexOfQuadratic).ToList();

            List <GaussianRow> selectedRows = relationsAsRows.Take(maxRelationsToSelect).ToList();

            int maxIndexRat = selectedRows.Select(row => row.LastIndexOfRational).Max();
            int maxIndexAlg = selectedRows.Select(row => row.LastIndexOfAlgebraic).Max();
            int maxIndexQua = selectedRows.Select(row => row.LastIndexOfQuadratic).Max();

            foreach (GaussianRow row in selectedRows)
            {
                row.ResizeRationalPart(maxIndexRat);
                row.ResizeAlgebraicPart(maxIndexAlg);
                row.ResizeQuadraticPart(maxIndexQua);
            }

            GaussianRow exampleRow = selectedRows.First();
            int         newLength  = exampleRow.GetBoolArray().Length;

            newLength++;

            selectedRows = selectedRows.Take(newLength).ToList();


            foreach (GaussianRow row in selectedRows)
            {
                relationMatrixTuple.Add(new Tuple <Relation, bool[]>(row.SourceRelation, row.GetBoolArray()));
            }
        }
Пример #5
0
        public void CaclulatePrimeFactorBaseBounds(BigInteger bound)
        {
            PrimeFactorBase = new FactorBase();

            PrimeFactorBase.RationalFactorBaseMax  = bound;
            PrimeFactorBase.AlgebraicFactorBaseMax = (PrimeFactorBase.RationalFactorBaseMax) * 3;

            PrimeFactorBase.QuadraticBaseCount = CalculateQuadraticBaseSize(PolynomialDegree);

            PrimeFactorBase.QuadraticFactorBaseMin = PrimeFactorBase.AlgebraicFactorBaseMax + 20;
            PrimeFactorBase.QuadraticFactorBaseMax = PrimeFactory.GetApproximateValueFromIndex((UInt64)(PrimeFactorBase.QuadraticFactorBaseMin + PrimeFactorBase.QuadraticBaseCount));

            Serialization.Save.All(this);
            LogMessage("Saved prime factor base bounds.");
        }
Пример #6
0
        public void SetPrimeFactorBases()
        {
            LogMessage($"Constructing new prime bases (- of 3)...");

            PrimeFactory.IncreaseMaxValue(PrimeFactorBase.QuadraticFactorBaseMax);

            PrimeFactorBase.RationalFactorBase = PrimeFactory.GetPrimesTo(PrimeFactorBase.RationalFactorBaseMax);
            //Serialization.Save.FactorBase.Rational(this);
            LogMessage($"Completed rational prime base (1 of 3).");

            PrimeFactorBase.AlgebraicFactorBase = PrimeFactory.GetPrimesTo(PrimeFactorBase.AlgebraicFactorBaseMax);
            //Serialization.Save.FactorBase.Algebraic(this);
            LogMessage($"Completed algebraic prime base (2 of 3).");

            PrimeFactorBase.QuadraticFactorBase = PrimeFactory.GetPrimesFrom(PrimeFactorBase.QuadraticFactorBaseMin).Take(PrimeFactorBase.QuadraticBaseCount);
            //Serialization.Save.FactorBase.Quadratic(this);
            LogMessage($"Completed quadratic prime base (3 of 3).");
        }
Пример #7
0
        public Tuple <BigInteger, BigInteger> CalculateAlgebraicSide(CancellationToken cancelToken)
        {
            bool solutionFound = false;

            RootsOfS.AddRange(RelationsSet.Select(rel => new Tuple <BigInteger, BigInteger>(rel.A, rel.B)));

            PolynomialRing = new List <IPolynomial>();
            foreach (Relation rel in RelationsSet)
            {
                // poly(x) = A + (B * x)
                IPolynomial newPoly =
                    new Polynomial(
                        new Term[]
                {
                    new Term(rel.B, 1),
                    new Term(rel.A, 0)
                }
                        );

                PolynomialRing.Add(newPoly);
            }

            if (cancelToken.IsCancellationRequested)
            {
                return(new Tuple <BigInteger, BigInteger>(1, 1));
            }

            BigInteger  m      = polyBase;
            IPolynomial f      = (Polynomial)monicPoly.Clone();
            int         degree = f.Degree;

            IPolynomial fd = Polynomial.GetDerivativePolynomial(f);
            IPolynomial d3 = Polynomial.Product(PolynomialRing);
            IPolynomial derivativeSquared = Polynomial.Square(fd);
            IPolynomial d2 = Polynomial.Multiply(d3, derivativeSquared);
            IPolynomial dd = Polynomial.Field.Modulus(d2, f);

            // Set the result to S
            S           = dd;
            SRingSquare = dd;
            TotalS      = d2;

            algebraicNormCollection = RelationsSet.Select(rel => rel.AlgebraicNorm);
            AlgebraicProduct        = d2.Evaluate(m);
            AlgebraicSquare         = dd.Evaluate(m);
            AlgebraicProductModF    = dd.Evaluate(m).Mod(N);
            AlgebraicSquareResidue  = AlgebraicSquare.Mod(N);

            IsAlgebraicIrreducible = IsPrimitive(algebraicNormCollection); // Irreducible check
            IsAlgebraicSquare      = AlgebraicSquareResidue.IsSquare();

            List <BigInteger> primes = new List <BigInteger>();
            List <Tuple <BigInteger, BigInteger> > resultTuples = new List <Tuple <BigInteger, BigInteger> >();

            BigInteger primeProduct = 1;

            BigInteger lastP = N / N.ToString().Length; //((N * 3) + 1).NthRoot(3); //gnfs.QFB.Select(fp => fp.P).Max();

            while (!solutionFound)
            {
                if (primes.Count > 0 && resultTuples.Count > 0)
                {
                    primes.Remove(primes.First());
                    resultTuples.Remove(resultTuples.First());
                }

                do
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        return(new Tuple <BigInteger, BigInteger>(1, 1));
                    }

                    lastP = PrimeFactory.GetNextPrime(lastP + 1);

                    Tuple <BigInteger, BigInteger> lastResult = AlgebraicSquareRoot(f, m, degree, dd, lastP);

                    if (lastResult.Item1 != 0)
                    {
                        primes.Add(lastP);
                        resultTuples.Add(lastResult);
                    }
                }while (primes.Count < degree);


                if (primes.Count > degree)
                {
                    primes.Remove(primes.First());
                    resultTuples.Remove(resultTuples.First());
                }

                primeProduct = (resultTuples.Select(tup => BigInteger.Min(tup.Item1, tup.Item2)).Product());

                if (primeProduct < N)
                {
                    continue;
                }

                AlgebraicPrimes = primes;

                if (cancelToken.IsCancellationRequested)
                {
                    return(new Tuple <BigInteger, BigInteger>(1, 1));;
                }

                IEnumerable <IEnumerable <BigInteger> > permutations =
                    Combinatorics.CartesianProduct(resultTuples.Select(tup => new List <BigInteger>()
                {
                    tup.Item1, tup.Item2
                }));

                BigInteger rationalSquareRoot  = RationalSquareRootResidue;
                BigInteger algebraicSquareRoot = 1;

                foreach (List <BigInteger> X in permutations)
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        return(new Tuple <BigInteger, BigInteger>(1, 1));;
                    }

                    algebraicSquareRoot = FiniteFieldArithmetic.ChineseRemainder(N, X, primes);

                    BigInteger min = BigInteger.Min(rationalSquareRoot, algebraicSquareRoot);
                    BigInteger max = BigInteger.Max(rationalSquareRoot, algebraicSquareRoot);

                    BigInteger A = max + min;
                    BigInteger B = max - min;

                    BigInteger U = GCD.FindGCD(N, A);
                    BigInteger V = GCD.FindGCD(N, B);

                    if (U > 1 && U != N)
                    {
                        BigInteger rem   = 1;
                        BigInteger other = BigInteger.DivRem(N, U, out rem);

                        if (rem == 0)
                        {
                            solutionFound              = true;
                            V                          = other;
                            AlgebraicResults           = X;
                            AlgebraicSquareRootResidue = algebraicSquareRoot;

                            return(new Tuple <BigInteger, BigInteger>(U, V));
                        }
                    }

                    if (V > 1 && V != N)
                    {
                        BigInteger rem   = 1;
                        BigInteger other = BigInteger.DivRem(N, V, out rem);

                        if (rem == 0)
                        {
                            solutionFound = true;

                            U = other;
                            AlgebraicResults           = X;
                            AlgebraicSquareRootResidue = algebraicSquareRoot;

                            return(new Tuple <BigInteger, BigInteger>(U, V));
                        }
                    }
                }

                if (!solutionFound)
                {
                    gnfs.LogFunction($"No solution found amongst the algebraic square roots {{ {string.Join(", ", resultTuples.Select(tup => $"({ tup.Item1}, { tup.Item2})"))} }} mod primes {{ {string.Join(", ", primes.Select(p => p.ToString()))} }}");
                }
            }

            return(new Tuple <BigInteger, BigInteger>(1, 1));
        }
Пример #8
0
 public override Result DoPrime()
 {
     return(PrimeFactory.GetIPrimable().DoPrime(this));
 }
Пример #9
0
        public static void GaussianSolve(CancellationToken cancelToken, GNFS gnfs)
        {
            Serialization.Save.Relations.Smooth.Append(gnfs);             // Persist any relations not already persisted to disk

            // Because some operations clear this collection after persisting unsaved relations (to keep memory usage light)...
            // We completely reload the entire relations collection from disk.
            // This ensure that all the smooth relations are available for the matrix solving step.
            Serialization.Load.Relations.Smooth(ref gnfs);


            List <Relation> smoothRelations = gnfs.CurrentRelationsProgress.SmoothRelations.ToList();

            int smoothCount = smoothRelations.Count;

            int maxRelationsToSelect =
                PrimeFactory.GetIndexFromValue(gnfs.PrimeFactorBase.RationalFactorBaseMax)
                + PrimeFactory.GetIndexFromValue(gnfs.PrimeFactorBase.AlgebraicFactorBaseMax)
                + gnfs.QuadraticFactorPairCollection.Count
                + 3;

            gnfs.LogFunction($"Total relations: {smoothCount}");
            gnfs.LogFunction($"MaxRelationsToSelect: {maxRelationsToSelect}");
            gnfs.LogFunction($"Total / Max = {smoothCount / maxRelationsToSelect}");

            while (smoothRelations.Count >= maxRelationsToSelect)
            {
                // Randomly select n relations from smoothRelations
                List <Relation> selectedRelations = new List <Relation>();
                while (
                    selectedRelations.Count < maxRelationsToSelect
                    ||
                    selectedRelations.Count % 2 != 0                             // Force number of relations to be even
                    )
                {
                    int randomIndex = StaticRandom.Next(0, smoothRelations.Count);
                    selectedRelations.Add(smoothRelations[randomIndex]);
                    smoothRelations.RemoveAt(randomIndex);
                }

                GaussianMatrix gaussianReduction = new GaussianMatrix(gnfs, selectedRelations);
                gaussianReduction.TransposeAppend();
                gaussianReduction.Elimination();

                int number        = 1;
                int solutionCount = gaussianReduction.FreeVariables.Count(b => b) - 1;
                List <List <Relation> > solution = new List <List <Relation> >();
                while (number <= solutionCount)
                {
                    List <Relation> relations = gaussianReduction.GetSolutionSet(number);
                    number++;

                    BigInteger algebraic = relations.Select(rel => rel.AlgebraicNorm).Product();
                    BigInteger rational  = relations.Select(rel => rel.RationalNorm).Product();

                    CountDictionary algCountDict = new CountDictionary();
                    foreach (var rel in relations)
                    {
                        algCountDict.Combine(rel.AlgebraicFactorization);
                    }

                    bool isAlgebraicSquare = algebraic.IsSquare();
                    bool isRationalSquare  = rational.IsSquare();

                    gnfs.LogFunction("---");
                    gnfs.LogFunction($"Relations count: {relations.Count}");
                    gnfs.LogFunction($"(a,b) pairs: {string.Join(" ", relations.Select(rel => $"({rel.A},{rel.B})"))}");
                    gnfs.LogFunction($"Rational  ∏(a+mb): IsSquare? {isRationalSquare} : {rational}");
                    gnfs.LogFunction($"Algebraic ∏ƒ(a/b): IsSquare? {isAlgebraicSquare} : {algebraic}");
                    gnfs.LogFunction($"Algebraic (factorization): {algCountDict.FormatStringAsFactorization()}");

                    if (isAlgebraicSquare && isRationalSquare)
                    {
                        solution.Add(relations);
                        gnfs.CurrentRelationsProgress.AddFreeRelationSolution(relations);
                    }

                    if (cancelToken.IsCancellationRequested)
                    {
                        break;
                    }
                }

                if (cancelToken.IsCancellationRequested)
                {
                    break;
                }
            }
        }