FLINT3.7.0-dev
Module · 64 functions

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, with fmpz 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, ulong or slong operand documented as "any integer" reduce it themselves. Canonicity is not checked, except by FLINT_ASSERT in builds with --enable-assert.
  • Canonical residues are compared with fmpz_equal, fmpz_is_zero and fmpz_is_one (except that for n = 1 the residue 0 is also one; see fmpz_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#

Initialises ctx for arithmetic modulo n. Throws an exception if n \le 0.

More

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.

Frees the memory used by ctx.

Returns a pointer to the modulus n, valid as long as the context is not cleared or changed.

More

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)

Sets a to b \bmod n in [0, n), for any integer b.

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#

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.

More

Powering#

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.

More

Random elements#

Sets a to a uniformly random residue in [0, n).

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).

fmpz_mod_discrete_log_pohlig_hellman_entry_struct
fmpz_mod_discrete_log_pohlig_hellman_table_entry_struct

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.

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.

Full documentation

Returns a pointer to the primitive root \alpha used as the base of the logarithms.

Full documentation

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 documentation

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.

Full documentation

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)

For n < 2^{\mathtt{FLINT\_BITS}}, with nmod_add, nmod_sub and nmod_mul and the nmod_t stored in the context.

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.

Cite this page

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).