Nat-level Montgomery reduction with radix R = 2^64.
7.5. Montgomery reduction
Montgomery reduction is the alternative single-word reducer used when
many modular multiplications share one odd modulus. It works in the
Montgomery domain (residues scaled by R), where reduction becomes a
multiply-add-shift with no trial division at all. As with Barrett, a
Nat-level model states the computation before the machine-word
encoding.
The model is proved to compute the reduced residue exactly and to land
below the modulus, given the precomputed inverse word p' and an odd
modulus below the radix.
montgomeryReduceNat_eq_mod {p p' T : Nat} (hp_pos : 0 < p) (hp_lt : p < UInt64.word) (hpp' : p * p' % UInt64.word = UInt64.word - 1) (hT : T < p * UInt64.word) : montgomeryReduceNat p p' T * UInt64.word % p = T % pmontgomeryReduceNat_eq_mod {p p' T : Nat} (hp_pos : 0 < p) (hp_lt : p < UInt64.word) (hpp' : p * p' % UInt64.word = UInt64.word - 1) (hT : T < p * UInt64.word) : montgomeryReduceNat p p' T * UInt64.word % p = T % p
Montgomery reduction computes a residue congruent to T * R⁻¹ modulo p.
montgomeryReduceNat_lt {p p' T : Nat} (hp_pos : 0 < p) (hp_lt : p < UInt64.word) (hpp' : p * p' % UInt64.word = UInt64.word - 1) (hT : T < p * UInt64.word) : montgomeryReduceNat p p' T < pmontgomeryReduceNat_lt {p p' T : Nat} (hp_pos : 0 < p) (hp_lt : p < UInt64.word) (hpp' : p * p' % UInt64.word = UInt64.word - 1) (hT : T < p * UInt64.word) : montgomeryReduceNat p p' T < p
Montgomery reduction lands in the canonical residue interval [0, p).
The executable side carries the machine-word Montgomery parameters in
a MontCtx. montgomeryReduce consumes a two-word product (Thi, Tlo)
and returns one reduced residue, proved to match the Nat model and to
stay canonical.
Runtime Montgomery context for an odd UInt64 modulus.
Constructor
MontCtx.mkCtx
Fields
p_odd : p % 2 = 1
The modulus is odd.
p' : UInt64
The Montgomery inverse word, satisfying p' · p ≡ -1 (mod R).
p'_eq : self.p'.toNat * p.toNat % UInt64.word = UInt64.word - 1
The inverse field satisfies p' · p ≡ R - 1 (mod R).
r2 : UInt64
The constant R² mod p, used to convert a residue into Montgomery form.
r2_eq : self.r2.toNat = UInt64.word * UInt64.word % p.toNat
The r2 field is exactly R² mod p.
Executable Montgomery reduction (classically REDC) from a two-word product
(Thi, Tlo) encoded in base 2^64.
toNat_montgomeryReduce {p : UInt64} (ctx : MontCtx p) (Thi Tlo : UInt64) (hT : Tlo.toNat + Thi.toNat * UInt64.word < p.toNat * UInt64.word) : (montgomeryReduce ctx Thi Tlo).toNat = montgomeryReduceNat p.toNat ctx.p'.toNat (Tlo.toNat + Thi.toNat * UInt64.word)toNat_montgomeryReduce {p : UInt64} (ctx : MontCtx p) (Thi Tlo : UInt64) (hT : Tlo.toNat + Thi.toNat * UInt64.word < p.toNat * UInt64.word) : (montgomeryReduce ctx Thi Tlo).toNat = montgomeryReduceNat p.toNat ctx.p'.toNat (Tlo.toNat + Thi.toNat * UInt64.word)
The executable REDC routine agrees with the Nat-level specification.
montgomeryReduce_lt {p : UInt64} (ctx : MontCtx p) (Thi Tlo : UInt64) (hT : Tlo.toNat + Thi.toNat * UInt64.word < p.toNat * UInt64.word) : montgomeryReduce ctx Thi Tlo < pmontgomeryReduce_lt {p : UInt64} (ctx : MontCtx p) (Thi Tlo : UInt64) (hT : Tlo.toNat + Thi.toNat * UInt64.word < p.toNat * UInt64.word) : montgomeryReduce ctx Thi Tlo < p
Executable REDC returns a canonical residue below the modulus.