package org.bouncycastle.pqc.math.linearalgebra;

This class describes operations with polynomials over finite field GF(2), i e polynomial ring R = GF(2)[X]. All operations are defined only for polynomials with degree <=32. For the polynomial representation the map f: R->Z, poly(X)->poly(2) is used, where integers have the binary representation. For example: X^7+X^3+X+1 -> (00...0010001011)=139 Also for polynomials type Integer is used.
See Also:
  • GF2mField
/** * This class describes operations with polynomials over finite field GF(2), i e * polynomial ring R = GF(2)[X]. All operations are defined only for polynomials * with degree &lt;=32. For the polynomial representation the map f: R-&gt;Z, * poly(X)-&gt;poly(2) is used, where integers have the binary representation. For * example: X^7+X^3+X+1 -&gt; (00...0010001011)=139 Also for polynomials type * Integer is used. * * @see GF2mField */
public final class PolynomialRingGF2 {
Default constructor (private).
/** * Default constructor (private). */
private PolynomialRingGF2() { // empty }
Return sum of two polyomials
Params:
  • p – polynomial
  • q – polynomial
Returns:p+q
/** * Return sum of two polyomials * * @param p polynomial * @param q polynomial * @return p+q */
public static int add(int p, int q) { return p ^ q; }
Return product of two polynomials
Params:
  • p – polynomial
  • q – polynomial
Returns:p*q
/** * Return product of two polynomials * * @param p polynomial * @param q polynomial * @return p*q */
public static long multiply(int p, int q) { long result = 0; if (q != 0) { long q1 = q & 0x00000000ffffffffL; while (p != 0) { byte b = (byte)(p & 0x01); if (b == 1) { result ^= q1; } p >>>= 1; q1 <<= 1; } } return result; }
Compute the product of two polynomials modulo a third polynomial.
Params:
  • a – the first polynomial
  • b – the second polynomial
  • r – the reduction polynomial
Returns:a * b mod r
/** * Compute the product of two polynomials modulo a third polynomial. * * @param a the first polynomial * @param b the second polynomial * @param r the reduction polynomial * @return <tt>a * b mod r</tt> */
public static int modMultiply(int a, int b, int r) { int result = 0; int p = remainder(a, r); int q = remainder(b, r); if (q != 0) { int d = 1 << degree(r); while (p != 0) { byte pMod2 = (byte)(p & 0x01); if (pMod2 == 1) { result ^= q; } p >>>= 1; q <<= 1; if (q >= d) { q ^= r; } } } return result; }
Return the degree of a polynomial
Params:
  • p – polynomial p
Returns:degree(p)
/** * Return the degree of a polynomial * * @param p polynomial p * @return degree(p) */
public static int degree(int p) { int result = -1; while (p != 0) { result++; p >>>= 1; } return result; }
Return the degree of a polynomial
Params:
  • p – polynomial p
Returns:degree(p)
/** * Return the degree of a polynomial * * @param p polynomial p * @return degree(p) */
public static int degree(long p) { int result = 0; while (p != 0) { result++; p >>>= 1; } return result - 1; }
Return the remainder of a polynomial division of two polynomials.
Params:
  • p – dividend
  • q – divisor
Returns:p mod q
/** * Return the remainder of a polynomial division of two polynomials. * * @param p dividend * @param q divisor * @return <tt>p mod q</tt> */
public static int remainder(int p, int q) { int result = p; if (q == 0) { System.err.println("Error: to be divided by 0"); return 0; } while (degree(result) >= degree(q)) { result ^= q << (degree(result) - degree(q)); } return result; }
Return the rest of devision two polynomials
Params:
  • p – polinomial
  • q – polinomial
Returns:p mod q
/** * Return the rest of devision two polynomials * * @param p polinomial * @param q polinomial * @return p mod q */
public static int rest(long p, int q) { long p1 = p; if (q == 0) { System.err.println("Error: to be divided by 0"); return 0; } long q1 = q & 0x00000000ffffffffL; while ((p1 >>> 32) != 0) { p1 ^= q1 << (degree(p1) - degree(q1)); } int result = (int)(p1 & 0xffffffff); while (degree(result) >= degree(q)) { result ^= q << (degree(result) - degree(q)); } return result; }
Return the greatest common divisor of two polynomials
Params:
  • p – polinomial
  • q – polinomial
Returns:GCD(p, q)
/** * Return the greatest common divisor of two polynomials * * @param p polinomial * @param q polinomial * @return GCD(p, q) */
public static int gcd(int p, int q) { int a, b, c; a = p; b = q; while (b != 0) { c = remainder(a, b); a = b; b = c; } return a; }
Checking polynomial for irreducibility
Params:
  • p – polinomial
Returns:true if p is irreducible and false otherwise
/** * Checking polynomial for irreducibility * * @param p polinomial * @return true if p is irreducible and false otherwise */
public static boolean isIrreducible(int p) { if (p == 0) { return false; } int d = degree(p) >>> 1; int u = 2; for (int i = 0; i < d; i++) { u = modMultiply(u, u, p); if (gcd(u ^ 2, p) != 1) { return false; } } return true; }
Creates irreducible polynomial with degree d
Params:
  • deg – polynomial degree
Returns:irreducible polynomial p
/** * Creates irreducible polynomial with degree d * * @param deg polynomial degree * @return irreducible polynomial p */
public static int getIrreduciblePolynomial(int deg) { if (deg < 0) { System.err.println("The Degree is negative"); return 0; } if (deg > 31) { System.err.println("The Degree is more then 31"); return 0; } if (deg == 0) { return 1; } int a = 1 << deg; a++; int b = 1 << (deg + 1); for (int i = a; i < b; i += 2) { if (isIrreducible(i)) { return i; } } return 0; } }