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

Binary XGCD #761

Draft
wants to merge 185 commits into
base: master
Choose a base branch
from
Draft

Binary XGCD #761

wants to merge 185 commits into from

Conversation

erik-3milabs
Copy link
Contributor

Continuation of the work started in #755

Comment on lines 87 to 91
/// **Warning**: this algorithm is only guaranteed to work for `self` and `rhs` for which the
/// msb is **not** set. May panic otherwise.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate a bit on where this restriction comes from and if it's a hard requirement or not? Skimming the example code for the paper doesn't seem to mention this.

It's a pretty limiting restriction; I think many applications will want to use full-fat uints with the MSB set.

Copy link
Contributor Author

@erik-3milabs erik-3milabs Mar 20, 2025

Choose a reason for hiding this comment

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

Can you elaborate a bit on where this restriction comes from and if it's a hard requirement or not? Skimming the example code for the paper doesn't seem to mention this.

It's a pretty limiting restriction; I think many applications will want to use full-fat uints with the MSB set.

I was encountering integer overflows whenever the top bit was set. However, in the past two days I learned a fact and a trick that we can use:

The trick

Currently, I'm using an Ints inside the matrix representing the xgcd state. However, I learned this interesting fact that the signs of this state matrix will always occur in one of the following two patterns:

[ + - ]       [ - + ]
[ - + ]   or  [ + - ]

Because of this, I can refactor this matrix to use Uints instead, as long as it also holds a pattern: ConstChoice. Then, the multiplication M3 = M1 x M2 is computed as a standard matrix multiplication and M3.pattern = M1.pattern.eq(M2.pattern).

This saves one bit in the representation and, as a result, should prevent overflows.

The fact.

This morning, I learned that if a does not divide b (or the other way around), then the Bézout coefficients x,y such that ax + by = gcd are such that $$|x| \leq \lfloor\frac{b}{2 * gcd}\rfloor$$ and $$|y| \leq \lfloor\frac{a}{2 * gcd}\rfloor$$.

These two things combined should give us ample bits to compute the Bézout coefficients without overflowing.

I hope to work on this soon!

Copy link
Contributor

Choose a reason for hiding this comment

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

That is good news! Thank you for explaining.

Can you point me to a source on “the fact”?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But of course! It is stated as fact on Extended GCD Wikipedia page, at the end of the Description section. Not the world's greatest source, but all my experiments point in the same direction 🙈

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dvdplm I rewrote parts of the code, allowing us to also compute the extended gcd for full-fat Uints. The refactor even resulted in a ~15% speedup!

(also for @tarcieri) While functional, I think the code is a touch ugly. Sadly, I don't have the time to work on this, probably for the next couple of weeks. I have aspirations to return to this and resolve these ugly points, but I cannot promise anything at this point. If the performance improvement is sufficiently attractive, I think (after your reviews) this can be merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants