예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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
            });
        }
예제 #4
0
        /// <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
            });
        }
예제 #5
0
 /// <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));
 }
예제 #6
0
        /// <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
            });
        }