public static Tuple <BigInteger, BigInteger> AlgebraicSquareRoot(IPolynomial f, BigInteger m, int degree, IPolynomial dd, BigInteger p) { IPolynomial startPolynomial = Polynomial.Field.Modulus(dd, p); IPolynomial startInversePolynomial = ModularInverse(startPolynomial, p); IPolynomial resultPoly1 = FiniteFieldArithmetic.SquareRoot(startPolynomial, f, p, degree, m); IPolynomial resultPoly2 = ModularInverse(resultPoly1, p); BigInteger result1 = resultPoly1.Evaluate(m).Mod(p); BigInteger result2 = resultPoly2.Evaluate(m).Mod(p); IPolynomial resultSquared1 = Polynomial.Field.ModMod(Polynomial.Square(resultPoly1), f, p); IPolynomial resultSquared2 = Polynomial.Field.ModMod(Polynomial.Square(resultPoly2), f, p); bool bothResultsAgree = (resultSquared1.CompareTo(resultSquared2) == 0); if (bothResultsAgree) { bool resultSquaredEqualsInput1 = (startPolynomial.CompareTo(resultSquared1) == 0); bool resultSquaredEqualsInput2 = (startInversePolynomial.CompareTo(resultSquared1) == 0); if (resultSquaredEqualsInput1) { return(new Tuple <BigInteger, BigInteger>(result1, result2)); } else if (resultSquaredEqualsInput2) { return(new Tuple <BigInteger, BigInteger>(result2, result1)); } } return(new Tuple <BigInteger, BigInteger>(BigInteger.Zero, BigInteger.Zero)); }
public static bool IsIrreducibleOverField(IPolynomial f, BigInteger p) { IPolynomial splittingField = new Polynomial( new Term[] { new Term(1, (int)p), new Term(-1, 1) }); IPolynomial reducedField = Field.ModMod(splittingField, f, p); IPolynomial gcd = Polynomial.GCD(reducedField, f); return(gcd.CompareTo(Polynomial.One) == 0); }
public static IPolynomial Mod(IPolynomial poly, IPolynomial mod) { int sortOrder = mod.CompareTo(poly); if (sortOrder > 0) { return(poly); } else if (sortOrder == 0) { return(Polynomial.Zero); } IPolynomial remainder = Polynomial.Zero; Divide(poly, mod, out remainder); return(remainder); }
public static IPolynomial Divide(IPolynomial left, IPolynomial right, out IPolynomial remainder) { if (left == null) { throw new ArgumentNullException(nameof(left)); } if (right == null) { throw new ArgumentNullException(nameof(right)); } if (right.Degree > left.Degree || right.CompareTo(left) == 1) { remainder = Polynomial.Zero; return(left); } int rightDegree = right.Degree; int quotientDegree = (left.Degree - rightDegree) + 1; BigInteger leadingCoefficent = new BigInteger(right[rightDegree].ToByteArray()); Polynomial rem = (Polynomial)left.Clone(); Polynomial quotient = (Polynomial)Polynomial.Zero; // The leading coefficient is the only number we ever divide by // (so if right is monic, polynomial division does not involve division at all!) for (int i = quotientDegree - 1; i >= 0; i--) { quotient[i] = BigInteger.Divide(rem[rightDegree + i], leadingCoefficent); rem[rightDegree + i] = BigInteger.Zero; for (int j = rightDegree + i - 1; j >= i; j--) { rem[j] = BigInteger.Subtract(rem[j], BigInteger.Multiply(quotient[i], right[j - i])); } } // Remove zeros rem.RemoveZeros(); quotient.RemoveZeros(); remainder = rem; return(quotient); }
public static IPolynomial ModPow(IPolynomial poly, BigInteger exponent, IPolynomial mod) { if (exponent < 0) { throw new NotImplementedException("Raising a polynomial to a negative exponent not supported. Build this functionality if it is needed."); } else if (exponent == 0) { return(Polynomial.One); } else if (exponent == 1) { return(poly.Clone()); } else if (exponent == 2) { return(Polynomial.Square(poly)); } IPolynomial total = Polynomial.Square(poly); BigInteger counter = exponent - 2; while (counter != 0) { total = Polynomial.Multiply(poly, total); if (total.CompareTo(mod) < 0) { total = Field.Modulus(total, mod); } counter -= 1; } return(total); }
public bool Equals(IPolynomial x, IPolynomial y) { return(x.CompareTo(y) == 0); }