Ejemplo n.º 1
0
        public Tuple <Polynomial, Polynomial, Polynomial> FindBezoutCoefficients(Polynomial firstArg, Polynomial secondArg)
        {
            var        polyMath = new PolynomialMath(-1);
            Polynomial u0       = new Polynomial(new BigInteger[] { 1 });

            Polynomial u1 = new Polynomial(new BigInteger[] { 0 });

            Polynomial v0 = new Polynomial(new BigInteger[] { 0 });

            Polynomial v1 = new Polynomial(new BigInteger[] { 1 });

            Polynomial u2, v2, q0, r2;

            Polynomial r0 = firstArg;

            Polynomial r1 = secondArg;

            while (r1.Deg != -1)
            {
                q0 = polyMath.Div(r0, r1);
                u2 = polyMath.Sub(u0, polyMath.Mul(q0, u1));
                v2 = polyMath.Sub(v0, polyMath.Mul(q0, v1));
                r2 = polyMath.Add(polyMath.Mul(u2, firstArg), polyMath.Mul(v2, secondArg));
                r0 = r1;
                r1 = r2;
                u0 = u1;
                u1 = u2;
                v0 = v1;
                v1 = v2;
            }
            return(new Tuple <Polynomial, Polynomial, Polynomial>(u0, v0, r0));
        }
Ejemplo n.º 2
0
        public List <long> FindRoots(Polynomial polynomial, long mod)
        {
            if (mod < 100)
            {
                var bruteForceMethod = new BruteforceRootFinder();
                return(bruteForceMethod.FindRoots(polynomial, mod));
            }
            var result = new List <long>();
            var gcd    = new PolynomialGcd();



            var polyMath = new PolynomialMath(mod);


            var x = new Polynomial(new BigInteger[] { 0, 1 });


            var powX = polyMath.ModPow(x, mod, polynomial);
            var h    = polyMath.Sub(powX, x);



            var g = gcd.Calculate(polynomial, h, mod);


            if (g.Value(0) % mod == 0)
            {
                result.Add(0);
                g = polyMath.Div(g, new Polynomial(new BigInteger[] { 0, 1 }));
            }
            Roots(g, mod, result);
            return(result);
        }
Ejemplo n.º 3
0
        void Roots(Polynomial polynomial, long mod, List <long> roots)
        {
            if (polynomial.Deg < 1)
            {
                return;
            }
            if (polynomial.Deg == 2)
            {
                if (mod % 2 == 0)
                {
                    for (long i = 0; i < mod; i++)
                    {
                        if (polynomial.Value(i) % mod == 0)
                        {
                            roots.Add(i);
                        }
                    }
                }
                else
                {
                    var a = polynomial[2];
                    var b = polynomial[1];
                    var c = polynomial[0];

                    var sqrt    = new ModularSqrt();
                    var inverse = new ModularInverse();
                    var inv2A   = inverse.Inverse(2 * a, mod);

                    var tmp  = inv2A * b;
                    var root = sqrt.Sqrt(tmp * tmp - inverse.Inverse(a, mod) * c, mod);
                    roots.Add((long)((-tmp + root) % mod));
                    roots.Add((long)((-tmp - root) % mod));
                }
                return;
            }
            if (polynomial.Deg == 1)
            {
                var lc = (polynomial[1] + mod) % mod;
                if (lc == 1)
                {
                    roots.Add((long)(-polynomial[0]));
                }
                else if (lc == mod - 1)
                {
                    roots.Add((long)(polynomial[0]));
                }
                else
                {
                    var inverse = new ModularInverse();

                    roots.Add((long)(-polynomial[0] * inverse.Inverse(polynomial[1], mod)));
                }
                return;
            }
            var polyMath = new PolynomialMath(mod);
            var arr      = new BigInteger[2];

            arr[0] = _random.Next() % mod;
            arr[1] = 1;
            var h = new Polynomial(arr);

            h    = polyMath.ModPow(h, (mod - 1) / 2, polynomial);
            h[0] = h[0] - 1;
            var gcd = new PolynomialGcd();
            var g   = gcd.Calculate(polynomial, h, mod);

            while (g.Deg == 0 || g == h)
            {
                arr[0] = _random.Next() % mod;
                h      = new Polynomial(arr);
                h      = polyMath.ModPow(h, (mod - 1) / 2, polynomial);
                h[0]  -= 1;
                g      = gcd.Calculate(polynomial, h, mod);
            }
            Roots(g, mod, roots);
            Roots(polyMath.Div(polynomial, g), mod, roots);
        }