nmod.h
#include <flint/nmod.h>This module implements arithmetic in for a word-size modulus . Elements are plain ulong values in , and the modulus is passed as an nmod_t holding together with a precomputed inverse. Most functions are inline wrappers around the _preinv functions of ulong_extras. They are the scalar building blocks of nmod_vec, nmod_poly, nmod_mat and the other modules over . The module also provides square roots modulo primes, discrete logarithms, Montgomery arithmetic, and the generic ring (gr) contexts for .
The guides below explain how to use the module; start with Basic arithmetic modulo n. The conventions common to all FLINT modules, including the naming of functions and the use of nmod_t as a context, are described in Types, naming and aliasing.
Guides#
nmod_t, which operations need reduced operands, how products are reduced, and how to divide when the divisor may not be invertible.GuideComputing discrete logarithmsHow to set up the Pohlig–Hellman precomputation for a prime, which primes it suits, how to take logarithms to another base, and examples.GuideUsing Montgomery arithmeticWhen Montgomery form pays off, how to convert values in and out, the rules for lazy residues and half-word arithmetic, and how the reduction works.Conventions#
Throughout, .
A modulus with precomputed data, set up by nmod_init. The fields are n (the modulus), norm (the number of leading zero bits of ) and ninv (the value n_preinvert_limb(n) used for Möller–Granlund division). An nmod_t is a small struct and is passed by value.
- Reduced means . Unless stated otherwise, operands must be reduced and results are reduced. Functions named
nmod_set_*andnmod_ui_*accept any input. - None of these assumptions is checked, except by
FLINT_ASSERTin builds configured with--enable-assert. - A leading underscore marks a function with an extra restriction on the modulus or the input (for example
_nmod_add), or an internal helper.
Initialisation and conversion#
NMOD_BITS(mod)The number of bits of mod.n, that is, FLINT_BITS - mod.norm.
Arithmetic#
Addition, multiplication, inversion and division of residues. The guide Basic arithmetic modulo n explains which of them need reduced operands and what to do when the divisor is not invertible.
Return , and modulo , for reduced operands and any .
ulong nmod_ui_add_ui(ulong a, ulong b, nmod_t mod)Returns for any and .
ulong _nmod_mul_fullword(ulong a, ulong b, nmod_t mod)Returns for reduced operands. Requires mod.norm , that is, . It saves the normalisation shift of nmod_mul.
ulong nmod_ui_mul_ui(ulong a, ulong b, nmod_t mod)Returns for any and .
Return and modulo , for reduced operands. nmod_addmul forms as a two-word integer and reduces it once.
NMOD_ADDMUL(r, a, b, mod)Sets r to , for reduced r, a and b. This is r = nmod_addmul(r, a, b, mod).
int nmod_divides(ulong * a, ulong b, ulong c, nmod_t mod)Powering#
ulong nmod_pow_ui(ulong a, ulong exp, nmod_t mod)ulong nmod_pow_fmpz(ulong a, const fmpz_t exp, nmod_t mod)Return for reduced , with (which is 0 when ). For a negative exponent, nmod_pow_fmpz returns and throws FLINT_IMPINV if is not invertible modulo .
ulong nmod_ui_pow_ui(ulong a, ulong exp, nmod_t mod)Returns for any .
ulong nmod_2_pow_ui(ulong exp, nmod_t mod)Returns .
Moreulong _nmod_pow_ui_binexp(ulong a, ulong exp, nmod_t mod)ulong _nmod_pow_ui_redc(ulong a, ulong exp, nmod_t mod)ulong _nmod_2_pow_ui_binexp(ulong exp, nmod_t mod)The algorithms behind nmod_pow_ui and nmod_2_pow_ui, with the same results. The first two require (they do not terminate for ), and _nmod_pow_ui_redc requires odd . _nmod_2_pow_ui_binexp accepts any and any exponent.
Square roots#
For prime and reduced : if is a square modulo , sets *res to the square root in and returns 1; otherwise sets *res to 0 and returns 0. Primality is not checked. For composite , a return value of 1 still gives a genuine square root, but 0 does not prove that none exists.
int _nmod_sqrt_small(ulong * res, ulong a, ulong n)For odd and , finds the least square root of modulo by exhaustive search in steps. Returns 1 and sets *res to the root, or returns 0 and sets *res to 0 if there is none. The answer is correct for composite too.
The bound 128 below which nmod_sqrt uses _nmod_sqrt_small for odd .
nmod_sqrt finds a square root modulo a word-size prime . It uses one exponentiation when or , and otherwise Tonelli–Shanks in two forms or Müller's variant of Cipolla–Lehmer, depending on the power of 2 dividing . Every candidate root is checked by squaring.
Discrete logarithms#
These functions compute discrete logarithms modulo a prime to the base of the least primitive root, by the Pohlig–Hellman method with baby-step giant-step. They are efficient when has only small prime factors. The guide Computing discrete logarithms shows how to use them, including logarithms to other bases.
Precomputed data for discrete logarithms modulo one prime: the factorisation of , the primitive root and lookup tables. The field mod is an nmod_t for .
Initialise L and free its memory. An initialised L must be set up with nmod_discrete_log_pohlig_hellman_precompute_prime before it is used.
double nmod_discrete_log_pohlig_hellman_precompute_prime(nmod_discrete_log_pohlig_hellman_t L, ulong p)Sets up L for the prime , which is not checked, freeing any earlier data. Returns an estimate of the number of multiplications modulo needed by one call to nmod_discrete_log_pohlig_hellman_run.
Returns the base of the logarithms, the least primitive root modulo .
Returns the with . Requires .
MoreMontgomery arithmetic#
In Montgomery arithmetic modulo an odd , a residue is represented by , where for the standard functions and for the half functions. Multiplication then needs no division. Values are converted into this Montgomery form once and back at the end. The prefix of a function name tells which representation it uses:
| Prefix | Requires | Residues | |
|---|---|---|---|
nmod_redc_ | odd | ||
nmod_redc_fast_ | odd | ||
nmod_redc_half_ | odd | ||
nmod_redc_half_fast_ | odd |
The fast functions take and return lazy residues in , which saves a conditional subtraction per multiplication. The guide Using Montgomery arithmetic explains when Montgomery form pays off and the rules for mixing standard, fast and half functions.
A context for Montgomery arithmetic. The field mod is an ordinary nmod_t for , used for conversions and for addition, and nred is . The context needs no clearing.
void nmod_redc_ctx_init_nmod(nmod_redc_ctx_t ctx, nmod_t mod)void nmod_redc_ctx_init_ui(nmod_redc_ctx_t ctx, ulong n)Initialise ctx for the standard and fast functions modulo , which must be odd.
int nmod_redc_can_use_fast(const nmod_redc_ctx_t ctx)Returns whether , the condition for the fast functions.
ulong nmod_redc_set_nmod(ulong x, const nmod_redc_ctx_t ctx)ulong nmod_redc_set_ui(ulong x, const nmod_redc_ctx_t ctx)Return the Montgomery form of . nmod_redc_set_nmod requires ; nmod_redc_set_ui accepts any .
ulong nmod_redc_get_nmod(ulong x, const nmod_redc_ctx_t ctx)Returns in , converting from Montgomery form. Any word is accepted, in particular a lazy residue.
ulong nmod_redc_neg(ulong x, const nmod_redc_ctx_t ctx)ulong nmod_redc_add(ulong x, ulong y, const nmod_redc_ctx_t ctx)ulong nmod_redc_sub(ulong x, ulong y, const nmod_redc_ctx_t ctx)ulong nmod_redc_mul(ulong x, ulong y, const nmod_redc_ctx_t ctx)Negation, addition, subtraction and multiplication in Montgomery form, for inputs and output in . Negation, addition and subtraction are the same as for ordinary residues.
ulong nmod_redc_fast_neg(ulong x, const nmod_redc_ctx_t ctx)ulong nmod_redc_fast_add(ulong x, ulong y, const nmod_redc_ctx_t ctx)ulong nmod_redc_fast_sub(ulong x, ulong y, const nmod_redc_ctx_t ctx)ulong nmod_redc_fast_mul(ulong x, ulong y, const nmod_redc_ctx_t ctx)The same operations on lazy residues: inputs and output are in . Require .
ulong nmod_redc_fast_mul_two(ulong x, const nmod_redc_ctx_t ctx)Returns a lazy residue in congruent to , for .
ulong nmod_redc_fast_normalise(ulong x, const nmod_redc_ctx_t ctx)Reduces a lazy residue to .
ulong _nmod_redc_pow_ui(ulong a, ulong exp, const nmod_redc_ctx_t ctx)ulong _nmod_redc_fast_pow_ui(ulong a, ulong exp, const nmod_redc_ctx_t ctx)Return with and the result in Montgomery form, by binary exponentiation. Require . The fast version takes and returns lazy residues.
ulong _nmod_redc_2_pow_ui(ulong exp, const nmod_redc_ctx_t ctx)ulong _nmod_redc_fast_2_pow_ui(ulong exp, const nmod_redc_ctx_t ctx)Return the Montgomery form of , for any . The fast version returns a lazy residue.
Half-word Montgomery arithmetic#
These functions use , so that every product fits in one word. They take the same context type, but it must be initialised with the functions below, and the resulting Montgomery form differs from that of the full-word functions, so the two cannot be mixed.
void nmod_redc_half_ctx_init_nmod(nmod_redc_ctx_t ctx, nmod_t mod)void nmod_redc_half_ctx_init_ui(nmod_redc_ctx_t ctx, ulong n)Initialise ctx for the half functions modulo , which must be odd with .
int nmod_redc_half_can_use_fast(const nmod_redc_ctx_t ctx)Returns whether , the condition for the half_fast functions.
ulong nmod_redc_half_set_nmod(ulong x, const nmod_redc_ctx_t ctx)ulong nmod_redc_half_set_ui(ulong x, const nmod_redc_ctx_t ctx)ulong nmod_redc_half_get_nmod(ulong x, const nmod_redc_ctx_t ctx)Convert to and from Montgomery form with . nmod_redc_half_set_nmod requires and nmod_redc_half_set_ui accepts any . nmod_redc_half_get_nmod returns a value in for any , in particular for lazy residues.
ulong nmod_redc_half_add(ulong x, ulong y, const nmod_redc_ctx_t ctx)ulong nmod_redc_half_sub(ulong x, ulong y, const nmod_redc_ctx_t ctx)ulong nmod_redc_half_mul(ulong x, ulong y, const nmod_redc_ctx_t ctx)Addition, subtraction and multiplication in Montgomery form, for inputs and output in .
ulong nmod_redc_half_fast_add(ulong x, ulong y, const nmod_redc_ctx_t ctx)ulong nmod_redc_half_fast_sub(ulong x, ulong y, const nmod_redc_ctx_t ctx)ulong nmod_redc_half_fast_mul(ulong x, ulong y, const nmod_redc_ctx_t ctx)The same on lazy residues in . Require .
Low-level functions#
The context functions are wrappers of the following ones, which take the odd modulus and nred directly. Here , except for the half functions, where .
ulong n_redc_fast(ulong x, ulong n, ulong nred)Return for any word . n_redc_fast returns a value in , which may need one more subtraction of .
ulong n_ll_redc_fast(ull_t x, ulong n, ulong nred)Return a value congruent to modulo , for a two-word . n_ll_redc requires and returns a value in . n_ll_redc_fast requires and returns a value below .
Return a value congruent to modulo . n_mulmod_redc requires (for example ) and returns a value in . n_mulmod_redc_fast maps to when .
Returns for , given ninv and norm as stored in an nmod_t for . This is one division step with the precomputed inverse.
ulong n_redc_half(ulong x, ulong n, ulong nred)ulong n_redc_half_fast(ulong x, ulong n, ulong nred)The same with . The reductions require , and the ranges of inputs and outputs are those of the corresponding nmod_redc_half functions. n_to_redc_half_preinv ignores norm.
An unsigned two-word integer: __uint128_t when compiling for a 64-bit machine with a GCC-compatible compiler, and otherwise a struct of two words lo and hi. It exists for the Montgomery helpers above and may change.
Construct the two-word integer , and return the high or the low word of .
ull_t ull_u_mul_u(ulong x, ulong y)Return , and the full product of two words.
Generic rings#
These functions create gr contexts for . Those without redc in the name are declared in gr.h.
int gr_ctx_init_nmod(gr_ctx_t ctx, ulong n)int gr_ctx_init_nmod8(gr_ctx_t ctx, ulong n)int gr_ctx_init_nmod32(gr_ctx_t ctx, ulong n)int gr_ctx_init_nmod_redc(gr_ctx_t ctx, ulong n)int gr_ctx_init_nmod_redc_fast(gr_ctx_t ctx, ulong n)Initialise ctx for the ring in the given representation and return GR_SUCCESS. If , return GR_DOMAIN; if violates the restrictions of the representation, return GR_UNABLE. In both cases ctx is not initialised.
void _gr_ctx_init_nmod(gr_ctx_t ctx, void * nmod_t_ref)Initialises ctx like gr_ctx_init_nmod, copying the nmod_t that nmod_t_ref points to instead of recomputing it.
NMOD_CTX(ctx)NMOD_CTX_REF(ctx)The nmod_t stored in a context created by gr_ctx_init_nmod, and a pointer to it.
GR_NMOD_REDC_CTX(ctx)A pointer to the nmod_redc_ctx_struct stored in a context created by gr_ctx_init_nmod_redc or gr_ctx_init_nmod_redc_fast.
Low-level macros#
These macros are the building blocks of the arithmetic functions above and of the vector, polynomial and matrix modules. Most reduce two or three words modulo with one or two steps of Möller–Granlund division; NMOD_RED reduces one word by Barrett reduction. Unless stated otherwise, the first argument receives the result and mod is an nmod_t. A pair a_hi, a_lo stands for the two-word integer .
NMOD_RED(r, a, mod)Sets r to for any word and any . It uses one high and one low product (none if has FLINT_BITS bits), with a constant derived from mod.ninv (Barrett reduction with an nmod_t), and is cheaper than reducing as a two-word number with NMOD_RED2.
NMOD_RED2(r, a_hi, a_lo, mod)Sets r to . Requires .
NMOD2_RED2(r, a_hi, a_lo, mod)NMOD_RED3(r, a_hi, a_me, a_lo, mod)Sets r to . Requires .
NMOD_RED2_FULLWORD(r, a_hi, a_lo, mod)NMOD_RED2_NONFULLWORD(r, a_hi, a_lo, mod)Versions of NMOD_RED2 without the test on mod.norm. NMOD_RED2_FULLWORD requires mod.norm (the top bit of is set) and NMOD_RED2_NONFULLWORD requires mod.norm . Both require .
NMOD_MUL_PRENORM(res, a, b, mod)NMOD_MUL_FULLWORD(res, a, b, mod)Multiply without the operand shift done by nmod_mul. NMOD_MUL_PRENORM requires and with , that is, is a reduced value already shifted left by mod.norm bits, and sets res to the reduced residue ; nmod_mul(a, c, mod) is this macro applied to a and c << mod.norm. NMOD_MUL_FULLWORD requires mod.norm and reduced operands, and sets res to .
NMOD_CAN_USE_SHOUP(mod)Nonzero if , the condition for multiplication by a fixed operand with n_mulmod_shoup.
The FLINT team, “nmod.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/nmod/index.html (generated 2026-11-02).
@misc{flint-doc-nmod-index,
author = {{The FLINT team}},
title = {{nmod.h (module overview)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/nmod/index.html},
note = {Generated 2026-11-02}
}