Example #1
0
        /// <summary>
        /// Method for recursive search of bivariate polynomial's <paramref name="polynomial"/> factors with max degree <paramref name="maxFactorDegree"/>
        /// </summary>
        /// <param name="polynomial">Bivariate polynomial for factorization</param>
        /// <param name="maxFactorDegree">Maximum degree of factor</param>
        /// <param name="xSubstitution">Substitution for x variable</param>
        /// <param name="ySubstitution">Substitution for y variable</param>
        /// <param name="factors">Array of finded factors</param>
        /// <param name="currentFactorCoefficients">Stack with current factor's coefficients</param>
        private void Factorize(BiVariablePolynomial polynomial, int maxFactorDegree,
                               BiVariablePolynomial xSubstitution, BiVariablePolynomial ySubstitution,
                               ISet <Polynomial> factors, Stack <int> currentFactorCoefficients)
        {
            if (polynomial.EvaluateY(polynomial.Field.Zero()).IsZero)
            {
                factors.Add(new Polynomial(polynomial.Field, currentFactorCoefficients.Reverse().ToArray()));
            }

            if (currentFactorCoefficients.Count > maxFactorDegree)
            {
                return;
            }
            var roots = FindPolynomialRoots(polynomial.EvaluateX(polynomial.Field.Zero()));

            foreach (var root in roots)
            {
                currentFactorCoefficients.Push(root.Representation);
                ySubstitution[_zeroMonomial] = root;
                Factorize(polynomial
                          .PerformVariablesSubstitution(xSubstitution, ySubstitution)
                          .DivideByMaxPossibleXDegree(), maxFactorDegree,
                          xSubstitution, ySubstitution,
                          factors, currentFactorCoefficients);

                currentFactorCoefficients.Pop();
            }
        }
Example #2
0
        /// <summary>
        /// Method for calculatin (<paramref name="r"/>, <paramref name="s"/>) Hasse derivative value for bivariate polynomial <paramref name="polynomial"/> at point the (<paramref name="xValue"/>, <paramref name="yValue"/>)
        /// </summary>
        /// <param name="polynomial">Polynomial which Hasse derivative'll be calculated</param>
        /// <param name="r">Hasse derivative order by x variable</param>
        /// <param name="s">Hasse derivative order by y variable</param>
        /// <param name="xValue">Value for x variable</param>
        /// <param name="yValue">Value fro y variable</param>
        /// <param name="combinationsCountCalculator">Combinations calculator contract implementation</param>
        /// <param name="combinationsCache">Cache for storing calculated numbers of combinations</param>
        /// <returns>Hasse derivative value</returns>
        public static FieldElement CalculateHasseDerivative(this BiVariablePolynomial polynomial,
                                                            int r, int s, FieldElement xValue, FieldElement yValue,
                                                            ICombinationsCountCalculator combinationsCountCalculator, FieldElement[][] combinationsCache = null)
        {
            var field           = polynomial.Field;
            var derivativeValue = 0;

            foreach (var coefficient in polynomial)
            {
                if (coefficient.Key.Item1 < r || coefficient.Key.Item2 < s)
                {
                    continue;
                }

                var currentAddition = combinationsCountCalculator.Calculate(field, coefficient.Key.Item1, r, combinationsCache).Representation;
                currentAddition = field.Multiply(currentAddition,
                                                 combinationsCountCalculator.Calculate(field, coefficient.Key.Item2, s, combinationsCache).Representation);
                currentAddition = field.Multiply(currentAddition, coefficient.Value.Representation);
                currentAddition = field.Multiply(currentAddition, field.Pow(xValue.Representation, coefficient.Key.Item1 - r));
                currentAddition = field.Multiply(currentAddition, field.Pow(yValue.Representation, coefficient.Key.Item2 - s));

                derivativeValue = field.Add(derivativeValue, currentAddition);
            }

            return(new FieldElement(field, derivativeValue));
        }
Example #3
0
        /// <summary>
        /// Method Calculating results of replacement bivariate polynomial <paramref name="polynomial"/> variable y by value <paramref name="yValue"/>
        /// </summary>
        /// <param name="polynomial">Modified polynomial</param>
        /// <param name="yValue">Value for y variable</param>
        /// <returns>Replacement results</returns>
        public static Polynomial EvaluateY(this BiVariablePolynomial polynomial, FieldElement yValue)
        {
            if (polynomial == null)
            {
                throw new ArgumentNullException(NameOfExtension.nameof(() => polynomial));
            }
            if (yValue == null)
            {
                throw new ArgumentNullException(NameOfExtension.nameof(() => yValue));
            }
            if (polynomial.Field.Equals(yValue.Field) == false)
            {
                throw new AggregateException(NameOfExtension.nameof(() => yValue));
            }

            var field = polynomial.Field;
            var resultCoefficients = new int[polynomial.MaxXDegree + 1];

            foreach (var coefficient in polynomial)
            {
                resultCoefficients[coefficient.Key.Item1] = field.Add(resultCoefficients[coefficient.Key.Item1],
                                                                      field.Multiply(coefficient.Value.Representation, field.Pow(yValue.Representation, coefficient.Key.Item2)));
            }

            return(new Polynomial(field, resultCoefficients));
        }
Example #4
0
        public void ShouldPerformFactorization(BiVariablePolynomial polynomial, int maxFactorDegree, Polynomial[] expectedFactors)
        {
            // When
            var actualFactors = _factorizator.Factorize(polynomial, maxFactorDegree);

            // Then
            Assert.Equal(expectedFactors.Length, actualFactors.Length);
            Assert.True(actualFactors.All(expectedFactors.Contains));
        }
        public void ShouldSetCoefficients(int coefficientValueRepresentation)
        {
            // Given
            var polynomial       = new BiVariablePolynomial(Gf5);
            var monomial         = new Tuple <int, int>(1, 1);
            var coefficientValue = new FieldElement(Gf5, coefficientValueRepresentation);

            // When
            polynomial[monomial] = coefficientValue;

            // Then
            Assert.Equal(coefficientValue, polynomial[monomial]);
        }
        /// <summary>
        /// Method for creation interpolation polynomial from linear system solution
        /// </summary>
        /// <param name="field">Finite field from which system coefficients were taken</param>
        /// <param name="systemSolution">Solution of the linear equations system</param>
        /// <param name="monomialByVariableIndex">Mapping from numbers to bivariate monomials</param>
        /// <returns>Interpolation polynomial</returns>
        private static BiVariablePolynomial ConstructInterpolationPolynomial(
            GaloisField field,
            SystemSolution systemSolution,
            IReadOnlyDictionary <int, Tuple <int, int> > monomialByVariableIndex)
        {
            var interpolationPolynomial = new BiVariablePolynomial(field);

            for (var i = 0; i < systemSolution.VariablesValues.Length; i++)
            {
                interpolationPolynomial[monomialByVariableIndex[i]] = systemSolution.VariablesValues[i];
            }

            if (interpolationPolynomial.IsZero)
            {
                throw new NonTrivialPolynomialNotFoundException();
            }
            return(interpolationPolynomial);
        }
Example #7
0
        /// <summary>
        /// Exponentiation of bivariate polynomial <paramref name="polynomial"/> to the degree <paramref name="degree"/>
        /// </summary>
        /// <param name="powersCache">Cache for storing Exponentiation results </param>
        /// <param name="polynomial">Bivariate polynomial for exponentiation</param>
        /// <param name="degree">Power for exponentiation</param>
        private static BiVariablePolynomial Pow(IDictionary <int, BiVariablePolynomial> powersCache, BiVariablePolynomial polynomial, int degree)
        {
            BiVariablePolynomial result;

            if (powersCache.TryGetValue(degree, out result) == false)
            {
                if (degree == 0)
                {
                    result = new BiVariablePolynomial(polynomial.Field);
                    var pos = new Tuple <int, int>(0, 0);
                    result[pos] = polynomial.Field.One();
                }
                else
                {
                    result = Pow(powersCache, polynomial, degree - 1) * polynomial;
                }
                powersCache[degree] = result;
            }

            return(result);
        }
Example #8
0
        /// <summary>
        /// Method for finding bivariate polynomial's <paramref name="interpolationPolynomial"/> factors with max degree <paramref name="maxFactorDegree"/>
        /// </summary>
        /// <param name="interpolationPolynomial">Bivariate polynomial for factorization</param>
        /// <param name="maxFactorDegree">Maximum degree of factor</param>
        /// <returns>Array of finded factors</returns>
        public Polynomial[] Factorize(BiVariablePolynomial interpolationPolynomial, int maxFactorDegree)
        {
            var xSubstitution = new BiVariablePolynomial(interpolationPolynomial.Field)
            {
                [new Tuple <int, int>(1, 0)] = interpolationPolynomial.Field.One()
            };
            var ySubstitution = new BiVariablePolynomial(interpolationPolynomial.Field)
            {
                [new Tuple <int, int>(0, 0)] = interpolationPolynomial.Field.One(),
                [new Tuple <int, int>(1, 1)] = interpolationPolynomial.Field.One()
            };

            var factors = new HashSet <Polynomial>();
            var currentFactorCoefficients = new Stack <int>();

            Factorize(interpolationPolynomial, maxFactorDegree,
                      xSubstitution, ySubstitution,
                      factors, currentFactorCoefficients);

            return(factors.ToArray());
        }
Example #9
0
        /// <summary>
        /// Method for dividing bivariate polynomial <paramref name="polynomial"/> by variable x in maximum possible degree
        /// </summary>
        /// <param name="polynomial">Modified polynomial</param>
        /// <returns>Dividing result</returns>
        public static BiVariablePolynomial DivideByMaxPossibleXDegree(this BiVariablePolynomial polynomial)
        {
            if (polynomial == null)
            {
                throw new ArgumentNullException(NameOfExtension.nameof(() => polynomial));
            }

            var result = new BiVariablePolynomial(polynomial.Field);

            if (polynomial.IsZero)
            {
                return(result);
            }

            var minXDegree = polynomial.Min(x => x.Key.Item1);

            foreach (var coefficient in polynomial)
            {
                result[new Tuple <int, int>(coefficient.Key.Item1 - minXDegree, coefficient.Key.Item2)] = new FieldElement(coefficient.Value);
            }

            return(result);
        }
Example #10
0
        /// <summary>
        /// Method for calculating results of replacement bivariate polynomial <paramref name="polynomial"/> variable x by <paramref name="xSubstitution"/> and y by <paramref name="ySubstitution"/>
        /// </summary>
        /// <param name="polynomial">Modified polynomial</param>
        /// <param name="xSubstitution">Substitution for x variable</param>
        /// <param name="ySubstitution">Substitution for x variable</param>
        /// <returns>Replacement results</returns>
        public static BiVariablePolynomial PerformVariablesSubstitution(this BiVariablePolynomial polynomial,
                                                                        BiVariablePolynomial xSubstitution, BiVariablePolynomial ySubstitution)
        {
            if (polynomial == null)
            {
                throw new ArgumentNullException(NameOfExtension.nameof(() => polynomial));
            }
            if (xSubstitution == null)
            {
                throw new ArgumentNullException(NameOfExtension.nameof(() => xSubstitution));
            }
            if (ySubstitution == null)
            {
                throw new ArgumentNullException(NameOfExtension.nameof(() => ySubstitution));
            }
            if (polynomial.Field.Equals(xSubstitution.Field) == false)
            {
                throw new ArithmeticException(NameOfExtension.nameof(() => xSubstitution));
            }
            if (polynomial.Field.Equals(ySubstitution.Field) == false)
            {
                throw new ArithmeticException(NameOfExtension.nameof(() => ySubstitution));
            }

            var result = new BiVariablePolynomial(polynomial.Field,
                                                  polynomial.CoefficientsCount * (Math.Max(xSubstitution.CoefficientsCount, ySubstitution.CoefficientsCount) + 1));
            var xCache = new Dictionary <int, BiVariablePolynomial>(polynomial.CoefficientsCount);
            var yCache = new Dictionary <int, BiVariablePolynomial>(polynomial.CoefficientsCount);

            foreach (var coefficient in polynomial)
            {
                result.Add(coefficient.Value, Pow(xCache, xSubstitution, coefficient.Key.Item1)
                           * Pow(yCache, ySubstitution, coefficient.Key.Item2));
            }

            return(result);
        }
        /// <summary>
        /// Method for bivariate interpolation polynomial building
        /// </summary>
        /// <param name="degreeWeight">Weight of bivariate monomials degree</param>
        /// <param name="maxWeightedDegree">Maximum value of bivariate monomial degree</param>
        /// <param name="roots">Roots of the interpolation polynomial</param>
        /// <param name="rootsMultiplicity">Multiplicity of bivariate polynomial's roots</param>
        /// <returns>Builded interpolation polynomial</returns>
        public BiVariablePolynomial Build(Tuple <int, int> degreeWeight, int maxWeightedDegree,
                                          Tuple <FieldElement, FieldElement>[] roots, int rootsMultiplicity)
        {
            if (degreeWeight == null)
            {
                throw new ArgumentNullException(nameof(degreeWeight));
            }
            if (roots == null)
            {
                throw new ArgumentNullException(nameof(roots));
            }
            if (roots.Length == 0)
            {
                throw new ArgumentException($"{nameof(roots)} is empty");
            }

            var field      = roots[0].Item1.Field;
            var maxXDegree = maxWeightedDegree / degreeWeight.Item1;
            var maxYDegree = maxWeightedDegree / degreeWeight.Item2;

            var combinationsCache        = new FieldElement[Math.Max(maxXDegree, maxYDegree) + 1][].MakeSquare();
            var transformationMultiplier = new BiVariablePolynomial(field)
            {
                [new Tuple <int, int>(1, 0)] = field.One()
            };
            var monomialsComparer = new BiVariableMonomialsComparer(degreeWeight);

            var buildingPolynomials = new BiVariablePolynomial[maxYDegree + 1];
            var leadMonomials       = new Tuple <int, int> [maxYDegree + 1];

            for (var i = 0; i < buildingPolynomials.Length; i++)
            {
                var leadMonomial = new Tuple <int, int>(0, i);
                buildingPolynomials[i] = new BiVariablePolynomial(field, (maxXDegree + 1) * (maxYDegree + 1))
                {
                    [leadMonomial] = field.One()
                };
                leadMonomials[i] = leadMonomial;
            }

            foreach (var root in roots)
            {
                for (var r = 0; r < rootsMultiplicity; r++)
                {
                    for (var s = 0; r + s < rootsMultiplicity; s++)
                    {
                        var anyCompatiblePolynomialFound = false;
                        var nonZeroDerivatives           = new List <Tuple <int, FieldElement> >();
                        for (var i = 0; i < buildingPolynomials.Length; i++)
                        {
                            if (CalculateMonomialWeight(leadMonomials[i], degreeWeight) > maxWeightedDegree)
                            {
                                continue;
                            }

                            anyCompatiblePolynomialFound = true;
                            var hasseDerivative = buildingPolynomials[i].CalculateHasseDerivative(r, s, root.Item1, root.Item2,
                                                                                                  _combinationsCountCalculator, combinationsCache);
                            if (hasseDerivative.Representation != 0)
                            {
                                nonZeroDerivatives.Add(new Tuple <int, FieldElement>(i, hasseDerivative));
                            }
                        }

                        if (anyCompatiblePolynomialFound == false)
                        {
                            throw new NonTrivialPolynomialNotFoundException();
                        }
                        if (nonZeroDerivatives.Count == 0)
                        {
                            continue;
                        }

                        var minimumIndex = FindMinimumIndexByLeadMonomial(nonZeroDerivatives,
                                                                          i => leadMonomials[nonZeroDerivatives[i].Item1], monomialsComparer);
                        var minimumPolynomialIndex = nonZeroDerivatives[minimumIndex].Item1;
                        var minimumPolynomial      = buildingPolynomials[minimumPolynomialIndex];
                        var minimumDerivative      = nonZeroDerivatives[minimumIndex].Item2;

                        for (var i = 0; i < nonZeroDerivatives.Count; i++)
                        {
                            if (i != minimumIndex)
                            {
                                buildingPolynomials[nonZeroDerivatives[i].Item1]
                                .Subtract(nonZeroDerivatives[i].Item2.Divide(minimumDerivative), minimumPolynomial);
                            }
                        }
                        transformationMultiplier[_zeroMonomial] = FieldElement.InverseForAddition(root.Item1);
                        minimumPolynomial
                        .Multiply(minimumDerivative * transformationMultiplier);
                        leadMonomials[minimumPolynomialIndex] = new Tuple <int, int>(leadMonomials[minimumPolynomialIndex].Item1 + 1,
                                                                                     leadMonomials[minimumPolynomialIndex].Item2);
                    }
                }
            }

            var resultPolynomialIndex = FindMinimumIndexByLeadMonomial(buildingPolynomials, i => leadMonomials[i], monomialsComparer);

            if (CalculateMonomialWeight(leadMonomials[resultPolynomialIndex], degreeWeight) > maxWeightedDegree)
            {
                throw new NonTrivialPolynomialNotFoundException();
            }
            return(buildingPolynomials[resultPolynomialIndex]);
        }
 public void ShouldCalculateHasseDerivative(BiVariablePolynomial polynomial, int r, int s, FieldElement xValue, FieldElement yValue,
                                            FieldElement expectedValue)
 {
     Assert.Equal(expectedValue, polynomial.CalculateHasseDerivative(r, s, xValue, yValue, _combinationsCountCalculator));
 }
 public void ShouldEvaluateY(BiVariablePolynomial polynomial, FieldElement yValue, Polynomial expectedResult)
 {
     Assert.Equal(expectedResult, polynomial.EvaluateY(yValue));
 }
 public void ShouldDivideByMaxPossibleXDegree(BiVariablePolynomial polynomial, BiVariablePolynomial expectedResult)
 {
     Assert.Equal(expectedResult, polynomial.DivideByMaxPossibleXDegree(), EqualityComparer <BiVariablePolynomial> .Default);
 }
 public void ShouldPerformVariablesSubstitution(BiVariablePolynomial polynomial,
                                                BiVariablePolynomial xSubstitution, BiVariablePolynomial ySubstitution,
                                                BiVariablePolynomial expectedResult)
 {
     Assert.Equal(expectedResult, polynomial.PerformVariablesSubstitution(xSubstitution, ySubstitution), EqualityComparer <BiVariablePolynomial> .Default);
 }
 public void ShouldMultiplyByFieldElement(BiVariablePolynomial a, FieldElement b, BiVariablePolynomial expectedResult)
 {
     Assert.Equal(expectedResult, a * b, EqualityComparer <BiVariablePolynomial> .Default);
 }
 public void ShouldMultiplyTwoPolynomials(BiVariablePolynomial a, BiVariablePolynomial b, BiVariablePolynomial expectedResult)
 {
     Assert.Equal(expectedResult, a * b, EqualityComparer <BiVariablePolynomial> .Default);
 }
        static BiVariablePolynomialTests()
        {
            Gf5 = new PrimeOrderField(5);

            var polynomialForEvoluation = new BiVariablePolynomial(Gf5)
            {
                [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 2),
                [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1),
                [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1),
                [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1),
                [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4)
            };

            EvaluateTestsData = new[]
            {
                new object[] { polynomialForEvoluation, new FieldElement(Gf5, 1), new FieldElement(Gf5, 3), Gf5.Zero() },
                new object[] { polynomialForEvoluation, new FieldElement(Gf5, 2), new FieldElement(Gf5, 4), Gf5.Zero() },
                new object[] { polynomialForEvoluation, new FieldElement(Gf5, 3), new FieldElement(Gf5, 2), Gf5.Zero() },
                new object[] { polynomialForEvoluation, new FieldElement(Gf5, 2), new FieldElement(Gf5, 3), Gf5.Zero() },
            };

            AddTestsData = new[]
            {
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4)
                    }
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1)
                    }
                }
            };

            SubtractTestsData = new[]
            {
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1)
                    }
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4)
                    }
                }
            };

            MultiplyPolynomialsTestsData = new[]
            {
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 2)
                    }
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 2)] = new FieldElement(Gf5, 3)
                    }
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4)
                    },
                    new BiVariablePolynomial(Gf5),
                    new BiVariablePolynomial(Gf5)
                }
            };

            var polynomialForMultiplication = new BiVariablePolynomial(Gf5)
            {
                [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4),
                [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1)
            };

            MultiplyByFieldElementTestsData = new[]
            {
                new object[] { polynomialForMultiplication, Gf5.Zero(), new BiVariablePolynomial(Gf5) },
                new object[]
                {
                    polynomialForMultiplication, new FieldElement(Gf5, 2),
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 2)
                    }
                }
            };

            SubstitutionTestsData = new[]
            {
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 2)
                    }
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 4),
                        [new Tuple <int, int>(2, 1)] = new FieldElement(Gf5, 1)
                    }
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2)
                    },
                    new BiVariablePolynomial(Gf5),
                    new BiVariablePolynomial(Gf5),
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1)
                    }
                }
            };

            DivideByXDegreeTestsData = new[]
            {
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 3)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3)
                    }
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3)
                    },
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3)
                    }
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5),
                    new BiVariablePolynomial(Gf5)
                }
            };

            EvaluateXTestsData = new[]
            {
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1)
                    },
                    new FieldElement(Gf5, 1),
                    new Polynomial(Gf5, 0, 1)
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1)
                    },
                    Gf5.Zero(),
                    new Polynomial(Gf5, 3)
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(0, 2)] = new FieldElement(Gf5, 1)
                    },
                    new FieldElement(Gf5, 3),
                    new Polynomial(Gf5, 4, 4, 1)
                }
            };

            EvaluateYTestsData = new[]
            {
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2)
                    },
                    new FieldElement(Gf5, 1),
                    new Polynomial(Gf5, 0, 1)
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1)
                    },
                    Gf5.Zero(),
                    new Polynomial(Gf5, 3)
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3),
                        [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(0, 2)] = new FieldElement(Gf5, 1)
                    },
                    new FieldElement(Gf5, 2),
                    new Polynomial(Gf5, 3, 0, 2)
                }
            };

            CalculateHasseDerivativeTestsData = new[]
            {
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1),
                        [new Tuple <int, int>(0, 2)] = new FieldElement(Gf5, 1)
                    },
                    1, 1, Gf5.One(), Gf5.One(),
                    Gf5.Zero()
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(2, 2)] = new FieldElement(Gf5, 1)
                    },
                    1, 1, Gf5.One(), Gf5.One(),
                    new FieldElement(Gf5, 4)
                },
                new object[]
                {
                    new BiVariablePolynomial(Gf5)
                    {
                        [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2),
                        [new Tuple <int, int>(2, 2)] = new FieldElement(Gf5, 1)
                    },
                    2, 1, Gf5.One(), Gf5.One(),
                    new FieldElement(Gf5, 2)
                }
            };
        }
Example #19
0
        static BiVariablePolynomialTests()
        {
            Gf5 = new PrimeOrderField(5);

            var polynomialForEvoluation = new BiVariablePolynomial(Gf5)
            {
                [new Tuple <int, int>(1, 1)] = Gf5.CreateElement(2),
                [new Tuple <int, int>(0, 1)] = Gf5.One(),
                [new Tuple <int, int>(2, 0)] = Gf5.One(),
                [new Tuple <int, int>(1, 0)] = Gf5.One(),
                [new Tuple <int, int>(0, 0)] = Gf5.CreateElement(4)
            };

            EvaluateTestsData
                = new TheoryData <EvaluationTestCase>
                {
                new EvaluationTestCase
                {
                    Polynomial = polynomialForEvoluation,
                    XValue     = Gf5.One(),
                    YValue     = Gf5.CreateElement(3),
                    Expected   = Gf5.Zero()
                },
                new EvaluationTestCase
                {
                    Polynomial = polynomialForEvoluation,
                    XValue     = Gf5.CreateElement(2),
                    YValue     = new FieldElement(Gf5, 4),
                    Expected   = Gf5.Zero()
                },
                new EvaluationTestCase
                {
                    Polynomial = polynomialForEvoluation,
                    XValue     = Gf5.CreateElement(3),
                    YValue     = Gf5.CreateElement(2),
                    Expected   = Gf5.Zero()
                },
                new EvaluationTestCase
                {
                    Polynomial = polynomialForEvoluation,
                    XValue     = Gf5.CreateElement(2),
                    YValue     = Gf5.CreateElement(3),
                    Expected   = Gf5.Zero()
                },
                };

            AddTestsData
                = new TheoryData <BinaryOperationTestCase>
                {
                new BinaryOperationTestCase
                {
                    FirstOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3)
                    },
                    SecondOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4)
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4)
                    }
                },
                new BinaryOperationTestCase
                {
                    FirstOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4)
                    },
                    SecondOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4),
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(4),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(4)
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 0)] = Gf5.One()
                    }
                }
                };

            SubtractTestsData
                = new TheoryData <BinaryOperationTestCase>
                {
                new BinaryOperationTestCase
                {
                    FirstOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3)
                    },
                    SecondOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4)
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(4),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.One()
                    }
                },
                new BinaryOperationTestCase
                {
                    FirstOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4)
                    },
                    SecondOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(4),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(4),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4)
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(4)
                    }
                }
                };

            MultiplyPolynomialsTestsData
                = new TheoryData <BinaryOperationTestCase>
                {
                new BinaryOperationTestCase
                {
                    FirstOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3)
                    },
                    SecondOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4)
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.One(),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(4),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 1)] = Gf5.CreateElement(2)
                    }
                },
                new BinaryOperationTestCase
                {
                    FirstOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4)
                    },
                    SecondOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(4),
                        [Tuple.Create(1, 0)] = Gf5.One(),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(2)
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(4),
                        [Tuple.Create(2, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 2)] = Gf5.CreateElement(3)
                    }
                },
                new BinaryOperationTestCase
                {
                    FirstOperand = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(4)
                    },
                    SecondOperand = new BiVariablePolynomial(Gf5),
                    Expected      = new BiVariablePolynomial(Gf5)
                }
                };

            var polynomialForMultiplication
                = new BiVariablePolynomial(Gf5)
                {
                [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                [Tuple.Create(0, 1)] = Gf5.CreateElement(4),
                [Tuple.Create(1, 1)] = Gf5.One()
                };

            MultiplyByFieldElementTestsData
                = new TheoryData <MultiplicationByFieldElementTestCase>
                {
                new MultiplicationByFieldElementTestCase
                {
                    Polynomial = polynomialForMultiplication,
                    Multiplier = Gf5.Zero(),
                    Expected   = new BiVariablePolynomial(Gf5)
                },
                new MultiplicationByFieldElementTestCase
                {
                    Polynomial = polynomialForMultiplication,
                    Multiplier = Gf5.CreateElement(2),
                    Expected   = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.One(),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(4),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 1)] = Gf5.CreateElement(2)
                    }
                }
                };

            SubstitutionTestsData
                = new TheoryData <SubstitutionTestCase>
                {
                new SubstitutionTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.One(),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(2)
                    },
                    XSubstitution = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(1, 0)] = Gf5.One()
                    },
                    YSubstitution = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 1)] = Gf5.One()
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 1)] = Gf5.CreateElement(2)
                    }
                },
                new SubstitutionTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.One(),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(2, 0)] = Gf5.One(),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 1)] = Gf5.One()
                    },
                    XSubstitution = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.One(),
                        [Tuple.Create(1, 0)] = Gf5.One()
                    },
                    YSubstitution = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 1)] = Gf5.One()
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.One(),
                        [Tuple.Create(2, 0)] = Gf5.One(),
                        [Tuple.Create(1, 1)] = Gf5.CreateElement(4),
                        [Tuple.Create(2, 1)] = Gf5.One()
                    }
                },
                new SubstitutionTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.One(),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(2)
                    },
                    XSubstitution = new BiVariablePolynomial(Gf5),
                    YSubstitution = new BiVariablePolynomial(Gf5),
                    Expected      = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.One()
                    }
                }
                };

            DivideByXDegreeTestsData
                = new TheoryData <DivideByXDegreeTestCase>
                {
                new DivideByXDegreeTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(2, 0)] = Gf5.One(),
                        [Tuple.Create(1, 1)] = Gf5.CreateElement(3)
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.One(),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(3)
                    }
                },
                new DivideByXDegreeTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(2, 0)] = Gf5.One(),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(3)
                    },
                    Expected = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(2, 0)] = Gf5.One(),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(3)
                    }
                },
                new DivideByXDegreeTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5),
                    Expected   = new BiVariablePolynomial(Gf5)
                }
                };

            EvaluateXTestsData
                = new TheoryData <PartialEvaluationTestCase>
                {
                new PartialEvaluationTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(0, 1)] = Gf5.One()
                    },
                    VariableValue = Gf5.One(),
                    Expected      = new Polynomial(Gf5, 0, 1)
                },
                new PartialEvaluationTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 1)] = Gf5.One()
                    },
                    VariableValue = Gf5.Zero(),
                    Expected      = new Polynomial(Gf5, 3)
                },
                new PartialEvaluationTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(2, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(0, 1)] = Gf5.One(),
                        [Tuple.Create(1, 1)] = Gf5.One(),
                        [Tuple.Create(0, 2)] = Gf5.One()
                    },
                    VariableValue = Gf5.CreateElement(3),
                    Expected      = new Polynomial(Gf5, 4, 4, 1)
                }
                };

            EvaluateYTestsData
                = new TheoryData <PartialEvaluationTestCase>
                {
                new PartialEvaluationTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(1, 0)] = Gf5.One(),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(2)
                    },
                    VariableValue = Gf5.One(),
                    Expected      = new Polynomial(Gf5, 0, 1)
                },
                new PartialEvaluationTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 1)] = Gf5.One()
                    },
                    VariableValue = Gf5.Zero(),
                    Expected      = new Polynomial(Gf5, 3)
                },
                new PartialEvaluationTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(3),
                        [Tuple.Create(2, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(0, 1)] = Gf5.One(),
                        [Tuple.Create(1, 1)] = Gf5.One(),
                        [Tuple.Create(0, 2)] = Gf5.One()
                    },
                    VariableValue = Gf5.CreateElement(2),
                    Expected      = new Polynomial(Gf5, 3, 0, 2)
                }
                };

            HasseDerivativeCalculationTestsData
                = new TheoryData <HasseDerivativeCalculationTestCase>
                {
                new HasseDerivativeCalculationTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(2),
                        [Tuple.Create(2, 0)] = Gf5.One(),
                        [Tuple.Create(0, 2)] = Gf5.One()
                    },
                    R        = 1,
                    S        = 1,
                    XValue   = Gf5.One(),
                    YValue   = Gf5.One(),
                    Expected = Gf5.Zero()
                },
                new HasseDerivativeCalculationTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(2),
                        [Tuple.Create(2, 2)] = Gf5.One()
                    },
                    R        = 1,
                    S        = 1,
                    XValue   = Gf5.One(),
                    YValue   = Gf5.One(),
                    Expected = new FieldElement(Gf5, 4)
                },
                new HasseDerivativeCalculationTestCase
                {
                    Polynomial = new BiVariablePolynomial(Gf5)
                    {
                        [Tuple.Create(0, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(1, 0)] = Gf5.CreateElement(2),
                        [Tuple.Create(0, 1)] = Gf5.CreateElement(2),
                        [Tuple.Create(2, 2)] = Gf5.One()
                    },
                    R        = 2,
                    S        = 1,
                    XValue   = Gf5.One(),
                    YValue   = Gf5.One(),
                    Expected = Gf5.CreateElement(2)
                }
                };
        }