Exemplo n.º 1
0
        ////Функция нахождения порядка кривой в афинных координатах
        //public static BigInteger FindOrder(EllipticCurve E)
        //{
        //    var Z = E.P;
        //    var rand = new Random();
        //    var startPoint = BasePoint.RandomPoint<PointAffine>(E);
        //    // Найдем границы по теореме Хассе
        //    var leftBorder = Z + 1 - 2 * (FieldsOperations.Sqrt(Z));
        //    var rightBorder = Z + 1 + 2 * (FieldsOperations.Sqrt(Z));
        //    for (int c = 0; c < NUMBER_OF_ATTEMPTS; c++)
        //    {
        //        //Сгенерируем точку на кривой и найдем ее порядок
        //        var P = BasePoint.RandomPoint<PointAffine>(E);
        //        var M = E.FindPointOrder(P);
        //        startPoint = P;
        //        if (M == 0)
        //            continue;
        //        int countOfDevided = 0;
        //        var order = BigInteger.Zero;
        //        //Найдем число делителей порядка точки в границах
        //        for (var i = leftBorder; i < rightBorder; )
        //        {
        //            if (i % M == 0)
        //            {
        //                order = i;
        //                i += M;
        //                countOfDevided++;
        //                if (countOfDevided > 1)
        //                    break;
        //            }
        //            else
        //            {
        //                i++;
        //            }
        //        }
        //        //Если оно равно единице, то порядок кривой - делитель порядка точки
        //        if (countOfDevided == 1)
        //        {
        //            E.Order = order;
        //            return order;
        //        }
        //    }
        //    return 0;
        //}

        public static BigInteger FindPointOrder(AffinePoint P)
        {
            var point = P;
            //var rand = new Random();
            var        rand = new BigIntegerRandom();
            BigInteger M    = 0;
            //Создаем список точек
            var A = new List <AffinePoint>();
            var Q = (P.E.P + 1) * point;

            A.Add(new AffinePoint());
            A[0].X = 0;
            A[0].Y = 0;
            A[0].Z = 1;
            A[0].E = P.E;
            A.Add(point);
            var max   = BigInteger.One;
            int count = 0;

            for (; count < P.E.P; count++)
            {
                M = 0;
                // генерерируем число m
                var m = BigIntegerExtension.Sqrt(BigIntegerExtension.Sqrt(P.E.P)) + 1 + rand.Next(0, P.E.P);
                if (m > max)
                {
                    //дозаполняем список
                    for (BigInteger i = 0; i < m - max; i++)
                    {
                        A.Add(point + A[A.Count - 1]);
                    }
                    max = m;
                }
                var  k     = -m - 1;
                int  j     = 0;
                bool flag  = true;
                var  twoMP = (2 * m) * point;
                var  temp  = Q + (k * twoMP);
                k++;
                //вычисляем параметры k и j
                for (; k < m && flag; k++)
                {
                    if (k < 0 && k != -m)
                    {
                        temp = temp - twoMP;
                    }
                    else
                    {
                        temp = temp + twoMP;
                    }

                    for (j = 0; j < A.Count && flag; j++)
                    {
                        if (temp == A[j])
                        {
                            j    = -j;
                            flag = false;
                            break;
                        }
                        if (temp == (-A[j]))
                        {
                            flag = false;
                            break;
                        }
                    }
                }
                k--;
                M = (P.E.P + 1 + 2 * m * k + j);
                if ((M * point) == P.E.GetInfiniteAffinePoint() && M != 0)
                {
                    break;
                }
            }
            if (count == P.E.P)
            {
                return(0);
            }
            // Раскладываем число M ро-методом Полларда
            List <BigInteger> factorsM;

            try
            {
                factorsM = BigIntegerExtension.PollardsAlg(BigInteger.Abs(M));
            }
            catch (Exception)
            {
                return(0);
            }
            // Проверяем простые делители числа M
            for (int i = 0; i < factorsM.Count;)
            {
                BigInteger temp = M / factorsM[i];
                if (M != factorsM[i] && M % factorsM[i] == 0 && (temp * point) == P.E.GetInfiniteAffinePoint())
                {
                    M = temp;
                    i = 0;
                }
                else
                {
                    i++;
                }
            }
            //P.Order = M;
            return(M);
        }