Commit Graph

13 Commits

Author SHA1 Message Date
Chip Hogg
de68b3a9f1 Replace old factoring with Baillie-PSW 2024-11-15 13:30:05 -05:00
Chip Hogg
3b586a685f Implement Baillie-PSW 2024-11-15 13:30:05 -05:00
Chip Hogg
9e8dfec265 Add the Strong Lucas Probable Prime test
This is more involved than the Miller-Rabin test, but we can tame the
complexity by breaking it down into helper functions, performing tasks
such as:

- Increment the index of the (U_k, V_k) sequence elements by one.
- Double the index of the (U_k, V_k) sequence elements.
- Find an appropriate D parameter.

etc.

With these helpers, the algorithm becomes straightforward (see, for
instance,
https://en.wikipedia.org/wiki/Lucas_pseudoprime#Strong_Lucas_pseudoprimes).
We start by ruling out perfect squares (because if we don't, then the
search for `D` will never terminate).  Then we find our `D`, and
decompose `n + 1` into `s` and `d` parameters (exactly as we did for
Miller-Rabin, except there we used `n - 1`).  At this point, the strong
test is easy: check whether `U_d` is 0, then check `V_d`, as well as `V`
for all successive doublings of the index less than `s`.

A similar testing strategy as for the Miller Rabin gives us sufficient
confidence.

1. Test that we get small primes right.
2. Test that we get known pseudoprimes "correctly wrong".
3. Test some really big primes.

(Remember, a probable prime test must mark every actual prime as
"probably prime".)

Helps #509.
2024-11-15 10:53:26 -05:00
Chip Hogg
26639dab34 Add some more 2024-11-15 09:39:39 -05:00
Chip Hogg
d56ffc08b8 Add utilities to make Strong Lucas tests easier
The Strong Lucas test coming in the next PR will already be complicated
enough.  It'll be convenient, and less distracting, if we already have
functions for certain operations we'll need.

One thing we'll need to do is detect inputs that are perfect squares.
Fortunately, this is pretty easy to do robustly and quickly, with
Newton's method.  We _don't_ want to use `std::sqrt`, because that takes
us into the floating point domain for no good reason, which could give
us wrong answers for larger integers.

The other thing we need is Jacobi symbols.  These are a lot more
obscure, but thankfully, still resonably straightforward to compute.
The Wikipedia page (https://en.wikipedia.org/wiki/Jacobi_symbol) has a
good explanation, and in particular, good instructions for computing
values.

With these utilities in place, the Strong Lucas code should be easier to
review.
2024-11-14 20:14:20 -05:00
Chip Hogg
cfd9ddb675 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.
2024-11-13 19:56:05 -05:00
Chip Hogg
8a7483f7ea Add helpers for modular arithmetic
The prime-testing techniques we will use (Miller-Rabin, Strong Lucas)
all make heavy usage of modular arithmetic.  Therefore, we lay those
foundations here, adding utilities to perform the basic arithmetic
operations robustly.

Since these are internal-only helper functions, we don't bother checking
the preconditions, although we state them clearly in the contract
comment for each utility.  After C++26, we could add contracts for
these.

Helps #509.
2024-11-11 12:55:41 -05:00
Mateusz Pusz
b870b85c25 feat: import std; support added
Resolves #595
2024-07-16 17:36:00 +02:00
Mateusz Pusz
f49b4c6f5f refactor: compile-time optimizations reverted 2024-06-14 13:37:56 +02:00
Mateusz Pusz
e38c7c4460 refactor: magnitudes support refactored to improve compile-times 2024-06-06 20:58:15 +02:00
Mateusz Pusz
c066104af7 refactor: 💥 framework.h introduced + IWYU 2024-04-24 21:09:29 +02:00
Mateusz Pusz
5ca9168381 feat: proper exports implemented for C++ modules 2024-02-23 21:09:17 +01:00
Mateusz Pusz
0eaf6e2e56 refactor: modules support redesigned 2024-01-06 08:51:01 +01:00