public PointOfEC(PointOfEC p) { EllepticCurve = p.EllepticCurve; X = p.X; Y = p.Y; IsInfinity = p.IsInfinity; }
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); }
public PointOfEC Mult(BigInteger k, PointOfEC p) { if (k.IsZero) { throw new Exception("Попытка умножить на 0"); } PointOfEC b = p; PointOfEC q = new PointOfEC() { IsInfinity = true }; while (!k.IsZero) { if (k % 2 == 1) { q = Sum(q, b); } b = Sum(b, b); k /= 2; } return(q); }
/// <summary> Сравнение на равенство двух точек </summary> public bool Equals(PointOfEC point) { return(this == point || this.IsInfinity && point.IsInfinity || X == point.X && Y == point.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="point1"> Первая точка</param> /// <param name="point2"> Вторая точка</param> public PointOfEC Sum(PointOfEC point1, PointOfEC point2) { if (point1.Equals(point2.Invariant())) { return new PointOfEC() { EllepticCurve = this, IsInfinity = true } } ; if (point1.IsInfinity) { return(point2); } if (point2.IsInfinity) { return(point1); } var lamdZnam = point2.X - point1.X >= BigInteger.Zero ? point2.X - point1.X : point2.X - point1.X + p; if (lamdZnam != 0 && BigInteger.GreatestCommonDivisor(lamdZnam, p) > 1) { throw new GcdFoundException(BigInteger.GreatestCommonDivisor(lamdZnam, p)); } point1.X = point1.X % p; point2.X = point2.X % p; point1.Y = point1.Y % p; point2.Y = point2.Y % p; BigInteger lambda; if (!point1.Equals(point2)) { lambda = BigInteger.Multiply(point2.Y - point1.Y, ExtraBigIntegerExtensions.Inverse(point2.X - point1.X, p)); } else { lambda = (3 * point1.X * point1.X + a) * ExtraBigIntegerExtensions.Inverse(2 * point2.Y, p); } lambda = lambda % p; var x = lambda * lambda - point1.X - point2.X; var y = lambda * (point1.X - x) - point1.Y; var result = new PointOfEC() { EllepticCurve = this, X = x % p, Y = y % p }; return(new PointOfEC() { //указать явно //IsInfinity = false, EllepticCurve = this, X = result.X >= BigInteger.Zero ? result.X : result.X + p, Y = result.Y >= BigInteger.Zero ? result.Y : result.Y + p }); }