Skip to content
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

Add utilities for modular arithmetic #320

Merged
merged 4 commits into from
Nov 8, 2024
Merged

Add utilities for modular arithmetic #320

merged 4 commits into from
Nov 8, 2024

Conversation

chiphogg
Copy link
Contributor

@chiphogg chiphogg commented Nov 8, 2024

These utilities all operate on unsigned 64-bit integers. The main
design goal is to produce correct answers for all inputs while avoiding
overflow.

Most operations are standard: addition, subtraction, multiplication,
powers. The one non-standard one is "half_mod_odd". This operation is
(x/2) % n, but only if n is odd. If x is also odd, we add n
before dividing by 2, which gives us an integer result. We'll need this
operation for the strong Lucas probable prime checking later on.

These are Au-internal functions, so we use unchecked preconditions: as
long as the caller makes sure the inputs are already reduced-mod-n,
we'll keep them that way.

Helps #217.

These utilities all operate on unsigned 64-bit integers.  The main
design goal is to produce correct answers for all inputs while avoiding
overflow.

Most operations are standard: addition, subtraction, multiplication,
powers.  The one non-standard one is "half_mod_odd".  This operation is
`(x/2) % n`, but only if `n` is odd.  If `x` is also odd, we add `n`
before dividing by 2, which gives us an integer result.  We'll need this
operation for the strong Lucas probable prime checking later on.

These are Au-internal functions, so we use unchecked preconditions: as
long as the caller makes sure the inputs are already reduced-mod-n,
we'll keep them that way.

Helps #217.
@chiphogg chiphogg added the release notes: ♻️ lib (refactoring) Under-the-hood changes to library structure label Nov 8, 2024
@chiphogg chiphogg requested a review from geoffviola November 8, 2024 02:40
@chiphogg chiphogg requested a review from geoffviola November 8, 2024 16:46
The new test would fail without this change!
Copy link
Contributor

@geoffviola geoffviola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation looks good. Tests look good. Thanks for the comments.

//
// Precondition: (a < n).
// Precondition: (n is odd).
constexpr uint64_t half_mod_odd(uint64_t a, uint64_t n) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we document this a little more? If a < n, then a / 2 < n. So (a / 2) % n would just be a.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

//
// Precondition: (a < n).
// Precondition: (b < n).
constexpr uint64_t mul_mod(uint64_t a, uint64_t b, uint64_t n) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation seems right. It gets the right answer for the JUST_UNDER_HALF, 10u, MAX case as opposed to https://www.geeksforgeeks.org/how-to-avoid-overflow-in-modular-multiplication/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Geeksforgeeks has such terrible quality control. I also stumbled on this supposed Baillie-PSW implementation, which is very clearly only the Miller-Rabin step! (Not to mention: their modPow implementation runs in O(exp) rather than O(log(exp)). Bring a pillow!)

@chiphogg chiphogg merged commit 35f151d into main Nov 8, 2024
13 checks passed
@chiphogg chiphogg deleted the chiphogg/mod#217 branch November 8, 2024 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release notes: ♻️ lib (refactoring) Under-the-hood changes to library structure
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants