public QuadraticCharacters Build() { var sieve = new EratosthenesSieve(); var primes = sieve.GetPrimes(_lowerBound + 1, _lowerBound + 100 * _size); var derivative = new PolynomialDerivative().Derivative(_polynomial); var result = new List <Pair>(); List <long> roots; for (int i = 0; i < primes.Length; i++) { roots = _rootFinder.FindRoots(_polynomial, primes[i]); for (int j = 0; j < roots.Count; j++) { if (derivative.Value(roots[j]) % primes[i] != 0) { result.Add(new Pair(roots[j], primes[i])); } if (result.Count == _size) { return(new QuadraticCharacters(result)); } } } return(new QuadraticCharacters(result)); }
public PolynomialMathTest() { var sieve = new EratosthenesSieve(); _primes = sieve.GetPrimes(2, 1000); _generator = new Random(); }
public RationalFactorbase Build() { var sieve = new EratosthenesSieve(); var result = new List <Pair>(); long interval = 10000000; if (_bound < interval) { interval = _bound; } for (long j = 3; j < _bound; j += interval) { var primes = sieve.GetPrimes(j, interval + j); result.Add(new Pair(_root % 2, 2)); for (int i = 0; i < primes.Length; i++) { result.Add(new Pair(_root % primes[i], primes[i])); } } return(new RationalFactorbase(result)); }
public void Init(ulong start) { _low = start; _sieveStep = 10000000; _sieve = new EratosthenesSieve(); _primes = _sieve.GetPrimes(_low, _low + _sieveStep); _currentIndex = 0; }
public ulong NextPrime() { if (_currentIndex == _primes.Length) { _low += _sieveStep; _primes = _sieve.GetPrimes(_low + 1, _low + _sieveStep); _currentIndex = 0; } return(_primes[_currentIndex++]); }
private long[] BuildFactorBase(BigInteger n) { var sieve = new EratosthenesSieve(); var legandre = new JacobiSymbol(); var sqt = new ModularSqrt(); _sqrtN = new Dictionary <long, long>(); return(sieve.GetPrimes(2, _primeBound).Where(p => { if (legandre.Calculate(n, p) == 1) { _sqrtN.Add(p, (long)sqt.Sqrt(n, p)); return true; } return false; }).ToArray()); }
public AlgebraicFactorbase Build() { var sieve = new EratosthenesSieve(); var result = new List <Pair>(); long interval = 10000000; if (_primeBound < interval) { interval = _primeBound; } var roots = _rootFinder.FindRoots(_polynomial, 2); for (int index = 0; index < roots.Count; index++) { result.Add(new Pair(roots[index], 2)); } for (long k = 3; k < _primeBound; k += interval) { var primes = sieve.GetPrimes(k, k + interval); for (int i = 0; i < primes.Length; i++) { Console.Write("\rAFB building. Current prime: " + primes[i] + " "); roots = _rootFinder.FindRoots(_polynomial, primes[i]); for (int j = 0; j < roots.Count; j++) { result.Add(new Pair(roots[j], primes[i])); } } } return(new AlgebraicFactorbase(result)); }
public Polynomial Sqrt(Polynomial sqr, Polynomial mod, Polynomial modDerivative, BigInteger sqrtNorm) { BigInteger max = 0; for (int i = 0; i <= sqr.Deg; i++) { if (BigInteger.Abs(sqr[i]) > max) { max = BigInteger.Abs(sqr[i]); } } var nextPrime = new NextPrime(); var bound = max * 10; var primes = new List <BigInteger>(); var sieve = new EratosthenesSieve(); var primesToCheck = sieve.GetPrimes(100000000, 110000000); BigInteger bigMod = 1; foreach (var primeToCheck in primesToCheck) { var irreducibilityTest = new IrreducibilityTest(); if (!irreducibilityTest.IsIrreducible(mod, primeToCheck)) { continue; } bigMod *= primeToCheck; primes.Add(primeToCheck); if (bigMod > bound) { break; } } var prime = 2 * primes[primes.Count - 1]; while (bigMod < bound) { prime = nextPrime.GetNext(prime); var irreducibilityTest = new IrreducibilityTest(); while (!irreducibilityTest.IsIrreducible(mod, prime)) { prime = nextPrime.GetNext(prime + 1); } bigMod *= prime; primes.Add(prime); } var sqrts = new List <Polynomial>(); foreach (var fieldChar in primes) { var polyMath = new PolynomialMath(fieldChar); var four = new Polynomial(new BigInteger[] { 4 }); Polynomial b; var isSqr = false; for (int i = 0; true; i++) { b = new Polynomial(new BigInteger[] { i }); var tmp = polyMath.ModPow(polyMath.Sub(polyMath.Mul(b, b), polyMath.Mul(four, sqr)), (BigInteger.Pow(fieldChar, mod.Deg) - 1) / 2, mod); isSqr = (tmp[0] == 1 || tmp[0] == -(fieldChar - 1)) && (tmp.Deg == 0); if (!isSqr) { break; } } var gfMath = new FiniteFieldMath(mod, fieldChar); var modPoly = new PolynomialOverFiniteField(new Polynomial[] { sqr, b, new Polynomial(new BigInteger[] { 1 }) }); var y = new PolynomialOverFiniteField(new Polynomial[] { new Polynomial(new BigInteger[] { 0 }), new Polynomial(new BigInteger[] { 1 }) }); var sqrt = gfMath.ModPow(y, (BigInteger.Pow(fieldChar, mod.Deg) + 1) / 2, modPoly)[0]; var sqrtNormMod = sqrtNorm * polyMath.ModPow(modDerivative, (BigInteger.Pow(fieldChar, mod.Deg) - 1) / (fieldChar - 1), mod)[0]; var norm = polyMath.ModPow(sqrt, (BigInteger.Pow(fieldChar, mod.Deg) - 1) / (fieldChar - 1), mod)[0]; sqrtNormMod %= fieldChar; if (sqrtNormMod < 0) { sqrtNormMod = sqrtNormMod + fieldChar; } if (norm < 0) { norm = norm + fieldChar; } if (norm != sqrtNormMod) { sqrt = polyMath.ConstMul(-1, sqrt); } sqrts.Add(sqrt); } BigInteger[] result = new BigInteger[mod.Deg]; var crt = new GarnerCrt(); for (int i = 0; i < mod.Deg; i++) { var coefficients = new List <BigInteger>(); for (int j = 0; j < primes.Count; j++) { coefficients.Add(sqrts[j][i]); } result[i] = crt.Calculate(coefficients, primes); } var resultPoly = new Polynomial(result); for (int i = 0; i <= resultPoly.Deg; i++) { var coeff = BigInteger.Abs(resultPoly[i]); if (coeff > max) { if (resultPoly[i] < 0) { resultPoly[i] += bigMod; } else { resultPoly[i] -= bigMod; } } } return(resultPoly); }
public BigInteger Calculate(Curve curve, ulong b1, ulong b2, ulong b3) { var arithmetic = new MontgomeryArithmetic(); var sieve = new EratosthenesSieve(); var primeManager = new PrimeManager(); var point = curve.Point; ulong prime = 2; var mod = curve.Mod; BigInteger product = 1; while (prime < b1) { point = arithmetic.Double(point, curve); prime = prime * 2; product = (point.Z * product) % mod; } var gcd = BigInteger.GreatestCommonDivisor(product, mod); if (gcd > 1) { return(gcd); } ulong[] primes; ulong upPrimeLimit = 1000000; ulong lowPrimeLimit = 3; ulong sievestep = 10000000; if (b1 < upPrimeLimit) { upPrimeLimit = b1; } ulong partCount = b1 / sievestep; for (ulong j = 0; j <= partCount; j++) { primes = sieve.GetPrimes(lowPrimeLimit, upPrimeLimit); for (int i = 0; i < primes.Length; i++) { var p = primes[i]; prime = p; while (prime < b1) { point = arithmetic.MontgomeryMul(point, p, curve); prime = prime * p; product = (point.Z * product) % mod; } gcd = BigInteger.GreatestCommonDivisor(product, mod); if (gcd > 1) { return(gcd); } } lowPrimeLimit = upPrimeLimit; upPrimeLimit += sievestep; } if (b2 % 2 == 0) { b2--; } ulong precomputedDataSize = 1000; var precomputedData = new ProjectivePoint[precomputedDataSize]; precomputedData[0] = arithmetic.Double(point, curve); precomputedData[1] = arithmetic.Double(precomputedData[0], curve); for (ulong i = 2; i < precomputedDataSize; i++) { precomputedData[i] = arithmetic.Add(precomputedData[i - 1], precomputedData[0], precomputedData[i - 2], curve); } if (b2 <= 2 * precomputedDataSize) { b2 = precomputedDataSize + 2; } product = 1; var R = arithmetic.MontgomeryMul(point, b2, curve); var T = arithmetic.MontgomeryMul(point, b2 - 2 * precomputedDataSize, curve); primeManager.Init(b2 + 1); for (ulong i = b2; i < b3; i = i + 2 * precomputedDataSize) { for (ulong j = 0; j < precomputedDataSize; j++) { prime = primeManager.NextPrime(); var delta = (prime - i) / 2; if (delta >= (ulong)precomputedData.Length) { break; } product = (product * (R.X * precomputedData[delta - 1].Z - R.Z * precomputedData[delta - 1].X)) % curve.Mod; } gcd = BigInteger.GreatestCommonDivisor(curve.Mod, product); if (gcd > 1) { return(gcd); } var temp = T; T = R; R = arithmetic.Add(R, precomputedData[precomputedDataSize - 1], temp, curve); } return(1); }