Purpose: Perform modular multiplication without any division, replacing % with shifts and multiplications. Typically 2-3Γ faster than % when the modulus is fixed and you do millions of multiplications β the standard speedup inside NTT, Miller-Rabin and Pollardβs rho.
The Idea
Fix an odd modulus and a radix (in code, or , so division by is a free shift).
Work in the Montgomery domain: represent by .
The reduction REDC(T) computes for :
where . The numerator is divisible by by construction, so the division is exact and free. If , subtract once.
Then , so a domain multiplication is one REDC.
Code
struct Montgomery {
uint64_t n, ninv, r2; // ninv = -n^{-1} mod 2^64
Montgomery(uint64_t mod) : n(mod) {
ninv = 1;
for (int i = 0; i < 6; i++) ninv *= 2 - n * ninv; // Newton, doubles bits
ninv = -ninv;
r2 = (__uint128_t(-(unsigned long long)n)) % n; // R^2 mod n
}
uint64_t reduce(__uint128_t t) const {
uint64_t m = (uint64_t)t * ninv;
uint64_t res = (t + (__uint128_t)m * n) >> 64;
return res >= n ? res - n : res;
}
uint64_t to(uint64_t a) const { return reduce((__uint128_t)a * r2); }
uint64_t from(uint64_t a) const { return reduce(a); }
uint64_t mul(uint64_t a, uint64_t b) const { return reduce((__uint128_t)a * b); }
};The Newton iteration ninv *= 2 - n * ninv doubles the number of correct bits each round, so six rounds suffice for 64 bits starting from 1 correct bit.
Complexity
- One
REDC: two 64Γ64β128 multiplications plus a shift and a conditional subtract; no division - Conversion in and out costs one
REDCeach β only worth it if you do many operations in the domain
Why It Works
, and was chosen precisely so that . Hence is an integer congruent to . Bounding: and , so , meaning at most one conditional subtraction restores the range. β
Addition and subtraction are unchanged by the representation (), so only multiplication needs the reduction. Comparison and equality also work directly, since the map is a bijection.
Odd modulus only
must be odd for to exist. For even moduli, split with CRT or use Barrett reduction instead.
Variants / Use Cases
- Barrett reduction β works for even moduli and needs no domain conversion; slightly slower per operation but simpler to drop in
- NTT β the inner butterfly is a modmul; Montgomery is the standard optimisation
- Miller-Rabin and Pollardβs rho on 64-bit inputs
- RSA / ECC β Montgomery is why modular exponentiation is fast in every crypto library
- Modular Arithmetic β the topic page