Beispiel #1
0
        static void MyQuadraticsTest()
        {
            BigInteger   N        = 9028325;
            int          B        = 35;
            SieveRequest sievereq = new SieveRequest();

            QuadraticSieve.InitSievingRequest(N, B, x => x * x - N, sievereq);
            QuadraticSieve.SegmentSievingRequest((int)N.Sqrt() + 1, B << 5, sievereq);
            SievingData sievedat = new SievingData();

            QuadraticSieve.Sieve(sievereq, sievedat);
            SieveResult sieveres = new SieveResult();

            QuadraticSieve.CreateFormattedSievingResult(sievereq, sievedat, sieveres);
            printarr(sieveres.V);
            printarr(sieveres.SmoothRelations);
            Console.WriteLine();
            SolveRequest solvereq = new SolveRequest();

            QuadraticSieve.InitSolveRequest(sievereq.B, sieveres.V.Count, solvereq);
            QuadraticSieve.AddDataToSolveRequest(sieveres, solvereq);
            printarr(solvereq.Coefficients);
            Console.WriteLine();
            QuadraticSieve.Gaussian(solvereq);
            printarr(solvereq.Coefficients);
            Console.WriteLine("First free = " + solvereq.FirstFree);
        }
 static void Main(string[] args)
 {
     QuadraticSieve.primeSupply = new derpy();
     BigInteger N = 90283;
     int B = 14;
     SieveRequest sievereq = new SieveRequest();
     QuadraticSieve.InitSievingRequest(N, B, x => x * x - N, sievereq);
     QuadraticSieve.SegmentSievingRequest(0, 60, sievereq);
     SievingData sievedat = new SievingData();
     QuadraticSieve.EvaluatePoly(sievereq, sievedat);
     QuadraticSieve.Sieve(sievereq, sievedat);
     SieveResult sieveres = new SieveResult();
     QuadraticSieve.CreateFormattedSievingResult(sievereq, sievedat, sieveres);
     printarr(sieveres.V);
     printarr(sieveres.SmoothRelations);
     Console.WriteLine();
     SolveRequest solvereq = new SolveRequest();
     QuadraticSieve.InitSolveRequest(sievereq.B, sieveres.V.Count, solvereq);
     QuadraticSieve.AddDataToSolveRequest(sieveres, solvereq);
     printarr(solvereq.Coefficients);
     Console.WriteLine();
     QuadraticSieve.Gaussian(solvereq);
     printarr(solvereq.Coefficients);
     Console.ReadLine();
 }
Beispiel #3
0
 public static void EvaluatePoly(SieveRequest sievereq, SievingData sievedat)
 {
     sievedat.V = new BigInteger[sievereq.L];
     for (int i = 0; i < sievereq.L; i++)
     {
         sievedat.V[i] = sievereq.polyFunction(i + sievereq.AStart + StartIdx);
     }
 }
 /// <summary>
 /// Generates data to be sieved from the given SieveRequest
 /// </summary>
 /// <param name="sievereq"></param>
 /// <param name="sievedat">The SieveData object to fill with data</param>
 public static void EvaluatePoly(SieveRequest sievereq, SievingData sievedat)
 {
     sievedat.V = new BigInteger[sievereq.L];
     for (int i = 0; i < sievereq.L; i++)
     {
         sievedat.V[i] = sievereq.polyFunction(i + sievereq.AStart + sievereq.StartIdx);
     }
 }
Beispiel #5
0
 public static void CreateFormattedSievingResult(SieveRequest sievereq, SievingData sievedat, SieveResult sieveres)
 {
     sieveres.SourceRequest   = sievereq;
     sieveres.SmoothRelations = new List <BinaryVector>();
     sieveres.V = new List <BigInteger>();
     for (int i = 0; i < sievereq.L; i++)
     {
         //if number only consisted of primes that were sieved, then it is smooth
         if (sievedat.V[i] == 1)
         {
             sieveres.V.Add(sievereq.polyFunction(i + sievereq.AStart + StartIdx));
             sieveres.SmoothRelations.Add(sievedat.Coefficients[i]);
         }
     }
 }
Beispiel #6
0
        //really weird sieving method
        public static void Sieve(SieveRequest sievereq, SievingData sievedat)
        {
            //get data first
            EvaluatePoly(sievereq, sievedat);

            //make transposed matrix (each BinaryVector holds the factorization for a number)
            sievedat.Coefficients = new BinaryVector[sievereq.L];

            //loop through each prime
            for (int i = 0; i < sievereq.B; i++)
            {
                //get value of prime
                int interval = sievereq.PrimeIntervals[i];
                //loop through each solution of the quadratic residue
                for (int j = 0; j < sievereq.PrimeStarts[i].Count; j++)
                {
                    //remap start location to this sieving interval
                    int remappedStart = (interval - (StartIdx - sievereq.PrimeStarts[i][j])) % interval;
                    if (remappedStart < 0)
                    {
                        remappedStart = remappedStart + interval;
                    }

                    //sieve out each prime
                    for (int k = remappedStart; k < sievereq.L; k += interval)
                    {
                        //attempt to save memory by not initializating the arrayelements that haven't been used yet
                        //NOTE: this doesn't work, because at least half of the elements will have been visited
                        if (Object.ReferenceEquals(sievedat.Coefficients[k], null))
                        {
                            sievedat.Coefficients[k] = new BinaryVector(sievereq.B);
                        }

                        //divide out the whole prime power
                        while (sievedat.V[k] % interval == 0)
                        {
                            sievedat.Coefficients[k][i] = sievedat.Coefficients[k][i] + 1;
                            sievedat.V[k] = sievedat.V[k] / interval;
                        }
                    }
                }
            }
        }
        /// <summary>  v    cQ1
        ///  Initializes a SievingRequest based on given parameters, and finds the quadratic residues for primes specified
        /// </summary>
        /// <param name="N">The number to factor</param>
        /// <param name="B">The limit for smooth numbers</param>
        /// <param name="f">The polynomial to sieve</param>
        /// <param name="sievereq">The SieveRequest that will be initialized</param>
        public static void InitSievingRequest(BigInteger N, int B, PolynomialFunction f, SieveRequest sievereq)
        {
            sievereq.AStart = (int)N.Sqrt() + 1;
            sievereq.StartIdx = 0;
            sievereq.polyFunction = f;
            sievereq.L = primeSupply[B];

            SievingData sievedat = new SievingData();

            EvaluatePoly(sievereq, sievedat);

            List<List<int>> tmpPrimeStarts = new List<List<int>>();
            List<int> tmpPrimeIntervals = new List<int>();

            for (int pI = 0; pI < B; pI++)
            {
                int p = primeSupply[pI];
                List<int> tmp = new List<int>();
                for (int a = 0; a < p; a++)
                {
                    if (sievedat.V[a] % p == 0)
                    {
                        tmp.Add(a);
                    }
                }
                if (tmp.Count > 0)
                {
                    tmpPrimeIntervals.Add(p);
                    tmpPrimeStarts.Add(tmp);
                }
            }

            sievereq.PrimeIntervals = tmpPrimeIntervals.ToArray();
            sievereq.PrimeStarts = tmpPrimeStarts.ToArray();
            sievereq.B = sievereq.PrimeIntervals.Length;
        }
        /// <summary>
        /// Sieves data in the sievedat object
        /// </summary>
        /// <param name="sievereq"></param>
        /// <param name="sievedat"></param>
        public static void Sieve(SieveRequest sievereq, SievingData sievedat)
        {
            sievedat.Coefficients = new BinaryVector[sievereq.L];

            for (int i = 0; i < sievereq.B; i++)
            {
                int interval = sievereq.PrimeIntervals[i];
                for (int j = 0; j < sievereq.PrimeStarts[i].Count; j++)
                {
                    int remappedStart = (interval - (sievereq.StartIdx - sievereq.PrimeStarts[i][j])) % interval;
                    if (remappedStart < 0)
                        remappedStart = remappedStart + interval;
                    for (int k = remappedStart; k < sievereq.L; k += interval)
                    {
                        if (Object.ReferenceEquals(sievedat.Coefficients[k], null))
                            sievedat.Coefficients[k] = new BinaryVector(sievereq.B);

                        while (sievedat.V[k] % interval == 0)
                        {
                            sievedat.Coefficients[k][i] = sievedat.Coefficients[k][i] + 1;
                            sievedat.V[k] = sievedat.V[k] / interval;
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Gets a segment of a sieve request
 /// </summary>
 /// <param name="startIdx">The start index of the segment</param>
 /// <param name="L">The length of the segment</param>
 /// <param name="sievereq">The SieveRequest to cut</param>
 public static void SegmentSievingRequest(int startIdx, int L, SieveRequest sievereq)
 {
     sievereq.StartIdx = startIdx;
     sievereq.L = L;
 }
 /// <summary>
 /// Formats data in a SieveData object into a proper SieveResult
 /// </summary>
 /// <param name="sievereq"></param>
 /// <param name="sievedat">The data to be formatted</param>
 /// <param name="sieveres">The SieveResult object where the formatted data will be put</param>
 public static void CreateFormattedSievingResult(SieveRequest sievereq, SievingData sievedat, SieveResult sieveres)
 {
     sieveres.SourceRequest = sievereq;
     sieveres.SmoothRelations = new List<BinaryVector>();
     sieveres.V = new List<BigInteger>();
     for (int i = 0; i < sievereq.L; i++)
     {
         if (sievedat.V[i] == 1)
         {
             sieveres.V.Add(sievereq.polyFunction(i + sievereq.AStart + sievereq.StartIdx));
             sieveres.SmoothRelations.Add(sievedat.Coefficients[i]);
         }
     }
 }
Beispiel #11
0
 public static void SegmentSievingRequest(int startIdx, int L, SieveRequest sievereq)
 {
     StartIdx   = startIdx;
     sievereq.L = L;
 }
Beispiel #12
0
        public static void InitSievingRequest(BigInteger N, int B, PolynomialFunction f, SieveRequest sievereq)
        {
            sievereq.AStart       = (int)N.Sqrt() + 1;
            StartIdx              = 0;
            sievereq.polyFunction = f;
            //the max amount of data we need to find the quadratic residues is the Bth prime (the highest one)
            sievereq.L = primeSupply[B];

            SievingData sievedat = new SievingData();

            EvaluatePoly(sievereq, sievedat);

            List <List <int> > tmpPrimeStarts    = new List <List <int> >();
            List <int>         tmpPrimeIntervals = new List <int>();

            for (int pI = 0; pI < B; pI++)
            {
                int        p   = primeSupply[pI];
                List <int> tmp = new List <int>();
                for (int a = 0; a < p; a++)
                {
                    if (sievedat.V[a] % p == 0)
                    {
                        //we found a quadratic residue (there are two for each prime that isn't 2)
                        tmp.Add(a);
                    }
                }
                if (tmp.Count > 0)
                {
                    //if the ith value is divisible by the prime k, then every k results after that will also be divisible
                    tmpPrimeIntervals.Add(p);
                    tmpPrimeStarts.Add(tmp);
                }
            }

            sievereq.PrimeIntervals = tmpPrimeIntervals.ToArray();
            sievereq.PrimeStarts    = tmpPrimeStarts.ToArray();
            //remove primes with no quadratic residues
            sievereq.B = sievereq.PrimeIntervals.Length;
        }