nmod.h – integers mod n (word-size n)¶
Generic rings¶
-
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)¶
Initialize the context object
ctxfor generic arithmetic in the ring \(R = \mathbb{Z} / n \mathbb{Z}\) for word-size \(n\) using the respective representation.The element datatype is
ulongfor all representations except fornmod8andnmod32where the type isuint8oruint32respectively.If the modulus is valid, returns
GR_SUCCESS. Otherwise, the context object is not initialized and an error code is returned:GR_DOMAINis returned if \(n = 0\).GR_UNABLEis returned if \(n\) does not satisfy the technical restrictions of a specific representation. For example,nmod8requires \(n \le 255\) andnmod_redcrequires that \(n\) is odd.
Note
Some generic algorithms need to check whether
\(R\) is a field, i.e. whether \(n\) is a prime number.
To avoid expensive on-the-fly primality tests, it is recommended
to call gr_ctx_set_is_field(ctx, T_TRUE) (if \(n\) is prime)
gr_ctx_set_is_field(ctx, T_FALSE) (if \(n\) is composite)
after constructing a context object.
This is not done automatically as it would slow down creating a context
object in the case where one is just interested in basic arithmetic.
Note
Presently, many operations for nmod8, nmod32, nmod_redc and
nmod_redc_fast are not as optimized as those for the general-purpose
nmod. It is currently recommended to use nmod8 and nmod32
only if one specifically wants to minimize memory usage.
Modular reduction and arithmetic¶
-
void nmod_init(nmod_t *mod, ulong n)¶
Initialises the given
nmod_tstructure for reduction modulo \(n\) with a precomputed inverse.
-
NMOD_BITS(mod)¶
Macro giving the number of bits in
mod.n.
-
NMOD_CAN_USE_SHOUP(mod)¶
Macro returning whether Shoup’s algorithm can be used for preconditioned multiplication mod
mod.n.
-
NMOD_RED2(r, a_hi, a_lo, mod)¶
Macro to set \(r\) to \(a\) reduced modulo
mod.n, where \(a\) consists of two limbs(a_hi, a_lo). Themodparameter must be a validnmod_tstructure. It is assumed thata_hiis already reduced modulomod.n.
-
NMOD_RED(r, a, mod)¶
Macro to set \(r\) to \(a\) reduced modulo
mod.n. Themodparameter must be a validnmod_tstructure.
-
NMOD2_RED2(r, a_hi, a_lo, mod)¶
Macro to set \(r\) to \(a\) reduced modulo
mod.n, where \(a\) consists of two limbs(a_hi, a_lo). Themodparameter must be a validnmod_tstructure. No assumptions are made abouta_hi.
-
NMOD_RED3(r, a_hi, a_me, a_lo, mod)¶
Macro to set \(r\) to \(a\) reduced modulo
mod.n, where \(a\) consists of three limbs(a_hi, a_me, a_lo). Themodparameter must be a validnmod_tstructure. It is assumed thata_hiis already reduced modulomod.n.
-
NMOD_MUL_PRENORM(res, a, b, mod)¶
Macro to set \(r\) to \(ab\) modulo
mod.n. Themodparameter must be a validnmod_tstructure. It is assumed that \(a\), \(b\) are already reduced modulomod.nand that either \(a\) or \(b\) is prenormalised by left-shifting bymod.norm.
-
NMOD_MUL_FULLWORD(res, a, b, mod)¶
Macro to set \(r\) to \(ab\) modulo
mod.n. Themodparameter must be a validnmod_tstructure. It is assumed that \(a\), \(b\) are already reduced modulomod.nand thatmod.nis exactlyFLINT_BITSbits large.
-
NMOD_ADDMUL(r, a, b, mod)¶
Macro to set \(r\) to \(r + ab\) reduced modulo
mod.n. Themodparameter must be a validnmod_tstructure. It is assumed that \(r\), \(a\), \(b\) are already reduced modulomod.n.
-
ulong _nmod_add(ulong a, ulong b, nmod_t mod)¶
Returns \(a + b\) modulo
mod.n. It is assumed thatmodis no more thanFLINT_BITS - 1bits. It is assumed that \(a\) and \(b\) are already reduced modulomod.n.
-
ulong nmod_add(ulong a, ulong b, nmod_t mod)¶
Returns \(a + b\) modulo
mod.n. No assumptions are made aboutmod.n. It is assumed that \(a\) and \(b\) are already reduced modulomod.n.
-
ulong nmod_ui_add_ui(ulong a, ulong b, nmod_t mod)¶
Returns \(a + b\) modulo
mod.n. Does not require that \(a\) and \(b\) are already reduced modulomod.n.
-
ulong _nmod_sub(ulong a, ulong b, nmod_t mod)¶
Returns \(a - b\) modulo
mod.n. It is assumed thatmodis no more thanFLINT_BITS - 1bits. It is assumed that \(a\) and \(b\) are already reduced modulomod.n.
-
ulong nmod_sub(ulong a, ulong b, nmod_t mod)¶
Returns \(a - b\) modulo
mod.n. No assumptions are made aboutmod.n. It is assumed that \(a\) and \(b\) are already reduced modulomod.n.
-
ulong nmod_neg(ulong a, nmod_t mod)¶
Returns \(-a\) modulo
mod.n. It is assumed that \(a\) is already reduced modulomod.n, but no assumptions are made about the latter.
-
ulong nmod_mul(ulong a, ulong b, nmod_t mod)¶
Returns \(ab\) modulo
mod.n. No assumptions are made aboutmod.n. It is assumed that \(a\) and \(b\) are already reduced modulomod.n.
-
ulong _nmod_mul_fullword(ulong a, ulong b, nmod_t mod)¶
Returns \(ab\) modulo
mod.n. Requires thatmod.nis exactlyFLINT_BITSlarge. It is assumed that \(a\) and \(b\) are already reduced modulomod.n.
-
ulong nmod_ui_mul_ui(ulong a, ulong b, nmod_t mod)¶
Returns \(ab\) modulo
mod.n. Does not require that \(a\) and \(b\) are already reduced modulomod.n.
-
ulong nmod_inv(ulong a, nmod_t mod)¶
Returns \(a^{-1}\) modulo
mod.n. The inverse is assumed to exist.
-
ulong nmod_div(ulong a, ulong b, nmod_t mod)¶
Returns \(ab^{-1}\) modulo
mod.n. The inverse of \(b\) is assumed to exist. It is assumed that \(a\) is already reduced modulomod.n.
-
int nmod_divides(ulong *a, ulong b, ulong c, nmod_t mod)¶
If \(a\cdot c = b \mod n\) has a solution for \(a\) return \(1\) and set \(a\) to such a solution. Otherwise return \(0\) and leave \(a\) undefined.
-
ulong nmod_pow_ui(ulong a, ulong e, nmod_t mod)¶
Returns \(a^e\) modulo
mod.n. No assumptions are made aboutmod.n. It is assumed that \(a\) is already reduced modulomod.n.
-
ulong nmod_pow_fmpz(ulong a, const fmpz_t e, nmod_t mod)¶
Returns \(a^e\) modulo
mod.n. No assumptions are made aboutmod.n. It is assumed that \(a\) is already reduced modulomod.nand that \(e\) is not negative.
Montgomery arithmetic¶
Let \(n\) be an odd integer smaller than the machine word modulus \(R = 2^{32}\) or \(R = 2^{64}\). The Montgomery representation of an integer \(x\) is the residue \(x R \bmod n\). We can use Montgomery representations for doing arithmetic in \(\mathbb{Z} / n \mathbb{Z}\), following the rules
The advantage of using the Montgomery representation instead of the standard representation \(x \bmod n\) is that it allows for faster multiplication. Montgomery arithmetic is also known as REDC arithmetic.
By default moduli up to the full word size are allowed and residues are strictly canonicalised to \([0, n)\). We provide sets of alternative methods for restricted moduli which, depending on the machine, can speed up arithmetic:
The
half(andhalf_fast) methods work with half-length \(R\), avoiding the need for double-word operations in the internal arithmetic. They are not necessarily faster than the non-halfversions. Mixinghalfand non-halfmethods and context objects is not allowed.The
fast(andhalf_fast) accept non-canonical residues in \([0, 2n)\) and return non-canonical residues in \([0, 2n)\). The user must convert back to the canonical range \([0, n)\) before using any non-fastfunctions. Thefastmethods are generally faster than the non-fastmethods.
The restrictions are summarized in the following table, assuming a 64-bit word size:
Prefix |
Maximum \(n\) |
\(R\) |
Canonicalisation |
|---|---|---|---|
|
\(2^{64} - 1\) |
\(2^{64}\) |
\([0, n)\) |
|
\(2^{62} - 1\) |
\(2^{64}\) |
\([0, 2n)\) |
|
\(2^{31} - 1\) |
\(2^{32}\) |
\([0, n)\) |
|
\(2^{30} - 1\) |
\(2^{32}\) |
\([0, 2n)\) |
For 32-bit machines, the maximum \(n\) become \(2^{32} - 1\), \(2^{30} - 1\), \(2^{15} - 1\), and \(2^{14} - 1\) respectively.
-
type nmod_redc_ctx_struct¶
-
type nmod_redc_ctx_t¶
A context object for Montgomery arithmetic. This holds the same content as an
nmod_tcontext, plus the precomputed constant \(-1/n\) modulo \(R\).
-
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)¶
Initialize
ctxfor Montgomery arithmetic modulo the given modulus \(n\) which is required to be odd.
-
ulong nmod_redc_set_nmod(ulong x, const nmod_redc_ctx_t ctx)¶
Convert \(x\) from the standard representation to Montgomery representation. If \(x\) is viewed a residue in the standard representation, this returns \(x R \bmod n\).
-
ulong nmod_redc_set_ui(ulong x, const nmod_redc_ctx_t ctx)¶
Convert \(x\) which is not necessarily reduced modulo \(n\) to Montgomery representation.
-
ulong nmod_redc_get_nmod(ulong x, const nmod_redc_ctx_t ctx)¶
Convert \(x\) back from Montgomery representation to standard representation. If \(x\) is viewed as a residue in the standard representation, this returns \(x / R \bmod n\). This function allows \(x \in [0, 2n)\).
-
ulong nmod_redc_neg(ulong x, ulong y, 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)¶
Arithmetic in the Montgomery representation.
-
int nmod_redc_can_use_fast(const nmod_redc_ctx_t ctx)¶
Return whether the modulus is small enough to safely use fast operations.
-
ulong nmod_redc_fast_normalise(ulong x, const nmod_redc_ctx_t ctx)¶
Convert a non-canonical residue in \([0, 2n)\) to a canonical residue in \([0, n)\).
-
ulong nmod_redc_fast_neg(ulong x, ulong y, 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)¶
-
ulong nmod_redc_fast_mul_two(ulong x, const nmod_redc_ctx_t ctx)¶
Arithmetic in Montgomery representation, using non-canonical residues.
-
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 \(a^{exp}\). The exponent is required to be positive.
-
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 \(2^{exp}\). There are no restrictions on the exponent.
-
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)¶
Initialize context for use with
halforhalf_fastmethods.
-
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)¶
-
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)¶
-
int nmod_redc_half_can_use_fast(const nmod_redc_ctx_t ctx)¶
-
ulong nmod_redc_half_fast_mul(ulong x, ulong y, const nmod_redc_ctx_t ctx)¶
-
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)¶
Methods analogous to their non-
halfcounterparts.
Discrete Logarithms via Pohlig-Hellman¶
-
void nmod_discrete_log_pohlig_hellman_init(nmod_discrete_log_pohlig_hellman_t L)¶
Initialize
L. Upon initializationLis not ready for computation.
-
void nmod_discrete_log_pohlig_hellman_clear(nmod_discrete_log_pohlig_hellman_t L)¶
Free any space used by
L.
-
double nmod_discrete_log_pohlig_hellman_precompute_prime(nmod_discrete_log_pohlig_hellman_t L, ulong p)¶
Configure
Lfor discrete logarithms modulopto an internally chosen base. It is assumed thatpis prime. The return is an estimate on the number of multiplications needed for one run.