/** * Reduce this polynomial modulo another polynomial. * * @param f the reduction polynomial * @return <tt>this mod f</tt> */ public PolynomialGF2mSmallM mod(PolynomialGF2mSmallM f) { int[] resultCoeff = mod(coefficients, f.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); }
/** * Compute a polynomial pair (a,b) from this polynomial and the given * polynomial g with the property b*this = a mod g and deg(a)<=deg(g)/2. * * @param g the reduction polynomial * @return PolynomialGF2mSmallM[] {a,b} with b*this = a mod g and deg(a)<= * deg(g)/2 */ public PolynomialGF2mSmallM[] modPolynomialToFracton(PolynomialGF2mSmallM g) { int dg = g.degree >> 1; int[] a0 = normalForm(g.coefficients); int[] a1 = mod(coefficients, g.coefficients); int[] b0 = {0}; int[] b1 = {1}; while (computeDegree(a1) > dg) { int[][] q = div(a0, a1); a0 = a1; a1 = q[1]; int[] b2 = add(b0, modMultiply(q[0], b1, g.coefficients)); b0 = b1; b1 = b2; } return new PolynomialGF2mSmallM[]{ new PolynomialGF2mSmallM(field, a1), new PolynomialGF2mSmallM(field, b1)}; }
/** * Compute a polynomial pair (a,b) from this polynomial and the given * polynomial g with the property b*this = a mod g and deg(a)<=deg(g)/2. * * @param g the reduction polynomial * @return PolynomialGF2mSmallM[] {a,b} with b*this = a mod g and deg(a)<= * deg(g)/2 */ public PolynomialGF2mSmallM[] modPolynomialToFracton(PolynomialGF2mSmallM g) { int dg = g.degree >> 1; int[] a0 = normalForm(g.coefficients); int[] a1 = mod(coefficients, g.coefficients); int[] b0 = {0}; int[] b1 = {1}; while (computeDegree(a1) > dg) { int[][] q = div(a0, a1); a0 = a1; a1 = q[1]; int[] b2 = add(b0, modMultiply(q[0], b1, g.coefficients)); b0 = b1; b1 = b2; } return new PolynomialGF2mSmallM[]{ new PolynomialGF2mSmallM(field, a1), new PolynomialGF2mSmallM(field, b1)}; }
/** * Reduce this polynomial modulo another polynomial. * * @param f the reduction polynomial * @return <tt>this mod f</tt> */ public PolynomialGF2mSmallM mod(PolynomialGF2mSmallM f) { int[] resultCoeff = mod(coefficients, f.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); }
/** * Compute the result of the division of two polynomials modulo a third * polynomial over the field <tt>GF(2^m)</tt>. * * @param a the first polynomial * @param b the second polynomial * @param g the reduction polynomial * @return <tt>a * b^(-1) mod g</tt> */ private int[] modDiv(int[] a, int[] b, int[] g) { int[] r0 = normalForm(g); int[] r1 = mod(b, g); int[] s0 = {0}; int[] s1 = mod(a, g); int[] s2; int[][] q; while (computeDegree(r1) != -1) { q = div(r0, r1); r0 = normalForm(r1); r1 = normalForm(q[1]); s2 = add(s0, modMultiply(q[0], s1, g)); s0 = normalForm(s1); s1 = normalForm(s2); } int hc = headCoefficient(r0); s0 = multWithElement(s0, field.inverse(hc)); return s0; }
/** * Compute the product of two polynomials modulo a third polynomial over the * finite field <tt>GF(2^m)</tt>. * * @param a the first polynomial * @param b the second polynomial * @param g the reduction polynomial * @return <tt>a * b mod g</tt> */ private int[] modMultiply(int[] a, int[] b, int[] g) { return mod(multiply(a, b), g); }
/** * Compute the result of the division of two polynomials modulo a third * polynomial over the field <tt>GF(2^m)</tt>. * * @param a the first polynomial * @param b the second polynomial * @param g the reduction polynomial * @return <tt>a * b^(-1) mod g</tt> */ private int[] modDiv(int[] a, int[] b, int[] g) { int[] r0 = normalForm(g); int[] r1 = mod(b, g); int[] s0 = {0}; int[] s1 = mod(a, g); int[] s2; int[][] q; while (computeDegree(r1) != -1) { q = div(r0, r1); r0 = normalForm(r1); r1 = normalForm(q[1]); s2 = add(s0, modMultiply(q[0], s1, g)); s0 = normalForm(s1); s1 = normalForm(s2); } int hc = headCoefficient(r0); s0 = multWithElement(s0, field.inverse(hc)); return s0; }
/** * Compute the product of two polynomials modulo a third polynomial over the * finite field <tt>GF(2^m)</tt>. * * @param a the first polynomial * @param b the second polynomial * @param g the reduction polynomial * @return <tt>a * b mod g</tt> */ private int[] modMultiply(int[] a, int[] b, int[] g) { return mod(multiply(a, b), g); }
/** * Compute the squaring matrix for this polynomial ring, using the base * field and the reduction polynomial. */ private void computeSquaringMatrix() { int numColumns = p.getDegree(); sqMatrix = new PolynomialGF2mSmallM[numColumns]; for (int i = 0; i < numColumns >> 1; i++) { int[] monomCoeffs = new int[(i << 1) + 1]; monomCoeffs[i << 1] = 1; sqMatrix[i] = new PolynomialGF2mSmallM(field, monomCoeffs); } for (int i = numColumns >> 1; i < numColumns; i++) { int[] monomCoeffs = new int[(i << 1) + 1]; monomCoeffs[i << 1] = 1; PolynomialGF2mSmallM monomial = new PolynomialGF2mSmallM(field, monomCoeffs); sqMatrix[i] = monomial.mod(p); } }
/** * Compute the squaring matrix for this polynomial ring, using the base * field and the reduction polynomial. */ private void computeSquaringMatrix() { int numColumns = p.getDegree(); sqMatrix = new PolynomialGF2mSmallM[numColumns]; for (int i = 0; i < numColumns >> 1; i++) { int[] monomCoeffs = new int[(i << 1) + 1]; monomCoeffs[i << 1] = 1; sqMatrix[i] = new PolynomialGF2mSmallM(field, monomCoeffs); } for (int i = numColumns >> 1; i < numColumns; i++) { int[] monomCoeffs = new int[(i << 1) + 1]; monomCoeffs[i << 1] = 1; PolynomialGF2mSmallM monomial = new PolynomialGF2mSmallM(field, monomCoeffs); sqMatrix[i] = monomial.mod(p); } }
/** * 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); }
/** * 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); }