Beispiel #1
0
        /// <summary>
        /// Остаток от деления. С возвратом целой части
        /// </summary>
        /// <param name="a">Делимое</param>
        /// <param name="b">Делитель</param>
        /// <param name="_div">Целая цасть</param>
        /// <returns>Остаток</returns>
        public static Polynom Remainder(Polynom a, Polynom b, out Polynom _div)
        {
            if (a.Degree < b.Degree)
            {
                _div = null;
                return(a);
            }
            List <Monom> div = new List <Monom>(); // целая часть

            while (a.Degree >= b.Degree)
            {
                BigInteger current_deg = a.Degree - b.Degree;
                Monom      c           = new Monom(current_deg, 1); // целая часть от деления

                BigInteger currentInt = a.coefficients[0].Coefficient * Extension.Inverse(b.coefficients[0].Coefficient, b.Fp);
                c.MultiplyInt(currentInt);
                div.Add(c);
                Polynom temp = new Polynom(new List <Monom> {
                    c
                }, a.Fp);
                a -= temp * b;
                a.NormPolynom();
            }
            _div = new Polynom(div, a.Fp);
            return(a);
        }
Beispiel #2
0
 /// <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);
 }
Beispiel #3
0
        void Roots(Polynom g)
        {
            if (g.Degree <= 2)
            {
                // Решение уравнений вида ax^2+bx+c = 0 mod p a,b,c>=0
                if (g.coefficients[0].Degree == 1) // bx + c = 0
                {
                    if (g.coefficients.Count == 1) // bx = 0
                    {
                        roots.Add(0);
                        return;
                    }
                    else // bx + c = 0
                    {
                        BigInteger b = g.coefficients[0].Coefficient;
                        BigInteger c = g.coefficients[1].Coefficient;

                        BigInteger x = BigInteger.Remainder(BigInteger.Negate(c) * Extension.Inverse(b, g.Fp), g.Fp);
                        while (x < 0)
                        {
                            x += g.Fp;
                        }
                        roots.Add(x);
                        return;
                    }
                    // ошибка
                }
                else // ax^2 + bx + c = 0
                {
                    if (g.coefficients[1].Degree == 0) // ax^2 + c = 0
                    {
                        BigInteger a  = g.coefficients[0].Coefficient;
                        BigInteger c  = g.coefficients[1].Coefficient;
                        BigInteger ac = BigInteger.Remainder(BigInteger.Negate(c) * Extension.Inverse(a, g.Fp), g.Fp);
                        BigInteger r  = Extension.SquareRootModPrime(ac, g.Fp);
                        roots.Add(r); // не проверенно
                        roots.Add(g.Fp - r);
                        return;
                    }
                    else // ax^2 + bx = 0 && ax^2 = 0 && ax^2 + bx + c = 0
                    {
                        if (g.coefficients.Count == 1)// ax ^ 2 = 0
                        {
                            roots.Add(0);
                            return;
                        }
                        else // ax^2 + bx = 0 && ax^2 + bx + c = 0
                        {
                            if (g.coefficients.Count == 2) // ax^2 + bx = 0
                            {
                                roots.Add(0);
                                Polynom div = null;
                                Polynom.Remainder(g, Parse("+x", this.Fp), out div);
                                Roots(div);
                            }
                            else // ax^2 + bx + c = 0
                            {
                                BigInteger a = g.coefficients[0].Coefficient;
                                BigInteger b = g.coefficients[1].Coefficient;
                                BigInteger c = g.coefficients[2].Coefficient;

                                BigInteger D = Extension.SquareRootModPrime(BigInteger.Remainder(b * b - 4 * a * c, g.Fp), g.Fp);

                                BigInteger x1 = BigInteger.Remainder((BigInteger.Negate(b) - D) * BigInteger.Remainder(Extension.Inverse(2 * a, g.Fp), g.Fp), g.Fp);
                                BigInteger x2 = BigInteger.Remainder((BigInteger.Negate(b) + D) * BigInteger.Remainder(Extension.Inverse(2 * a, g.Fp), g.Fp), g.Fp);
                                while (x1 < 0)
                                {
                                    x1 += g.Fp;
                                }
                                while (x2 < 0)
                                {
                                    x2 += g.Fp;
                                }
                                roots.Add(x1);
                                roots.Add(x2);
                            }
                        }
                    }
                }
            }
            else
            {
                Polynom one = Parse("+1", g.Fp);
                Polynom h   = one;
                while (h.Degree == 0 || h.Eguals(g))
                {
                    BigInteger a = Extension.Random(1, g.Fp);
                    Polynom    s = ModPow(Parse(string.Format("+x-{0}", a), g.Fp), (g.Fp - 1) / 2, g);
                    h = Polynom.GreatCommonDivisor(s - one, g);
                }
                Polynom div = null;
                Remainder(g, h, out div);
                Roots(h);
                Roots(div);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Параметры кривых полученных комплексным умножением
        /// </summary>
        /// <param name="D">Фундаментальный Дискриминант</param>
        /// <returns></returns>
        private List <BigInteger[]> GetCurveComplexMultiply(int D)
        {
            List <BigInteger[]> paramCurve = new List <BigInteger[]>();
            BigInteger          g          = GetNonQuadr();

            if (D == -3)
            {
                for (int i = 0; i < 6; i++)
                {
                    paramCurve.Add(new BigInteger[] { 0, -BigInteger.ModPow(g, i, Number) });
                }
                return(paramCurve);
            }
            else if (D == -4)
            {
                for (int i = 0; i < 4; i++)
                {
                    paramCurve.Add(new BigInteger[] { -BigInteger.ModPow(g, i, Number), 0 });
                }
                return(paramCurve);
            }
            else
            {
                Polynom GilbPolFp;
                if (GilbertPolynoms.ContainsKey(D))
                {
                    ComplexPolynom GilbPol;
                    GilbertPolynoms.TryGetValue(D, out GilbPol);
                    GilbPolFp = GilbPol.GetPolynomReal(Number);
                }
                else
                {
                    ComplexPolynom GilbPol = Extension.GilbertPolynom(D);
                    GilbertPolynoms.Add(D, GilbPol);
                    GilbPolFp = GilbPol.GetPolynomReal(Number);
                }
                //---------------------------------------------------------------
                //-----------------Получение корня полинома----------------------

                BigInteger root;
                if (GilbPolFp.Degree <= 2)
                {
                    var roots = GilbPolFp.GetRoots();
                    if (roots.Count != 0)
                    {
                        root = roots[0];
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    #region Поиск нод
                    //var nod = Polynom.GreatCommonDivisor(GilbPolFp, Polynom.Derivative(GilbPolFp));
                    //if(nod.Degree!=0 && nod.Degree<3)
                    //{
                    //    var roots = nod.GetRoots();
                    //    if (roots.Count != 0)
                    //        root = roots[0];
                    //    else
                    //    {
                    //        return null;
                    //    }
                    //}
                    //else
                    //{
                    //    using (StreamWriter sw = new StreamWriter(new FileStream("polynom.txt", FileMode.Append)))
                    //    {
                    //        sw.WriteLine("//------------------------------------------------------------------------");
                    //        sw.WriteLine(Number);
                    //        sw.WriteLine("D = " + D);
                    //        sw.WriteLine(GilbPolFp + " mod " + Number);
                    //        sw.WriteLine("//------------------------------------------------------------------------");
                    //        sw.Close();
                    //    }
                    //    return null;
                    //}
                    #endregion
                    return(null);
                }

                //---------------------------------------------------------------
                //------------------Получение параметров-------------------------
                BigInteger c = root * Extension.Inverse(root - 1728, Number);
                c = BigInteger.Remainder(c, Number);
                BigInteger r = BigInteger.Remainder(3 * BigInteger.Negate(c), Number);
                BigInteger s = BigInteger.Remainder(2 * c, Number);
                //---------------------------------------------------------------
                paramCurve.Add(new BigInteger[] { r, s });
                paramCurve.Add(new BigInteger[] { BigInteger.Remainder(r * BigInteger.ModPow(g, 2, Number), Number), BigInteger.Remainder(s * BigInteger.ModPow(g, 3, Number), Number) });
                return(paramCurve);
                //---------------------------------------------------------------
            }
        }