Factoring polynomials over finite fields
- Cost
- For of degree over : Cantor–Zassenhaus expected; Kaltofen–Shoup with Brent–Kung composition expected, ; Berlekamp expected.
Let be a finite field with elements and let have degree . Every factorisation algorithm used by FLINT reduces the problem to three steps, which go back to Berlekamp [Ber1967] [Ber1970] and to Cantor and Zassenhaus [CanZas1981]:
- Squarefree factorisation writes with squarefree, pairwise coprime and distinct (Squarefree factorisation).
- Distinct-degree factorisation (DDF) splits a squarefree into , where is the product of the irreducible factors of of degree .
- Equal-degree factorisation (EDF) splits each into its irreducible factors, by a randomised algorithm.
The algorithms differ in how they perform steps 2 and 3. The Cantor–Zassenhaus algorithm computes the DDF with one exponentiation by per degree; the Kaltofen–Shoup algorithm [KalSho1998] [Sho1995] uses a baby-step giant-step method in which the exponentiations are replaced by modular compositions; Berlekamp's algorithm skips the DDF and splits with the kernel of a linear map. Textbook accounts are [GG2003, Ch. 14] and [Sho2009, Ch. 20].
All of them are implemented once, generically, in gr_poly (gr_poly_factor_finite_field and the functions it calls), for any gr context that is a finite field: nmod, fmpz_mod, fq, fq_nmod and fq_zech. The modules nmod_poly_factor, fmpz_mod_poly_factor and the fq_*_poly_factor modules are wrappers. Throughout, denotes the cost of multiplying polynomials of degree over , counted in field operations, and the cost of one modular composition for of degree less than (Modular composition).
Finite fields and the Frobenius map#
Theorem 1. For every ,
in .
Proof. The polynomial is squarefree, since its derivative is . Its roots in an algebraic closure are the elements of . A monic irreducible of degree divides it if and only if a root of lies in , that is, if and only if is a subfield of , which happens exactly when [LN1997, Ch. 2].
Corollary 2. If is squarefree, is the product of the irreducible factors of whose degree divides . In particular, of degree is irreducible if and only if for .
The gcd is computed with , never with the huge polynomial itself. The powers are linked by the Frobenius endomorphism of :
Lemma 3. For , . Consequently, if , then and, more generally, .
Proof. The map is a ring endomorphism in characteristic () and fixes the coefficients, since for . Hence . Applying this times gives , and reducing modulo gives . With this is (the two orders are equal by symmetry).
So there are two ways to step from to : an exponentiation , which costs about multiplications modulo , and a composition , which costs independently of . With the Brent–Kung algorithm and the matrix of powers of precomputed, a composition costs about multiplications modulo plus a product of an and an matrix, so composition wins when is large compared to . (The Frobenius map on elements of itself is discussed in Frobenius map, norm, trace and roots.) The generic code uses composition when has more than bits.
Squarefree factorisation and deflation#
Squarefree factorisation needs only gcds, divisions, derivatives and, in characteristic , -th roots of coefficients; it costs operations per gcd and is described in Squarefree factorisation. It reduces the problem to monic squarefree polynomials, and all steps below assume this.
Before the squarefree factorisation, _gr_poly_factor_finite_field deflates the input: if for some (all exponents of nonzero terms are multiples of ), it factors , and then factors for each factor of (without deflating again). Each factor of divides exactly one , so this splits the problem into independent problems of smaller size; polynomials like or benefit most.
Distinct-degree factorisation#
The classical algorithm#
Input: monic squarefree of degree .
Output: the pairs with .
- , , .
While :
- ; .
- ; if , output , set and .
- If , output .
By induction on , when is computed has no factors of degree less than , so by Corollary 2 is the product of the factors of degree exactly . When , the remaining has no factor of degree at most and therefore cannot be a product of two or more factors; it is irreducible. The loop runs at most times, and each iteration costs an exponentiation, , and a gcd, for a total of .
Baby steps and giant steps#
Shoup [Sho1995] and Kaltofen and Shoup [KalSho1998] remove the factor by grouping the degrees into intervals. Choose and , so that the intervals , , cover all degrees up to .
Lemma 4. Let and . An irreducible factor of of degree divides if and only if .
Proof. Modulo , , since the -th power map is additive. Since is irreducible, it divides a -th power if and only if it divides the base, and by Theorem 1 that happens if and only if .
Input: monic squarefree of degree , and .
Output: the pairs with .
- Baby steps: for .
Coarse DDF: . For :
- if , else (a modular composition with the precomputed matrix of powers of ).
- , omitting the terms for degrees .
- (or if ); .
- Stop if .
- If , output .
- Fine DDF: for each with : if or , then for : ; if , output and set . Otherwise output .
Theorem 5. Algorithm 2 is correct. With Brent–Kung modular composition it uses modular compositions (or exponentiations, see below), at most multiplications modulo , and gcds, in total
operations, plus for .
Proof. By Lemma 4, the factors of that divide are those whose degree divides some integer in . By induction on , when is computed every factor of has degree greater than (smaller degrees divide itself, which lies in an earlier interval), so is the product of the factors with degree in . Omitting the terms for degrees above loses nothing, because if had a factor of such a degree and were reducible, it would also have a factor of degree , already removed. The stopping rule and step 3 are justified as in the classical algorithm. Reducing and the matrix of powers of modulo the new after a split is valid since divides the old modulus.
In the fine phase, for the factors of have degrees in , an interval in which no degree divides another (since ); so is exactly the product of the factors of degree . If , has a single factor, since two factors would have total degree greater than . For the degrees are processed in increasing order and the factors found are removed, so the gcd for degree only contains factors of degree exactly , as in the classical algorithm.
The cost bound counts the compositions of steps 1 and 2.1, the multiplications per interval of step 2.2, and one gcd per interval and per degree in the fine phase, in total, which is dominated by the compositions.
The baby steps are computed in _gr_poly_iterated_frobenius_preinv, by repeated exponentiation by if is small (see Finite fields and the Frobenius map) and otherwise by modular composition using a doubling scheme: given , the vector composition , , is a single matrix product with the powers of (gr_poly_preinv_compose_mod_brent_kung_vec). The giant steps always use composition with the precomputed matrix of powers of .
With the bound of Theorem 5 is and no longer depends on except through ; this is what makes the algorithm fast for large . Kaltofen and Shoup also show how to make the interval products subquadratic, which together with fast matrix multiplication gives a factorisation algorithm with operations [KalSho1998]; the asymptotically fastest known method, based on the modular composition algorithm of Kedlaya and Umans, uses bit operations per field operation [KU2011]. FLINT uses neither of these refinements.
Equal-degree factorisation#
Let now be monic, squarefree, of degree , the product of irreducible factors of degree . By the Chinese remainder theorem
The Berlekamp subalgebra consists of the elements whose components all lie in , so . Every whose components are not all equal gives a proper factor for some ; the algorithms below produce such at random and then find a , or a polynomial in playing the same role.
Lemma 6 (Trace map). The map is an -linear surjection . If is uniformly random, then is uniformly random in .
Proof. Componentwise, is the trace of over , which is -linear and surjective [LN1997, §2.3]. A surjective linear map sends the uniform distribution to the uniform distribution, since all fibres are cosets of the kernel.
Lemma 7 (Splitting probability). Let be odd and let be uniformly random. Then is a proper factor of with probability at least . For and the absolute trace , is a proper factor with probability .
Proof. For odd , a component of satisfies if and only if is a nonzero square, which happens with probability , independently for the components. The gcd is the product of the for which this holds, so it is trivial with probability , and for . For even , is the trace of over on each component, so the components of are independent and uniform in , and the gcd is trivial only if they are all 0 or all 1.
Input: as above, .
Output: the irreducible factors of .
- If , return .
- Choose at random and compute ; repeat if is constant.
- for odd , for even ; .
- If is a proper factor, recurse on and (with reduced modulo each); otherwise go to step 2.
By Lemma 7, each attempt succeeds with probability at least , and because each factor goes to either side independently, the expected depth of the recursion is . The cost of an attempt is that of the trace, an exponentiation, , and a gcd. FLINT computes the trace in one of three ways (_gr_poly_trace):
- for small (the same test as in Finite fields and the Frobenius map), as with exponentiations by ;
- for , with compositions using the precomputed matrix of powers of ;
- otherwise by the doubling method of von zur Gathen and Shoup [GatSho1992]: with , the identities , and compute along the binary expansion of with compositions.
Roots (). Every element of is then in , so no trace is needed, and with random suffices (for even , with random ): the components of are the values at the roots of , so collects the roots for which is a nonzero square. For of more than 16 bits, the power is computed as where , because powers of modulo a polynomial are cheaper (the multiplications by in the exponentiation are shifts); this costs two Taylor shifts. See Roots of polynomials over finite fields.
Splitting by the minimal polynomial. When is large and the number of factors is moderate, it is cheaper to split into all its factors at once [Mar2014]. If has components , its minimal polynomial over is , where is the set of distinct values , and
FLINT computes the sequence , , for a random linear form , obtains its minimal polynomial with the Berlekamp–Massey algorithm [Mas1969] (which equals unless is degenerate, in which case the attempt is repeated), finds the roots of by the case above, and splits by divide and conquer: with for the first half of the roots, is the product of the with , and is a modular composition. This uses multiplications modulo and no exponentiation by for the splitting element. A random has distinct components with probability at least , in which case the factorisation is complete after one round. The generic code uses this method when , and , where denotes the bit length.
Berlekamp's algorithm#
Berlekamp's algorithm [Ber1967] [Ber1970] does not need the DDF. Let be monic squarefree of degree with irreducible factors (of arbitrary degrees). The map on is -linear, and its matrix in the basis has as column the coefficients of minus the unit vector .
Theorem 8. has dimension . In particular is irreducible if and only if the nullity of is 1.
Proof. By the Chinese remainder theorem , and holds in exactly for . So .
gr_poly_factor_berlekamp computes , the columns by repeated multiplication, and a basis of the kernel with gr_mat_nullspace. If the nullity is 1, is irreducible. Otherwise it takes random linear combinations of the basis vectors (uniform in ), tries and then (or for even ), and recurses on the two parts of the first proper split, recomputing the matrix for each part. The kernel costs , the matrix , and each split attempt ; since random splits are balanced on average, the expected total is . The cubic linear algebra makes the algorithm uncompetitive for large in FLINT, where it serves mainly as an independent check.
The complete algorithms and FLINT's choice#
All three algorithms begin with gr_poly_factor_squarefree and treat each squarefree factor separately.
gr_poly_factor_cantor_zassenhausruns Algorithm 1 on each squarefree factor, computing by binary exponentiation, and calls the equal-degree factorisation (_gr_poly_factor_equal_deg_with_frob) on each with , passing obtained from the first exponentiation.gr_poly_factor_kaltofen_shoupcomputes once, runs Algorithm 2 (_gr_poly_factor_distinct_deg_with_frob), and calls the equal-degree factorisation on each piece with reduced modulo the piece.gr_poly_factor_berlekampis described above.
gr_poly_factor_finite_field (after deflation) uses Cantor–Zassenhaus for degree
and Kaltofen–Shoup otherwise. The rule fits measured crossovers for dense random polynomials over nmod: about for , 70 for , 32 for , 16 for , 8 for and 4 for . For small the exponentiation by is a few squarings and the classical DDF has the smaller constant; for large the factor dominates and the modular compositions win.
Parallelism. When threads are available (flint_set_num_threads) and the context is thread-safe, polynomials of degree above 200 (GR_POLY_FACTOR_THREADED_CUTOFF) use _gr_poly_factor_distinct_deg_with_frob_threaded: the giant steps are computed in blocks of (the number of threads) independent compositions with a precomputed matrix for , the interval polynomials of a block in parallel, and the fine DDF in parallel over the intervals; is only reduced after each block, which costs a little extra work when there are factors of small degree. The equal-degree factorisation processes the pieces on the top of its work stack in parallel, each with its own random state. Matrix products use the threads of gr_mat_mul.
Randomness. Each top-level function initialises its own flint_rand_t with the default seed, so results, including the order of the factors, are reproducible from run to run (but not across FLINT versions). The factors are returned in no particular order.
Use in FLINT#
The generic implementations are gr_poly_factor_finite_field (with _gr_poly_factor_finite_field for a fixed algorithm), gr_poly_factor_cantor_zassenhaus, gr_poly_factor_kaltofen_shoup, gr_poly_factor_berlekamp, gr_poly_factor_squarefree, gr_poly_factor_distinct_deg, gr_poly_factor_equal_deg and gr_poly_factor_equal_deg_prob, with the helpers gr_poly_iterated_frobenius_preinv, _gr_poly_factor_distinct_deg_with_frob and _gr_poly_factor_equal_deg_with_frob. The gr method GR_METHOD_POLY_FACTOR of the finite field contexts points to gr_poly_factor_finite_field. The type-specific modules wrap these functions without copying the polynomials:
ulong nmod_poly_factor(nmod_poly_factor_t result, const nmod_poly_t input)ulong nmod_poly_factor_with_cantor_zassenhaus(nmod_poly_factor_t result, const nmod_poly_t input)ulong nmod_poly_factor_with_berlekamp(nmod_poly_factor_t result, const nmod_poly_t input)ulong nmod_poly_factor_with_kaltofen_shoup(nmod_poly_factor_t result, const nmod_poly_t input)void nmod_poly_factor_squarefree(nmod_poly_factor_t res, const nmod_poly_t f)void nmod_poly_factor_distinct_deg(nmod_poly_factor_t res, const nmod_poly_t poly, slong * const * degs)void nmod_poly_factor_equal_deg(nmod_poly_factor_t factors, const nmod_poly_t pol, slong d)void fmpz_mod_poly_factor(fmpz_mod_poly_factor_t res, const fmpz_mod_poly_t f, const fmpz_mod_ctx_t ctx)void fmpz_mod_poly_factor_cantor_zassenhaus(fmpz_mod_poly_factor_t res, const fmpz_mod_poly_t f, const fmpz_mod_ctx_t ctx)void fmpz_mod_poly_factor_berlekamp(fmpz_mod_poly_factor_t factors, const fmpz_mod_poly_t f, const fmpz_mod_ctx_t ctx)void fmpz_mod_poly_factor_kaltofen_shoup(fmpz_mod_poly_factor_t res, const fmpz_mod_poly_t poly, const fmpz_mod_ctx_t ctx)void fmpz_mod_poly_factor_distinct_deg(fmpz_mod_poly_factor_t res, const fmpz_mod_poly_t poly, slong * const * degs, const fmpz_mod_ctx_t ctx)void fmpz_mod_poly_factor_equal_deg(fmpz_mod_poly_factor_t factors, const fmpz_mod_poly_t pol, slong d, const fmpz_mod_ctx_t ctx)The fq_poly_factor, fq_nmod_poly_factor and fq_zech_poly_factor modules are generated from the same template and wrap the same functions; the arithmetic of the finite fields themselves is described in Arithmetic in finite fields. The modular factorisations used by the Zassenhaus algorithm over (Factoring polynomials over the integers) and by the multivariate factorisation code (Factoring over finite fields) call nmod_poly_factor and fmpz_mod_poly_factor. Irreducibility tests are described in Irreducibility testing over finite fields, and root finding, which is the case with a cheaper first split, on Roots of polynomials over finite fields.
Referenced from#
- Finite fields (overview)
- Factoring polynomials over the integers (algorithm)
- Irreducibility testing over finite fields (algorithm)
- Polynomial arithmetic over generic rings and its specialisations (overview)
- Roots of polynomials over finite fields (algorithm)
- Squarefree factorisation (algorithm)
fmpz_mod_poly_frobenius_power- fmpz_mod_poly_factor.h (module)
fmpz_mod_poly_factorfmpz_mod_poly_factor_distinct_deg,fmpz_mod_poly_factor_distinct_deg_threadedfmpz_mod_poly_factor_equal_deg- fq_default_poly_factor.h (module)
- fq_nmod_poly_factor.h (module)
- fq_poly_factor.h (module)
fq_poly_is_irreducible,fq_poly_is_irreducible_ddf,fq_poly_is_irreducible_ben_or- fq_zech_poly_factor.h (module)
- gr_poly.h (module)
- Factoring polynomials over a prime field
- nmod_poly_factor.h (module)
nmod_poly_factor_distinct_deg,nmod_poly_factor_distinct_deg_threadednmod_poly_factor_equal_deg
References#
- [Ber1967] E. R. Berlekamp. Factoring polynomials over finite fields. Bell System Technical Journal 46 (1967), 1853–1859.
- [Ber1970] E. R. Berlekamp. Factoring polynomials over large finite fields. Mathematics of Computation 24 (1970), 713–735.
- [CanZas1981] D. G. Cantor and H. Zassenhaus. A new algorithm for factoring polynomials over finite fields. Mathematics of Computation 36 (1981), 587–592. https://doi.org/10.1090/S0025-5718-1981-0606517-5
- [KalSho1998] E. Kaltofen and V. Shoup, "Subquadratic-time factoring of polynomials over finite fields", Mathematics of Computation 67 (1998), 1179-1197. https://doi.org/10.1090/S0025-5718-98-00944-2
- [Sho1995] V. Shoup, "A new polynomial factorization algorithm and its implementation", Journal of Symbolic Computation 20:4 (1995), 363–397
- [GG2003] J. von zur Gathen and J. Gerhard, Modern Computer Algebra, second edition, Cambridge University Press (2003)
- [Sho2009] V. Shoup. A Computational Introduction to Number Theory and Algebra. Second edition, Cambridge University Press, 2009. https://shoup.net/ntb/
- [LN1997] R. Lidl and H. Niederreiter. Finite Fields. Second edition, Encyclopedia of Mathematics and its Applications 20, Cambridge University Press, 1997.
- [KU2011] K. S. Kedlaya and C. Umans, "Fast polynomial factorization and modular composition", SIAM Journal on Computing 40:6 (2011), 1767–1802
- [GatSho1992] J. von zur Gathen and V. Shoup, "Computing Frobenius maps and factoring polynomials", Computational Complexity 2 (1992), 187-224. https://doi.org/10.1007/BF01272074
- [Mar2014] D. Marquis. Deterministic factorization of polynomials over finite fields. Master's thesis, Carleton University, 2014.
- [Mas1969] J. L. Massey. Shift-register synthesis and BCH decoding. IEEE Transactions on Information Theory 15 (1969), 122–127.
The FLINT team, “Factoring polynomials over finite fields,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/polynomials/factoring-finite-fields.html (generated 2026-11-02).
@misc{flint-doc-algorithms-polynomials-factoring-finite-fields,
author = {{The FLINT team}},
title = {{Factoring polynomials over finite fields}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/algorithms/polynomials/factoring-finite-fields.html},
note = {Generated 2026-11-02}
}