Montgomery multiplication (REDC)
- Cost
- One full product, one low product and one high or full product per multiplication, plus one conditional correction (none in the lazy variants). Conversions cost one division step with a precomputed inverse.
Montgomery's method [Mon1985] replaces the division in by a division by a power of two, which is free. The price is that residues are kept in a scaled form, and that the modulus must be odd. FLINT implements it in nmod.h for full words () and half words (). A textbook treatment is in [BZ2011].
Throughout, , is odd, and is a power of two with .
Montgomery form#
The Montgomery form of is . Since is invertible modulo , this is a bijection, and
Addition and subtraction are therefore unchanged, and multiplication needs the map , called REDC. Conversion into Montgomery form costs one ordinary reduction of , and conversion back is one REDC of .
Reduction#
Let , which exists because is odd. FLINT stores it in the field nred of an nmod_redc_ctx_t and computes it with n_binvert.
Input: , and .
Output: .
- .
- .
- If , set . Return .
Theorem 1. In Algorithm 1 the division in step 2 is exact, , and before step 3. In particular, the result is correct for .
Proof. By the choice of , , so divides . Then , and multiplying by gives . Since , we have , which is the bound. If , then , so the single subtraction in step 3 brings into .
With and for reduced and , step 1 is a low product, is a full product, and the division by is taking the high word.
The subtractive variant#
n_ll_redc, used by nmod_redc_mul, works with instead of . This avoids the carry from the addition in step 2, which matters when is close to and does not fit in two words.
Input: as two words , and .
Output: .
- .
- (a high product).
- If , return ; otherwise return .
Theorem 2. Algorithm 2 is correct for every odd .
Proof. We have , so the low word of equals and exactly. Hence . Both and are in : the first because , the second because . So , and step 3 returns the representative in .
Every intermediate value fits in a word, so this works for all odd moduli up to . It is what the plain nmod_redc_ functions use.
Lazy reduction#
Skipping step 3 of Algorithm 1 saves a comparison and a conditional subtraction per multiplication, at the cost of an output in instead of . Such lazy residues can be fed back into the next multiplication if the modulus is small enough. This observation is due to Walter [Wal1999].
Theorem 3 (Lazy multiplication). Let and let . Then REDC of without step 3 returns with .
Proof. By Theorem 1, .
The fast functions use this with , so they require ; nmod_redc_can_use_fast tests exactly this. The condition is needed: for and close to , the output of nmod_redc_fast_mul can exceed , and the sum can overflow two words, so that the result is not even congruent to . The bound also keeps all intermediate values in range: , and for the lazy addition and subtraction modulo .
A lazy residue is turned into an ordinary one by subtracting once if needed (nmod_redc_fast_normalise). Comparing two lazy residues for equality requires normalising both first.
Half-word arithmetic#
With and , the product of two reduced operands fits in one word, and so does provided that . REDC then needs only single-word multiplications: step 1 is a product reduced modulo (a mask), step 2 a product, an addition and a shift.
- For (the
halffunctions) we need , which holds for . - For lazy (the
half_fastfunctions) we need by Theorem 3, so . Then also .
On 64-bit machines this limits the modulus to 31 or 30 bits. Whether the half-word version is faster depends on the processor; it saves the two-word arithmetic but not the number of multiplications.
Costs#
| Operation | Plain (n_mulmod2_preinv) | nmod_redc_mul | nmod_redc_fast_mul |
|---|---|---|---|
| Products | 2 full, 1 low | 1 full, 1 high, 1 low | 2 full, 1 low |
| Corrections | up to 2, and normalisation shifts | 1 | none |
| Allowed | any | odd | odd, |
The number of products is the same as with Möller–Granlund reduction, but Montgomery reduction needs no normalisation shifts and fewer corrections. This shortens the chain of dependent operations, which matters most in exponentiation and other long chains of dependent products. The conversions cost about one ordinary modular multiplication each, so Montgomery arithmetic pays off only when many operations are done between them.
Use in FLINT#
nmod_pow_uiswitches to Montgomery arithmetic for odd and exponents of at least , andnmod_2_pow_uifor exponents of at least . Both use the lazy variant when .n_is_primeperforms its strong probable prime tests for in Montgomery form, andn_factor_pollard_brent_singleiterates in Montgomery form.- The multimodular algorithms for Bell numbers (
arith_bell_number_multi_mod) and Euler numbers (inarb_euler_number_ui) use lazy Montgomery arithmetic modulo each prime. nmod_sqrtdoes all its arithmetic in Montgomery form, using thehalf_fast,fastor plain functions depending on the size of ._nmod_vec_scalar_mul_nmodusesnmod_redc_mulfor full-word odd moduli and vectors of length at least 8, where Shoup's method is not available.nmod_polycomputes Euclidean gcds and resultants of medium length in agr_ctx_init_nmod_redc_fastcontext when .
ulong nmod_redc_mul(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_half_mul(ulong x, ulong y, const nmod_redc_ctx_t ctx)Referenced from#
- Factoring word-size integers (overview)
- Square roots modulo a prime (algorithm)
- Stirling and Bell numbers (algorithm)
- Strong probable prime test (algorithm)
- Half-GCD (algorithm)
- Basic arithmetic modulo n
nmod_pow_ui,nmod_pow_fmpz- nmod.h (module)
- Using Montgomery arithmetic
- Square roots modulo a prime
- nmod_poly.h (module)
References#
- [Mon1985] P. L. Montgomery, "Modular multiplication without trial division", Mathematics of Computation 44 (1985), 519–521
- [BZ2011] R. P. Brent and P. Zimmermann, Modern Computer Arithmetic, Cambridge University Press (2011), http://www.loria.fr/~zimmerma/mca/pub226.html
- [Wal1999] C. D. Walter, "Montgomery exponentiation needs no final subtractions", Electronics Letters 35 (1999), 1831–1832, https://doi.org/10.1049/el:19991230
The FLINT team, “Montgomery multiplication (REDC),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/arithmetic/montgomery.html (generated 2026-11-02).
@misc{flint-doc-algorithms-arithmetic-montgomery,
author = {{The FLINT team}},
title = {{Montgomery multiplication (REDC)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/algorithms/arithmetic/montgomery.html},
note = {Generated 2026-11-02}
}