-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Strong Lucas test and Baillie-PSW #323
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The [Baillie-PSW] is the star of the show: it's fully deterministic for all 64-bit integers, and there are no known counterexamples of any size. In order to reach it, we need to combine the existing Miller-Rabin test with a [Strong Lucas] test, the latter of which is the "hard work" part of this PR. The first step is to find the right value of the "D" parameter to use: the first from the sequence {5, -7, 9, -11, ...} whose Jacobi symbol (see parent PR) is -1. We represent this as an `uint64_t`-and-`bool` struct, rather than a simple `int`, for two reasons. First, it's easier to write this incrementing/alternating pattern with a separate sign. Second, when we use `D.mag` in calculations, it's convenient if it's already a `uint64_t` like almost all of the rest of our types. Oh --- and, this step won't work if `n` is a perfect square, so we add a separate guarding step to filter this situation out. Now for the meat of the calculation. We need to compute elements of the Lucas Sequences, $U_k$ and $V_k$ for certain specific indices. To do that efficiently, we use the fact that $U_1 = V_1 = 1$, and apply the index-doubling and index-incrementing relations: ![Equations for U and V](https://github.com/user-attachments/assets/8cfc1ec9-067e-4c8b-b855-9d86194f4296) The above are derived assuming the Lucas parameters $P=1$, $Q=(1-D)/4$, as is always done for the best-studied parameterization of Baillie-PSW. We use a bit-representation of the desired indices to decide when to double and when to increment, also commonly done (see the Implementation section in the [Strong Lucas] reference). Finally, we are able to combine the new Strong Lucas test with the existing Miller-Rabin test to obtain a working Baillie-PSW test. We use the same kinds of verification strategies for Strong Lucas and Baillie-PSW as we used for Miller-Rabin, except that we don't test pseudoprimes for Baillie-PSW because nobody has ever found any yet. Helps #217. [Baillie-PSW]: https://en.wikipedia.org/wiki/Baillie%E2%80%93PSW_primality_test [Strong Lucas]: https://en.wikipedia.org/wiki/Lucas_pseudoprime#Strong_Lucas_pseudoprimes
chiphogg
added
the
release notes: ♻️ lib (refactoring)
Under-the-hood changes to library structure
label
Nov 12, 2024
The old version worked fine, but it felt a little sketchy the way we were handling implicit conversion from a wrapped-around unsigned to a smaller signed type. (Note that if the signed type had been bigger, we would silently get the wrong answer!)
It's harder to reason about a negative. This code just reads better.
hoffbrinkle
reviewed
Nov 13, 2024
Co-authored-by: Michael Hordijk <[email protected]>
geoffviola
approved these changes
Nov 13, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool. Good work! 🎉
Co-authored-by: Geoffrey Viola <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The Baillie-PSW is the star of the show: it's fully deterministic for
all 64-bit integers, and there are no known counterexamples of any size.
In order to reach it, we need to combine the existing Miller-Rabin test
with a Strong Lucas test, the latter of which is the "hard work" part
of this PR.
The first step is to find the right value of the "D" parameter to use:
the first from the sequence {5, -7, 9, -11, ...} whose Jacobi symbol
(see parent PR) is -1. We represent this as an
uint64_t
-and-bool
struct, rather than a simple
int
, for two reasons. First, it's easierto write this incrementing/alternating pattern with a separate sign.
Second, when we use
D.mag
in calculations, it's convenient if it'salready a
uint64_t
like almost all of the rest of our types.Oh --- and, this step won't work if
n
is a perfect square, so we add aseparate guarding step to filter this situation out.
Now for the meat of the calculation. We need to compute elements of the$U_k$ and $V_k$ for certain specific indices. To do$U_1 = V_1 = 1$ , and apply the
Lucas Sequences,
that efficiently, we use the fact that
index-doubling and index-incrementing relations:
The above are derived assuming the Lucas parameters$P=1$ , $Q=(1-D)/4$ ,
as is always done for the best-studied parameterization of Baillie-PSW.
We use a bit-representation of the desired indices to decide when to
double and when to increment, also commonly done (see the Implementation
section in the Strong Lucas reference).
Finally, we are able to combine the new Strong Lucas test with the
existing Miller-Rabin test to obtain a working Baillie-PSW test.
We use the same kinds of verification strategies for Strong Lucas and
Baillie-PSW as we used for Miller-Rabin, except that we don't test
pseudoprimes for Baillie-PSW because nobody has ever found any yet.
Helps #217.