////Функция нахождения порядка кривой в афинных координатах //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); }