示例#1
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
            });
        }
示例#2
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
            });
        }