-
Notifications
You must be signed in to change notification settings - Fork 831
Verify and fix the U256::mul_u64
method
#1496
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
Verify and fix the U256::mul_u64
method
#1496
Conversation
5530402
to
c1997a0
Compare
I think it'd be more useful if you also checked |
Oh, it found a bug, that's kinda cool! |
0edb0d5
to
56bec1a
Compare
Please ignore all the pushes, I was on the wrong branch. |
56bec1a
to
73993c6
Compare
U256::mul_u64
method
U256::mul_u64
methodU256::mul_u64
method
Force push is total re-write, PR description has been updated. |
cf0cb81
to
9dd9682
Compare
I don't rekon we should be running kani on every PR - it takes too long. |
Can I propose this implementation instead? It's very straight forward: fn mul_u64(self, rhs: u64) -> (U256, bool) {
let mut carry: u128 = 0;
let mut splitted_le = [self.1 as u64, (self.1 >> 64) as u64, self.0 as u64, (self.0 >> 64) as u64];
for word in &mut splitted_le {
// TODO: Use `carrying_mul` when stabilized: https://github.com/rust-lang/rust/issues/85532
let n = carry + (rhs as u128) * (*word as u128);
*word = n as u64;
carry = (n >> 64) as u128;
}
let low = splitted_le[0] as u128 | (splitted_le[1] as u128) << 64;
let high = splitted_le[2] as u128 | (splitted_le[3] as u128) << 64;
(Self(high, low), carry != 0)
} |
Yeah, @elichai's impl looks better, ACK that one but I want all non-truncated casts to be changed to use |
It can't overflow because 2 bitwise multiplications of |
I think you meant to say "2 bitwise multiplications of |
Right, I'm sorry, I'll try again:
Which means we can safely add another 2^b integer into the 2^{2b} multiplication result |
OK, I guess a comment linking to your very nice proof is even better then. :) Thanks! |
Doing a math degree does come in handy here and there 😜 |
0034749
to
fd35efd
Compare
Thanks @elichai, mad geek props to you! |
Needs #1508 to pass CI. |
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.
ACK
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.
ACK fd35efd796a1452eabad6417d08ff766a92e2e5f
(upper, lower) | ||
} | ||
let mut carry: u128 = 0; | ||
let mut split_le = [self.1 as u64, (self.1 >> 64) as u64, self.0 as u64, (self.0 >> 64) as u64]; |
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.
This is missing a comment about intentional truncation but maybe it's obvious enough from variable name.
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.
Yeah I tried using buf
as the name and adding a comment but I think its clean like it is.
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.
I find split_le
more clear than buf
.
fd35efd
to
b138218
Compare
Implemented |
I don't know why kani is failing here? |
4e677cb
to
0e372c6
Compare
Add kani verification for `U256::mul_u64`, doing so uncovered a bug in the current implementation due to overflow. Re-write the `mul_u64` method. Props to Elichai for the algorithm. Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
0e372c6
to
cf9733d
Compare
Not sure if that or it calls rustc directly. But they do document that they inject the crate. |
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.
ACK cf9733d
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.
ACK cf9733d
Add kani verification for
U256::mul_u64
, doing so uncovered a bug in the current implementation due to overflow. Re-write themul_u64
method.Fix: #1497
Note
This PR now only tests
mul_u64
, I will add testing div as a separate PR.