FLINT3.7.0-dev
Algorithm

Discrete logarithm tables

Cost
After a precomputation of O(kn)O(\sqrt{kn}), each of kk logarithms in a group of prime order nn costs O(n/k)O(\sqrt{n/k}) multiplications; for composite order the cost is the sum over the prime factors.

The dlog module computes discrete logarithms in a cyclic group ⟨a⟩⊆(Z/mZ)×\langle a \rangle \subseteq (\mathbb{Z}/m\mathbb{Z})^\times of order nn, for word-size mm. Its use case, Dirichlet characters (Dirichlet characters), asks for many logarithms to the same base, typically with mm a prime power and aa a primitive root. The module therefore separates a precomputation, sized for an expected number kk of queries, from the queries themselves. For the general theory see [CraPom2005, §5.2–5.3]; the single-logarithm algorithm of nmod is described in Discrete logarithms modulo a prime (Pohlig–Hellman).

Baby-step giant-step with a balanced table#

Shanks' method [Sha1971] stores the baby steps (j,aj)(j, a^j) for 0≤j<M0 \le j < M, sorted by value, and for a query bb computes the giant steps ba−iMb a^{-iM}, i=0,1,…i = 0, 1, \ldots, until one of them is found in the table as aja^j; then log⁡ab=iM+j\log_a b = iM + j.

Proposition 1. A query needs at most ⌊n/M⌋+1\lfloor n/M \rfloor + 1 giant steps, each one multiplication and one binary search. For kk queries the total cost, MM to build the table plus kn/Mk n / M for the queries, is minimised by M≈knM \approx \sqrt{kn}, giving O(kn)O(\sqrt{kn}) multiplications in total, or O(n/k)O(\sqrt{n/k}) per query after the precomputation.

Proof. Write x=log⁡ab=iM+jx = \log_a b = iM + j with 0≤j<M0 \le j < M; then i≤(n−1)/Mi \le (n-1)/M and ba−iM=ajb a^{-iM} = a^j is in the table. The optimum of M+kn/MM + kn/M is at M=knM = \sqrt{kn}.

dlog_bsgs_size(n, k) returns (1+⌊n⌋)(1+⌊k⌋)(1 + \lfloor\sqrt n\rfloor)(1 + \lfloor\sqrt k\rfloor) when 2k<n2k < n, and nn (a complete table, so that every query is one search) otherwise. For groups of order at most 3 no table is needed, and for moduli below 50 a table indexed by the residue replaces the sorted array.

Pohlig–Hellman decomposition#

If n=∏ipiein = \prod_i p_i^{e_i}, the logarithm modulo pieip_i^{e_i} of bb is the logarithm of bn/pieib^{n/p_i^{e_i}} to the base an/pieia^{n/p_i^{e_i}}, of order pieip_i^{e_i}, and the Chinese remainder theorem combines them [PohHel1978]. Within a group of order pep^e, write x=∑t<extptx = \sum_{t < e} x_t p^t; then

(b a−(x0+⋯+xt−1pt−1))pe−1−t=(ape−1)xt,\bigl(b\, a^{-(x_0 + \cdots + x_{t-1} p^{t-1})}\bigr)^{p^{e-1-t}} = \bigl(a^{p^{e-1}}\bigr)^{x_t},

so each digit xtx_t is a logarithm in the subgroup of order pp, generated by ape−1a^{p^{e-1}}. A logarithm in a group of order nn thus costs O(∑iei(log⁡n+c(pi)))O(\sum_i e_i (\log n + c(p_i))) multiplications, where c(p)c(p) is the cost of a logarithm in a group of order pp; the structure is the same as for nmod_discrete_log_pohlig_hellman. In FLINT, dlog_crt_t holds one precomputation per prime power, and dlog_power_t one precomputation of the subgroup of order pp, built for eke k queries.

Prime power moduli and pp-adic logarithms#

For m=pem = p^e with pp odd and aa a primitive root modulo p2p^2, the group (Z/peZ)×(\mathbb{Z}/p^e\mathbb{Z})^\times has order (p−1)pe−1(p-1)p^{e-1}, and its pp-Sylow part is the subgroup U1={x≡1(modp)}U_1 = \{x \equiv 1 \pmod p\}, cyclic of order pe−1p^{e-1} and generated by 1+p1 + p. Logarithms there are cheap:

Lemma 2. For odd pp and f≥1f \ge 1, (1+p)pf−1≡1+pf(modpf+1)(1 + p)^{p^{f-1}} \equiv 1 + p^f \pmod {p^{f+1}}. Consequently, if b≡1+c pf(modpf+1)b \equiv 1 + c\, p^f \pmod{p^{f+1}} with 0≤c<p0 \le c < p, then b(1+p)−cpf−1≡1(modpf+1)b (1 + p)^{-c p^{f-1}} \equiv 1 \pmod{p^{f+1}}.

Proof. By induction on ff with the binomial theorem: if x=1+pf+ypf+1x = 1 + p^f + y p^{f+1}, then xp≡1+pf+1(modpf+2)x^p \equiv 1 + p^{f+1} \pmod{p^{f+2}}, the other terms being divisible by p2f+1p^{2f+1} or, for the term (p2)p2f\binom{p}{2} p^{2f}, by p2f+1p^{2f+1} since pp is odd.

So log⁡1+pb\log_{1+p} b is found one base-pp digit at a time (dlog_1modpe_1modp), with e−1e - 1 modular powers. The logarithm to the base aa is then obtained from two smaller problems.

Proposition 3. Let L=log⁡abL = \log_a b modulo (p−1)pe−1(p-1)p^{e-1}, x=log⁡a mod p(b mod p)x = \log_{a \bmod p}(b \bmod p) modulo p−1p - 1, and y=log⁡ap−1(bp−1)y = \log_{a^{p-1}} (b^{p-1}) modulo pe−1p^{e-1}. Then L≡x(modp−1)L \equiv x \pmod {p-1}, L≡y(modpe−1)L \equiv y \pmod {p^{e-1}}, and

L=y+pe−1((x−y) mod (p−1)).L = y + p^{e-1} \bigl((x - y) \bmod (p - 1)\bigr).

Proof. The first congruence is reduction modulo pp, the second follows from bp−1=(ap−1)Lb^{p-1} = (a^{p-1})^L with ap−1a^{p-1} of order pe−1p^{e-1}. Since pe−1≡1(modp−1)p^{e-1} \equiv 1 \pmod{p-1}, the right-hand side is congruent to xx modulo p−1p - 1 and to yy modulo pe−1p^{e-1}, and it lies in [0,(p−1)pe−1)[0, (p-1)p^{e-1}).

The logarithm yy is log⁡1+p(bp−1)\log_{1+p}(b^{p-1}) divided by log⁡1+p(ap−1)\log_{1+p}(a^{p-1}) modulo pe−1p^{e-1}, which is precomputed (dlog_1modpe_init). For m=2em = 2^e the subgroup of elements ≡1(mod4)\equiv 1 \pmod 4 is generated by 5, and log⁡5\log_5 is found one bit at a time in the same way (dlog_mod2e_1mod4). The cost of a logarithm modulo pep^e is therefore a logarithm modulo pp, in a group of order p−1p - 1, plus O(e)O(e) modular powers.

Choosing the method#

dlog_precomp_modpe_init, dlog_precomp_n_init, dlog_precomp_pe_init and dlog_precomp_p_init choose the method from what is known about the group, recursively:

SituationMethod
modulus pe<50p^e < 50complete table
modulus pep^e, e≥2e \ge 2logarithm modulo pp and pp-adic logarithm
order n≤3n \le 3direct comparison
order nn an odd prime <50< 50, or other n<50n < 50complete table (residue-indexed if the modulus is <50< 50, else sorted)
order nn an odd prime ≥50\ge 50baby-step giant-step with dlog_bsgs_size(n, k) baby steps
order nn composite, 50≤n<50050 \le n < 500baby-step giant-step
order n≥500n \ge 500 compositePohlig–Hellman over the prime powers
order pep^e, e≥2e \ge 2, pe≥50p^e \ge 50digits in the subgroup of order pp

Each method returns an estimate of the cost of one logarithm in multiplications (cost), which the sieve below uses to decide whether to look for relations.

Pollard's rho method [Pol1978], which needs O(n)O(\sqrt n) time and no memory, is available as dlog_rho but is not used by these precomputations.

The logarithms of all small integers#

To evaluate a Dirichlet character at 0,1,…,N−10, 1, \ldots, N - 1, one needs log⁡ak\log_a k for all k<Nk < N. Two methods are used.

Enumeration (dlog_vec_loop). Running through a0,a1,…,an−1a^0, a^1, \ldots, a^{n-1} and recording the exponent of every power below NN costs nn multiplications. It is the method of choice when NN is comparable with nn (FLINT uses it when 6n<N6n < N).

Sieving (dlog_vec_sieve). Logarithms are additive, log⁡a(jk)=log⁡aj+log⁡ak\log_a(jk) = \log_a j + \log_a k, so it suffices to compute log⁡ap\log_a p for the primes p<Np < N and to fill in the other entries in increasing order, v[pk]=v[k]+v[p]v[pk] = v[k] + v[p]. A prime pp costs one precomputed logarithm. For larger primes, a relation with smaller numbers may be cheaper: with c=aXc = a^X for a fixed XX, compute for i=1,2,…i = 1, 2, \ldots a partial extended Euclidean algorithm on (m,pci mod m)(m, p c^i \bmod m), stopped when the remainder rr and the cofactor uu are both about m\sqrt m, so that

u⋅p ci≡±r(modm).u \cdot p\, c^i \equiv \pm r \pmod m.

If rr and uu factor into primes below pp, whose logarithms are already known, then log⁡ap=log⁡ar−log⁡au−iX±log⁡a(−1)\log_a p = \log_a r - \log_a u - iX \pm \log_a(-1). The probability that two numbers of size m\sqrt m are pp-smooth is about ρ(s)2\rho(s)^2 with s=log⁡m/log⁡ps = \log \sqrt m / \log p, which FLINT estimates crudely by s−ss^{-s} with s=log⁡m/log⁡ps = \log m/\log p; it searches for relations only when this predicts fewer multiplications than a precomputed logarithm. This is a small instance of the index calculus method [CraPom2005, §6.4], without the linear algebra.

Use in FLINT#

Referenced from#

References#

  • [CraPom2005] R. Crandall and C. Pomerance, Prime Numbers: A Computational Perspective, second edition, Springer (2005).
  • [Sha1971] D. Shanks, "Class number, a theory of factorization, and genera", Proc. Symp. Pure Math. 20, American Mathematical Society (1971), 415–440
  • [PohHel1978] S. C. Pohlig and M. E. Hellman, "An improved algorithm for computing logarithms over GF(p) and its cryptographic significance", IEEE Transactions on Information Theory 24 (1978), 106–110, https://doi.org/10.1109/TIT.1978.1055817
  • [Pol1978] J. M. Pollard, "Monte Carlo methods for index computation (mod p)", Mathematics of Computation 32 (1978), 918–924. https://doi.org/10.1090/S0025-5718-1978-0491431-9
Cite this page

The FLINT team, “Discrete logarithm tables,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/number-theory/discrete-log-tables.html (generated 2026-11-02).