fmpz_mod.h
#include <flint/fmpz_mod.h>This module implements arithmetic in \mathbb{Z}/n\mathbb{Z} for an arbitrary modulus n \ge 1. Residues are ordinary fmpz_t integers in the canonical range [0, n), and the modulus is held in a context object fmpz_mod_ctx_t, which every function takes as its last argument. The context also selects the fastest code for the size of n: nmod arithmetic for one-word moduli, an inline two-limb Barrett reduction for moduli below 2^{2\mathtt{FLINT\_BITS}}, and fmpz division (with a precomputed inverse for very large moduli) beyond. The module is the scalar layer of fmpz_mod_vec, fmpz_mod_poly, fmpz_mod_mat, fmpz_mod_mpoly and the finite fields of fq with a multiword characteristic. It also provides discrete logarithms modulo primes by the Pohlig–Hellman method.
For moduli of 2 to 16 limbs, polynomial and matrix computations are faster with the generic ring mpn_mod, which stores residues as fixed-length limb arrays; see Arithmetic modulo multiword integers. The generic ring with fmpz residues is gr_ctx_init_fmpz_mod. For a single operation modulo n without a context, the functions of fmpz described in Modular arithmetic with integers suffice.
The guide Using fmpz_mod shows the typical use.
OverviewArithmetic modulo multiword integersFLINT represents \mathbb{Z}/n\mathbb{Z} for n \ge 2^{64} in two ways, withfmpz residues in fmpz_mod and with fixed-length limb arrays in the generic ring mpn_mod. This page compares the representations, the reductions they use, and how they relate to nmod and to the generic rings.Guides#
Conventions#
- n is the modulus of the context ctx. A residue is canonical if it lies in [0, n).
- Unless stated otherwise, inputs must be canonical and outputs are canonical. Functions with an
fmpz,ulongorslongoperand documented as "any integer" reduce it themselves. Canonicity is not checked, except byFLINT_ASSERTin builds with--enable-assert. - Canonical residues are compared with
fmpz_equal,fmpz_is_zeroandfmpz_is_one(except that for n = 1 the residue 0 is also one; seefmpz_mod_is_one). - Outputs may alias inputs.
Types#
The context for arithmetic modulo n. An fmpz_mod_ctx_t is an array of one fmpz_mod_ctx_struct, passed by reference. The fields are n (the modulus), function pointers add_fxn, sub_fxn and mul_fxn chosen by fmpz_mod_ctx_init, mod (an nmod_t for one-word moduli), n_limbs and ninv_limbs (the modulus and the three-limb Barrett inverse \lfloor 2^{4\mathtt{FLINT\_BITS}}/n \rfloor for two-limb moduli) and ninv_huge (a precomputed inverse for moduli of more than 20 limbs, or NULL). Use fmpz_mod_ctx_modulus to read n.
Context#
void fmpz_mod_ctx_init(fmpz_mod_ctx_t ctx, const fmpz_t n)void fmpz_mod_ctx_init_ui(fmpz_mod_ctx_t ctx, ulong n)Initialises ctx for arithmetic modulo n. Throws an exception if n \le 0.
Morevoid fmpz_mod_ctx_init_rand_bits(fmpz_mod_ctx_t ctx, flint_rand_t state, flint_bitcnt_t max_bits)void fmpz_mod_ctx_init_rand_bits_prime(fmpz_mod_ctx_t ctx, flint_rand_t state, flint_bitcnt_t max_bits)Initialise ctx with a random modulus, for testing: 2 + m with m a random integer of at most max_bits bits (from fmpz_randtest_unsigned), respectively the least probable prime (fmpz_nextprime without proof) greater than such an m. The modulus can have slightly more than max_bits bits.
void fmpz_mod_ctx_clear(fmpz_mod_ctx_t ctx)Frees the memory used by ctx.
const fmpz * fmpz_mod_ctx_modulus(const fmpz_mod_ctx_t ctx)Returns a pointer to the modulus n, valid as long as the context is not cleared or changed.
Morevoid fmpz_mod_ctx_set_modulus(fmpz_mod_ctx_t ctx, const fmpz_t n)void fmpz_mod_ctx_set_modulus_ui(fmpz_mod_ctx_t ctx, ulong n)Changes the modulus of the initialised context ctx to n, which must be positive. Residues computed for the old modulus are not reduced.
Conversion and canonical form#
void fmpz_mod_set_fmpz(fmpz_t a, const fmpz_t b, const fmpz_mod_ctx_t ctx)void fmpz_mod_set_ui(fmpz_t a, ulong b, const fmpz_mod_ctx_t ctx)void fmpz_mod_set_si(fmpz_t a, slong b, const fmpz_mod_ctx_t ctx)Sets a to b \bmod n in [0, n), for any integer b.
int fmpz_mod_is_canonical(const fmpz_t a, const fmpz_mod_ctx_t ctx)void fmpz_mod_assert_canonical(const fmpz_t a, const fmpz_mod_ctx_t ctx)fmpz_mod_is_canonical returns 1 if 0 \le a < n and 0 otherwise. fmpz_mod_assert_canonical throws an exception if a is not canonical, in every build.
Comparison#
int fmpz_mod_is_one(const fmpz_t a, const fmpz_mod_ctx_t ctx)Returns 1 if a is 1 modulo n, that is, if a = 1 or n = 1, and 0 otherwise.
int fmpz_mod_equal_fmpz(const fmpz_t a, const fmpz_t b, const fmpz_mod_ctx_t ctx)int fmpz_mod_equal_si(const fmpz_t a, slong b, const fmpz_mod_ctx_t ctx)Return 1 if the canonical residue a is congruent to the integer b modulo n (any b), and 0 otherwise.
Arithmetic#
void fmpz_mod_add(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void fmpz_mod_sub(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void fmpz_mod_neg(fmpz_t a, const fmpz_t b, const fmpz_mod_ctx_t ctx)Set a to b + c, b - c and -b modulo n, for canonical b and c.
void fmpz_mod_add_fmpz(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void fmpz_mod_add_ui(fmpz_t a, const fmpz_t b, ulong c, const fmpz_mod_ctx_t ctx)void fmpz_mod_add_si(fmpz_t a, const fmpz_t b, slong c, const fmpz_mod_ctx_t ctx)void fmpz_mod_sub_fmpz(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void fmpz_mod_sub_ui(fmpz_t a, const fmpz_t b, ulong c, const fmpz_mod_ctx_t ctx)void fmpz_mod_sub_si(fmpz_t a, const fmpz_t b, slong c, const fmpz_mod_ctx_t ctx)Set a to b + c or b - c modulo n, for canonical b and any integer c. The sum is computed exactly and reduced with fmpz_mod.
void fmpz_mod_fmpz_sub(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void fmpz_mod_ui_sub(fmpz_t a, ulong b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void fmpz_mod_si_sub(fmpz_t a, slong b, const fmpz_t c, const fmpz_mod_ctx_t ctx)Set a to b - c modulo n, for any integer b and canonical c.
void fmpz_mod_mul(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)Sets a to bc modulo n, for canonical b and c, with the function selected by the context: nmod_mul for one-word moduli, a two-limb Barrett reduction with at most two corrections for two-limb moduli, and fmpz_mul followed by fmpz_mod (or fmpz_fdiv_r_preinvn above 20 limbs) otherwise.
void fmpz_mod_mul_fmpz(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void fmpz_mod_mul_ui(fmpz_t a, const fmpz_t b, ulong c, const fmpz_mod_ctx_t ctx)void fmpz_mod_mul_si(fmpz_t a, const fmpz_t b, slong c, const fmpz_mod_ctx_t ctx)Set a to bc modulo n, for canonical b and any integer c. The product is computed exactly and reduced.
void fmpz_mod_addmul(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_t d, const fmpz_mod_ctx_t ctx)Sets a to b + cd modulo n. The sum is computed exactly with fmpz arithmetic and reduced once, so b, c and d may be any integers.
Inversion and division#
int fmpz_mod_is_invertible(const fmpz_t a, const fmpz_mod_ctx_t ctx)Returns 1 if \gcd(a, n) = 1, that is, if a is invertible modulo n, and 0 otherwise. Works for any integer a.
void fmpz_mod_inv(fmpz_t a, const fmpz_t b, const fmpz_mod_ctx_t ctx)Sets a to b^{-1} modulo n, for canonical b. Throws an exception (FLINT_IMPINV) if b is not invertible; test first with fmpz_mod_is_invertible when this is possible.
int fmpz_mod_divides(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)If the congruence ac \equiv b \pmod n has a solution, sets a to one solution in [0, n) and returns 1; otherwise returns 0 and leaves a undefined. b and c must be canonical.
MorePowering#
void fmpz_mod_pow_ui(fmpz_t a, const fmpz_t b, ulong e, const fmpz_mod_ctx_t ctx)Sets a to b^e modulo n, for canonical b. 0^0 = 1.
int fmpz_mod_pow_fmpz(fmpz_t a, const fmpz_t b, const fmpz_t e, const fmpz_mod_ctx_t ctx)Sets a to b^e modulo n and returns 1, for canonical b and any integer e. If e < 0 and b is not invertible, returns 0 and leaves a undefined.
MoreRandom elements#
void fmpz_mod_rand(fmpz_t a, flint_rand_t state, const fmpz_mod_ctx_t ctx)Sets a to a uniformly random residue in [0, n).
void fmpz_mod_rand_not_zero(fmpz_t a, flint_rand_t state, const fmpz_mod_ctx_t ctx)Sets a to a random nonzero residue: it draws up to three uniformly random residues and returns the first nonzero one, or 1 if all three are zero. (For n = 1 there is no nonzero residue, and the result is the non-canonical value 1.)
Discrete logarithms via Pohlig–Hellman#
These functions compute discrete logarithms modulo a prime p for which the prime factors of p - 1 are small. A precomputation for p finds a primitive root and tables for each prime factor of p - 1; each logarithm then costs a few exponentiations and baby-step giant-step searches. See Discrete logarithms modulo a multiprecision prime and Discrete logarithms modulo a prime (Pohlig–Hellman).
The precomputed data: a context for p, p - 1, the primitive root \alpha and its inverse, and for each prime power q^e exactly dividing p - 1 an entry with the idempotent for the Chinese remainder theorem, the element \gamma = \alpha^{(p-1)/q} of order q and a sorted table of powers of \gamma for the baby-step giant-step search.
Initialise L, which is not ready for computation until fmpz_mod_discrete_log_pohlig_hellman_precompute_prime is called, and free the memory used by L.
double fmpz_mod_discrete_log_pohlig_hellman_precompute_prime(fmpz_mod_discrete_log_pohlig_hellman_t L, const fmpz_t p)Configures L for logarithms modulo p to the base of the least primitive root modulo p, and returns an estimate of the number of multiplications modulo p that one call of fmpz_mod_discrete_log_pohlig_hellman_run needs. p must be prime, which is not checked.
const fmpz * fmpz_mod_discrete_log_pohlig_hellman_primitive_root(fmpz_mod_discrete_log_pohlig_hellman_t L)Returns a pointer to the primitive root \alpha used as the base of the logarithms.
Full documentationvoid fmpz_mod_discrete_log_pohlig_hellman_run(fmpz_t x, const fmpz_mod_discrete_log_pohlig_hellman_t L, const fmpz_t y)Sets x to the logarithm of y to the base \alpha, the integer x \in [0, p - 1) with \alpha^x \equiv y \pmod p. y must be reduced modulo p and nonzero (not checked); if no logarithm is found, which can only happen for invalid input, an exception is thrown.
Full documentationint fmpz_next_smooth_prime(fmpz_t a, const fmpz_t b)Sets a to a prime p > b for which p - 1 is smooth and returns 1, or sets a to 0 and returns 0 if there is none. Such primes are suitable for fmpz_mod_discrete_log_pohlig_hellman_precompute_prime.
Internal functions#
The arithmetic functions selected by fmpz_mod_ctx_init. They have the interface of fmpz_mod_add, fmpz_mod_sub and fmpz_mod_mul and require canonical inputs and a modulus of the stated size.
void _fmpz_mod_add1(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void _fmpz_mod_sub1(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void _fmpz_mod_mul1(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void _fmpz_mod_add2s(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void _fmpz_mod_sub2s(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void _fmpz_mod_mul2s(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)For n = 2^{\mathtt{FLINT\_BITS}}, with wrapping word arithmetic.
void _fmpz_mod_add2(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void _fmpz_mod_sub2(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void _fmpz_mod_mul2(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)For 2^{\mathtt{FLINT\_BITS}} < n < 2^{2\mathtt{FLINT\_BITS}}, with two- and three-limb arithmetic; _fmpz_mod_mul2 is the Barrett reduction of Two-limb Barrett reduction in fmpz_mod.
void _fmpz_mod_addN(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void _fmpz_mod_subN(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)void _fmpz_mod_mulN(fmpz_t a, const fmpz_t b, const fmpz_t c, const fmpz_mod_ctx_t ctx)For any modulus, with fmpz arithmetic; _fmpz_mod_mulN reduces with fmpz_mod, or with fmpz_fdiv_r_preinvn when the context has a precomputed inverse.
The FLINT team, “fmpz_mod.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/fmpz_mod/index.html (generated 2026-10-20).
@misc{flint-doc-fmpz-mod-index,
author = {{The FLINT team}},
title = {{fmpz\_mod.h (module overview)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/fmpz_mod/index.html},
note = {Generated 2026-10-20}
}