public static BigInteger SolveDLP(BigInteger g, BigInteger h, BigInteger p) { var order = p - 1; if (h == 1) { return(0); } if (h == g) { return(1); } var giantSteps = new Dictionary <BigInteger, BigInteger>(); var m = BigIntegerExtension.Sqrt(order) + 1; var temp = BigInteger.ModPow(g, m, p); var y = temp; //Console.WriteLine("g = {0}, h = {1}, p = {2}, realOrder = {3}, m = {4}",g, h, p, BigIntegerExtension.FindElementOrder(g, p), m); //Console.WriteLine(); //Console.WriteLine("Table of y = g^(m*i) mod p"); for (int i = 1; i <= m; i++) { //babySteps.Add(i, y); //Console.WriteLine("y = {0}, k*i = {1}", y, i * m); try { giantSteps.Add(y, i); } catch (Exception e) { //if (BigIntegerExtension.FindElementOrder(g, p) == order) // Console.WriteLine("dublicates with generators mod" + p); //babySteps[y] = i; } y = (y * temp).ModPositive(p); } temp = (h * g).ModPositive(p); for (int j = 1; j <= m; j++) { //if (babySteps.ContainsValue(temp)) // return (m * babySteps[temp] - j).ModPositive(order); BigInteger i = -1; try { i = giantSteps[temp]; } catch (KeyNotFoundException e) { } if (i != -1) { return((m * i - j).ModPositive(order)); } temp = (temp * g).ModPositive(p); } return(-1); }
public AffinePoint GetRandomAffinePoint() { BigIntegerRandom rand = new BigIntegerRandom(); var start = rand.Next(0, P); var x = start; BigInteger t; do { t = (x * (x * x + A) + B).ModPositive(P); if (BigIntegerExtension.JacobiSymbol(t, P) != -1) { return(new AffinePoint(x, BigIntegerExtension.Sqrt(t).ModPositive(P), this)); } if (x > P - 1) { x = -1; } x++; }while (x != start); return(GetInfiniteAffinePoint()); }
//public static BigInteger SolveDLP(AffinePoint P, AffinePoint Q) //{ // var order = P.E.HasseTheorem(); // var babySteps = new Dictionary<AffinePoint, BigInteger>(); // var m = BigIntegerExtension.Sqrt(order) + 1; // AffinePoint babyStep; // for (BigInteger i = 0; i < m; i++) // { // babyStep = (i * P.ToProjectivePoint()).ToAffinePoint(); // babySteps.Add(babyStep, i); // Console.WriteLine(babyStep); // } // AffinePoint temp; // ProjectivePoint giantStep = (m * P.ToProjectivePoint()); // for (BigInteger j = 0; j < m; j++) // { // temp = (Q.ToProjectivePoint() - j * giantStep).ToAffinePoint(); // Console.WriteLine(temp); // BigInteger i = -1; // try // { // i = babySteps[temp]; // } // catch (KeyNotFoundException e) { } // if (i != -1) // return BigIntegerExtension.ModPositive(i + j * m, order); // } // return -1; //} public static BigInteger SolveDLP(ProjectivePoint P, ProjectivePoint Q) { var order = P.E.HasseTheorem(); var babySteps = new Dictionary <AffinePoint, BigInteger>(); var m = BigIntegerExtension.Sqrt(order) + 1; AffinePoint babyStep; for (BigInteger i = 0; i <= m; i++) { babyStep = (i * P).ToAffinePoint(); babySteps.Add(babyStep, i); //Console.WriteLine(babyStep); } AffinePoint temp; ProjectivePoint giantStep = (m * P); //Console.WriteLine(); //Console.WriteLine(giantStep.ToAffinePoint()); //Console.WriteLine(); for (BigInteger j = 0; j <= m; j++) { temp = (Q - j * giantStep).ToAffinePoint(); // Console.WriteLine(temp); BigInteger i = -1; try { i = babySteps[temp]; } catch (KeyNotFoundException e) { } if (i != -1) { //Console.WriteLine(temp + " dfsd"); return(BigIntegerExtension.ModPositive(i + j * m, order)); } } //make modification with m/2 and +-iP return(-1); }
public BigInteger HasseTheorem() { return(P + 1 + (BigIntegerExtension.Sqrt(P) + 1)); }
////Функция нахождения порядка кривой в афинных координатах //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); }