dlog.h
#include <flint/dlog.h>This module computes discrete logarithms in cyclic subgroups of for word-size moduli , mostly primes and prime powers: given of order and , it finds with . It was written for Dirichlet characters (dirichlet, acb_dirichlet), where many logarithms are taken in the same group, so its central object is a precomputation, dlog_precomp_t, built for a given base and an expected number of queries: the choice of method (complete table, baby-step giant-step, Pohlig–Hellman decomposition, -adic logarithm) and the amount of stored data depend on the structure of the group and on that number. The module also computes the logarithms of all integers at once, by enumeration or by sieving.
Little effort has been made for a single logarithm in a large group of prime order. For one-off logarithms modulo a prime with smooth , see also nmod_discrete_log_pohlig_hellman (Discrete logarithms modulo a prime (Pohlig–Hellman)). Precomputed discrete logarithms explains how to set up a precomputation, and the algorithms are described in Discrete logarithm tables.
Conventions#
Logarithms are returned as ulong values in , where is the order of the base. The base must have exactly the order passed to the functions, and the moduli must fit in a word; none of this is checked. The result for an argument outside the subgroup generated by the base is not specified (some methods throw, others return a wrong value).
The value UWORD_MAX, used in vectors of logarithms for the entries whose logarithm does not exist (integers not coprime to the modulus).
Single logarithms#
Returns with modulo mod.n, where has order : by enumerating the powers of for (throwing if is not found), and otherwise with a precomputation for one query (dlog_precomp_n_init with num ), which is cleared afterwards.
Precomputed logarithms#
Precomputed data for logarithms to a fixed base: the method (type), an estimate of the cost of one logarithm (cost, in multiplications), and the data of the method. A dlog_precomp_t is an array of length one of dlog_precomp_struct.
void dlog_precomp_n_init(dlog_precomp_t pre, ulong a, ulong mod, ulong n, ulong num)Initialises pre for about num logarithms to the base of order modulo mod, with no further information on . If is an odd prime the function calls dlog_precomp_p_init; otherwise it uses a complete table for , baby-step giant-step for , and the Pohlig–Hellman decomposition (dlog_crt_init) above.
void dlog_precomp_p_init(dlog_precomp_t pre, ulong a, ulong mod, ulong p, ulong num)As dlog_precomp_n_init for a base of prime order : a complete table for , otherwise baby-step giant-step with a table of dlog_bsgs_size(p, num) powers.
void dlog_precomp_pe_init(dlog_precomp_t pre, ulong a, ulong mod, ulong p, ulong e, ulong pe, ulong num)As dlog_precomp_n_init for a base of prime power order : a complete table for , dlog_precomp_p_init for , and otherwise the base- digit decomposition (dlog_power_init).
void dlog_precomp_modpe_init(dlog_precomp_t pre, ulong a, ulong p, ulong e, ulong pe, ulong num)Initialises pre for logarithms to the base modulo , where generates (for odd ), or, for and , generates the subgroup of elements congruent to 1 modulo 4. Uses a complete table for , the reduction to a logarithm modulo and a -adic logarithm (dlog_modpe_init) for , and dlog_precomp_n_init modulo for .
void dlog_precomp_small_init(dlog_precomp_t pre, ulong a, ulong mod, ulong n, ulong num)Initialises pre for a group of small order : the trivial method for , a complete table indexed by the residues if , and otherwise a baby-step giant-step table containing all powers (so that a logarithm is one binary search).
ulong dlog_precomp(const dlog_precomp_t pre, ulong b)Returns the logarithm of (reduced modulo the modulus) to the base of pre.
void dlog_precomp_clear(dlog_precomp_t pre)Frees the memory used by pre. Does nothing if pre is NULL.
Vectors of logarithms#
These functions compute, for all , the value , where is the logarithm of to a base of order (na) generating (so is a prime power or twice one). The modulus order must divide , so that the result is well defined; with and these are the plain logarithms. Entries for not coprime to are DLOG_NONE. This is the form needed for the exponents of Dirichlet characters.
Set to , or (the add version) add it to modulo order for every with DLOG_NONE. They do nothing if . Both use loop if and sieve otherwise.
As dlog_vec and dlog_vec_add, by enumerating the powers of and copying the values to the entries by periodicity. Costs and needs no discrete logarithm.
As dlog_vec and dlog_vec_add, by computing the logarithms of the primes and extending them to all by complete multiplicativity. The logarithms of the primes are computed with a precomputation for 50 queries, except that for primes large enough a relation with smaller numbers is searched first (dlog_vec_pindex_factorgcd). The full index calculus method is not implemented.
void dlog_vec_sieve_precomp(ulong * v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order)void dlog_vec_sieve_add_precomp(ulong * v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order)void dlog_vec_add_precomp(ulong * v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order)As dlog_vec_sieve, dlog_vec_sieve_add and dlog_vec_add, with the logarithms of the primes taken from an existing precomputation pre for the base .
void dlog_vec_eratos_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order)As dlog_vec and dlog_vec_add, by computing the logarithm of every prime below with a precomputation and adding it to all multiples of its powers, as in the sieve of Eratosthenes. The add version assumes that the entries not coprime to are already DLOG_NONE.
void dlog_vec_fill(ulong * v, ulong nv, ulong x)Sets for .
void dlog_vec_set_not_found(ulong * v, ulong nv, nmod_t mod)Sets to DLOG_NONE for the divisible by a prime factor of the modulus.
ulong dlog_vec_pindex_factorgcd(ulong * v, ulong nv, ulong p, nmod_t mod, ulong a, ulong na, ulong loga, ulong logm1, nmod_t order, int maxtry)Tries to find the logarithm of the prime from the logarithms already stored in : for up to maxtry, writes with about by a partial extended Euclidean algorithm, and if and factor over the entries of already known (after removing primes below ), returns (adjusted by logm1, the logarithm of ). Here loga is the value to use for . Returns DLOG_NOT_FOUND if no relation is found.
Methods#
Each method has a structure, an init function that returns an estimate of the cost of one logarithm, the logarithm function and a clear function. They are used through dlog_precomp_t, but can also be called directly. In all of them is the base and the argument.
Complete table#
A table of size mod giving the logarithm of every residue (for small moduli only).
ulong dlog_table_init(dlog_table_t t, ulong a, ulong mod)void dlog_table_clear(dlog_table_t t)ulong dlog_table(const dlog_table_t t, ulong b)Build the table of the logarithms of the powers of modulo mod (an array of mod words; must be invertible, which is not checked), free it, and look up . The cost estimate is 1.
Orders 2 and 3#
The base of a group of order at most 3.
void dlog_order23_clear(dlog_order23_t t)ulong dlog_order23(const dlog_order23_t t, ulong b)Store , do nothing, and return 0 if , 1 if , and 2 otherwise. The cost estimate is 0.
Baby-step giant-step#
A sorted table of pairs (apow_t), for , together with and the number of giant steps .
ulong dlog_bsgs_init(dlog_bsgs_t t, ulong a, ulong mod, ulong n, ulong m)Initialises with the baby steps (or if ), sorted by value, for a base of order . Returns the number of giant steps , the worst-case cost of one logarithm. For logarithms, minimises the total cost.
ulong dlog_bsgs_size(ulong n, ulong num)Returns the table size used for num logarithms in a group of order : if , and otherwise.
void dlog_bsgs_clear(dlog_bsgs_t t)ulong dlog_bsgs(const dlog_bsgs_t t, ulong b)Free the table, and return by multiplying by until the product is found in the table (by binary search). Throws if is not a power of .
Comparison function of the pairs by the value , for qsort and bsearch.
Pohlig–Hellman decomposition#
For a base of composite order : for each prime power, the cofactor , the CRT coefficient and a precomputation in the subgroup of order .
ulong dlog_crt_init(dlog_crt_t t, ulong a, ulong mod, ulong n, ulong num)void dlog_crt_clear(dlog_crt_t t)ulong dlog_crt(const dlog_crt_t t, ulong b)Initialise for num logarithms to the base of order modulo mod, by factoring and initialising dlog_precomp_pe_init for in each subgroup of prime power order (the returned cost is the sum of their costs); free it; and return , combining the logarithms of by the Chinese remainder theorem.
Prime power order#
For a base of order : the powers , , and a precomputation in the subgroup of order , generated by .
ulong dlog_power_init(dlog_power_t t, ulong a, ulong mod, ulong p, ulong e, ulong num)void dlog_power_clear(dlog_power_t t)ulong dlog_power(const dlog_power_t t, ulong b)Initialise for num logarithms to the base of order (the subgroup precomputation is made for logarithms and the cost is times its cost); free it; and return , found one base- digit at a time, each digit a logarithm in the subgroup of order .
Prime power modulus#
For the modulus with a generator : a precomputation modulo (for odd ) and the data for logarithms in the subgroup of elements congruent to 1 modulo : and the inverse of the logarithm of to the base .
ulong dlog_modpe_init(dlog_modpe_t t, ulong a, ulong p, ulong e, ulong pe, ulong num)void dlog_modpe_clear(dlog_modpe_t t)ulong dlog_modpe(const dlog_modpe_t t, ulong b)Initialise for num logarithms to the base modulo ; free it; and return , combining the logarithm of modulo with the logarithm of in , which determines modulo . For the base must be 5 (or a generator of the elements congruent to 1 modulo 4) and ; this case uses dlog_mod2e.
void dlog_1modpe_init(dlog_1modpe_t t, ulong a1, ulong p, ulong e, nmod_t pe)ulong dlog_1modpe(const dlog_1modpe_t t, ulong b1, ulong p, ulong e, nmod_t pe)For odd and generating modulo , precompute the inverse of the logarithm of to the base (throws if and ), and return the logarithm of to the base , modulo .
Returns the logarithm of to the base modulo , given inv1p , determining one base- digit per step. Throws if .
ulong dlog_mod2e(const dlog_modpe_t t, ulong b)Return the logarithm of to the base 5 modulo , given inv5 , determining one bit per step (throws if ); and the logarithm for a dlog_modpe_t with (for , whether ).
Pollard rho#
void dlog_rho_init(dlog_rho_t t, ulong a, ulong mod, ulong n)void dlog_rho_clear(dlog_rho_t t)ulong dlog_rho(const dlog_rho_t t, ulong b)Initialise for the base of order modulo mod; do nothing; and return with Pollard's rho method [Pol1978], using a random walk with 20 steps and Floyd's cycle detection, in expected time and constant memory. For composite a relation that does not determine the logarithm is completed recursively. This method is not used by dlog_precomp_t.
Internal functions and constants#
void dlog_n_factor_group(n_factor_t * fac, ulong bound)Regroups the prime power factors in fac into products not exceeding bound, marking them DLOG_G_SMALL, and multiplies the remaining factors into one marked DLOG_G_BIG. Not used by the library.
Tuning constants: the limits (all 50) below which complete tables or enumeration are used, the limit (500) on the order below which baby-step giant-step is used without decomposition, and the factor (6) in the choice between dlog_vec_loop and dlog_vec_sieve.
The values of the type field of dlog_precomp_struct.
References#
- [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, “dlog.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/dlog/index.html (generated 2026-11-02).
@misc{flint-doc-dlog-index,
author = {{The FLINT team}},
title = {{dlog.h (module overview)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/dlog/index.html},
note = {Generated 2026-11-02}
}