Remainders modulo an available word #
The remainder of an m-bit number modulo a nonzero w-bit word d is computed by long
division, from the most significant bit: shift the current remainder, append the next bit, and
subtract d once if the result is at least d (streamRemainder). If 2 * d fits in w bits,
the shifted remainder never overflows, and the result is exact (toNat_streamRemainder). Each
bit costs one subtraction, one comparison and one selection, 22 * w + 3 gates, so the cost is
linear in the number of bits for a fixed modulus width (synthesis_streamRemainder). In
particular an m-bit number modulo a nonzero k-bit input modulus has a circuit of size
1 + m * (22 * (k + 1) + 3) (bounded_modulus_remainder).
Reducing both arguments this way gives a difference modulo d in O(w ^ 2) gates
(subMod, synthesis_subMod).
All gates of the native De Morgan basis, including constants, are charged; wiring and fanout are free.
Main definitions #
Cslib.Circuits.Boolean.Iteration.streamRemainder: long division, most significant bit first.Cslib.Circuits.Boolean.Iteration.subMod: modular difference of two words.
Main results #
Cslib.Circuits.Boolean.Iteration.toNat_streamRemainder: the remainder is exact.Cslib.Circuits.Boolean.Iteration.synthesis_streamRemainder: linear cost per bit.Cslib.Circuits.Boolean.Iteration.bounded_modulus_remainder: the circuit form.Cslib.Circuits.Boolean.Iteration.toNat_subMod,synthesis_subMod: modular differences.
References #
- Adapted from lean/Proofs/{StreamingRemainder,PhaseArithmetic}.lean in S. Schlesinger, Square-root circuit bounds for iterated functions. The source's modular difference reduces by a cubic shift-and-subtract division circuit (lean/Proofs/Division.lean); here both arguments are reduced by the streaming remainder.
Streaming remainders #
One step of long division: a subtraction, a comparison and a selection.
Streaming an available m-bit number through long division by an available word costs
22 * w + 3 gates per bit.
Bounded-modulus remainders. Some circuit of size at most 1 + m * (22 * (k + 1) + 3)
reads an m-bit number and then a k-bit modulus, both least significant bit first, and returns
the number modulo the modulus whenever the modulus is nonzero. The circuit is total; nothing is
claimed about its output for the zero modulus.
Modular differences #
a - b modulo d, from the remainders of a and b: their difference, plus d if it
would be negative.
Instances For
A modular difference of available words costs two streaming remainders and a constant
number of word operations: at most 50 * (w + 1) ^ 2 gates.