{"id":13992879,"url":"https://github.com/hanwenzhu/primality-tests","last_synced_at":"2025-04-22T14:27:00.286Z","repository":{"id":213044914,"uuid":"732880315","full_name":"hanwenzhu/primality-tests","owner":"hanwenzhu","description":"Miller–Rabin primality test in Lean","archived":false,"fork":false,"pushed_at":"2023-12-30T01:25:36.000Z","size":65,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-16T14:51:42.295Z","etag":null,"topics":["lean","lean4","primality-test","theorem-proving"],"latest_commit_sha":null,"homepage":"","language":"Lean","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hanwenzhu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-18T04:21:08.000Z","updated_at":"2024-05-31T22:01:21.000Z","dependencies_parsed_at":"2024-11-30T02:47:27.829Z","dependency_job_id":null,"html_url":"https://github.com/hanwenzhu/primality-tests","commit_stats":null,"previous_names":["hanwenzhu/primality-tests"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hanwenzhu%2Fprimality-tests","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hanwenzhu%2Fprimality-tests/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hanwenzhu%2Fprimality-tests/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hanwenzhu%2Fprimality-tests/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hanwenzhu","download_url":"https://codeload.github.com/hanwenzhu/primality-tests/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250257836,"owners_count":21400807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lean","lean4","primality-test","theorem-proving"],"created_at":"2024-08-09T14:02:09.950Z","updated_at":"2025-04-22T14:27:00.268Z","avatar_url":"https://github.com/hanwenzhu.png","language":"Lean","funding_links":[],"categories":["Lean"],"sub_categories":[],"readme":"# Primality tests in Lean\n\n## Main definitions\n\nFast modular exponentiation\n```lean\n/-- Fast modular exponentiation, tail recursive -/\ndef pow {n : ℕ} (x : ZMod n) (m : ℕ) : ZMod n\n\ntheorem pow_eq {n : ℕ} (x : ZMod n) (m : ℕ) :\n  x.pow m = x ^ m\n```\n\nFermat probable primality\n```lean\n/-- `n` is a *Fermat probable prime* to base `a` if `a ^ (n - 1) = 1`. -/\ndef FPP (n : ℕ) (a : ZMod n) : Prop :=\n  a ^ (n - 1) = 1\n\ninstance FPP.decidable {n : ℕ} {a : ZMod n} :\n  Decidable (FPP n a)\n\n/-- A prime is a Fermat probable prime to any nonzero base. -/\ntheorem FPP.of_prime {p : ℕ} [Fact p.Prime] {a : ZMod p} (ha : a ≠ 0) :\n  FPP p a\n\ndef FPP.Carmichael (n : ℕ) : Prop :=\n  ∀ a : (ZMod n)ˣ, FPP n a\n```\n\nStrong probable primality\n```lean\n/-- `n` is a *strong probable prime* to base `a`, if `a ^ d = 1` or `∃ s \u003c s', a ^ (2 ^ s * d) = -1`\nwhere `d` is odd and `n - 1 = 2 ^ s' * d`. -/\ndef SPP (n : ℕ) (a : ZMod n) : Prop :=\n  a ^ oddPart (n - 1) = 1 ∨\n  ∃ s : ℕ, s \u003c val₂ (n - 1) ∧ a ^ (2 ^ s * oddPart (n - 1)) = -1\n\n/-- The algorithm that decides `SPP` in $O(\\log^3 n)$. -/\ninstance SPP.decidable {n : ℕ} {a : ZMod n} :\n  Decidable (SPP n a)\n\n/-- A prime is a strong probable prime to any nonzero base. -/\ntheorem SPP.of_prime {p : ℕ} [Fact p.Prime] {a : ZMod p} (ha : a ≠ 0) :\n  SPP p a\n\n/-- The proportion of Miller–Rabin nonwitnesses of composite `n` is at most 1/4. -/\ntheorem SPP.card_SPP_of_not_prime {n : ℕ} [hn : n.AtLeastTwo] (ho : Odd n) (hnp : ¬n.Prime) :\n  Fintype.card {a // SPP n a} * 4 ≤ n - 1\n```\n\nMiller–Rabin\n```lean\n/-- The *Miller–Rabin* primality test on input `n`, run `r` times. -/\ndef millerRabin {gen : Type*} [RandomGen gen] (g : gen) (n r : ℕ) :\n  Bool × gen\n\ndef runMillerRabin (n r : ℕ) : IO Bool\n```\n\n## Possible extensions\n\n1. Show `millerRabin` has probability of correctness aribitrarily close to `1` when `r` large enough and the random generator `g` is uniform and independent enough\n2. Verify Pratt, ECPP, Pocklington certificates (useful for proofs actually needing a particular large prime)\n3. More primality tests: Euler/Euler–Jacobi, (strong) Lucas, Baillie–PSW, AKS\n4. Format, docstrings, simplify / abstract lemmas from some long proofs\n\n## References\n1. https://kconrad.math.uconn.edu/blurbs/ugradnumthy/carmichaelkorselt.pdf\n2. https://kconrad.math.uconn.edu/blurbs/ugradnumthy/millerrabin.pdf\n3. https://math.stackexchange.com/questions/487011/showing-that-a-homomorphism-between-groups-of-units-is-surjective\n4. Of course, mathlib\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhanwenzhu%2Fprimality-tests","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhanwenzhu%2Fprimality-tests","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhanwenzhu%2Fprimality-tests/lists"}