private static void SingleThread(SieveReqGen gen, long smoothsNeeded, SolveRequest o) { long start; long len; SieveInitInfo req; while (true) { if (!gen.NextSegment(out start, out len, out req)) { break; } var currResult = new SieveResult(); Sieve(req, currResult, start, len); lock (o) { if (!o.AddDataToSolveRequestMax(currResult)) { break; } Console.WriteLine("{0} out of {1} smooth numbers found...", o.L, smoothsNeeded); } } }
public static SolveRequest MultiThreadSieve(long smoothsNeeded, int B, SieveReqGen reqGen, int numThreads, int milliswait) { SolveRequest ret = new SolveRequest(B, smoothsNeeded); Thread[] t = new Thread[numThreads]; for (int i = 0; i < numThreads; i++) { t[i] = new Thread(() => SingleThread(reqGen, smoothsNeeded, ret)); t[i].Start(); } bool flag = true; while (flag) { flag = false; for (int i = 0; i < numThreads; i++) { if (t[i].IsAlive) { flag = true; } } Thread.Sleep(milliswait); } return(ret); }
public static SolveResult Gaussian(SolveRequest solvereq) { GuassianSolveResult result = new GuassianSolveResult(solvereq.B, solvereq.L); for (int i = 0; i < Math.Min(solvereq.B, solvereq.L); i++) { if (solvereq.Coefficients[i][i] == 0) { for (int j = i + 1; j < solvereq.B; j++) { if (solvereq.Coefficients[j][i] == 1) { BinaryVector tmp = solvereq.Coefficients[j]; solvereq.Coefficients[j] = solvereq.Coefficients[i]; solvereq.Coefficients[i] = tmp; break; } } } if (solvereq.Coefficients[i][i] == 1) { for (int j = 0; j < solvereq.B; j++) { if (j != i) { if (solvereq.Coefficients[j][i] == 1) { BinaryVector.FastAdd(solvereq.Coefficients[j], solvereq.Coefficients[i]); } } } } else { solvereq.Coefficients[i][i] = 1;//<-this may or may not work BinaryVector col = new BinaryVector(solvereq.B); for (int j = 0; j < solvereq.B; j++) { col[j] = solvereq.Coefficients[j][i]; } result.reducedMatrix.Add(col); } } result.End(); return(result); }
public static bool GetFactor(BigInteger n, SolveRequest req, SolveResult res, out BigInteger factor) { while (!res.HasNext()) { BinaryVector v = res.GetNextSolution(); // Program.printarr(v); BigInteger S = 1; BigInteger A = 1; for (int i = 0; i < req.L; i++) { if (v[i] == 1) { S *= req.VOut[i]; A *= req.V[i]; } } BigInteger sqrtS = S.Sqrt(); BigInteger f1 = A - sqrtS; BigInteger f2 = A + sqrtS; // Console.WriteLine("A={0}, S={1}, sqrt(S)={2}, f1={3}, f2={4}",A,S,sqrtS,f1,f2); factor = BigInteger.GreatestCommonDivisor(f1, n); if (factor != n && factor != 1) { return(true); } factor = BigInteger.GreatestCommonDivisor(f2, n); if (factor != n && factor != 1) { return(true); } } factor = -1; return(false); }
static void MyQuadraticsTest() { BigInteger N = BigInteger.Parse(Console.ReadLine()); int B = slkjhjdf.SmallPrimes.Length - 1; SieveInitInfo req = new SieveInitInfo(B, new AS2MNPolyFunc(N)); //the max amount of data we need to find the quadratic residues is the Bth prime (the highest one) QuadraticSieve.FindQuadraticResidues(req); // QuadraticSieve.Sieve(req, res, 0, 109090); Console.WriteLine("Sieving for smooths..."); SolveRequest sreq = QuadraticSieve.MultiThreadSieve(B + 10, B, new SinglePolynomialGen(req, 200000), 2, 500); Console.WriteLine("Done sieving. Performing solve..."); SolveResult sres = QuadraticSieve.Gaussian(sreq); // sreq.V.ForEach(x => Console.WriteLine(x * x - N)); BigInteger factor; if (QuadraticSieve.GetFactor(N, sreq, sres, out factor)) { Console.WriteLine("{0} = {1} * {2}", N, factor, N / factor); } }