Add Miller-Rabin probable prime test

This can mark a number as either "probably prime", or "definitely
composite".  The first parameter is the base, and the second is the
number to test.

Future PRs will build up the Strong Lucas test which complements this,
and then form the Baillie-PSW test by composing the two.

Helps #506.
This commit is contained in:
Chip Hogg
2024-11-13 19:56:05 -05:00
parent e4bccad75c
commit cfd9ddb675
2 changed files with 63 additions and 0 deletions

View File

@ -104,4 +104,22 @@ static_assert(half_mod_odd(MAX_U64 - 2u, MAX_U64) == MAX_U64 - 1u);
static_assert(pow_mod(5u, 8u, 9u) == ((5u * 5u * 5u * 5u) * (5u * 5u * 5u * 5u)) % 9u);
static_assert(pow_mod(2u, 64u, MAX_U64) == 1u);
// Miller-Rabin primality testing.
static_assert(miller_rabin_probable_prime(2u, 5u));
static_assert(miller_rabin_probable_prime(2u, 7u));
static_assert(!miller_rabin_probable_prime(2u, 9u));
static_assert(miller_rabin_probable_prime(2u, 11u));
static_assert(miller_rabin_probable_prime(2u, 2047u), "Known base 2 pseudoprime");
static_assert(miller_rabin_probable_prime(2u, 3277u), "Known base 2 pseudoprime");
static_assert(miller_rabin_probable_prime(3u, 121u), "Known base 3 pseudoprime");
static_assert(miller_rabin_probable_prime(3u, 703u), "Known base 3 pseudoprime");
static_assert(miller_rabin_probable_prime(2u, 225'653'407'801u), "Large known prime");
static_assert(miller_rabin_probable_prime(2u, 334'524'384'739u), "Large known prime");
static_assert(miller_rabin_probable_prime(2u, 9'007'199'254'740'881u), "Large known prime");
static_assert(miller_rabin_probable_prime(2u, 18'446'744'073'709'551'557u), "Largest 64-bit prime");
} // namespace