Пример #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));
        }
Пример #2
0
        public PolynomialOverFiniteField(Polynomial[] arr, Polynomial mod, BigInteger fieldChar)
        {
            var polyMath = new PolynomialMath(fieldChar);

            _deg = arr.Length - 1;
            for (int i = _deg; i >= 0; i--)
            {
                if (polyMath.Rem(arr[i], mod) == new Polynomial(new BigInteger[] { 0 }))
                {
                    _deg--;
                }
                else
                {
                    break;
                }
            }

            var length = _deg + 1;

            if (length == 0)
            {
                length++;
            }
            _coefficients = new Polynomial[length];
            for (int i = 0; i <= _deg; i++)
            {
                _coefficients[i] = polyMath.Rem(arr[i], mod);
            }
        }
Пример #3
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);
        }
Пример #4
0
        public bool IsIrreducible(Polynomial poly, BigInteger mod)
        {
            var factors = new List <int>();
            var deg     = poly.Deg;

            if (deg % 2 == 0)
            {
                factors.Add(2);
            }
            for (int i = 3; i <= deg; i += 2)
            {
                if (deg % i == 0)
                {
                    factors.Add(i);
                }
            }
            var polyMath = new PolynomialMath(mod);
            var x        = new Polynomial(new BigInteger[] { 0, 1 });
            var xPow     = polyMath.ModPow(x, BigInteger.Pow(mod, deg), poly);
            var bigPoly  = polyMath.Sub(xPow, x);

            if (bigPoly.Deg != -1)
            {
                return(false);
            }
            var polynomialGcd = new PolynomialGcd();

            foreach (var factor in factors)
            {
                xPow    = polyMath.ModPow(x, BigInteger.Pow(mod, deg / factor), poly);
                bigPoly = polyMath.Sub(xPow, x);
                var gcd = polynomialGcd.Calculate(bigPoly, poly, mod);
                if (gcd.Deg != 0 || (gcd[0] + mod) % mod != 1)
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #5
0
        public Polynomial Calculate(Polynomial firstArg, Polynomial secondArg, BigInteger mod)
        {
            if (firstArg.Deg == secondArg.Deg && firstArg.Deg == -1)
            {
                throw new InvalidOperationException();
            }
            if (firstArg.Deg == 0 || secondArg.Deg == 0)
            {
                return(new Polynomial(new BigInteger[] { 1 }));
            }
            if (firstArg.Deg == -1)
            {
                return(secondArg);
            }
            if (secondArg.Deg == -1)
            {
                return(firstArg);
            }
            if (firstArg.Deg < secondArg.Deg || secondArg.Deg == -1)
            {
                var tmp = secondArg;
                secondArg = firstArg;
                firstArg  = tmp;
            }
            var polyMath = new PolynomialMath(mod);

            firstArg  = firstArg.Reduce(mod);
            secondArg = secondArg.Reduce(mod);
            while (secondArg.Deg != -1)
            {
                var tmp = firstArg;
                firstArg  = secondArg;
                secondArg = polyMath.Rem(tmp, secondArg);
            }
            return(polyMath.Normalize(firstArg));
        }
Пример #6
0
 public FiniteFieldMath(Polynomial mod, BigInteger fieldChar)
 {
     Mod             = mod;
     FieldChar       = fieldChar;
     _polynomialMath = new PolynomialMath(FieldChar);
 }
Пример #7
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);
        }