Roots of polynomials over finite fields
- Cost
- Over , degree : expected. Over : one root finding modulo plus lifting steps per root, each one evaluation of and . Over : the product of the numbers of roots modulo the prime powers, which can be exponential in the number of prime factors.
A root of in a field is the same as a linear factor , so finding all roots of is the part of the factorisation that concerns factors of degree 1 (Factoring polynomials over finite fields). It is much cheaper than a complete factorisation, because only one distinct-degree step is needed and the splitting does not require the trace map. Over the ring with composite the situation is different: a polynomial can have more roots than its degree, and the roots are found prime by prime.
Roots in a finite field#
By Theorem 1 of Factoring polynomials over finite fields with ,
so for squarefree the product of the linear factors of is . For odd the nonzero elements split further:
Lemma 1. For odd ,
For and , , and , are the products of over the elements of absolute trace 0 and 1 respectively.
Proof. is cyclic of even order , so exactly half of its elements are squares, and these are the roots of (Euler's criterion). The other half are roots of the second factor of . For even , since squaring is additive, so ; is the trace of .
The same splitting applies to the shifted roots , which gives a randomised equal-degree factorisation for , due to Berlekamp [Ber1970] and Rabin [Rab1980b]:
Input: nonzero.
Output: the roots of with multiplicities.
- Compute the squarefree factorisation (Squarefree factorisation). For each :
- If , output the root 0 and remove the factor .
- For odd : ; and . For : ; and .
- Split and into linear factors: while a piece has degree at least 2, choose a random and replace by and its cofactor if this is a proper split (for even , use with random ).
- Output the roots of the linear pieces with multiplicity .
Step 3 discards all factors of of degree at least 2 and already splits the roots into two classes; this initial split is Rabin's. In step 4 a root of goes into the gcd if and only if is a nonzero square, which for a uniformly random happens with probability about , independently enough for distinct roots that a piece of degree is split with probability at least (Lemma 7 of Factoring polynomials over finite fields) and the expected depth of the recursion is . Each level costs exponentiations of total degree , so the expected total cost is , dominated by the exponentiations.
Powers of . An exponentiation is cheaper than for a general , since the multiplications by in the square-and-multiply loop are shifts. FLINT uses this for the random shifts when has more than 16 bits:
Lemma 2. Let have degree and let . Then .
Proof. Write with and substitute : , and .
So costs two Taylor shifts of degree (Taylor shifts) and one exponentiation of .
Distinct nonzero roots. When is known to split into distinct linear factors with , as in the decoding of Reed–Solomon codes and in sparse interpolation, the squarefree factorisation is unnecessary, and step 3 decides at once whether has this form: the degrees of and add up to if and only if it does. nmod_poly_find_distinct_nonzero_roots and fmpz_mod_poly_find_distinct_nonzero_roots implement this test and the splitting (see Finding roots that are expected to be distinct).
Roots modulo prime powers#
Let and . Every root of modulo reduces to a root modulo for every , so the roots modulo can be found by lifting all roots modulo , doubling the precision in each step. Unlike the classical form of Hensel's lemma [Hen1908] (see also Hensel lifting for the lifting of factorisations), this lifts roots that are multiple modulo as well.
Lemma 3. Let and . For ,
Proof. By Taylor's formula with (the coefficients of the expansion are integral). With the last term is divisible by , hence by , so . Dividing by gives the claim.
The linear congruence has no solution if does not divide , and otherwise exactly solutions modulo , an arithmetic progression with step (computed by fmpz_divides_mod_list). Hence a simple root modulo () lifts to exactly one root modulo , while a multiple root can lift to none or to many. The lifts for modulo are distinct modulo , and every root modulo arises from its reduction modulo , so lifting every root at every step enumerates all roots modulo . If , all residues are roots modulo and are lifted in the same way.
The number of roots can be large: the roots of modulo are the multiples of , of which there are .
Composite moduli#
For , the Chinese remainder theorem gives , and the roots of modulo are the CRT combinations of all tuples of roots modulo the . Their number is the product of the numbers of roots modulo the prime powers, which is zero as soon as one factor is zero, and can be far larger than .
In the multiplicity of a root is defined as the largest such that divides ; since is monic, divisibility holds modulo if and only if it holds modulo every , so the multiplicity is the minimum of the multiplicities modulo the prime powers, and each of these is found by repeated exact division by .
Use in FLINT#
gr_poly_roots_finite_field implements Algorithm 1 for every finite field context; step 4 is _gr_poly_factor_equal_deg_with_frob with , which also contains the Taylor shift trick. nmod_poly_roots and fmpz_mod_poly_roots wrap it and return the roots as linear factors in an nmod_poly_factor_t or fmpz_mod_poly_factor_t; the fq_*_poly_roots functions of fq_poly_factor and its variants are analogous, with the field arithmetic of Arithmetic in finite fields.
nmod_poly_roots_factored and fmpz_mod_poly_roots_factored take the factorisation of the modulus and implement the prime-power lifting and the CRT combination. They give up and return 0 when a list of roots would exceed about entries ( on 32-bit systems); fmpz_mod_poly_roots_factored_with_length_limit takes the limit for the CRT combination as a parameter. The generic method gr_poly_roots over nmod and fmpz_mod contexts uses the finite field algorithm when the modulus is prime and otherwise factors the modulus and calls fmpz_mod_poly_roots_factored_with_length_limit with a limit of roots, returning GR_UNABLE if the modulus has more than 20 prime factors (with multiplicity) or there are too many roots.
void nmod_poly_roots(nmod_poly_factor_t r, const nmod_poly_t f, int with_multiplicity)int nmod_poly_roots_factored(nmod_poly_factor_t r, const nmod_poly_t f, int with_multiplicity, const n_factor_t * n)void fmpz_mod_poly_roots(fmpz_mod_poly_factor_t r, const fmpz_mod_poly_t f, int with_multiplicity, const fmpz_mod_ctx_t ctx)int fmpz_mod_poly_roots_factored(fmpz_mod_poly_factor_t r, const fmpz_mod_poly_t f, int with_multiplicity, const fmpz_factor_t n, const fmpz_mod_ctx_t ctx)int fmpz_mod_poly_roots_factored_with_length_limit(fmpz_mod_poly_factor_t x0, const fmpz_mod_poly_t f, int with_mult, slong length_limit, const fmpz_factor_t fac, const fmpz_mod_ctx_t ctx)int nmod_poly_find_distinct_nonzero_roots(ulong * roots, const nmod_poly_t P)int fmpz_mod_poly_find_distinct_nonzero_roots(fmpz * roots, const fmpz_mod_poly_t P, const fmpz_mod_ctx_t ctx)Rational roots of integer polynomials (fmpz_poly_roots_fmpq) are found from the roots modulo a suitable prime by -adic lifting, which is the same lifting as above for simple roots.
Referenced from#
- Embeddings of finite fields (algorithm)
- Factoring polynomials over finite fields (algorithm)
- Polynomial arithmetic over generic rings and its specialisations (overview)
- Getting started with fmpz_mod_poly
fmpz_mod_poly_find_distinct_nonzero_roots- fmpz_mod_poly_factor.h (module)
fmpz_mod_poly_rootsfmpz_mod_poly_roots_factored,fmpz_mod_poly_roots_factored_with_length_limitfq_nmod_poly_rootsfq_poly_rootsfq_zech_poly_rootsgr_poly_roots_finite_fieldgr_poly_roots,gr_poly_roots_other- nmod_poly.h (module)
- Finding roots that are expected to be distinct
- nmod_poly_factor.h (module)
nmod_poly_rootsnmod_poly_roots_factored- Roots modulo a prime and modulo composite numbers
References#
- [Ber1970] E. R. Berlekamp. Factoring polynomials over large finite fields. Mathematics of Computation 24 (1970), 713–735.
- [Rab1980b] M. O. Rabin. Probabilistic algorithms in finite fields. SIAM Journal on Computing 9 (1980), 273–280.
- [Hen1908] K. Hensel. Theorie der algebraischen Zahlen. Teubner, Leipzig, 1908.
The FLINT team, “Roots of polynomials over finite fields,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/polynomials/root-finding.html (generated 2026-11-02).
@misc{flint-doc-algorithms-polynomials-root-finding,
author = {{The FLINT team}},
title = {{Roots of 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/root-finding.html},
note = {Generated 2026-11-02}
}