Barrett and Lemire reduction
- Cost
- Barrett: one high and one low product and one conditional subtraction. Lemire: one low and one high product, no correction.
The methods of Barrett and of Lemire, Kaser and Kurz reduce a single word modulo , rather than a two-word product, using a precomputed approximation of . They are cheaper than a two-word Möller–Granlund reduction when the value to be reduced is known to fit in one word, as in hashing, sieving and table lookups. Throughout, .
Barrett reduction#
Barrett's method [Bar1987] estimates the quotient as follows.
Proposition 1. Let , and , and let . Then , so .
Proof. From we get
using . Taking floors gives the claim.
The value is at most , so it is computed exactly with word arithmetic even when . n_mod_barrett_lazy returns it, and n_mod_barrett subtracts once if needed. n_barrett_precomp computes with one division.
Barrett reduction with an nmod_t#
NMOD_RED reduces a word with the same kind of quotient estimate, but its constant comes from the nmod_t, so it needs no division and no extra field. Let be the number of bits of , that is and . The ninv field is the Möller–Granlund reciprocal of .
Lemma 2. Let . Then , and .
Proof. By definition , using for integers and . Hence . With , an integer satisfies if and only if , since is even; so this is . The bounds follow from .
Theorem 3. Let , , as in Lemma 2, and . Then , so .
Proof. Write with (Lemma 2). Then
and the subtracted term is in because , and . Taking floors gives the claim.
So NMOD_RED computes as the high word of shifted right by bits, subtracts (at most , so there is no overflow) and corrects once. This holds for every modulus , including powers of two and , and every word . The cost is one high product, one low product and one comparison, against a full product, a low product and two corrections for a Möller–Granlund step on the two-word number .
When has FLINT_BITS bits (mod.norm ), for every word , so NMOD_RED skips the product and only corrects once. The test on mod.norm is moved out of loops by the compiler, and the remaining loop of comparisons can then be trivially vectorized.
Shifting gives the constants of the same family for other input sizes: for . For instance gives , which is the constant of n_barrett_precomp unless is a power of two.
Lemire–Kaser–Kurz reduction#
The method of Lemire, Kaser and Kurz [LKK2019] computes the remainder directly from the fractional part of . With , the low word approximates , where denotes the fractional part; multiplying it by and keeping the high word gives . The approximation is exact when and are below , which is the condition required by n_mod_lemire. The method needs no correction step, but its range restriction makes it useful only for half-word values.
Referenced from#
- Division by an invariant word (algorithm)
- Modular multiplication with a multiword modulus (algorithm)
- Integer division and Newton iteration (algorithm)
- Dot products modulo a word-size integer (algorithm)
- Gaussian elimination and LU decomposition (algorithm)
- nmod.h (module)
NMOD_RED
References#
- [Bar1987] P. Barrett, "Implementing the Rivest Shamir and Adleman public key encryption algorithm on a standard digital signal processor", Advances in Cryptology – CRYPTO '86, LNCS 263 (1987), 311–323
- [LKK2019] D. Lemire, O. Kaser and N. Kurz, "Faster remainder by direct computation: applications to compilers and software libraries", Software: Practice and Experience 49 (2019), 953–970, https://arxiv.org/abs/1902.01961
The FLINT team, “Barrett and Lemire reduction,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/arithmetic/barrett.html (generated 2026-11-02).
@misc{flint-doc-algorithms-arithmetic-barrett,
author = {{The FLINT team}},
title = {{Barrett and Lemire reduction}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/algorithms/arithmetic/barrett.html},
note = {Generated 2026-11-02}
}