/// <summary> /// Encode an array of data codeword with GaloisField 256. /// </summary> /// <param name="dataBytes">Array of data codewords for a single block.</param> /// <param name="numECBytes">Number of error correction codewords for data codewords</param> /// <param name="generatorPoly">Cached or newly create GeneratorPolynomial</param> /// <returns>Return error correction codewords array</returns> /// <remarks></remarks> internal static byte[] Encode(byte[] dataBytes, int numECBytes, GeneratorPolynomial generatorPoly) { int dataLength = dataBytes.Length; if (generatorPoly == null) throw new ArgumentNullException("generator", "GeneratorPolynomial var is null"); if (dataLength == 0) throw new ArgumentException("There is no data bytes to encode"); if (numECBytes <= 0) throw new ArgumentException("No Error Correction bytes"); int[] toEncode = ConvertToIntArray(dataBytes, dataLength, numECBytes); Polynomial generator = generatorPoly.GetGenerator(numECBytes); var dataPoly = new Polynomial(generator.GField, toEncode); PolyDivideStruct divideResult = dataPoly.Divide(generator); int[] remainderCoeffs = divideResult.Remainder.Coefficients; return ConvertTosByteArray(remainderCoeffs, numECBytes); }
/// <summary> /// Multiply current Polynomial to anotherone. /// </summary> /// <param name="other">The other.</param> /// <returns>Result polynomial after multiply</returns> /// <remarks></remarks> internal Polynomial Multiply(Polynomial other) { if (Primitive != other.Primitive) { throw new ArgumentException( "Polynomial can not perform Multiply as they don't have same Primitive for GaloisField256"); } if (isMonomialZero || other.isMonomialZero) return new Polynomial(GField, new[] {0}); int[] aCoefficients = Coefficients; int aLength = aCoefficients.Length; int[] bCoefficient = other.Coefficients; int bLength = bCoefficient.Length; var rCoefficients = new int[aLength + bLength - 1]; for (int aIndex = 0; aIndex < aLength; aIndex++) { int aCoeff = aCoefficients[aIndex]; for (int bIndex = 0; bIndex < bLength; bIndex++) { rCoefficients[aIndex + bIndex] = GField.Addition(rCoefficients[aIndex + bIndex], GField.Product(aCoeff, bCoefficient[bIndex])); } } return new Polynomial(GField, rCoefficients); }
/// <summary> /// divide current polynomial by "other" /// </summary> /// <param name="other">The other.</param> /// <returns>Result polynomial after divide</returns> /// <remarks></remarks> internal PolyDivideStruct Divide(Polynomial other) { if (Primitive != other.Primitive) { throw new ArgumentException( "Polynomial can not perform Devide as they don't have same Primitive for GaloisField256"); } if (other.isMonomialZero) { throw new ArgumentException("Can not devide by Polynomial Zero"); } //this devide by other = a devide by b int aLength = Coefficients.Length; //We will make change to aCoefficient. It will return as remainder var aCoefficients = new int[aLength]; Array.Copy(Coefficients, 0, aCoefficients, 0, aLength); int bLength = other.Coefficients.Length; if (aLength < bLength) return new PolyDivideStruct(new Polynomial(GField, new[] {0}), this); else { //quotient coefficients //qLastIndex = alength - blength qlength = qLastIndex + 1 var qCoefficients = new int[(aLength - bLength) + 1]; //Denominator int otherLeadingTerm = other.GetCoefficient(other.Degree); int inverseOtherLeadingTerm = GField.inverse(otherLeadingTerm); for (int aIndex = 0; aIndex <= aLength - bLength; aIndex++) { if (aCoefficients[aIndex] != 0) { int aScalar = GField.Product(inverseOtherLeadingTerm, aCoefficients[aIndex]); Polynomial term = other.MultiplyScalar(aScalar); qCoefficients[aIndex] = aScalar; int[] bCoefficient = term.Coefficients; if (bCoefficient[0] != 0) { for (int bIndex = 0; bIndex < bLength; bIndex++) { aCoefficients[aIndex + bIndex] = GField.Subtraction(aCoefficients[aIndex + bIndex], bCoefficient[bIndex]); } } } } return new PolyDivideStruct(new Polynomial(GField, qCoefficients), new Polynomial(GField, aCoefficients)); } }
/// <summary> /// Add another Polynomial to current one /// </summary> /// <param name="other">The polynomial need to add or subtract to current one</param> /// <returns>Result polynomial after add or subtract</returns> /// <remarks></remarks> internal Polynomial AddOrSubtract(Polynomial other) { if (Primitive != other.Primitive) { throw new ArgumentException( "Polynomial can not perform AddOrSubtract as they don't have same Primitive for GaloisField256"); } if (isMonomialZero) return other; else if (other.isMonomialZero) return this; int otherLength = other.Coefficients.Length; int thisLength = Coefficients.Length; if (otherLength > thisLength) return CoefficientXor(Coefficients, other.Coefficients); else return CoefficientXor(other.Coefficients, Coefficients); }