-
Couldn't load subscription status.
- Fork 70
Bring the overflow behavior in bit shifts in sync with std
#395
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
Conversation
|
I think these are reasonably OK things to bring in line with |
8c67ba9 to
7300c19
Compare
| let nlimbs = self.nlimbs(); | ||
| let mut limbs = vec![Limb::ZERO; nlimbs].into_boxed_slice(); | ||
|
|
||
| fn shl_vartime_into(&self, dest: &mut Self, shift: u32) -> Option<()> { |
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.
As a convention I'm a fan of putting this sort of output parameter on the end, at least as far as an output buffer which is simply written into otherwise uninitialized, though I will acknowledge that's inconsistent with *_assign APIs, which operate on &mut self (and might those be applicable here?)
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.
It's not exactly assign, since it writes in a new buffer. But I don't mind changing the argument order, it's a private method anyway.
The reason it's not assign is because I wanted to optimize the cache usage, and in some cases it's impossible to do the forward iteration inplace.
|
Running the benchmarks vs |
|
Yep, I bisected to that point too, seems to be the reason. |
4d15f1e to
f7a016e
Compare
6e5c878 to
f9813f5
Compare
f9813f5 to
1640e79
Compare
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.
Looks fine now aside from the commented out test
A part of #268
Fixes #121
const fnbit shifts forUintreturn the overflow status asCtChoice(and set the result to zero in that case, which is documented, so it's a part of the API now).Optionwould be better for the vartime shifts, but its methods are notconstyet in stable.shl/shrforBoxedUintreturn(Self, Choice)(notCtOptionsince most of its methods need the type to beConditionallySelectable, whichBoxedUintisn't). The vartime equivalents returnOption<Self>.uint/shl.rsandshr.rsmore uniform and improved vartime shift performance (before it was calling a constant-time shift-by-no-more-than-limb which added some overhead)BoxedUintby reducing the amount of allocationsBoxedUint::shl1()implementationLimbmethods which improved shift performance noticeablyUintshifts: we need to iterate to log2(BITS-1), not log2(BITS), because that's the maximum size of the shift.sh(r/l)1_with_overflow()tosh(r/l)1_with_carryto avoid confusion - in the context of shifts we call the shift being too large an overflow.