Binary Polynomials: Arithmetic & Algorithms
Binary Polynomials: Arithmetic & Algorithms
Binary polynomials
We introduce binary polynomials and their arithmetic. Tests for irreducibility, primitivity, and a method
for factorization are given. Many of the algorithms shown can easily be implemented in hardware. An
important application is the linear feedback shift registers, described in chapter 41. The arithmetic
operations with binary polynomials are the underlying methods for computations in binary finite fields
which are treated in chapter 42.
A polynomial with coefficients in the field GF(2) = Z/2Z (that is, ‘coefficients modulo 2’) is called a
binary polynomial. The operations proceed as for usual polynomials except that the coefficients have to
be reduced modulo 2. To represent a binary polynomial in a binary computer we use words where the
bits are set at the positions where the polynomial coefficients are one. We use the convention that the
coefficient of xk appears at bit k, so the constant term lies at the least significant bit.
1..11.111 * 11.1.1
product as bitpol ordinary product
1..11.111 1 t= .....1..11.111 c= ......1..11.111
0
1..11.111.. 1 t= ...1.1111.1.11 c= ....11....1..11
0
1..11.111.... 1 t= .1.11.1..11.11 c= ..11..11.....11
1..11.111..... 1 t= 11.....1111.11 c= 1.......11...11
1..11.111 * 1..11.111
product as bitpol ordinary product
1..11.111 1 t= ........1..11.111 c= .........1..11.111
1..11.111. 1 t= .......11.1.11..1 c= ........111.1..1.1
1..11.111.. 1 t= ......1111....1.1 c= ......1...1......1
0
1..11.111.... 1 t= ....1.1..1111.1.1 c= .....11.111111...1
1..11.111..... 1 t= ...11..1....1.1.1 c= ...1....1.11.1...1
0
0
1..11.111........ 1 t= 1.....1.1...1.1.1 c= .1.1111..111.1...1
Figure 40.1-A: Multiplication (top) and squaring (bottom) of binary polynomials and numbers.
8 m <<= 2;
9 a >>= 1;
10 }
11 return t; // == bitpol_mult(a, a);
12 }
2: ba 01 00 00 00 mov $0x1,%edx // m = 1
7: 48 89 c8 mov %rcx,%rax // tmp = t
a: 48 31 d0 xor %rdx,%rax // tmp ^= m
d: 40 f6 c7 01 test $0x1,%dil // if ( a&1 )
11: 48 0f 45 c8 cmovne %rax,%rcx // then t = tmp
15: 48 c1 e2 02 shl $0x2,%rdx // m <<= 2
19: 48 d1 ef shr %rdi // a >>= 1
1c: 48 89 c8 mov %rcx,%rax
1f: 48 31 d0 xor %rdx,%rax
22: 40 f6 c7 01 test $0x1,%dil
26: 48 0f 45 c8 cmovne %rax,%rcx
2a: 48 c1 e2 02 shl $0x2,%rdx
2e: 48 d1 ef shr %rdi
31: 48 89 c8 mov %rcx,%rax
[--snip--]
43: 48 d1 ef shr %rdi
46: 48 89 c8 mov %rcx,%rax
[--snip--]
58: 48 d1 ef shr %rdi
5b: 75 aa jne 7 <_Z13bitpol_squarem+0x7> // a!=0 ?
5d: 48 89 c8 mov %rcx,%rax
60: c3 retq
The multiplication algorithm is optimized in the same way. For squaring we can also use the bit-zip
function given in section 1.15 on page 39:
1 inline ulong bitpol_square(ulong a) { return bit_zip0( a ); }
40.1.3 Exponentiation
With a multiplication (and squaring) function at hand, it is straightforward (see section 28.5 on page 563)
to implement the algorithm for binary exponentiation [FXT: bpol/bitpol-arith.h]:
1 inline ulong bitpol_power(ulong a, ulong e)
2 // Return A ** e
3 {
4 if ( 0==e ) return 1;
5
6 ulong s = a;
7 while ( 0==(e&1) )
8 {
9 s = bitpol_square(s);
10 e >>= 1;
11 }
12
13 a = s;
14 while ( 0!=(e>>=1) )
15 {
16 s = bitpol_square(s);
17 if ( e & 1 ) a = bitpol_mult(a, s);
18 }
19 return a;
20 }
Note that overflow will occur even for moderate exponents.
is not strictly correct as the swap can also happen with deg(a) = deg(b) but that does no harm.
The binary GCD algorithm can be implemented as follows:
826 Chapter 40: Binary polynomials
Only the three multiplications indicated by a dot are expensive, the multiplications by a power of x
are just shifts. The resulting scheme is the Karatsuba multiplication for polynomials, relation 28.1-3 on
page 550 interpreted for polynomials (set xN/2 = B). Recursive application of the scheme leads to the
asymptotic cost O(N log2 (3) ) ≈ O(N 1.585 ).
A = a2 x2 + a1 x + a0 (40.2-2a)
B = b2 x2 + b1 x + b0 (40.2-2b)
C = A B = c4 x4 + c3 x3 + c2 x2 + c1 x + c0 (40.2-2c)
c0 = d0,0 (40.2-3a)
c1 = d0,1 − d0,0 − d1,1 (40.2-3b)
c2 = d0,2 − d0,0 − d2,2 + d1,1 (40.2-3c)
c3 = d1,2 − d1,1 − d2,2 (40.2-3d)
c4 = d2,2 (40.2-3e)
where
d0,0 = a0 b0 (40.2-4a)
d1,1 = a1 b1 (40.2-4b)
d2,2 = a2 b2 (40.2-4c)
d0,1 = (a0 + a1 ) (b0 + b1 ) (40.2-4d)
d0,2 = (a0 + a2 ) (b0 + b2 ) (40.2-4e)
d1,2 = (a1 + a2 ) (b1 + b2 ) (40.2-4f)
The scheme involves 6 multiplications and 13 additions. Recursive application leads to the asymptotic
cost (N log3 (6) ) ≈ O(N 1.6309 ) which is slightly worse than for the 2-term scheme. However, applying this
scheme first for a polynomial with N = 3 · 2n terms and then using the Karatsuba scheme recursively
can be advantageous.
We generalize the method for n-term polynomials and denote the scheme by KA-n. The 2-term scheme
KA-2 is the Karatsuba algorithm. With
n−1
X
A = ak xk (40.2-5a)
k=0
n−1
X
B = bk xk (40.2-5b)
k=0
2n−2
X
C = A B =: ck xk (40.2-5c)
k=0
define
Then
c0 = d0,0 (40.2-7a)
c2 n−2 = dn−1,n−1 (40.2-7b)
40.2: Multiplying binary polynomials of high degree 829
c∗i
if i odd
ci = (40.2-7c)
c∗i + di/2,i/2 otherwise
d00 = a0 * b0
d11 = a1 * b1
d22 = a2 * b2
d33 = a3 * b3
d44 = a4 * b4
d01 = (a0 + a1) * (b0 + b1)
d02 = (a0 + a2) * (b0 + b2)
d12 = (a1 + a2) * (b1 + b2)
d03 = (a0 + a3) * (b0 + b3)
d13 = (a1 + a3) * (b1 + b3)
d23 = (a2 + a3) * (b2 + b3)
d04 = (a0 + a4) * (b0 + b4)
d14 = (a1 + a4) * (b1 + b4)
d24 = (a2 + a4) * (b2 + b4)
d34 = (a3 + a4) * (b3 + b4)
c0 = + d00
c1 = + d01 - d00 - d11
c2 = + d02 - d00 - d22 + d11
c3 = + d03 - d00 - d33 + d12 - d11 - d22
c4 = + d04 - d00 - d44 + d13 - d11 - d33 + d22
c5 = + d14 - d11 - d44 + d23 - d22 - d33
c6 = + d24 - d22 - d44 + d33
c7 = + d34 - d33 - d44
c8 = + d44
Figure 40.2-A: Code for the algorithm KA-5.
b4*a4
(b0 + b1)*a0 + (a1*b0 + b1*a1)
(b0 + b2)*a0 + (a2*b0 + b2*a2)
[--snip--]
(b3 + b4)*a3 + (a4*b3 + b4*a4)
/* the c_i in terms of d(s,t), evaluated: */
b0*a0
b1*a0 + a1*b0
b2*a0 + (a2*b0 + b1*a1)
b3*a0 + (a3*b0 + (b2*a1 + a2*b1))
b4*a0 + (a4*b0 + (b3*a1 + (a3*b1 + b2*a2)))
b4*a1 + (a4*b1 + (b3*a2 + a3*b2))
b4*a2 + (a4*b2 + b3*a3)
b4*a3 + a4*b3
b4*a4
/* polynomials: */
a4*x^4 + a3*x^3 + a2*x^2 + a1*x + a0
b4*x^4 + b3*x^3 + b2*x^2 + b1*x + b0
/* direct computation of product: */
b4*a4*x^8 + (b4*a3 + a4*b3)*x^7 + (b4*a2 + (a4*b2 + b3*a3))*x^6 + [...]
/* Karatsuba computation of product: */
b4*a4*x^8 + (b4*a3 + a4*b3)*x^7 + (b4*a2 + (a4*b2 + b3*a3))*x^6 + [...]
/* difference: */
0
OK. /* looks good */
The number of multiplications with the KA-n splitting scheme is (n2 + n)/2 which is suboptimal except
for n = 2. However, recursive application can be worthwhile. One should start with the biggest prime
factors as the number of additions is then minimized. The number of multiplications does not depend
on the order of recursion (see [347] which also tabulates the number of additions and multiplications for
n ≤ 128).
With n just below a highly composite number one may append zeros as ‘dummy’ terms and recursively
use KA-n algorithms for small n. For example, for polynomials of degree 63 the recursion with KA-2
(and n = 64) will beat the scheme “KA-7, then KA-3”.
One can write code generators that create expanded versions of the recursions for n the product of
small primes. If the cost of multiplication is much higher than for addition (as for binary polynomial
multiplication on general purpose CPUs), then substantial savings can be expected.
A = a0 + a1 xN + a2 x2N =: a0 + a1 Y + a2 Y 2 (40.2-8)
and identically for B. A 3-way splitting scheme for multiplication is shown in figure 40.2-B. The multi-
plications and divisions by x are shifts and the exact divisions are linear operations if we use the method
of section 40.1.6 on page 826.
A = a0 + a1 Y + a2 Y 2 + a3 Y 3 (40.2-9)
where Y := xN and identically for B. The 4-way splitting multiplication scheme is shown in figure 40.2-C.
832 Chapter 40: Binary polynomials
A = a2*Y^2 + a1*Y + a0
B = b2*Y^2 + b1*Y + b0
S3 = a2 + a1 + a0;
S2 = b2 + b1 + b0;
S1 = S3 * S2; \\ Mult (1)
S0 = a2*x^2 + a1*x;
S4 = b2*x^2 + b1*x;
S3 += S0;
S2 += S4;
S0 += a0;
S4 += b0;
S3 *= S2; \\ Mult (2)
S2 = S0 * S4; \\ Mult (3)
S4 = a2 * b2; \\ Mult (4)
S0 = a0 * b0; \\ Mult (5)
S3 += S2;
S2 += S0; S2 /= x; S2 += S3;
T = S4; T *= (x^3+1); \\ temporary variable
S2 += T; S2 /= (x+1); \\ exact division
S1 += S0;
S3 += S1; S3 /= x; S3 /= (x+1); \\ exact division
S1 += S4; S1 += S2;
S2 += S3;
P = S4*Y^4 + S3*Y^3 + S2*Y^2 + S1*Y + S0;
Mod(1,2)* (P - A*B) \\ == zero
(P - A*B) \\ NOT zero, the scheme only works over GF(2)
Figure 40.2-B: Implementation of the 3-way multiplication scheme for binary polynomials. The five
expensive multiplications are commented with ‘Mult (n)’.
7 if ( b & 1 ) t ^= a;
8 b >>= 1;
9
10 ulong s = a & h;
11 a <<= 1;
12 if ( s ) a ^= c;
13 }
14 return t;
15 }
40.3.3 Exponentiation
The following routine for modular exponentiation uses the right-to-left powering algorithm from sec-
tion 28.5.1 on page 563 [FXT: bpol/bitpolmod-arith.h]:
1 inline ulong bitpolmod_power(ulong a, ulong e, ulong c, ulong h)
2 // Return (A ** e) mod C
3 {
4 if ( 0==e ) return 1; // avoid hang with e==0 in next while()
40.3: Modular arithmetic with binary polynomials 835
5
6 ulong s = a;
7 while ( 0==(e&1) )
8 {
9 s = bitpolmod_square(s, c, h);
10 e >>= 1;
11 }
12
13 a = s;
14 while ( 0!=(e>>=1) )
15 {
16 s = bitpolmod_square(s, c, h);
17 if ( e & 1 ) a = bitpolmod_mult(a, s, c, h);
18 }
19 return a;
20 }
The left-to-right powering algorithm given in section 28.5.2 on page 564 can be implemented as:
1 inline ulong bitpolmod_power(ulong a, ulong e, ulong c, ulong h)
2 {
3 ulong s = a;
4 ulong b = highest_one(e);
5 while ( b>1 )
6 {
7 b >>= 1;
8 s = bitpolmod_square(s, c, h); // s *= s;
9 if ( e & b ) s = bitpolmod_mult(s, a, c, h); // s *= a;
10 }
11 return s;
12 }
Computing a power of x can be optimized with this scheme:
1 inline ulong bitpolmod_xpower(ulong e, ulong c, ulong h)
2 // Return (x ** e) mod C
3 {
4 ulong s = 2; // ’x’
5 ulong b = highest_one(e);
6 while ( b>1 )
7 {
8 b >>= 1;
9 s = bitpolmod_square(s, c, h); // s *= s;
10 if ( e & b ) s = bitpolmod_times_x(s, c, h); // s *= x;
11 }
12 return s;
13 }
40.3.4 Division by x
Division by x is possible if the modulus has a nonzero constant term (that is, gcd(C, x) = 1). The routine
is quite simple [FXT: bpol/bitpolmod-arith.h]:
1 static inline ulong bitpolmod_div_x(ulong a, ulong c, ulong h)
2 // Return (A / x) mod C
3 // C must have nonzero constant term: (c&1)==1
4 {
5 ulong s = a & 1;
6 a >>= 1;
7 if ( s )
8 {
9 a ^= (c>>1);
10 a |= h; // so it also works for n == BITS_PER_LONG
11 }
12 return a;
13 }
If we do not insist on correct results for the case that the degree of C equals the number of bits in a
word, we could simply use the following two-liner:
if ( a & 1 ) a ^= c;
a >> 1;
The operation needs only about two CPU cycles. The inverse of x can be computed with:
1 static inline ulong bitpolmod_inv_x(ulong c, ulong h)
2 // Return (1 / x) mod C
836 Chapter 40: Binary polynomials
g = u · iu + v · iv (40.3-1)
If g = 1, we have
1 ≡ u · iu mod v (40.3-2)
6 a = bitpolmod_mult(a, i, c, h);
7 return a;
8 }
The inverse of a number a modulo a prime m can be computed as a−1 = am−2 (m − 1 is the maximal
order of an element in Z/mZ). With an irreducible (see section 40.4) polynomial C of degree n the inverse
n
modulo C of a polynomial A can be computed as A−1 = A2 −2 (2n − 1 is the maximal order modulo C,
see section 40.5 on page 841):
1 inline ulong bitpolmod_inverse_irred(ulong a, ulong c, ulong h)
2 // Return (A ** -1) mod C
3 // Must have: C irreducible.
4 {
5 ulong r1 = (h<<1) - 2; // max order minus one
6 ulong i = bitpolmod_power(a, r1, c, h);
7 return i;
8 }
· x3 + x + 1 · x3 + x2 + 1 ·
· x6 + x + 1 · x6 + x3 + 1 · x6 + x4 + x2 + x + 1 ·
· x6 + x4 + x3 + x + 1 · x6 + x5 + 1 · x6 + x5 + x2 + x + 1 ·
· x6 + x5 + x3 + x2 + 1 · x6 + x5 + x4 + x + 1 · x6 + x5 + x4 + x2 + 1
6 if ( c<4 )
7 {
8 if ( c>=2 ) return true; // x, and 1+x are irreducible
9 else return false; // constant polynomials are reducible
10 }
11
12 if ( 0==(1&c) ) return false; // x is a factor
13
14 // if ( 0==(c & 0xaaaaaaaaUL ) ) return 0; // at least one odd degree term
15 // if ( 0==parity(c) ) return 0; // need odd number of nonzero coeff.
16 // if ( 0!=bitpol_test_squarefree(c) ) return 0; // must be square-free
17
18 ulong d = h >> 1;
19 ulong u = 2; // =^= x
20 while ( 0 != d ) // floor( degree/2 ) times
21 {
22 // Square r-times for coefficients of c in GF(2^r).
23 // We have r==1:
24 u = bitpolmod_square(u, c, h);
25
26 ulong upx = u ^ 2; // =^= u+x
27
28 ulong g = bitpol_binary_gcd(upx, c);
29
30 if ( 1!=g ) return false; // reducible
31
32 d >>= 2;
33 }
34 return true; // irreducible
35 }
Commented out at the beginning are a few tests for some necessary conditions for irreducibility. For the
test bitpol_test_squarefree() (for a square factor) see section 40.12.2 on page 860. The routine will
fail if deg c =BITS_PER_LONG, because the gcd-computation fails in this case.
The implied test is called Rabin’s algorithm for irreducibility testing, see [276, p.7]. The number of GCD
computations equals the number of prime divisors of d.
If the prime divisors are processed in decreasing order, the successive exponents are increasing and the
power of x can be updated via squarings. The total number of squarings equals d which is minimal.
A C++ implementation of Rabin’s test is given in [FXT: bpol/bitpol-irred-rabin.cc]. A table of auxiliary
bit-masks gives the number of squarings between the GCD computations:
1 static const ulong rabin_tab[] =
2 {
3 0UL, // x = 0 (bits: ...........) OPS:
4 0UL, // x = 1 (bits: ...........) OPS: finally sqr 1 times
5 0UL, // x = 2 (bits: ...........) OPS: finally sqr 2 times
6 0UL, // x = 3 (bits: ...........) OPS: finally sqr 3 times
7 4UL, // x = 4 (bits: ........1..) OPS: sqr 2 times, finally sqr 2 times
8 0UL, // x = 5 (bits: ...........) OPS: finally sqr 5 times
9 12UL, // x = 6 (bits: .......11..) OPS: sqr 2 times, sqr 1 times, finally sqr 3 times
10 0UL, // x = 7 (bits: ...........) OPS: finally sqr 7 times
11 16UL, // x = 8 (bits: ......1....) OPS: sqr 4 times, finally sqr 4 times
12 8UL, // x = 9 (bits: .......1...) OPS: sqr 3 times, finally sqr 6 times
13 36UL, // x = 10 (bits: .....1..1..) OPS: sqr 2 times, sqr 3 times, finally sqr 5 times
14 [--snip--]
The GCD computation for the divisor 1 can be avoided by noting that only the polynomial x2 + x =
(x + 1) x would wrongly pass the test, so we exclude the factor x explicitly. The testing routine is
40.4: Irreducible polynomials 839
a strong pseudo irreducible (SPI). The test whether a polynomial is SPI does not involve any GCD
computation. The test for a polynomial C of degree d can be given as
1. If C has a linear factor (x or x + 1), then return false.
k
2. For k = 1, . . . , d compute sk := x2 mod C by successive squarings.
3. If sk = x for any k < d, then return false.
4. If sd 6= x, then return false.
5. Return true.
If d is a prime, the power of a prime, or the product of two primes, then strong pseudo irreducibility
implies irreducibility (see [23]). We list the degrees 1 < d < 63 where strong pseudo irreducibility does
not imply irreducibility (and GCDs are needed for irreducibility testing):
12, 18, 20, 24, 28, 30, 36, 40, 42, 44, 45, 48, 50, 52, 54, 56, 60, 63
840 Chapter 40: Binary polynomials
The sequence is entry A102467 in [312]. For the degrees 44 = 4 · 11 and 52 = 4 · 13 no GCDs are needed
e
because (see [23]) if d = re s where r and s are distinct primes and s > (2r − 2)/r. We have re = 4 so
we need s > (24 − 2)/2 = 7 which holds for primes s ≥ 11.
In the implementation of the SPI test an extra branch is needed if the polynomial C does not fit into a
word. In that case the parity must be even [FXT: bpol/bitpol-spi.cc]:
1 bool
2 bitpol_spi_q(ulong c, ulong h)
3 // Return whether C is a strong pseudo irreducible (SPI).
4 // A polynomial C of degree d is an SPI if
5 // it has no linear factors, x^(2^k)!=x for 0<k<d, and x^(2^d)==x.
6 // h needs to be a mask with one bit set:
7 // h == highest_one(C) >> 1 == 1UL << (degree(C)-1)
8 {
9 const bool md = (bool)((h<<1)==0); // whether degree == BITS_PER_LONG
10
11 if ( md )
12 {
13 if ( (c&1)==0 ) return false; // factor x
14 if ( 0 != parity(c) ) return false; // factor x+1
15 }
16 else
17 {
18 if ( c<4 ) // C is one of 0, 1, x, 1+x
19 {
20 if ( c>=2 ) return true; // x, and 1+x are irreducible
21 else return false; // constant polynomials are reducible
22 }
23
24 if ( (c&1)==0 ) return false; // factor x
25 if ( 0 == parity(c) ) return false; // factor x+1
26 }
27
28 ulong t = 1;
29 ulong m = 2; // x
30 m = bitpolmod_square(m, c, h);
31 do
32 {
33 if ( m==2 ) return false;
34 m = bitpolmod_square(m, c, h);
35 t <<= 1;
36 }
37 while ( t!=h );
38
39 if ( m!=2 ) return false;
40
41 return true;
42 }
An auxiliary function returns whether GCDs are needed with the irreducibility test (64-bit version):
1 bool bitpol_need_gcd(ulong h)
2 // Return whether GCDs are needed for irreducibility test.
3 {
4 // degrees where GCDs are needed:
5 // 12, 18, 20, 24, 28, 30, 36, 40, 42, 45, 48, 50, 54, 56, 60, 63
6 const ulong gn =
7 (1UL<<12)|(1UL<<18)|(1UL<<20)|(1UL<<24)|(1UL<<28)|(1UL<<30)|
8 (1UL<<36)|(1UL<<40)|(1UL<<42)|(1UL<<45)|(1UL<<48)|(1UL<<50)|
9 (1UL<<54)|(1UL<<56)|(1UL<<60)|(1UL<<63);
10 return 0 != ( h & (gn>>1) );
11 }
Now the irreducibility test can be implemented as follows:
1 inline bool bitpol_irreducible_q(ulong c, ulong h)
2 {
3 if ( bitpol_need_gcd(h) ) return bitpol_irreducible_ben_or_q(c, h);
4 else return bitpol_spi_q(c, h);
5 }
As the SPI test also works for polynomials not fitting into a word we can test those for irreducibility.
40.5: Primitive polynomials 841
as α is a root of the polynomial C. Therefore we can use exactly the same modular reduction as with
polynomial computation modulo C. The same is true for the multiplication of two linear combinations
(of the powers of the same root α).
We see that the order of a polynomial p is the order of its root α modulo p and that a polynomial is
primitive if and only if its root has maximal order. An irreducible polynomial C of degree n has n distinct
k
roots, they are equal to α2 mod C for 0 ≤ k < n. The orders of all roots are identical.
13 g1 = g1^tp;
14 te = te * tp;
15 );
16 );
17 return( te );
18 }
The function uses the following global variables that must be set up before call:
1 nn_ = 0; /* max order = 2^n-1 */
2 np_ = 0; /* number of primes in factorization */
3 vp_ = []; /* vector of primes */
4 vf_ = []; /* vector of factors (prime powers) */
5 vx_ = []; /* vector of exponents */
As given, the algorithm will do np exponentiations modulo p where np is the number of different primes in
the factorization in m. A C++ implementation of the algorithm is given in [FXT: bpol/bitpol-order.cc].
A shortcut that makes the algorithm terminate as soon as the computed order drops below maximum is
1 polmaxorder_q(p) =
2 /* Whether order of x modulo p is maximal (p irreducible over GF(2)) */
3 /* Early-out variant */
4 {
5 local(g1, te, tp, tf, tx, ct);
6 p *= Mod(1,2);
7 te = nn_;
8 for(i=1, np_,
9 tf = vf_[i]; tp = vp_[i]; tx = vx_[i];
10 te = te / tf;
11 g1 = Mod(g, p)^te;
12 ct = 0;
13 while ( 1!=g1,
14 g1 = g1^tp;
15 te = te * tp;
16 ct = ct + 1;
17 );
18 if ( ct<tx, return(0) );
19 );
20 return(1);
21 }
With polmaxorder_q() and GP’s built-in polisirreducible() the search for the lexicographically min-
imal primitive polynomials up to degree n = 100 is a matter of about ten seconds. Extending the list
up to n = 200 takes three minutes. The computation of all polynomials up to degree n = 400 takes less
than an hour.
Again, the algorithm depends on precomputed factorizations. The table [FXT: data/mersenne-factors.txt]
taken from [89] was used to save computation time.
For prime m = 2n − 1 (that is, m is a Mersenne prime) irreducibility suffices for primality: The one-liner
n=607; for(k=1,n-1,if(polisirreducible(Mod(1,2)*(1+t^k+t^n)),print1(" ",k)))
finds all primitive trinomials xn +xk +1 whose degree is the Mersenne exponent n = 607. The computation
of the following list takes about two minutes.
89: 38 51
127: 1 7 15 30 63 64 97 112 120 126
521: 32 48 158 168 353 363 473 489
607: 105 147 273 334 460 502
Note we did not exploit the symmetry (reversed polynomials are also primitive). Techniques to find
primitive trinomials whose degrees are very big Mersenne exponents are described in [80] and [84].
Pd
Here is a surprising theorem: Let p(x) = k=0 ck xk be an irreducible binary polynomial and Lp (x) :=
2k
Pd d
k=0 ck x . Then all irreducible factors of Lp (x)/x (a polynomial of degree 2 − 1) are of degree equal
to ord(p) (the order of x modulo p(x)). Especially, if p(x) is primitive, then Lp (x)/x is irreducible. The
theorem is proved in [368] and also in [233, p.110]. An example: x7 + x + 1 is primitive, so x127 + x + 1
40.6: The number of irreducible and primitive polynomials 843
127
−1
is irreducible. But, as 2127 − 1 is prime, x127 + x + 1 is also primitive. Therefore x2 + x + 1 is
irreducible.
n: In n: In n: In n: In
1: 2 11: 186 21: 99858 31: 69273666
2: 1 12: 335 22: 190557 32: 134215680
3: 2 13: 630 23: 364722 33: 260300986
4: 3 14: 1161 24: 698870 34: 505286415
5: 6 15: 2182 25: 1342176 35: 981706806
6: 9 16: 4080 26: 2580795 36: 1908866960
7: 18 17: 7710 27: 4971008 37: 3714566310
8: 30 18: 14532 28: 9586395 38: 7233615333
9: 56 19: 27594 29: 18512790 39: 14096302710
10: 99 20: 52377 30: 35790267 40: 27487764474
Figure 40.6-A: The number of irreducible binary polynomials for degrees n ≤ 40.
n: Pn n: Pn n: Pn n: Pn
1: 1 11: 176 21: 84672 31: 69273666
2: 1 12: 144 22: 120032 32: 67108864
3: 2 13: 630 23: 356960 33: 211016256
4: 2 14: 756 24: 276480 34: 336849900
5: 6 15: 1800 25: 1296000 35: 929275200
6: 6 16: 2048 26: 1719900 36: 725594112
7: 18 17: 7710 27: 4202496 37: 3697909056
8: 16 18: 7776 28: 4741632 38: 4822382628
9: 48 19: 27594 29: 18407808 39: 11928047040
10: 60 20: 24000 30: 17820000 40: 11842560000
Figure 40.6-B: The number of primitive binary polynomials for degrees n ≤ 40.
The Möbius function µ is defined by relation 37.1-6 on page 705. The expression is identical to the
n
formula for the number of Lyndon words (relation 18.3-2 on page 380). If n is prime, then In = 2 n−2 .
Figure 40.6-A gives In for n ≤ 40, the sequence is entry A001037 in [312]. The list of all irreducible
polynomials up to degree 11 is given in [FXT: data/all-irredpoly.txt].
For large degrees n the probability that a randomly chosen polynomial is irreducible is about 1/n. With
polynomials in two or more variables the situation is very different: the probability that a random
polynomial is irreducible tends to 1 for large n, see [58].
The number of primitive binary polynomials of degree n equals
ϕ(2n − 1)
Pn = (40.6-2)
n
n
If n is the exponent of a Mersenne prime we have Pn = 2 n−2 = In . The values of Pn for n ≤ 40 are
shown in figure 40.6-B. The sequence is entry A011260 in [312]. The list of all primitive polynomials up
to degree 11 is given in [FXT: data/all-primpoly.txt].
844 Chapter 40: Binary polynomials
n: Dn n: Dn n: Dn n: Dn
1: 1 11: 10 21: 15186 31: 0
2: 0 12: 191 22: 70525 32: 67106816
3: 0 13: 0 23: 7762 33: 49284730
4: 1 14: 405 24: 422390 34: 168436515
5: 0 15: 382 25: 46176 35: 52431606
6: 3 16: 2032 26: 860895 36: 1183272848
7: 0 17: 0 27: 768512 37: 16657254
8: 14 18: 6756 28: 4844763 38: 2411232705
9: 8 19: 0 29: 104982 39: 2168255670
10: 39 20: 28377 30: 17970267 40: 15645204474
Figure 40.6-C: The number of irreducible non-primitive binary polynomials for degrees n ≤ 40.
The difference Dn := In − Pn is the number of irreducible non-primitive polynomials (see figure 40.6-C).
If n is the exponent of a Mersenne prime, we have Dn = 0. The complete list of these polynomials up to
degree 12 inclusive is given in [FXT: data/all-nonprim-irredpoly.txt].
Figure 40.6-D gives the probability that a randomly chosen irreducible polynomial of degree n is primitive.
A polynomial of prime degree is very likely primitive, so any conjecture suggesting that polynomials of
a certain type are always primitive for prime degree is dubious: if we take one random irreducible
polynomial for each prime degree n, then chances are that all of them are primitive.
The roots of F ∗ (x) are the inverses of the roots of F (x). The reciprocal of a binary polynomial is the
reversed binary word:
1 inline ulong bitpol_recip(ulong c)
2 // Return x^deg(C) * C(1/x) (the reciprocal polynomial)
3 {
4 ulong t = 0;
5 while ( c )
6 {
7 t <<= 1;
8 t |= (c & 1);
9 c >>= 1;
10 }
11 return t;
12 }
Alternatively, we can use the bit-reversal routines given in section 1.14 on page 33. The reciprocal
of an irreducible polynomial is again irreducible. The order of the polynomial is preserved under the
transformation.
A faster routine that finishes in time log2 (b) (where b = bits per word) is the blue_code() from sec-
tion 1.19 on page 49.
In general the sequence of successive ‘compose’ and ‘reverse’ operations leads to six different polynomials:
C= [11, 10, 4, 3, 0]
[11, 10, 4, 3, 0] -- recip (C=bitpol_recip(C)) -->
846 Chapter 40: Binary polynomials
Figure 40.8-A: All irreducible self-reciprocal binary polynomials of degree 18 (right) and the corre-
sponding irreducible polynomials of degree 9 with constant linear coefficient (left).
A polynomial is called self-reciprocal if it is its own reciprocal. The irreducible self-reciprocal polynomials
(SRPs), except for 1 + x, are of even degree 2 d. They can be computed from the irreducible polynomials
Pd
of degree d with nonzero linear coefficient. Let F (x) = j=0 fj xj and SF (x) the corresponding SRP,
then
d
X
d
SF (x) = x F (x + 1/x) = Fj xd−j (1 + x2 )j (40.8-1)
j=0
The irreducible SRPs of degree 18 and their corresponding polynomials are shown in figure 40.8-A [FXT:
gf2n/bitpol-srp-demo.cc]. The conversion can be implemented as [FXT: bpol/bitpol-srp.h]:
1 inline ulong bitpol_pol2srp(ulong f, ulong d)
2 // Return the self-reciprocal polynomial S=x^d*F(x+1/x) where d=deg(f).
3 // W = sum(j=0, d, F(j)*x^(d-j)*(1+x^2)^j ) where
4 // F(j) is the j-th coefficient of F.
5 // Must have: d==degree(F)
6 {
7 ulong w = 1; // == (x^2+1)^j
8 ulong s = 0;
9 do // for j = 0 ... d:
10 {
11 if ( f & 1 ) s ^= (w << d); // S += F(j)*x^(d-j)*(1+x^2)^j
12 w ^= (w<<2); // w *= (1+x^2)
13 f >>= 1; // next coefficient to low end
14 }
15 while ( d-- );
16 return s;
17 }
40.8: Self-reciprocal polynomials 847
The order of a self-reciprocal polynomial of degree 2n is a divisor of 2n + 1. The list of all irreducible
SRP up to degree 22 is given in [FXT: data/all-irred-srp.txt].
n: Sn n: Sn n: Sn n: Sn
1: 1 11: 93 21: 49929 31: 34636833
2: 1 12: 170 22: 95325 32: 67108864
3: 1 13: 315 23: 182361 33: 130150493
4: 2 14: 585 24: 349520 34: 252645135
5: 3 15: 1091 25: 671088 35: 490853403
6: 5 16: 2048 26: 1290555 36: 954437120
7: 9 17: 3855 27: 2485504 37: 1857283155
8: 16 18: 7280 28: 4793490 38: 3616814565
9: 28 19: 13797 29: 9256395 39: 7048151355
10: 51 20: 26214 30: 17895679 40: 13743895344
Figure 40.8-B: Number of irreducible self-reciprocal polynomials of degree 2n.
848 Chapter 40: Binary polynomials
n: Tn n: Tn n: Tn n: Tn
1: 1 11: 62 21: 32508 31: 23091222
2: 1 12: 160 22: 76032 32: 67004160
3: 1 13: 210 23: 121574 33: 85342752
4: 2 14: 448 24: 344064 34: 200422656
5: 2 15: 660 25: 405000 35: 289531200
6: 4 16: 2048 26: 1005888 36: 892477440
7: 6 17: 2570 27: 1569780 37: 1237491936
8: 16 18: 5184 28: 4511520 38: 2874507264
9: 18 19: 9198 29: 6066336 39: 4697046900
10: 40 20: 24672 30: 12672000 40: 13690417152
Figure 40.8-C: Number of primitive self-reciprocal polynomials of degree 2n.
Values of Sn for n ≤ 40 are shown in figure 40.8-B. The sequence of values Sn is entry A000048 in [312].
The number of irreducible polynomials of degree n with linear coefficient one is also Sn .
The number S̃n of irreducible SRPs of degree n is
−1 X
S̃n = µ(d) 2n/d (40.8-3)
n
d\n, d even
We have S̃n = 0 for n odd and S̃n = Sn/2 for n even. The number Tn of primitive SRPs of degree 2n is
ϕ (2n + 1)
Tn = (40.8-4)
2n
The sequence of values Tn is entry A069925 in [312], values for n ≤ 40 are shown in figure 40.8-C.
Figure 40.9-B: All irreducible trinomials xn + xk + 1 for degrees n ≤ 49. The format of the entries is
n,k for primitive trinomials and -n,k for non-primitive trinomials.
6: 1 5
7: 1 3 4 6
9: 4 5
10: 3 7
11: 2 9
15: 1 4 7 8 11 14
A line starts with the entry for the degree followed by all possible positions of the middle coefficient.
The corresponding files giving primitive trinomials only are [FXT: data/all-trinomial-primpoly.txt] and
[FXT: data/all-trinomial-primpoly-short.txt]. A list of irreducible trinomials that are not primitive is
[FXT: data/all-trinomial-nonprimpoly.txt].
Values of n such that an irreducible trinomial of degree n exists are given in sequence A073571 in [312].
Values such that at least one primitive trinomial exists are given in entry A073726. The values n, k for
primitive polynomials of the form (x + 1)n + (x + 1)k + 1 are listed in [FXT: data/all-t1-primpoly.txt].
850 Chapter 40: Binary polynomials
Polynomials of that form are irreducible whenever xn + xk + 1 is irreducible. The list is not the same as
for primitive trinomials as the transformation p(x) 7→ p(x+1) does in general not preserve the order. The
sequence of degrees n such that there is a primitive polynomial (x + 1)n + (x + 1)k + 1 where 0 < k < n
is entry A136416 in [312].
Regarding trinomials, there is a theorem by Swan (given in [327]): The trinomial xn + xk + 1 over GF(2)
has an even number of irreducible factors (and therefore is reducible) if
1. n is even, k is odd, n 6= 2k, and either nk/2 ≡ 0 mod 4 or nk/2 ≡ 1 mod 4,
2. n is odd, k is even and does not divide 2n, and n ≡ ±3 mod 8,
3. n is even, k is odd and does divide 2n, and n ≡ ±1 mod 8,
4. any of the above holds for k replaced by n − k (that is, for the reciprocal trinomial).
The first condition implies that no irreducible trinomial for n a multiple of 8 exists (as n is even, k
must be odd, else the trinomial is a perfect square; and nk/2 ≡ 0 mod 4). Further, if n is a prime with
n ≡ ±3 mod 8, then the trinomial can be irreducible only if k = 2 (or n − k = 2). In the note [106] it is
shown that no irreducible trinomial exists for n a prime such that n ≡ 13 mod 24 or n ≡ 19 mod 24.
For some applications one may want to use reducible trinomials whose period is close to that of a primitive
one. For example, the trinomial
has the period p = 4, 292, 868, 097 which is very close to 232 − 1 = 4, 294, 967, 295. Note that the degree
is a multiple of 8, so no irreducible trinomial of that degree exists. See [82], [126], and [107].
The trinomials are primitive for the following n ≤ 400: 7, 9, 15, 39, 81.
k=5: p = 1 + x5 + xd is irreducible for the following 6 ≤ d ≤ 1000 (sequence A057474):
40.9: Irreducible and primitive polynomials of special forms ‡ 851
Figure 40.9-C: The first (in lexicographic order) primitive pentanomials for n ≤ 89.
A pentanomial is a polynomial that has exactly five nonzero coefficients. PPs that are pentanomials
are given in [FXT: data/pentanomial-primpoly.txt]. For all degrees n ≥ 5 an irreducible (and primitive)
pentanomial seems to exist, but this has not been proved so far. Pentanomials of the form xn + x3 + x2 +
x + 1 are primitive for n ∈ {5, 7, 17, 25, 31, 41, 151} (and n ≤ 400), and irreducible for
5, 7, 10, 17, 20, 25, 28, 31, 41, 52, 130, 151, 196, 503, 650, 761, 986, 1391, 2047,
6172, 6431, 6730, 8425, 10162, 11410, 12071, 13151, 14636, 17377, 18023, 32770, ...
The data in [FXT: data/minweight-primpoly.txt] lists minimal-weight PPs where in addition the coef-
ficients are as close to the low end as possible. The first entries are shown in figure 40.9-D A list of
minimal-weight PPs that fit into a machine word is given in [FXT: bpol/primpoly-minweight.cc].
By choosing those PPs where the highest nonzero coefficient is as low as possible one obtains the list in
[FXT: data/lowbit-primpoly.txt]. It starts as shown in figure 40.9-E. The corresponding extract for small
degrees is given in [FXT: bpol/primpoly-lowbit.cc]. The index (position) of the second highest nonzero
coefficient (the subdegree of the polynomial) grows slowly with n and is ≤ 12 for all n ≤ 400. So we can
store the list compactly as an array of 16-bit words.
Equivalent tables for degrees DEG= 63, 64, 127, 128, 256, 512, 521, 607, 1000, and 1024, can be found in
the files data/lowbitDEG-primpoly.txt (where DEG has to be replaced by the number).
The PPs listed in [FXT: data/lowblock-primpoly.txt] have the smallest possible block of set bits.
162, 172, 178, 180, 196, 210, 226, 268, 292, 316, 346, 348, 372, 378, 388
For computations modulo all-ones polynomials it is advisable to use the redundant polynomial xn+1 + 1
during the calculations:
1 + x + x2 + x3 + . . . + xn · (1 + x) = 1 + xn+1
(40.9-2)
One does all computations modulo the product (with cheap reductions) and only reduces the final result
modulo the all-ones polynomial.
The all-ones polynomials are a special case for the factorization of cyclotomic polynomials, see sec-
tion 40.11 on page 857. Irreducible polynomials of high weight are considered in [6] where irreducible
polynomials of the form (xn+1 + 1)/(x + 1) + xk up to degree 340 are given.
Similar to the all-ones polynomials, a speedup can be achieved by using the redundant modulus
1 + x + x3 + x5 + . . . + xn · 1 + x2 = 1 + x + x2 + xn+2
(40.9-3)
2,1,0 % 1 14,9,7,5,0 % 1
14,10,8,7,6,4,0 % 1
14,11,10,9,8,7,6,5,4,3,0 % 3
4,3,2,1,0 % 1 14,12,10,7,4,2,0 % 3
14,12,9,8,7,6,5,2,0 % 1
14,13,10,8,7,6,4,1,0 % 1
6,3,0 % 1 14,13,11,7,3,1,0 % 3
14,13,12,11,10,9,7,5,4,3,2,1,0 % 1
14,13,12,9,8,7,6,5,2,1,0 % 1
8,5,4,3,0 % 1
8,7,6,4,2,1,0 % 1 16,15,8,1,0 % 1
16,12,11,8,5,4,0 % 1
16,13,12,10,8,6,4,3,0 % 1
10,7,5,3,0 % 1 16,13,8,3,0 % 1
10,9,5,1,0 % 1 16,14,12,11,8,5,4,2,0 % 1
10,9,8,7,6,5,4,3,2,1,0 % 3 16,14,13,11,10,9,8,7,6,5,3,2,0 % 1
16,14,13,12,10,8,6,4,3,2,0 % 1
16,14,13,12,11,9,8,7,5,4,3,2,0 % 1
12,10,7,6,5,2,0 % 1 16,15,13,11,10,8,6,5,3,1,0 % 1
12,10,9,8,6,4,3,2,0 % 1 16,15,13,12,10,9,8,7,6,4,3,1,0 % 1
12,11,10,9,8,7,6,5,4,3,2,1,0 % 5 16,15,13,9,8,7,3,1,0 % 1
12,11,9,7,6,5,3,1,0 % 1 16,15,14,12,10,8,6,4,2,1,0 % 1
12,8,7,6,5,4,0 % 1 16,15,14,13,11,10,8,6,5,3,2,1,0 % 1
16,15,14,13,12,11,8,5,4,3,2,1,0 % 1
16,15,14,13,9,8,7,3,2,1,0 % 1
16,15,14,8,2,1,0 % 1
Figure 40.9-F: Irreducible self-reciprocal polynomials up to degree 16.
m: deg polynomial fm
0: 1 11 == x + 1
1: 2 111 == x^2 + x + 1
2: 4 11111 == x^4 + x^3 + x^2 + x + 1
3: 8 111.1.111 == x^8 + x^7 + x^6 + x^4 + x^2 + x + 1
4: 16 111111..1..111111
5: 32 111.111.1.1....111....1.1.111.111
6: 64 11111...1.1.11..11..11.1.1...1111111...1.1.11..11..11.1.1...11111
7: 128 111.1.1111...1..11..1...1111.1.11.11.1.1111...1..11..1...1111.1.1 \
.1.1111...1..11..1...1111.1.11.11.1.1111...1..11..1...1111.1.111
........1.......
.........1...... == M4
..........1.....
...........1....
............1...
.............1..
..............1.
...............1
1...........1... ....1...
.1...........1.. .....1.. == M3
..1...........1. ......1.
...1...........1 .......1
....1...1.....1. 1.....1. ..1. == M2
.....1...1.....1 .1.....1 ...1
......1...1.1..1 ..1.1..1 1..1 .1 == M1
.......1...1.111 ...1.111 .111 11
Figure 40.9-G: A family fm of irreducible self-reciprocal binary polynomials (top) and matrices Mm
whose characteristic polynomials are fm (bottom).
40.9: Irreducible and primitive polynomials of special forms ‡ 855
Pn
Given an irreducible polynomial f0 (x) = k=0 ck xk where c1 = 1 and cn−1 = 1 an infinite family of
irreducible polynomials fm (x) of degrees n 2m can be given as follows [113]: for m > 0 set fm (x) =
S (fm−1 (x)) where S (p(x)) = xd p(x + 1/x) and d is the degree of p (relation 40.8-1 on page 846). The
polynomials fm are self-reciprocal for m ≥ 1. A formula for the number of degree-n polynomials suitable
as f0 is given in [260], see sequence A175390 in [312].
Starting with f0 = x + 1 we obtain the polynomials shown in figure 40.9-G. The matrices Mm whose
characteristic polynomials are fm have a simple structure.
The polynomials fm can be computed in a different way [149, p.63]: set a0 = x, b0 = 1, am+1 = am bm ,
2
and bm+1 = a2m + b2m = (am + bm ) , then fm = am + bm .
The normal irreducible polynomials are those whose roots are linearly independent (see section 42.6 on
page 900). A complete list up to degree n = 13 is given in [FXT: data/all-normalpoly.txt], figure 40.9-H
shows the polynomials up to degree n = 9 (polynomials that are not primitive are marked with a ‘-’).
Normal polynomials must have subdegree n − 1, that is, they are of the form xn + xn−1 + . . .. The
condition is necessary but not sufficient: not all irreducible polynomials of subdegree n − 1 are normal. A
list of primitive normal polynomials xn + xn−1 + . . . + xw + 1 with w as big as possible is given in [FXT:
data/highbit-normalpoly.txt]. Primitive normal polynomials xn + xn−1 + xw + . . . + 1 where w is as small
as possible are given in [FXT: data/lowbit-normalprimpoly.txt]. Every irreducible all-ones polynomial is
normal.
The polynomials fm (see figure 40.9-G) are normal for all m, they are primitve only for m = 0 and m = 1.
856 Chapter 40: Binary polynomials
All normal polynomials whose roots form a self-dual basis (see section 42.6.4 on page 908) up to degree
n = 19 are given in [FXT: data/all-irred-self-dual.txt]. The list, up to degree n = 14 is shown in figure
40.9-I. No such polynomials exist for n a multiple of 4.
Then all coefficients of pe (x) are either zero or one and the polynomial is irreducible over GF(2).
b e p b e p
....1 4 m ...1. .11..1 P ....1 4 m ...1. .11..1 P
...1. 4 ..1.. .11..1 P ...11 4 m .1... .11111
...11 4 m .1... .11111 ..1.1 2 m .1.11 .1.1.1 red.
..1.. 4 .1..1 .11..1 P ..111 4 m ..111 .1..11 P
..1.1 2 m .1.11 .1.1.1 red. .1111 1 m ....1 .1...1 red.
..11. 4 .1111 .11111
..111 4 m ..111 .1..11 P
.1... 4 .111. .11..1 P
.1..1 4 ..1.1 .11111
.1.1. 2 .1.1. .1.1.1 red.
.1.11 4 .11.1 .1..11 P
.11.. 4 ...11 .11111
.11.1 4 ..11. .1..11 P
.111. 4 .11.. .1..11 P
.1111 1 m ....1 .1...1 red.
Figure 40.10-A: Polynomials pe (x) for the powers e = xb of the primitive element x modulo c =
x4 + x3 + 1 (left). If only necklaces are used as exponents b, each polynomial is found only once (right).
Irreducible polynomials are obtained for aperiodic necklaces.
30 {
31 ulong t = x ^ s;
32 m = bitpolmod_mult(m, t, c_, h_);
33 s = bitpolmod_square(s, c_, h_);
34 }
35 bp_ = m ^ c_;
36 return bp_;
37 }
38 };
The computation of the polynomials is a variant of the second algorithm in section 42.2 on page 892.
Figure 40.10-A (left) shows all polynomials that are generated with c = x4 + x3 + 1 and the generator
a = x. This is the output of [FXT: gf2n/necklace2irred-demo.cc]. The columns are: b and its cyclic
period (symbol ‘m’ appended if the word is the cyclic minimum), e and p where a ‘P’ indicates that p is
primitive. Observe that cyclic shifts of the same word give identical polynomials p. Further, if the period
is not maximal, then p is reducible. Restricting our attention to the necklaces b we obtain each polynomial
just once (right of figure 40.10-A). The Lyndon words b give all degree-n irreducible polynomials. The
primitive polynomials are exactly those where gcd(b, 2n − 1) = 1.
To generate all irreducible binary polynomials of fixed degree use [FXT: class all irredpoly in
bpol/all-irredpoly.h]. The usage is shown in [FXT: gf2n/all-irredpoly-demo.cc]. It turns out that the gen-
eration via exhaustive search [FXT: gf2n/bitpol-search-irred-demo.cc] is not much slower, figure 40.10-B
gives the rates of generation for various degrees and both methods.
The number of factors of Yd equals ϕ(d)/n so we can count how many degree-n irreducible polynomials
correspond to which divisor of N = 2n − 1:
1: [1:1] 1
2: [3:1] 1
3: [7:2] 2
4: [5:1] [15:2] 3
5: [31:6] 6
6: [9:1] [21:2] [63:6] 9
7: [127:18] 18
8: [17:2] [51:4] [85:8] [255:16] 30
9: [73:8] [511:48] 56
10: [11:1] [33:2] [93:6] [341:30] [1023:60] 99
11: [23:2] [89:8] [2047:176] 186
Line 6 tells us that one irreducible polynomial of degree 6 is due to the factor 9, two are due to the
factor 21, and the 6 primitive polynomials correspond to N = 63 itself, which we have verified a moment
ago. Further, the a polynomials corresponding to an entry [d:a] all have order d. The list was produced
using
1 { for (n=1, 11,
2 print1(n,": ");
3 s = 0;
4 N = 2^n-1;
5 fordiv (N, d,
6 if ( n==znorder(Mod(2,d)) ,
7 a = eulerphi(d)/n;
8 print1(" [",d,":",a,"] ");
9 s += a;
10 );
11 );
12 print(" ",s);
13 ); }
c = x7 + x + 1 (irreducible):
Q= Q-id= nullspace=
1...... ....... 1......
....1.. .1..1..
.1..1.. .11.1..
.....1. ...1.1.
..1..1. ..1.11.
......1 .....11
...1..1 ...1...
The Q-matrix and nullspace of Q − id for the irreducible binary polynomial c = x7 + x + 1 are shown at
the top of figure 40.12-A. The vector n0 = [1, 0, . . . , 0] lies in the nullspace of Q − id for every polynomial.
For c = x7 + x3 + x + 1 = (x + 1) (x2 + x + 1) (x4 + x + 1) the nullspace has rank three (middle of
figure 40.12-A). the rank of the nullspace equals the number of distinct irreducible factors if c is square-
free. For polynomials containing a square factor we do not get the total number of factors, the data for
c = (1 + x)7 = x7 + x6 + x5 + x4 + x3 + x2 + x + 1 is shown at the bottom of figure 40.12-A. The figure
was created with the program [FXT: gf2n/qmatrix-demo.cc].
To find the irreducible factors of c, the vectors spanning the nullspace must be post-processed. The
algorithm can be described as follows: let F be a set of binary polynomials whose product equals c, the
refinement step Ri proceeds as follows:
Let t be the i-th element of the nullspace. For each element f ∈ F do the following: if the degree of f
equals 1, keep it in the set, else remove f from the set and add from the set X = {gcd(f, t), gcd(f, t + 1)}
those elements whose degrees are greater than or equal to 1.
One starts with F = {c} and does the refinement steps R0 , R1 , . . . Rr−1 corresponding to the vectors of
the nullspace. Afterwards the set F will contain exactly the distinct irreducible factors of c. This is done
in the following routine [FXT: bpol/berlekamp.cc]:
1 ulong
2 bitpol_refine_factors(ulong *f, ulong nf, const ulong *nn, ulong r)
3 // Given the nullspace nn[0,...,r-1] of (Q-id)
4 // and nf factors f[0,...,nf-1] whose product equals c
5 // (typically nf=1 and f[0]==c)
6 // then get all r irreducible factors of c.
7 {
8 ulong ss[r];
9 for (ulong j=0; j<r; ++j) // for all elements t in nullspace
10 {
11 ulong t = nn[j];
12
13 // skip trivial elements in nullspace:
14 if ( bitpol_deg(t)==0 ) continue;
15
16 ulong sc = 0;
860 Chapter 40: Binary polynomials
The coefficients at the even powers have to be cleared because derivation multiplies them with an even
factor which equals 0 modulo 2.
If the derivative of a binary polynomial is zero, then it is a perfect square or a constant polynomial:
1 inline ulong bitpol_pure_square_q(ulong c)
2 // Return whether polynomial is a pure square != 1
3 {
4 if ( 1UL==c ) return 0;
5 c &= 0xaaaaaaaaaaaaaaaaUL;
6 return (0==c);
7 }
The following routine returns zero if c is square-free. If c is has a square factor s 6= 1, then s is returned:
1 inline ulong bitpol_test_squarefree(ulong c)
2 {
3 ulong d = bitpol_deriv(c);
4 if ( 0==d ) return (1==c ? 0 : c);
5 ulong g = bitpol_gcd(c, d);
6 return (1==g ? 0 : g);
7 }
If a polynomial is a perfect square, then its square root can be computed as
1 inline ulong bitpol_pure_sqrt(ulong c)
2 {
3 ulong t = 0;
4 for (ulong mc=1,mt=1; mc; mc<<=2,mt<<=1)
5 {
6 if ( mc & c ) t |= mt;
7 }
8 return t;
9 }
A faster way to do the computation is to use the function bit_unzip0() from section 1.15 on page 38.
For the factorization algorithm for general polynomials we have to extract the product of all distinct
irreducible factors (the square-free part) from a polynomial. The following routine returns a polynomial
where the even exponents in the factorization are reduced [FXT: bpol/bitpol-squarefree.cc]:
1 ulong
2 bitpol_sreduce(ulong c)
3 {
4 ulong s = bitpol_test_squarefree(c);
5 if ( 0==s ) return c; // c is square-free
6
7 ulong f = bitpol_div(c, s);
8
9 do // here s is a pure square and s>1
10 {
11 s = bitpol_pure_sqrt(s);
12 }
13 while ( bitpol_pure_square_q(s) );
14
15 ulong g = bitpol_gcd(s, f);
16 s = bitpol_div(s, g);
862 Chapter 40: Binary polynomials
17 f = bitpol_mult(f, s);
18
19 return f;
20 }
t
With c = f · sk 2 (k odd, the factors of f and s not necessarily distinct) the returned polynomial equals
f · sk . Some examples:
a2 7→ a (40.12-1a)
a4 7 → a (40.12-1b)
a3 = a a2 7 → aa (40.12-1c)
a5 = a a4 7 → aa (40.12-1d)
a b2 7 → ab (40.12-1e)
a b b2 7 → a b b = a b2 7→ a b (40.12-1f)
t
f · sk 2 7→ f · sk (40.12-1g)
To extract the square-free part of a polynomial call the routine repeatedly until the returned polynomial
equals the input:
1 inline ulong bitpol_make_squarefree(ulong c)
2 {
3 ulong z = c, t;
4 while ( z!=(t=bitpol_sreduce(z)) ) z = t;
5 return z;
6 }
The reduction routine will be called at most log2 (n) times for a polynomial of degree n: the worst case
k
is a perfect power p = a2 −1 where 2k − 1 ≤ n. Observe that (2k − 1) = 1 + 2 (2k−1 − 1), so the reduction
k−1
routine will split p as p = a s2 7→ a s where s = a2 −1 is of the same form.
31 ulong fj = f[j];
32 ulong g = bitpol_gcd(cs, fj);
33 while ( 1!=g )
34 {
35 ++e[j];
36 cs = bitpol_div(cs, fj);
37 if ( 1==cs ) break;
38 g = bitpol_gcd(cs, fj);
39 }
40 }
41
42 return fct;
43 }
0: x^5 == (x)^5
1: x^5 +1 == (x+1) * (x^4+x^3+x^2+x+1)
2: x^5 +x == (x) * (x+1)^4
3: x^5 +x+1 == (x^2+x+1) * (x^3+x^2+1)
4: x^5 +x^2 == (x)^2 * (x+1) * (x^2+x+1)
5: x^5 +x^2 +1 == (x^5+x^2+1)
6: x^5 +x^2+x == (x) * (x^4+x+1)
7: x^5 +x^2+x+1 == (x+1)^2 * (x^3+x+1)
8: x^5 +x^3 == (x)^3 * (x+1)^2
9: x^5 +x^3 +1 == (x^5+x^3+1)
10: x^5 +x^3 +x == (x) * (x^2+x+1)^2
11: x^5 +x^3 +x+1 == (x+1) * (x^4+x^3+1)
12: x^5 +x^3+x^2 == (x)^2 * (x^3+x+1)
13: x^5 +x^3+x^2 +1 == (x+1)^3 * (x^2+x+1)
14: x^5 +x^3+x^2+x == (x) * (x+1) * (x^3+x^2+1)
15: x^5 +x^3+x^2+x+1 == (x^5+x^3+x^2+x+1)
16: x^5+x^4 == (x)^4 * (x+1)
17: x^5+x^4 +1 == (x^2+x+1) * (x^3+x+1)
18: x^5+x^4 +x == (x) * (x^4+x^3+1)
19: x^5+x^4 +x+1 == (x+1)^5
20: x^5+x^4 +x^2 == (x)^2 * (x^3+x^2+1)
21: x^5+x^4 +x^2 +1 == (x+1) * (x^4+x+1)
22: x^5+x^4 +x^2+x == (x) * (x+1)^2 * (x^2+x+1)
23: x^5+x^4 +x^2+x+1 == (x^5+x^4+x^2+x+1)
24: x^5+x^4+x^3 == (x)^3 * (x^2+x+1)
25: x^5+x^4+x^3 +1 == (x+1)^2 * (x^3+x^2+1)
26: x^5+x^4+x^3 +x == (x) * (x+1) * (x^3+x+1)
27: x^5+x^4+x^3 +x+1 == (x^5+x^4+x^3+x+1)
28: x^5+x^4+x^3+x^2 == (x)^2 * (x+1)^3
29: x^5+x^4+x^3+x^2 +1 == (x^5+x^4+x^3+x^2+1)
30: x^5+x^4+x^3+x^2+x == (x) * (x^4+x^3+x^2+x+1)
31: x^5+x^4+x^3+x^2+x+1 == (x+1) * (x^2+x+1)^2
Figure 40.12-B: Factorizations of the binary polynomials of degree 5.
Figure 40.12-B shows the factorizations of the binary polynomials of degree 5. It was created with the
program [FXT: gf2n/bitpolfactor-demo.cc]. Factoring the first million polynomials of degrees 20, 30, 40
and 60 takes about 5, 10, 15 and 30 seconds, respectively.
A variant of the factorization algorithm often given uses the square-free factorization c = i aii where
Q
the polynomials ai are square-free and pair-wise coprime. Given the square-free factorization one has to
call the core routine for each nontrivial ai .
As noted, the refinement step becomes expensive if the coefficients are in a field GF(q) where q is not
small because q computations of the polynomial gcd are involved. For an algorithm that is efficient also
for large values of q see [110] or [154, ch.14]. A ‘baby step/giant step’ method is given in [308].