Beispiel #1
0
        /// <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]]);
        }
Beispiel #2
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));
                }
            }
        }