FLINT3.7.0-dev
Algorithm

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 ab mod nab \bmod n 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 (R=2FLINT_BITSR = 2^{\mathtt{FLINT\_BITS}}) and half words (R=2FLINT_BITS/2R = 2^{\mathtt{FLINT\_BITS}/2}). A textbook treatment is in [BZ2011].

Throughout, B=2FLINT_BITSB = 2^{\mathtt{FLINT\_BITS}}, nn is odd, and RR is a power of two with n<R≤Bn < R \le B.

Montgomery form#

The Montgomery form of x∈Z/nZx \in \mathbb{Z}/n\mathbb{Z} is x~=xR mod n\tilde x = xR \bmod n. Since RR is invertible modulo nn, this is a bijection, and

x+y~=x~+y~ mod n,xy~=x~y~R−1 mod n.\widetilde{x + y} = \tilde x + \tilde y \bmod n, \qquad \widetilde{xy} = \tilde x \tilde y R^{-1} \bmod n.

Addition and subtraction are therefore unchanged, and multiplication needs the map T↦TR−1 mod nT \mapsto T R^{-1} \bmod n, called REDC. Conversion into Montgomery form costs one ordinary reduction of xRxR, and conversion back is one REDC of x~\tilde x.

Reduction#

Let n′=−n−1 mod Rn' = -n^{-1} \bmod R, which exists because nn is odd. FLINT stores it in the field nred of an nmod_redc_ctx_t and computes it with n_binvert.

Algorithm 1: REDC

Input: 0≤T<nR0 \le T < nR, and n′=−n−1 mod Rn' = -n^{-1} \bmod R.

Output: TR−1 mod nT R^{-1} \bmod n.

  1. m←(T mod R) n′ mod Rm \gets (T \bmod R)\, n' \bmod R.
  2. t←(T+mn)/Rt \gets (T + mn) / R.
  3. If t≥nt \ge n, set t←t−nt \gets t - n. Return tt.

Theorem 1. In Algorithm 1 the division in step 2 is exact, t≡TR−1(modn)t \equiv T R^{-1} \pmod n, and 0≤t<T/R+n0 \le t < T/R + n before step 3. In particular, the result is correct for T<nRT < nR.

Proof. By the choice of mm, mn≡−Tn−1n=−T(modR)mn \equiv -T n^{-1} n = -T \pmod R, so RR divides T+mnT + mn. Then tR=T+mn≡T(modn)tR = T + mn \equiv T \pmod n, and multiplying by R−1R^{-1} gives t≡TR−1t \equiv T R^{-1}. Since 0≤m≤R−10 \le m \le R - 1, we have 0≤tR<T+Rn0 \le tR < T + Rn, which is the bound. If T<nRT < nR, then t<2nt < 2n, so the single subtraction in step 3 brings tt into [0,n)[0, n).

With R=BR = B and T=abT = ab for reduced aa and bb, step 1 is a low product, mnmn is a full product, and the division by RR is taking the high word.

The subtractive variant#

n_ll_redc, used by nmod_redc_mul, works with n−1 mod R=−n′n^{-1} \bmod R = -n' instead of n′n'. This avoids the carry from the addition in step 2, which matters when nn is close to BB and T+mnT + mn does not fit in two words.

Algorithm 2: REDC with subtraction

Input: 0≤T<nB0 \le T < nB as two words T=T1B+T0T = T_1 B + T_0, and v=n−1 mod Bv = n^{-1} \bmod B.

Output: TB−1 mod nT B^{-1} \bmod n.

  1. m←T0v mod Bm \gets T_0 v \bmod B.
  2. h←⌊mn/B⌋h \gets \lfloor mn / B \rfloor (a high product).
  3. If T1<hT_1 < h, return T1−h+nT_1 - h + n; otherwise return T1−hT_1 - h.

Theorem 2. Algorithm 2 is correct for every odd n<Bn < B.

Proof. We have mn≡T0vn=T0(modB)mn \equiv T_0 v n = T_0 \pmod B, so the low word of mnmn equals T0T_0 and T−mn=(T1−h)BT - mn = (T_1 - h) B exactly. Hence T1−h≡TB−1(modn)T_1 - h \equiv T B^{-1} \pmod n. Both T1T_1 and hh are in [0,n)[0, n): the first because T<nBT < nB, the second because m<Bm < B. So T1−h∈(−n,n)T_1 - h \in (-n, n), and step 3 returns the representative in [0,n)[0, n).

Every intermediate value fits in a word, so this works for all odd moduli up to B−1B - 1. 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 [0,2n)[0, 2n) instead of [0,n)[0, n). 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 4n≤R4n \le R and let 0≤a,b<2n0 \le a, b < 2n. Then REDC of T=abT = ab without step 3 returns t≡abR−1(modn)t \equiv ab R^{-1} \pmod n with 0≤t<2n0 \le t < 2n.

Proof. By Theorem 1, t<T/R+n<4n2/R+n≤n+n=2nt < T/R + n < 4n^2/R + n \le n + n = 2n.

The fast functions use this with R=BR = B, so they require n<2FLINT_BITS−2n < 2^{\mathtt{FLINT\_BITS} - 2}; nmod_redc_can_use_fast tests exactly this. The condition is needed: for 2FLINT_BITS−2<n<2FLINT_BITS−12^{\mathtt{FLINT\_BITS} - 2} < n < 2^{\mathtt{FLINT\_BITS} - 1} and a,ba, b close to 2n2n, the output of nmod_redc_fast_mul can exceed 2n2n, and the sum T+mnT + mn can overflow two words, so that the result is not even congruent to abR−1ab R^{-1}. The bound also keeps all intermediate values in range: T+mn<4n2+Bn<B2T + mn < 4n^2 + Bn < B^2, and 2n<B2n < B for the lazy addition and subtraction modulo 2n2n.

A lazy residue is turned into an ordinary one by subtracting nn once if needed (nmod_redc_fast_normalise). Comparing two lazy residues for equality requires normalising both first.

Half-word arithmetic#

With R=2FLINT_BITS/2R = 2^{\mathtt{FLINT\_BITS}/2} and n<Rn < R, the product T=abT = ab of two reduced operands fits in one word, and so does T+mnT + mn provided that T+(R−1)n<BT + (R - 1) n < B. REDC then needs only single-word multiplications: step 1 is a product reduced modulo RR (a mask), step 2 a product, an addition and a shift.

  • For a,b<na, b < n (the half functions) we need n2+(R−1)n<Bn^2 + (R - 1)n < B, which holds for n<R/2=2FLINT_BITS/2−1n < R/2 = 2^{\mathtt{FLINT\_BITS}/2 - 1}.
  • For lazy a,b<2na, b < 2n (the half_fast functions) we need 4n≤R4n \le R by Theorem 3, so n<2FLINT_BITS/2−2n < 2^{\mathtt{FLINT\_BITS}/2 - 2}. Then also 4n2+Rn<B4n^2 + Rn < B.

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#

OperationPlain (n_mulmod2_preinv)nmod_redc_mulnmod_redc_fast_mul
Products2 full, 1 low1 full, 1 high, 1 low2 full, 1 low
Correctionsup to 2, and normalisation shifts1none
Allowed nnanyoddodd, n<2FLINT_BITS−2n < 2^{\mathtt{FLINT\_BITS} - 2}

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_ui switches to Montgomery arithmetic for odd nn and exponents of at least 2112^{11}, and nmod_2_pow_ui for exponents of at least 2202^{20}. Both use the lazy variant when n<2FLINT_BITS−2n < 2^{\mathtt{FLINT\_BITS} - 2}.
  • n_is_prime performs its strong probable prime tests for n≥232n \ge 2^{32} in Montgomery form, and n_factor_pollard_brent_single iterates x↦x2+cx \mapsto x^2 + c in Montgomery form.
  • The multimodular algorithms for Bell numbers (arith_bell_number_multi_mod) and Euler numbers (in arb_euler_number_ui) use lazy Montgomery arithmetic modulo each prime.
  • nmod_sqrt does all its arithmetic in Montgomery form, using the half_fast, fast or plain functions depending on the size of nn.
  • _nmod_vec_scalar_mul_nmod uses nmod_redc_mul for full-word odd moduli and vectors of length at least 8, where Shoup's method is not available.
  • nmod_poly computes Euclidean gcds and resultants of medium length in a gr_ctx_init_nmod_redc_fast context when 2FLINT_BITS/2−1≤n<2FLINT_BITS−22^{\mathtt{FLINT\_BITS}/2 - 1} \le n < 2^{\mathtt{FLINT\_BITS} - 2}.

Referenced from#

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
Cite this page

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