Exemple #1
0
        /// <summary>
        /// Случайная точка на Данной кривой.
        /// </summary>
        /// <returns></returns>
        BigInteger[] GetPoint()
        {
            BigInteger rnd = Extension.Random(1, P);

            while (Extension.Lezhandr(BigInteger.Remainder((rnd * rnd * rnd + A * rnd + B), P), P) != 1)
            {
                rnd = Extension.Random(1, P);
            }
            BigInteger xcoord = BigInteger.Remainder((rnd * rnd * rnd + A * rnd + B), P); // Правая часть уравнения кривой

            return(new BigInteger[] { rnd, Extension.SquareRootModPrime(xcoord, P) });
        }
Exemple #2
0
 /// <summary>
 /// Случайный квадратичный невычет по модулю тестируемого числа
 /// </summary>
 /// <returns>Случайный квадратичный невычет</returns>
 private static BigInteger GetNonQuadr()
 {
     if (Number % 3 == 1)
     {
         BigInteger g = Extension.Random(1, Number);
         while ((Extension.Lezhandr(g, Number) != -1) || (BigInteger.ModPow(g, (Number - 1) / 3, Number) == 1))
         {
             g = Extension.Random(1, Number);
         }
         return(g);
     }
     else
     {
         BigInteger g = Extension.Random(1, Number);
         while (Extension.Lezhandr(g, Number) != -1)
         {
             g = Extension.Random(1, Number);
         }
         return(g);
     }
 }
Exemple #3
0
        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));
                }
            }
        }