private int countPointInner(long start, long end) { var count = 0; var pLong = (long)p; if (end >= pLong) { end = pLong; } for (long x = start; x < end; x++) { var z = (long)ExtraBigIntegerExtensions.Mod(x * x * x + a * x + b, p); if (z == 0) { count++; } else { var legendreSymbol = BigIntegerExtensions.jacobi(z, pLong); if (legendreSymbol == 1) { count += 2; } } } return(count); }
public void CreateBasis() { BigInteger x = 0; var y = Math.Sqrt((double)ExtraBigIntegerExtensions.Mod(x * x * x + a * x + b, p)); while (x < p && ((long)(y * tenExp) % tenExp != 0)) { x++; y = Math.Sqrt((double)ExtraBigIntegerExtensions.Mod(x * x * x + a * x + b, p)); } Basis = CreatePoint(x, (BigInteger)y); }
/// <summary> /// Возвращает объект LenstraFactorizationResult, /// если находится какое-то число, то все осатльные потоки прекращаются /// </summary> /// <param name="n">Число, у которого требуется найти делитель</param> /// <param name="token">Токен отмены</param> public LenstraFactorizationResult GetDividerWithCancel(BigInteger n, Random random, CancellationToken token) { var startTime = DateTime.Now; BigInteger g, x, y, a, b; int k = 0; do { x = BigIntegerExtensions.GetNextRandom(random, n); y = BigIntegerExtensions.GetNextRandom(random, n); a = BigIntegerExtensions.GetNextRandom(random, n); k++; b = ExtraBigIntegerExtensions.Mod(y * y - x * x * x - a * x, n); g = BigInteger.GreatestCommonDivisor(n, 4 * a * a * a + 27 * b * b); } while (g == n); EllepticCurve ec = null; try { if (g != 1) { throw new GcdFoundException(g); } ec = new EllepticCurve(a, b, n); var p0 = new PointOfEC { EllepticCurve = ec, X = x, Y = y }; ec.LenstraStartingPoint = p0; var P = new PointOfEC(p0); BigInteger p = 2; while (p < B1 && !token.IsCancellationRequested) { var pr = p; while (pr < B1) { P = ec.Mult(p, P); pr *= p; } p = BigIntegerExtensions.NextPrimaryMillerRabin(p); } } catch (GcdFoundException exc) { Console.WriteLine("Поток {0} молодец: {1} = {2} * {3}", Task.CurrentId, n, exc.GreatestCommonDivisor, n / exc.GreatestCommonDivisor); return(new LenstraFactorizationResult { EllepticCurve = ec, TargetNumber = n, Divider = exc.GreatestCommonDivisor, WastedTime = DateTime.Now - startTime }); } if (token.IsCancellationRequested) { Console.WriteLine("Поток {0} остановлен", Task.CurrentId); } else { Console.WriteLine("Поток {0} не смог", Task.CurrentId); } return(new LenstraFactorizationResult { EllepticCurve = ec, TargetNumber = n, WastedTime = DateTime.Now - startTime }); }
/// <summary> Возвращает объект LenstraFactorizationResult </summary> /// <param name="n">Число, у которого требуется найти делитель</param> public LenstraFactorizationResult GetDivider(BigInteger n, Random random) { var startTime = DateTime.Now; BigInteger g, x, y, a, b; int k = 0; do { x = BigIntegerExtensions.GetNextRandom(random, n); y = BigIntegerExtensions.GetNextRandom(random, n); a = BigIntegerExtensions.GetNextRandom(random, n); k++; b = ExtraBigIntegerExtensions.Mod(y * y - x * x * x - a * x, n); g = BigInteger.GreatestCommonDivisor(n, 4 * a * a * a + 27 * b * b); } while (g == n); //убираем влияние выбора рандомного числа на время работы алгоритма //startTime = startTime + new TimeSpan(0, 0, 0, k*3); EllepticCurve ec = null; try { if (g != 1) { throw new GcdFoundException(g); } ec = new EllepticCurve(a, b, n); var p0 = new PointOfEC { EllepticCurve = ec, X = x, Y = y }; ec.LenstraStartingPoint = p0; var P = new PointOfEC(p0); BigInteger p = 2; while (p < B1) { var pr = p; while (pr < B1) { P = ec.Mult(p, P); pr *= p; } p = BigIntegerExtensions.NextPrimaryMillerRabin(p); } } catch (GcdFoundException exc) { Console.WriteLine("Поток {0} молодец: {1} = {2} * {3}", Task.CurrentId, n, exc.GreatestCommonDivisor, n / exc.GreatestCommonDivisor); return(new LenstraFactorizationResult { EllepticCurve = ec, TargetNumber = n, Divider = exc.GreatestCommonDivisor, WastedTime = DateTime.Now - startTime }); } return(new LenstraFactorizationResult { EllepticCurve = ec, TargetNumber = n, WastedTime = DateTime.Now - startTime }); }
/// <summary> Содержит ли ЭК точку? </summary> /// <param name="X">координата Х</param> /// <param name="Y">координата Y</param> /// <returns></returns> public bool ContainsPoint(BigInteger X, BigInteger Y) { return(ExtraBigIntegerExtensions.Mod(Y * Y, p) == ExtraBigIntegerExtensions.Mod(X * X * X + a * X + b, p)); }