public GF256Poly multiply(GF256Poly other) { if (!field.Equals(other.field)) { throw new ArgumentException("GF256Polys do not have same GF256 field"); } if (isZero() || other.isZero()) { return(field.getZero()); } int[] aCoefficients = this.coefficients; int aLength = aCoefficients.Length; int[] bCoefficients = other.coefficients; int bLength = bCoefficients.Length; int[] product = new int[aLength + bLength - 1]; for (int i = 0; i < aLength; i++) { int aCoeff = aCoefficients[i]; for (int j = 0; j < bLength; j++) { product[i + j] = GF256.addOrSubtract(product[i + j], field.multiply(aCoeff, bCoefficients[j])); } } return(new GF256Poly(field, product)); }
/** * @param field the {@link GF256} instance representing the field to use * to perform computations * @param coefficients coefficients as ints representing elements of GF(256), arranged * from most significant (highest-power term) coefficient to least significant * @throws ArgumentException if argument is null or empty, * or if leading coefficient is 0 and this is not a * constant polynomial (that is, it is not the monomial "0") */ public GF256Poly(GF256 field, int[] coefficients) { if (coefficients == null || coefficients.Length == 0) { throw new ArgumentException(); } this.field = field; int coefficientsLength = coefficients.Length; if (coefficientsLength > 1 && coefficients[0] == 0) { // Leading term must be non-zero for anything except the constant polynomial "0" int firstNonZero = 1; while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) { firstNonZero++; } if (firstNonZero == coefficientsLength) { this.coefficients = field.getZero().coefficients; } else { this.coefficients = new int[coefficientsLength - firstNonZero]; System.Array.Copy(coefficients, firstNonZero, this.coefficients, 0, this.coefficients.Length); } } else { this.coefficients = coefficients; } }
/** * @param field the {@link GF256} instance representing the field to use * to perform computations * @param coefficients coefficients as ints representing elements of GF(256), arranged * from most significant (highest-power term) coefficient to least significant * @throws ArgumentException if argument is null or empty, * or if leading coefficient is 0 and this is not a * constant polynomial (that is, it is not the monomial "0") */ public GF256Poly(GF256 field, int[] coefficients) { if (coefficients == null || coefficients.Length == 0) { throw new ArgumentException(); } this.field = field; int coefficientsLength = coefficients.Length; if (coefficientsLength > 1 && coefficients[0] == 0) { // Leading term must be non-zero for anything except the constant polynomial "0" int firstNonZero = 1; while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) { firstNonZero++; } if (firstNonZero == coefficientsLength) { this.coefficients = field.getZero().coefficients; } else { this.coefficients = new int[coefficientsLength - firstNonZero]; System.Array.Copy(coefficients,firstNonZero,this.coefficients,0,this.coefficients.Length); } } else { this.coefficients = coefficients; } }
private GF256Poly[] runEuclideanAlgorithm(GF256Poly a, GF256Poly b, int R) { // Assume a's degree is >= b's if (a.getDegree() < b.getDegree()) { GF256Poly temp = a; a = b; b = temp; } GF256Poly rLast = a; GF256Poly r = b; GF256Poly sLast = field.getOne(); GF256Poly s = field.getZero(); GF256Poly tLast = field.getZero(); GF256Poly t = field.getOne(); // Run Euclidean algorithm until r's degree is less than R/2 while (r.getDegree() >= R / 2) { GF256Poly rLastLast = rLast; GF256Poly sLastLast = sLast; GF256Poly tLastLast = tLast; rLast = r; sLast = s; tLast = t; // Divide rLastLast by rLast, with quotient in q and remainder in r if (rLast.isZero()) { // Oops, Euclidean algorithm already terminated? throw new ReedSolomonException("r_{i-1} was zero"); } r = rLastLast; GF256Poly q = field.getZero(); int denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree()); int dltInverse = field.inverse(denominatorLeadingTerm); while (r.getDegree() >= rLast.getDegree() && !r.isZero()) { int degreeDiff = r.getDegree() - rLast.getDegree(); int scale = field.multiply(r.getCoefficient(r.getDegree()), dltInverse); q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale)); r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale)); } s = q.multiply(sLast).addOrSubtract(sLastLast); t = q.multiply(tLast).addOrSubtract(tLastLast); } int sigmaTildeAtZero = t.getCoefficient(0); if (sigmaTildeAtZero == 0) { throw new ReedSolomonException("sigmaTilde(0) was zero"); } int inverse = field.inverse(sigmaTildeAtZero); GF256Poly sigma = t.multiply(inverse); GF256Poly omega = r.multiply(inverse); return(new GF256Poly[] { sigma, omega }); }