private bool TrialDivision( BigInteger b, List <long> p, List <PrimeExpon> lpe) { BigInteger tb = b; PrimeExpon pe = new PrimeExpon(); if (b == 0 || b == 1 || b == -1) { return(false); } if (tb < 0) { tb = -tb; pe.prime = -1; pe.expon = +1; lpe.Add(pe); } for (int i = 1; i < p.Count; i++) { long exp = 0; BigInteger q = p[i]; if (tb % q == 0) { do { exp++; tb /= q; } while (tb % q == 0); pe.prime = (long)q; pe.expon = exp; lpe.Add(pe); if (tb == 1 || !hcr.Composite(tb, 20)) { return(true); } } } return(false); }
public int Sieve(int maxI, int maxKernels, ref BigInteger n, ref List <long> times, ref List <FactorExpon> lfe) { if (n <= 1) { return(-3); } if (!hcr.Composite(n, 20)) { return(0); } bool done = false; int i = 1, count = 0, kernels = 0, result = -1; List <long> p = null; List <BigInteger> ai = new List <BigInteger>(); List <BigInteger> bi = new List <BigInteger>(); List <BigInteger> ff = new List <BigInteger>(); sw0.Start(); while (!done) { if (bw.CancellationPending) { return(-2); } p = new List <long>(); p.Add(-1); for (int j = 0; !done && j < primes.Count; j++) { BigInteger q = primes[j]; if (hcr.Jacobi(n, q) != -1) { p.Add((long)q); done = p.Count == t; } } if (!done) { B0 += 1000000; primes = new List <long>(); sp.Sieve(B0, ref primes); } } sw0.Stop(); long millis0 = sw0.ElapsedMilliseconds, millis1 = 0; BigInteger m = Sqrt(n), x = 0; times.Add(millis0); sw0.Restart(); while (i <= maxI && kernels < maxKernels) { if (bw.CancellationPending) { return(-2); } if (i == 1) { x = 0; } else if (i % 2 == 0) { x = +i / 2; } else { x = -i / 2; } BigInteger xm = x + m, b = xm * xm - n; List <PrimeExpon> lpe = new List <PrimeExpon>(); if (TrialDivision(b, p, lpe)) { for (int j = 0; j < t; j++) { e[count, j] = v[count, j] = 0; } for (int j = 0; j < t; j++) { long q = p[j]; for (int k = 0; k < lpe.Count; k++) { PrimeExpon pe = lpe[k]; if (q == pe.prime) { e[count, j] = (sbyte)pe.expon; v[count, j] = (sbyte)(pe.expon % 2); break; } } } ai.Add(xm); bi.Add(b); count++; if (count == t1) { int r = 0; int[] d = new int[t]; sw1.Restart(); la.KernelOverZ2(t1, t, d, ref v, ref r); sw1.Stop(); millis1 += sw1.ElapsedMilliseconds; kernels++; BigInteger X = 1; for (int k = 0; k < t1; k++) { X = (ai[k] * X) % n; } for (int k = 0; k < t; k++) { if (bw.CancellationPending) { return(-2); } int dk = d[k]; if (dk >= 0) { BigInteger Y = 1; for (int j = 0; j < t; j++) { if (e[dk, j] % 2 != 0) { Y = (p[j] * Y) % n; } } BigInteger XmY = (X - Y) % n; if (XmY != 0 && XmY != 1) { BigInteger factor = BigInteger.GreatestCommonDivisor(XmY, n); if (factor > 1 && !ff.Contains(factor)) { ff.Add(factor); if (CompositeFactor(factor, ref n, ref lfe)) { result = 2; } else { result = 1; } } } } } count -= 10; if (count < 0) { count = 0; } kernels++; } } if (result != -1) { break; } i++; } sw0.Stop(); millis0 = sw0.ElapsedMilliseconds; times.Add(millis0); times.Add(millis1); return(result); }