1-- Every residue coprime to n has a multiplicative inverse mod n: scaling the2-- residues below n by a is injective, so by counting it is onto, and some3-- residue is sent to one4-- Part of Cumulus, the Grace17 mathematics library.5-- Copyright (c) 2026 Grant Passmore.6-- Released under the Apache License 2.0. See LICENSE in the repository root.7-- Authors: Grant Passmore89module Grace.Cumulus.NumberTheory.ModularInverse10import CoprimeCancel11import Cardinal1213-- Multiplication by a on the residues below n.14defgraph scaleMod (a n : Nat) (x ∈ n) : n := mod(mul(a, x), n)15requires nonzero : n ≠016proof17have xNat := natural.member at n with member18have bound := mod.less at a * x, n with nonzero19exact membership.of_Less at (a * x) % n, n with*, *, bound2021theorem scaleMod.injective (a n : Nat)22requires nonzero : n ≠023requires coprime : gcd(a, n) =124shows InjectiveBetween(scaleMod(a, n), n, n)25proof26have function := scaleMod.function at a, n with nonzero27constructor28 . exact function29 . intros x hx y hy z hz hxz hyz30have xValue := FunctionBetween.apply_value with function, hx, hxz31have yValue := FunctionBetween.apply_value with function, hy, hyz32have xScaled := scaleMod.value at a, n, x with*33have yScaled := scaleMod.value at a, n, y with*34have xNat := natural.member at n with hx35have yNat := natural.member at n with hy36have same : (a * x) % n = (a * y) % n37rw [← xScaled, ← yScaled, xValue, yValue]38rfl39have residues := coprime.mul_cancel_mod with nonzero, coprime, same40have xBelow := Less.of_membership with hx41have yBelow := Less.of_membership with hy42have xSelf := mod.of_less with xBelow43have ySelf := mod.of_less with yBelow44 rwa [xSelf, ySelf] at residues4546theorem scaleMod.onto (a n : Nat)47requires nonzero : n ≠048requires coprime : gcd(a, n) =149shows functionImage(scaleMod(a, n), n, n) = n50proof51have injective := scaleMod.injective with nonzero, coprime52have finite := Finite.natural at n53have subset : functionImage(scaleMod(a, n), n, n) ⊆ n54intros y hy55have parts := functionImage.membership.forward with hy56exact parts.left57have reflexive : n ⊆ n58intros y hy59exact hy60have same := cardinality.injective_image with injective, reflexive, finite61exact cardinality.eq_subset with finite, subset, same6263theorem coprime.inverse (a n : Nat)64requires aboveOne : 1 < n65requires coprime : gcd(a, n) =166shows∃ b, Nat(b) ∧ b < n ∧ (a * b) % n =167proof68have nonzero : n ≠069intro zero70rw zero at aboveOne71have impossible : ¬(1:N) < 0byarith72exact impossible with aboveOne73have onto := scaleMod.onto with nonzero, coprime74have oneIn : (1:N) ∈ n byexact membership.of_Less at (1:N), n with*, *, aboveOne75rw← onto at oneIn76have parts := functionImage.membership.forward with oneIn77obtain⟨b, hb, equation⟩:= parts.right78have bNat := natural.member at n with hb79have value := scaleMod.value at a, n, b with*80witness b81constructor82 . exact Less.of_membership with hb83 . rw [value] at equation84 symm at equation85exact equation86