FermatPrimalityTest (Fermat primality test v1.0.0)
A probabilistic primality test implementation based on Fermat's Little Theorem.
Overview
This module implements the Fermat primality test, a probabilistic algorithm for determining whether a given number is likely to be prime. The test is based on Fermat's Little Theorem, which states that if $p$ is a prime number and $a$ is any integer not divisible by $p$, then:
$$ a^{p-1} \equiv 1 \pmod{p} $$
Algorithm
For a given number $n$:
- If $n = 1$, return
false
(1 is not prime) - If $n = 2$, return
true
(2 is prime) - For numbers $n > 2$:
- Generate 100 random bases $a$ where $1 < a < n$
- For each base, check if $\gcd(a, n) = 1$ (coprime)
- If coprime, compute $a^{n-1} \bmod n$
- If the result is not 1, $n$ is definitely composite
- If all 100 tests pass, $n$ is probably prime
Mathematical Foundation
The test relies on the contrapositive of Fermat's Little Theorem: if there exists an $a$ coprime to $n$ such that $a^{n-1} \not\equiv 1 \pmod{n}$, then $n$ is composite.
However, the converse is not always true. There exist composite numbers called Fermat pseudoprimes that pass the test for some bases. Carmichael numbers are composite numbers that pass the test for all bases coprime to them.
Accuracy
- True positives: All prime numbers will pass the test
- False positives: Some composite numbers (pseudoprimes) may pass the test
- False negatives: None (if the test says composite, it's definitely composite)
The probability of a false positive decreases with the number of bases tested. With 100 random bases, the probability of a false positive is extremely low for most practical purposes.
Performance
The algorithm uses efficient modular exponentiation with $O(\log n)$ complexity for each base test. The overall complexity is $O(k \log n)$ where $k$ is the number of bases tested (100 in this implementation).
Examples
iex> FermatPrimalityTest.of(2)
true
iex> FermatPrimalityTest.of(3)
true
iex> FermatPrimalityTest.of(4)
false
iex> FermatPrimalityTest.of(17)
true
iex> FermatPrimalityTest.of(100)
false
Limitations
- This is a probabilistic test, not deterministic
- Very large numbers may have higher false positive rates
- For cryptographic applications, consider using deterministic tests like AKS
- The test may be slow for very large numbers due to modular exponentiation
References
- Fermat's Little Theorem
- Modular Exponentiation
- Probabilistic Primality Testing
Summary
Functions
Calculates modular exponentiation using the square-and-multiply algorithm.
Tests whether a number is prime using the Fermat primality test.
Functions
@spec mod_pow(non_neg_integer(), non_neg_integer(), non_neg_integer()) :: non_neg_integer()
Calculates modular exponentiation using the square-and-multiply algorithm.
This function efficiently computes $base^{exp} \bmod mod$ using the binary exponentiation method, also known as the square-and-multiply algorithm.
Mathematical Background
The algorithm works by expressing the exponent in binary and using the identity: $a^{2k} = (a^k)^2$ and $a^{2k+1} = a \cdot (a^k)^2$
This reduces the number of multiplications from $O(exp)$ to $O(\log exp)$.
Parameters
base
- The base numberexp
- The exponent (must be non-negative)mod
- The modulus
Returns
The result of $base^{exp} \bmod mod$
Examples
iex> FermatPrimalityTest.mod_pow(10, 2, 3)
1
iex> FermatPrimalityTest.mod_pow(7, 3, 5)
3
iex> FermatPrimalityTest.mod_pow(2, 10, 1000)
24
iex> FermatPrimalityTest.mod_pow(5, 0, 7)
1
Algorithm
- If $exp = 0$, return 1
- If $exp < 0$, raise ArithmeticError
- Use square-and-multiply algorithm:
- Initialize result = 1
- For each bit in the binary representation of exp:
- Square the current result: $result = result^2 \bmod mod$
- If the bit is 1, multiply by base: $result = result \cdot base \bmod mod$
Time Complexity
$O(\log exp)$ - logarithmic in the exponent.
Space Complexity
$O(1)$ - constant space usage.
Raises
ArithmeticError
when the exponent is negative
@spec of(pos_integer()) :: boolean()
Tests whether a number is prime using the Fermat primality test.
This function implements a probabilistic primality test based on Fermat's Little Theorem. It tests the number against 100 random bases to determine primality.
Parameters
n
- The integer to test for primality
Returns
true
if the number is probably primefalse
if the number is definitely composite
Examples
iex> FermatPrimalityTest.of(1)
false
iex> FermatPrimalityTest.of(2)
true
iex> FermatPrimalityTest.of(3)
true
iex> FermatPrimalityTest.of(4)
false
iex> FermatPrimalityTest.of(17)
true
iex> FermatPrimalityTest.of(100)
false
Algorithm Details
- Edge cases: 1 returns
false
, 2 returnstrue
- Random base generation: Creates 100 random bases $a$ where $1 < a < n$
- Coprimality check: Ensures $\gcd(a, n) = 1$ using Lehmer's GCD algorithm
- Fermat test: Computes $a^{n-1} \bmod n$ using efficient modular exponentiation
- Decision: If any test fails, returns
false
; if all pass, returnstrue
Time Complexity
$O(k \log n)$ where $k = 100$ (number of bases) and $n$ is the input number.
Space Complexity
$O(1)$ - constant space usage regardless of input size.