Discrete logarithm tables
- Cost
- After a precomputation of O(\sqrt{kn}), each of k logarithms in a group of prime order n costs 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 \langle a \rangle \subseteq (\mathbb{Z}/m\mathbb{Z})^\times of order n, for word-size m. Its use case, Dirichlet characters (Dirichlet characters), asks for many logarithms to the same base, typically with m a prime power and a a primitive root. The module therefore separates a precomputation, sized for an expected number k 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, a^j) for 0 \le j < M, sorted by value, and for a query b computes the giant steps b a^{-iM}, i = 0, 1, \ldots, until one of them is found in the table as a^j; then \log_a b = iM + j.
Proposition 1. A query needs at most \lfloor n/M \rfloor + 1 giant steps, each one multiplication and one binary search. For k queries the total cost, M to build the table plus k n / M for the queries, is minimised by M \approx \sqrt{kn}, giving O(\sqrt{kn}) multiplications in total, or O(\sqrt{n/k}) per query after the precomputation.
Proof. Write x = \log_a b = iM + j with 0 \le j < M; then i \le (n-1)/M and b a^{-iM} = a^j is in the table. The optimum of M + kn/M is at M = \sqrt{kn}.
dlog_bsgs_size(n, k) returns (1 + \lfloor\sqrt n\rfloor)(1 + \lfloor\sqrt k\rfloor) when 2k < n, and n (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 = \prod_i p_i^{e_i}, the logarithm modulo p_i^{e_i} of b is the logarithm of b^{n/p_i^{e_i}} to the base a^{n/p_i^{e_i}}, of order p_i^{e_i}, and the Chinese remainder theorem combines them [PohHel1978]. Within a group of order p^e, write x = \sum_{t < e} x_t p^t; then
so each digit x_t is a logarithm in the subgroup of order p, generated by a^{p^{e-1}}. A logarithm in a group of order n thus costs O(\sum_i e_i (\log n + c(p_i))) multiplications, where c(p) is the cost of a logarithm in a group of order p; 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 p, built for e k queries.
Prime power moduli and p-adic logarithms#
For m = p^e with p odd and a a primitive root modulo p^2, the group (\mathbb{Z}/p^e\mathbb{Z})^\times has order (p-1)p^{e-1}, and its p-Sylow part is the subgroup U_1 = \{x \equiv 1 \pmod p\}, cyclic of order p^{e-1} and generated by 1 + p. Logarithms there are cheap:
Lemma 2. For odd p and f \ge 1, (1 + p)^{p^{f-1}} \equiv 1 + p^f \pmod {p^{f+1}}. Consequently, if b \equiv 1 + c\, p^f \pmod{p^{f+1}} with 0 \le c < p, then b (1 + p)^{-c p^{f-1}} \equiv 1 \pmod{p^{f+1}}.
Proof. By induction on f with the binomial theorem: if x = 1 + p^f + y p^{f+1}, then x^p \equiv 1 + p^{f+1} \pmod{p^{f+2}}, the other terms being divisible by p^{2f+1} or, for the term \binom{p}{2} p^{2f}, by p^{2f+1} since p is odd.
So \log_{1+p} b is found one base-p digit at a time (dlog_1modpe_1modp), with e - 1 modular powers. The logarithm to the base a is then obtained from two smaller problems.
Proposition 3. Let L = \log_a b modulo (p-1)p^{e-1}, x = \log_{a \bmod p}(b \bmod p) modulo p - 1, and y = \log_{a^{p-1}} (b^{p-1}) modulo p^{e-1}. Then L \equiv x \pmod {p-1}, L \equiv y \pmod {p^{e-1}}, and
Proof. The first congruence is reduction modulo p, the second follows from b^{p-1} = (a^{p-1})^L with a^{p-1} of order p^{e-1}. Since p^{e-1} \equiv 1 \pmod{p-1}, the right-hand side is congruent to x modulo p - 1 and to y modulo p^{e-1}, and it lies in [0, (p-1)p^{e-1}).
The logarithm y is \log_{1+p}(b^{p-1}) divided by \log_{1+p}(a^{p-1}) modulo p^{e-1}, which is precomputed (dlog_1modpe_init). For m = 2^e the subgroup of elements \equiv 1 \pmod 4 is generated by 5, and \log_5 is found one bit at a time in the same way (dlog_mod2e_1mod4). The cost of a logarithm modulo p^e is therefore a logarithm modulo p, in a group of order p - 1, plus 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:
| Situation | Method |
|---|---|
| modulus p^e < 50 | complete table |
| modulus p^e, e \ge 2 | logarithm modulo p and p-adic logarithm |
| order n \le 3 | direct comparison |
| order n an odd prime < 50, or other n < 50 | complete table (residue-indexed if the modulus is < 50, else sorted) |
| order n an odd prime \ge 50 | baby-step giant-step with dlog_bsgs_size(n, k) baby steps |
| order n composite, 50 \le n < 500 | baby-step giant-step |
| order n \ge 500 composite | Pohlig–Hellman over the prime powers |
| order p^e, e \ge 2, p^e \ge 50 | digits in the subgroup of order p |
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(\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, \ldots, N - 1, one needs \log_a k for all k < N. Two methods are used.
Enumeration (dlog_vec_loop). Running through a^0, a^1, \ldots, a^{n-1} and recording the exponent of every power below N costs n multiplications. It is the method of choice when N is comparable with n (FLINT uses it when 6n < N).
Sieving (dlog_vec_sieve). Logarithms are additive, \log_a(jk) = \log_a j + \log_a k, so it suffices to compute \log_a p for the primes p < N and to fill in the other entries in increasing order, v[pk] = v[k] + v[p]. A prime p costs one precomputed logarithm. For larger primes, a relation with smaller numbers may be cheaper: with c = a^X for a fixed X, compute for i = 1, 2, \ldots a partial extended Euclidean algorithm on (m, p c^i \bmod m), stopped when the remainder r and the cofactor u are both about \sqrt m, so that
If r and u factor into primes below p, whose logarithms are already known, then \log_a p = \log_a r - \log_a u - iX \pm \log_a(-1). The probability that two numbers of size \sqrt m are p-smooth is about \rho(s)^2 with s = \log \sqrt m / \log p, which FLINT estimates crudely by s^{-s} with s = \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#
dlog_precomp_tand its initialisation functions implement the strategy table above withdlog_table_t,dlog_bsgs_t,dlog_crt_t,dlog_power_t,dlog_modpe_tanddlog_order23_t;dlog_onceenumerates for orders below 50 and otherwise uses a precomputation for one query.dlog_vecanddlog_vec_addchoose betweendlog_vec_loopanddlog_vec_sieve;dlog_vec_add_precompreuses an existing precomputation.dlog_vec_eratoscomputes the logarithm of every prime directly.dirichlet_group_dlog_precomputebuildsdlog_precomp_modpe_inittables for each prime power component;dirichlet_char_loganddirichlet_chi_vecuse them, ordlog_onceanddlog_vec_addwhen no tables were requested.
void dlog_precomp_n_init(dlog_precomp_t pre, ulong a, ulong mod, ulong n, ulong num)void dlog_precomp_modpe_init(dlog_precomp_t pre, ulong a, ulong p, ulong e, ulong pe, ulong num)ulong dlog_precomp(const dlog_precomp_t pre, ulong b)ulong dlog_bsgs_init(dlog_bsgs_t t, ulong a, ulong mod, ulong n, ulong m)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
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-10-20).
@misc{flint-doc-algorithms-number-theory-discrete-log-tables,
author = {{The FLINT team}},
title = {{Discrete logarithm tables}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/algorithms/number-theory/discrete-log-tables.html},
note = {Generated 2026-10-20}
}