Intuition, Vocabulary and Foundations
Miller–Rabin tests whether an odd integer behaves like a prime under carefully chosen modular exponentiations. Think of each base as an independent checkpoint: a composite may imitate a prime at one checkpoint, but a suitable witness exposes the imitation.
For an odd candidate $n\gt2$, factor all powers of two from $n-1$ to obtain $n-1=2^s d$ with $d$ odd. For a base $a$, compute $x_0\equiv a^d\pmod n$ and repeatedly square, obtaining $x_r\equiv a^{2^r d}\pmod n$.
If $n$ is prime and $a\not\equiv0\pmod n$, Fermat’s theorem gives $a^{n-1}\equiv1\pmod n$. In a prime field, the only square roots of $1$ are $1$ and $-1$. A prime must therefore begin with $x_0=1$, begin with $x_0=-1$, or reach $-1$ before the final square reaches $1$.
A composite that violates this pattern is exposed by base $a$, called a witness. A composite that passes is a strong probable prime to that base. Passing arbitrary bases is usually probabilistic evidence; for unsigned 64-bit inputs, a proven finite base set covers the whole domain and makes the algorithm deterministic.
For every unsigned 64-bit candidate, the bases $2,325,9375,28178,450775,9780504,$ and $1795265022$ are deterministic when the strong-witness test and modular arithmetic are correct. This coverage claim is domain-specific and must not be extended silently to larger integers.
| Concept | Definition or invariant | Concrete example | Non-example or boundary | Question answered |
|---|---|---|---|---|
| Odd decomposition | $n-1=2^s d$ with odd $d$ | $21-1=2^2\cdot5$ | Leaving a factor of two in $d$ | Which exponent chain is tested? |
| Strong probable prime | Passes the strong test for one base | $2047$ passes base $2$ | One passing base is not a proof | Does the candidate imitate a prime for this base? |
| Witness | A base whose chain proves compositeness | Base $3$ exposes $2047$ | A passing base is not a witness | Which base certifies compositeness? |
| Nontrivial square root | $x^2\equiv1\pmod n$ with $x\not\equiv\pm1$ | Such a value proves compositeness | Prime moduli have only $\pm1$ | Why can an early return to $1$ reject? |
| Deterministic coverage | A base set proven sufficient over a bounded domain | Seven special bases cover unsigned 64-bit inputs | A few small bases do not cover all inputs | When does testing become a proof? |
| Modular exponentiation | Repeated squaring modulo $n$ | Computes $a^d\bmod n$ efficiently | Computing $a^d$ before reduction is impractical | How is the chain evaluated? |
| Tiny-value handling | Classify $n\lt4$ explicitly | $2,3$ are prime; $0,1$ are not | Entering the odd loop for $1$ | Which values bypass the main test? |
| Safe multiplication | Compute $ab\bmod n$ without overflow | Use a 128-bit intermediate | Wrapped 64-bit multiplication changes residues | Are modular powers correct? |
Step-by-Step Derivations and Algorithms
Reject values below $2$, accept small known primes, and reject even values. Trial division by a short list of small primes removes many composites and prevents a small prime from being rejected as divisible by itself.
For the remaining odd candidate, decompose $n-1=2^s d$. For each deterministic base, reduce it modulo $n$. If the result is zero, continue because that base supplies no contrary information.
Compute $x=a^d\bmod n$. If $x=1$ or $x=n-1$, the base passes. Otherwise square at most $s-1$ times. Reaching $n-1$ passes; reaching $1$ first exposes a nontrivial square root of $1$; and ending without $n-1$ makes the base a witness.
For a prime, the final chain value is $a^{2^s d}=a^{n-1}\equiv1\pmod n$. Moving backward, the preceding value must be a square root of $1$. If the chain did not start at $1$, its first transition into $1$ must come from $-1$. Failure to exhibit that pattern contradicts primality.
flowchart TD
A["Receive unsigned 64-bit n"] --> B{"n below 4?"}
B -->|Yes| C["Return whether n is 2 or 3"]
B -->|No| D{"Even or small-prime divisible?"}
D -->|Yes| E["Return composite unless equal to divisor"]
D -->|No| F["Write n minus 1 as 2^s times d"]
F --> G["Select next deterministic base"]
G --> H["Compute x = a^d mod n"]
H --> I{"x is 1 or n minus 1?"}
I -->|Yes| J{"More bases?"}
I -->|No| K["Repeatedly square x"]
K --> L{"Reached n minus 1?"}
L -->|Yes| J
L -->|No and chain ended| M["Return composite"]
J -->|Yes| G
J -->|No| N["Return prime"]
During witness testing, after $r$ squarings the invariant is $x\equiv a^{2^r d}\pmod n$. Each base uses $O(\log n)$ modular multiplications plus at most $O(\log n)$ squarings; with a constant seven-base set, deterministic 64-bit testing uses $O(\log n)$ modular multiplications and $O(1)$ auxiliary space.
Implementation, Complexity and Engineering
Python’s arbitrary-precision integers make multiplication safe, and three-argument pow performs modular exponentiation efficiently. In C or C++, an unsigned 128-bit intermediate is usual when available. Portable alternatives include add-and-double multiplication, Barrett reduction, or Montgomery reduction; wrapped 64-bit multiplication is invalid.
The implementation enforces the unsigned 64-bit domain, handles tiny and even values before decomposition, filters small primes, and uses the deterministic seven-base set. A trace helper exposes one witness chain for teaching and debugging.
| Engineering choice | Correctness domain | Cost | Failure mode | Mitigation |
|---|---|---|---|---|
| Seven deterministic bases | Unsigned 64-bit integers | Seven strong tests | Reusing the guarantee above $2^{64}-1$ | Enforce the domain at the API boundary |
| Small-prime filtering | Any integer candidate | Constant divisions | Rejecting a small prime as divisible by itself | Test equality before rejection |
| Built-in modular power | Language-dependent | $O(\log n)$ multiplications | Assuming overflow safety | Confirm documented modular semantics |
| 128-bit multiplication | Two 64-bit operands | Constant native operations | Platform lacks wider type | Select a portable reduction strategy |
| Add-and-double multiplication | Portable fixed-width arithmetic | $O(\log n)$ additions | Addition overflows before reduction | Use overflow-aware modular addition |
| Montgomery multiplication | Repeated operations with odd modulus | Efficient after setup | Incorrect representation conversion | Compare with a big-integer oracle |
| Random bases | Larger odd integers | Configurable rounds | Calling a probabilistic result deterministic | Report rounds and error model |
| Trial-division oracle | Small values | $O(\sqrt n)$ | Using it for full 64-bit production inputs | Restrict it to differential testing |
Applications, Case Studies and Exercises
A primality checker is often a gate inside factorization, key generation, hash-table sizing, or arithmetic software. Its production quality depends as much on domain enforcement and modular multiplication as on the witness rule.
Apply Miller-Rabin for 64-Bit Integers
Case study 1 — expose a base-2 pseudoprime. Trace $n=2047=23\cdot89$. Its decomposition is $2046=2\cdot1023$, and base $2$ gives $2^{1023}\equiv1\pmod{2047}$, so that base passes. Repeat with base $3$, which is a witness. Success means the full checker rejects $2047$ and the explanation distinguishes evidence from proof.
Case study 2 — harden a 64-bit service boundary. Test 0, 1, small primes, even values, Carmichael numbers, known strong pseudoprimes, the maximum domain value, and out-of-domain inputs. Include $341550071728321$, $3825123056546413051$, $2^{64}-1$, and the prime $18446744073709551557$. Success means every result matches a trusted big-integer oracle and invalid inputs are rejected.
Hands-on differential test. Compare Miller–Rabin with trial division for every value below $10^6$. Then generate seeded composites as products of random 32-bit factors and record which deterministic base first rejects each. Success means zero mismatches and evidence that no single small base catches every adversarial composite.
Tiered exercises. Recall: define witness and strong probable prime. Derive: explain why the first return to $1$ must come from $-1$ for a prime. Implement: write overflow-safe modular multiplication without a 128-bit type. Debug: replace the base set with $2,3,5$ and find a counterexample. Extend: create a separate probabilistic API for larger integers that reports rounds and correctness mode.
Use deterministic Miller–Rabin for unsigned 64-bit inputs with the proven seven-base set and verified overflow-safe arithmetic; use trial division only for tiny values or testing, and label larger-domain Miller–Rabin as probabilistic unless another bound-specific theorem applies. Never leave the base list, arithmetic backend, or domain assumption implicit.