EllipticCurvePoint(EllipticCurvePoint otherPoint) { p = otherPoint.P; a = otherPoint.A; b = otherPoint.B; x = otherPoint.X; y = otherPoint.Y; z = otherPoint.Z; }
/// <summary> /// Привидение точки к афинным координатам /// </summary> /// <param name="p">Точка на кривой</param> /// <returns></returns> public static EllipticCurvePoint AffineCoords(EllipticCurvePoint p) { if (p.Z == 0) { return(p); } p.X = BigInteger.Remainder(p.X * Extension.Inverse(p.Z, p.P), p.P); p.Y = BigInteger.Remainder(p.Y * Extension.Inverse(p.Z, p.P), p.P); p.Z = 1; return(p); }
/// <summary> /// Проверка принадлежности точки кривой /// </summary> /// <returns></returns> public bool CheckPoint() { if (this.X == 0 && this.Z == 0) { return(true); } EllipticCurvePoint z = new EllipticCurvePoint(this); z = AffineCoords(z); BigInteger left = BigInteger.Remainder(z.Y * z.Y, z.P); BigInteger right = BigInteger.Remainder((z.X * z.X * z.X + z.A * z.X + z.B), z.P); return(right.Equals(left)); }
/// <summary> /// Поиск кривой с заданным порядком /// </summary> /// <param name="orderCurve">Необходимый порядок</param> /// <param name="paramCurve">Параметры кривых</param> /// <returns></returns> private static BigInteger[] GetCurveParamForOrder(BigInteger orderCurve, List <BigInteger[]> paramCurve) { int count = 0; List <int> curveNum = new List <int>();; int iteration = 0; while (iteration < 5) { curveNum = new List <int>(); for (int i = 0; i < paramCurve.Count; i++) { EllipticCurvePoint point = new EllipticCurvePoint(Number, paramCurve[i][0], paramCurve[i][1]); if (!point.CheckPoint()) { return(null); } EllipticCurvePoint orderPoint = EllipticCurvePoint.Multiply(orderCurve, point); if (!orderPoint.CheckPoint()) { return(null); } if (orderPoint.X == 0 && orderPoint.Z == 0) { count++; curveNum.Add(i); } } if (count == 1) { return(paramCurve[curveNum[0]]); } count = 0; iteration++; } if (curveNum.Count == 0) { return new BigInteger[] { 0 } } ; // Порядки не подошли return(paramCurve[curveNum[1]]); }
public static EllipticCurvePoint Multiply(BigInteger k, EllipticCurvePoint point) { EllipticCurvePoint temp = point; k--; while (k != 0) { if (BigInteger.Remainder(k, 2) != 0) { if ((temp.X == point.X) && (temp.Y == point.Y)) { temp = X2(temp); } else { temp = AddPoint(temp, point); } k--; } k = k / 2; point = X2(point); } return(temp); }
BigInteger Testing(int _currentD = 0) { //--наименьшее псевдопростое по 4 базам if (Number < 3215031751) { if (FactorOrders.MRTest(Number, new List <int> { 2, 3, 5, 7, 11 })) { return(1); } else { return(-1); } } if (_currentD == D.Length) //Кончились дискриминанты { //D = FundamentalDiscrim(9000,D); //return Testing(_currentD); return(-2); } int currentD = _currentD; //--------------L(D,N) = 1------------------------------------ while (Extension.Lezhandr(D[currentD], Number) != 1) { currentD++; if (currentD == D.Length) { //D = FundamentalDiscrim(9000,D); //return Testing(_currentD); return(-2); }// Кончились дискриминанты } //-----------Пытаемся-найти-представление-4p=u^2+|D|v^2----------------------- List <BigInteger> uv = new List <BigInteger>(); while (currentD < D.Length) { uv = Extension.KornakiSmit(Number, D[currentD]); if (uv.Count == 0) { currentD++; } else { break; } } if (currentD == D.Length) { //D = FundamentalDiscrim(9000,D); //return Testing(_currentD); return(-2); }// Кончились дискриминанты //----------------------------------------------------------------------- //-------------------Получаем возможные порядки------------------------------ List <BigInteger> ordersCurve = new List <BigInteger>(); if (D[currentD] == -3) // 6 порядков { ordersCurve.Add(Number + 1 + ((uv[0] + 3 * uv[1]) >> 1)); ordersCurve.Add(Number + 1 - ((uv[0] + 3 * uv[1]) >> 1)); ordersCurve.Add(Number + 1 + ((uv[0] - 3 * uv[1]) >> 1)); ordersCurve.Add(Number + 1 - ((uv[0] - 3 * uv[1]) >> 1)); ordersCurve.Add(Number + 1 + uv[0]); ordersCurve.Add(Number + 1 - uv[0]); } else if (D[currentD] == -4)// 4 порядка { ordersCurve.Add(Number + 1 + 2 * uv[1]); ordersCurve.Add(Number + 1 - 2 * uv[1]); ordersCurve.Add(Number + 1 + uv[0]); ordersCurve.Add(Number + 1 - uv[0]); } else { ordersCurve.Add(Number + 1 + uv[0]); ordersCurve.Add(Number + 1 - uv[0]); } //----------------------------------------------------------------------- //-----------------Раскладываем порядки на множители--------------------- fct.SetNewNumbers(ordersCurve); while (true) { fct.StartFact(); if (fct.result != null) { //---------------Если попал простой порядок----------------------- if (fct.result.Count == 1) { ordersCurve.RemoveRange(0, fct.NumberResult + 1); fct.SetNewNumbers(ordersCurve); continue; } BigInteger orderCurve = ordersCurve[fct.NumberResult]; //-----------------Получаем параметры кривой--------------------- var curveParam = GetCurveComplexMultiply(D[currentD]); // var curveParam = GetClearCurveComplexMultiply(D[currentD]); if (curveParam == null) { return(-2); // Проблемы с нахождением корней многочлена } var paramCurve = GetCurveParamForOrder(orderCurve, curveParam); if (paramCurve == null) { return(-1); // Составное } if (paramCurve.Length == 1) { ordersCurve.RemoveRange(0, fct.NumberResult + 1); fct.SetNewNumbers(ordersCurve); continue; } //--------------------------------------------------------------- //-------------Операции с точкой--------------------------------- EllipticCurvePoint P = new EllipticCurvePoint(Number, paramCurve[0], paramCurve[1]); BigInteger k = orderCurve / fct.result[fct.result.Count - 1]; var U = EllipticCurvePoint.Multiply(k, P); if (U.CheckPoint() == false) { return(-1); // Составное } while (U.X == 0 && U.Z == 0) { P.NextPoint(); U = EllipticCurvePoint.Multiply(k, P); if (U.CheckPoint() == false) { return(-1); // Составное } } var V = EllipticCurvePoint.Multiply(fct.result[fct.result.Count - 1], U); if (V.X != 0 && V.Z != 0) { return(-1); // Составное } //--------------Формирование Сертификата--------------------- Cert.Append(string.Format("N = {0}", Number) + "\r\n"); Cert.Append(string.Format("D = {0} U = {1} V = {2}", D[currentD], uv[0], uv[1]) + "\r\n"); Cert.Append("#E = "); foreach (var del in fct.result) { Cert.Append(del + " * "); } Cert.Remove(Cert.Length - 3, 3); Cert.Append("\r\n"); Cert.Append(string.Format("E({0}, {1}, {2}, {3}, {4}, {5} )", P.A, P.B, P.P, P.X, P.Y, P.Z) + "\r\n"); Cert.Append("\r\n"); //--------------------------------------------------------------- //-----------Возврат числа q------------------------------------- return(fct.result[fct.result.Count - 1]); //--------------------------------------------------------------- } else // если порядки разложить не удалось, то начинаем с начала со следующего дискриминанта { return(Testing(currentD + 1)); } } }
public static EllipticCurvePoint AddPoint(EllipticCurvePoint pointA, EllipticCurvePoint pointB) { if ((pointA.X == pointA.Z) && (pointA.X == 0)) { return(pointB); } if ((pointB.X == pointB.Z) && (pointB.X == 0)) { return(pointA); } BigInteger A = pointB.Y * pointA.Z - pointA.Y * pointB.Z; A = BigInteger.Remainder(A, pointA.P); if (A < 0) { while (A < 0) { A += pointA.P; } } BigInteger B = pointB.X * pointA.Z - pointA.X * pointB.Z; B = BigInteger.Remainder(B, pointA.P); if (B < 0) { while (B < 0) { B += pointA.P; } } BigInteger C = pointB.X * pointA.Z + pointA.X * pointB.Z; C = BigInteger.Remainder(C, pointA.P); if (C < 0) { while (C < 0) { C += pointA.P; } } BigInteger D = pointB.X * pointA.Z + 2 * pointA.X * pointB.Z; D = BigInteger.Remainder(D, pointA.P); if (D < 0) { while (D < 0) { D += pointA.P; } } BigInteger E = pointB.Z * pointA.Z; E = BigInteger.Remainder(E, pointA.P); if (E < 0) { while (E < 0) { E += pointA.P; } } BigInteger X = B * (E * A * A - C * B * B); X = BigInteger.Remainder(X, pointA.P); if (X < 0) { while (X < 0) { X += pointA.P; } } BigInteger Y = A * (B * B * D - A * A * E) - pointA.Y * pointB.Z * B * B * B; Y = BigInteger.Remainder(Y, pointA.P); if (Y < 0) { while (Y < 0) { Y += pointA.P; } } BigInteger Z = B * B * B * E; Z = BigInteger.Remainder(Z, pointA.P); if (Z < 0) { while (Z < 0) { Z += pointA.P; } } if (X == 0 && Z == 0) { return(new EllipticCurvePoint(pointA.P, pointA.A, pointA.B, 0, 1, 0)); } return(new EllipticCurvePoint(pointA.P, pointA.A, pointA.B, X, Y, Z)); }
private static EllipticCurvePoint X2(EllipticCurvePoint point) { BigInteger A = 3 * point.X * point.X + point.A * point.Z * point.Z; A = BigInteger.Remainder(A, point.P); if (A < 0) { while (A < 0) { A += point.P; } } BigInteger B = 2 * point.Y * point.Z; B = BigInteger.Remainder(B, point.P); if (B < 0) { while (B < 0) { B += point.P; } } BigInteger X = B * (A * A - 4 * point.X * point.Y * B); X = BigInteger.Remainder(X, point.P); if (X < 0) { while (X < 0) { X += point.P; } } BigInteger Y = A * (6 * point.Y * point.X * B - A * A) - 2 * point.Y * point.Y * B * B; Y = BigInteger.Remainder(Y, point.P); if (Y < 0) { while (Y < 0) { Y += point.P; } } BigInteger Z = B * B * B; Z = BigInteger.Remainder(Z, point.P); if (Z < 0) { while (Z < 0) { Z += point.P; } } return(new EllipticCurvePoint(point.P, point.A, point.B, X, Y, Z)); }