/** * 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)}; }
/** * 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(); }
/** * Return the greatest common divisor of this and a polynomial <i>f</i> * * @param f polynomial * @return GCD(this, f) */ public PolynomialGF2mSmallM gcd(PolynomialGF2mSmallM f) { int[] resultCoeff = gcd(coefficients, f.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); }
/** * Add the given polynomial to this polynomial (overwrite this). * * @param addend the addend */ public void addToThis(PolynomialGF2mSmallM addend) { coefficients = add(coefficients, addend.coefficients); computeDegree(); }
/** * Compute the sum of this polynomial and the given polynomial. * * @param addend the addend * @return <tt>this + a</tt> (newly created) */ public PolynomialGF2mSmallM add(PolynomialGF2mSmallM addend) { int[] resultCoeff = add(coefficients, addend.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); }
PolynomialGF2mSmallM syndrome = new PolynomialGF2mSmallM(syndVec .toExtensionFieldVector(field)); PolynomialGF2mSmallM t = syndrome.modInverse(gp); PolynomialGF2mSmallM tau = t.addMonomial(1); tau = tau.modSquareRootMatrix(sqRootMatrix); PolynomialGF2mSmallM[] ab = tau.modPolynomialToFracton(gp); PolynomialGF2mSmallM a2 = ab[0].multiply(ab[0]); PolynomialGF2mSmallM b2 = ab[1].multiply(ab[1]); PolynomialGF2mSmallM xb2 = b2.multWithMonomial(1); PolynomialGF2mSmallM a2plusXb2 = a2.add(xb2); int headCoeff = a2plusXb2.getHeadCoefficient(); int invHeadCoeff = field.inverse(headCoeff); PolynomialGF2mSmallM elp = a2plusXb2.multWithElement(invHeadCoeff); int z = elp.evaluateAt(i);
/** * 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; }
/** * 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; }
int numColumns = p.getDegree(); for (int i = numColumns - 1; i >= 0; i--) tmpMatrix[i] = new PolynomialGF2mSmallM(sqMatrix[i]); for (int i = numColumns - 1; i >= 0; i--) sqRootMatrix[i] = new PolynomialGF2mSmallM(field, i); if (tmpMatrix[i].getCoefficient(i) == 0) if (tmpMatrix[j].getCoefficient(i) != 0) int coef = tmpMatrix[i].getCoefficient(i); int invCoef = field.inverse(coef); tmpMatrix[i].multThisWithElement(invCoef); sqRootMatrix[i].multThisWithElement(invCoef); coef = tmpMatrix[j].getCoefficient(i); if (coef != 0) .multWithElement(coef); PolynomialGF2mSmallM tmpInvColumn = sqRootMatrix[i] .multWithElement(coef); tmpMatrix[j].addToThis(tmpSqColumn); sqRootMatrix[j].addToThis(tmpInvColumn);
if (computeDegree(a) < computeDegree(b)) mult1 = normalForm(mult1); mult2 = normalForm(mult2); return multWithElement(mult1, mult2[0]); System.arraycopy(mult1, 0, res1, 0, res1.length); System.arraycopy(mult1, d2, res2, 0, res2.length); res1 = multiply(res1, mult2); res2 = multiply(res2, mult2); res2 = multWithMonomial(res2, d2); result = add(res1, res2); System.arraycopy(mult2, d2, secondPartMult2, 0, secondPartMult2.length); int[] helpPoly1 = add(firstPartMult1, secondPartMult1); int[] helpPoly2 = add(firstPartMult2, secondPartMult2); int[] res1 = multiply(firstPartMult1, firstPartMult2); int[] res2 = multiply(helpPoly1, helpPoly2); int[] res3 = multiply(secondPartMult1, secondPartMult2); res2 = add(res2, res1); res2 = add(res2, res3); res3 = multWithMonomial(res3, d2); result = add(res2, res3); result = multWithMonomial(result, d2); result = add(result, res1);
int d = computeDegree(a) >> 1; int[] u = {0, 1}; final int[] Y = {0, 1}; u = modMultiply(u, u, a); u = normalForm(u); int[] g = gcd(add(u, Y), a); if (computeDegree(g) != 0)
/** * Compute the square root of this polynomial modulo the given polynomial. * * @param a the reduction polynomial * @return <tt>this^(1/2) mod a</tt> */ public PolynomialGF2mSmallM modSquareRoot(PolynomialGF2mSmallM a) { int[] resultCoeff = IntUtils.clone(coefficients); int[] help = modMultiply(resultCoeff, resultCoeff, a.coefficients); while (!isEqual(help, coefficients)) { resultCoeff = normalForm(help); help = modMultiply(resultCoeff, resultCoeff, a.coefficients); } return new PolynomialGF2mSmallM(field, resultCoeff); }
/** * 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 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); } }
int t = gp.getDegree(); yz[0][j] = field.inverse(gp.evaluateAt(j)); gp.getCoefficient(t + k - i)));
public PolynomialGF2mSmallM[] getQInv() { PolynomialGF2mSmallM[] qInv = new PolynomialGF2mSmallM[encqInv.length]; GF2mField field = this.getField(); for (int i = 0; i < encqInv.length; i++) { qInv[i] = new PolynomialGF2mSmallM(field, encqInv[i]); } return qInv; }
/** * Compute the inverse of this polynomial modulo the given polynomial. * * @param a the reduction polynomial * @return <tt>this^(-1) mod a</tt> */ public PolynomialGF2mSmallM modInverse(PolynomialGF2mSmallM a) { int[] unit = {1}; int[] resultCoeff = modDiv(unit, coefficients, a.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); }
/** * 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]; }
/** * Compute the product of this polynomial and the given factor using a * Karatzuba like scheme. * * @param factor the polynomial * @return <tt>this * factor</tt> */ public PolynomialGF2mSmallM multiply(PolynomialGF2mSmallM factor) { int[] resultCoeff = multiply(coefficients, factor.coefficients); return new PolynomialGF2mSmallM(field, resultCoeff); }
/** * 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); }