/** * Return the head coefficient of a polynomial. * * @param a the polynomial * @return the head coefficient of <tt>a</tt> */ private static int headCoefficient(int[] a) { int degree = computeDegree(a); if (degree == -1) { return 0; } return a[degree]; }
/** * Return the head coefficient of a polynomial. * * @param a the polynomial * @return the head coefficient of <tt>a</tt> */ private static int headCoefficient(int[] a) { int degree = computeDegree(a); if (degree == -1) { return 0; } return a[degree]; }
/** * Compare two polynomials given as int arrays. * * @param a the first polynomial * @param b the second polynomial * @return <tt>true</tt> if <tt>a</tt> and <tt>b</tt> represent the * same polynomials, <tt>false</tt> otherwise */ private static boolean isEqual(int[] a, int[] b) { int da = computeDegree(a); int db = computeDegree(b); if (da != db) { return false; } for (int i = 0; i <= da; i++) { if (a[i] != b[i]) { return false; } } return true; }
/** * Compare two polynomials given as int arrays. * * @param a the first polynomial * @param b the second polynomial * @return <tt>true</tt> if <tt>a</tt> and <tt>b</tt> represent the * same polynomials, <tt>false</tt> otherwise */ private static boolean isEqual(int[] a, int[] b) { int da = computeDegree(a); int db = computeDegree(b); if (da != db) { return false; } for (int i = 0; i <= da; i++) { if (a[i] != b[i]) { return false; } } return true; }
/** * Compute the product of a polynomial with a monomial X^k. * * @param a the polynomial * @param k the degree of the monomial * @return <tt>a * X^k</tt> */ private static int[] multWithMonomial(int[] a, int k) { int d = computeDegree(a); if (d == -1) { return new int[1]; } int[] result = new int[d + k + 1]; System.arraycopy(a, 0, result, k, d + 1); return result; }
/** * Compute the product of a polynomial with a monomial X^k. * * @param a the polynomial * @param k the degree of the monomial * @return <tt>a * X^k</tt> */ private static int[] multWithMonomial(int[] a, int k) { int d = computeDegree(a); if (d == -1) { return new int[1]; } int[] result = new int[d + k + 1]; System.arraycopy(a, 0, result, k, d + 1); return result; }
/** * Add the given polynomial to this polynomial (overwrite this). * * @param addend the addend */ public void addToThis(PolynomialGF2mSmallM addend) { coefficients = add(coefficients, addend.coefficients); computeDegree(); }
/** * Add the given polynomial to this polynomial (overwrite this). * * @param addend the addend */ public void addToThis(PolynomialGF2mSmallM addend) { coefficients = add(coefficients, addend.coefficients); computeDegree(); }
/** * Construct the polynomial over the given finite field GF(2^m) from the * given coefficient vector. * * @param field finite field GF2m * @param coeffs the coefficient vector */ public PolynomialGF2mSmallM(GF2mField field, int[] coeffs) { this.field = field; coefficients = normalForm(coeffs); computeDegree(); }
/** * Construct the polynomial over the given finite field GF(2^m) from the * given coefficient vector. * * @param field finite field GF2m * @param coeffs the coefficient vector */ public PolynomialGF2mSmallM(GF2mField field, int[] coeffs) { this.field = field; coefficients = normalForm(coeffs); computeDegree(); }
/** * Construct a polynomial over the finite field GF(2^m). * * @param field the finite field GF(2^m) * @param deg degree of polynomial * @param typeOfPolynomial type of polynomial * @param sr PRNG */ public PolynomialGF2mSmallM(GF2mField field, int deg, char typeOfPolynomial, SecureRandom sr) { this.field = field; switch (typeOfPolynomial) { case PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL: coefficients = createRandomIrreduciblePolynomial(deg, sr); break; default: throw new IllegalArgumentException(" Error: type " + typeOfPolynomial + " is not defined for GF2smallmPolynomial"); } computeDegree(); }
/** * Construct a polynomial over the finite field GF(2^m). * * @param field the finite field GF(2^m) * @param deg degree of polynomial * @param typeOfPolynomial type of polynomial * @param sr PRNG */ public PolynomialGF2mSmallM(GF2mField field, int deg, char typeOfPolynomial, SecureRandom sr) { this.field = field; switch (typeOfPolynomial) { case PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL: coefficients = createRandomIrreduciblePolynomial(deg, sr); break; default: throw new IllegalArgumentException(" Error: type " + typeOfPolynomial + " is not defined for GF2smallmPolynomial"); } computeDegree(); }
/** * Strip leading zero coefficients from the given polynomial. * * @param a the polynomial * @return the reduced polynomial */ private static int[] normalForm(int[] a) { int d = computeDegree(a); // if a is the zero polynomial if (d == -1) { // return new zero polynomial return new int[1]; } // if a already is in normal form if (a.length == d + 1) { // return a clone of a return IntUtils.clone(a); } // else, reduce a int[] result = new int[d + 1]; System.arraycopy(a, 0, result, 0, d + 1); return result; }
/** * Strip leading zero coefficients from the given polynomial. * * @param a the polynomial * @return the reduced polynomial */ private static int[] normalForm(int[] a) { int d = computeDegree(a); // if a is the zero polynomial if (d == -1) { // return new zero polynomial return new int[1]; } // if a already is in normal form if (a.length == d + 1) { // return a clone of a return IntUtils.clone(a); } // else, reduce a int[] result = new int[d + 1]; System.arraycopy(a, 0, result, 0, d + 1); return result; }
/** * Multiply this polynomial with an element from GF(2^m). * * @param element an element of the finite field GF(2^m) * @throws ArithmeticException if <tt>element</tt> is not an element of the finite * field this polynomial is defined over. */ public void multThisWithElement(int element) { if (!field.isElementOfThisField(element)) { throw new ArithmeticException( "Not an element of the finite field this polynomial is defined over."); } coefficients = multWithElement(coefficients, element); computeDegree(); }
/** * Multiply this polynomial with an element from GF(2^m). * * @param element an element of the finite field GF(2^m) * @throws ArithmeticException if <tt>element</tt> is not an element of the finite * field this polynomial is defined over. */ public void multThisWithElement(int element) { if (!field.isElementOfThisField(element)) { throw new ArithmeticException( "Not an element of the finite field this polynomial is defined over."); } coefficients = multWithElement(coefficients, element); computeDegree(); }
/** * Return the greatest common divisor of two polynomials over the field * <tt>GF(2^m)</tt>. * * @param f the first polynomial * @param g the second polynomial * @return <tt>gcd(f, g)</tt> */ private int[] gcd(int[] f, int[] g) { int[] a = f; int[] b = g; if (computeDegree(a) == -1) { return b; } while (computeDegree(b) != -1) { int[] c = mod(a, b); a = new int[b.length]; System.arraycopy(b, 0, a, 0, a.length); b = new int[c.length]; System.arraycopy(c, 0, b, 0, b.length); } int coeff = field.inverse(headCoefficient(a)); return multWithElement(a, coeff); }
/** * Compute the product of a polynomial a with an element from the finite * field <tt>GF(2^m)</tt>. * * @param a the polynomial * @param element an element of the finite field GF(2^m) * @return <tt>a * element</tt> */ private int[] multWithElement(int[] a, int element) { int degree = computeDegree(a); if (degree == -1 || element == 0) { return new int[1]; } if (element == 1) { return IntUtils.clone(a); } int[] result = new int[degree + 1]; for (int i = degree; i >= 0; i--) { result[i] = field.mult(a[i], element); } return result; }
/** * Compute the product of a polynomial a with an element from the finite * field <tt>GF(2^m)</tt>. * * @param a the polynomial * @param element an element of the finite field GF(2^m) * @return <tt>a * element</tt> */ private int[] multWithElement(int[] a, int element) { int degree = computeDegree(a); if (degree == -1 || element == 0) { return new int[1]; } if (element == 1) { return IntUtils.clone(a); } int[] result = new int[degree + 1]; for (int i = degree; i >= 0; i--) { result[i] = field.mult(a[i], element); } return result; }
/** * Reduce a polynomial modulo another polynomial. * * @param a the polynomial * @param f the reduction polynomial * @return <tt>a mod f</tt> */ private int[] mod(int[] a, int[] f) { int df = computeDegree(f); if (df == -1) { throw new ArithmeticException("Division by zero"); } int[] result = new int[a.length]; int hc = headCoefficient(f); hc = field.inverse(hc); System.arraycopy(a, 0, result, 0, result.length); while (df <= computeDegree(result)) { int[] q; int coeff = field.mult(headCoefficient(result), hc); q = multWithMonomial(f, computeDegree(result) - df); q = multWithElement(q, coeff); result = add(q, result); } return result; }