-
Notifications
You must be signed in to change notification settings - Fork 0
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
Remove slip10-like derivation and add stark-specific derivation #14
Conversation
Signed-off-by: Denis Varlakov <[email protected]>
Signed-off-by: Denis Varlakov <[email protected]>
Signed-off-by: Denis Varlakov <[email protected]>
Signed-off-by: Denis Varlakov <[email protected]>
Signed-off-by: Denis Varlakov <[email protected]>
Signed-off-by: Denis Varlakov <[email protected]>
Signed-off-by: Denis Varlakov <[email protected]>
Signed-off-by: Denis Varlakov <[email protected]>
order_minus_one + 1 | ||
}; | ||
let order_log2 = order.significant_bits(); | ||
let l: rug::Integer = rug::Rational::from((order_log2 + 128, 8)).ceil_ref().into(); |
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.
Why not (order_log2 + 128 + 7) / 8
?
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 wanted to explicitly use ceiling function to have less opportunities to mess up, and to match the formula from RFC precisely
for (lo, hi) in (1..).zip(0..) { | ||
let x_lo = rug::Rational::from((rug::Integer::ONE, rug::Integer::ONE << lo)); | ||
let x_hi = rug::Rational::from((rug::Integer::ONE, rug::Integer::ONE << hi)); | ||
if x_lo <= *x && *x <= x_hi { | ||
return (lo, hi); | ||
} | ||
} |
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.
You don't need two variables here: as soon as x_lo <= x you can take hi = lo - 1
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.
What you suggest is supposed to decrease amount of the code, but adding let hi = lo - 1
actually adds extra line of code
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.
(if I correctly understood what you suggested)
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.
No, I'm suggesting reducing the amount of computation done, not necessarily code. You remove hi in the loop, you remove x_hi altogether, and when the comparison succeeds, you compute hi = lo - 1
. By my calculations, the amount of lines of code will stay the same, but the lines will get shorter and we drop one comparison
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.
if
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.
In general no, but the loop finds not a general k
, but a minimal k such that
Reformulating imperatively, you're iterating lo <- [1, 2, ..]
, you compute x_lo = 1 / (1 << lo)
. You condition for breaking is x_lo <= x
. that means if you're evaluating the loop, you have x_lo' = 1 / (1 << (lo - 1))
and x_lo' > x
. Note that this x_lo' is exactly x_hi.
What it means is that you can skip comparing x_hi, and move computing x_hi altogether into the same branch as return.
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 get your view about not optimizing much for performance, since it's a piece of code ran rarely. But also when I first saw it, it took me some time to verify that hi
is indeed computed from k-1, so readability gain here is dubious
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.
Here's my logic: when I see in the output of the program that "stat diff lies in
hd-wallet/examples/curves_analysis.rs
Lines 126 to 130 in 158b65c
let x_lo = rug::Rational::from((rug::Integer::ONE, rug::Integer::ONE << lo)); | |
let x_hi = rug::Rational::from((rug::Integer::ONE, rug::Integer::ONE << hi)); | |
if x_lo <= *x && *x <= x_hi { | |
return (lo, hi); | |
} |
So that's very easy to audit and analyze. If we do what you suggested, in my opinion, it will be more difficult to analyze the function, as it's now required to understand how the loop works. As you said, in general, this approach does not yield correct result, but it does in this particular case, and it will take some time to come to the same conclusion.
In this case, I want to keep the option that looks correct right away,
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.
But also when I first saw it, it took me some time to verify that hi is indeed computed from k-1
How come? It's very clearly defined in the loop that lo
goes in 1..
while hi
goes in 0..
let i = generic_array::sequence::Concat::concat(i0, i1); | ||
let (shift, chain_code) = split(&i); |
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.
Wait, why is concatenation not done in the calling function? Does this optimize better?
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.
To have less of repeating code. Two different function are calling this one, if we were doing concat in the calling functions, we needed to write concat twice.
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.
But this way you leak implementation details! It's not a big problem since it's an internal function, but it looks like a bizzare choice to me to mangle the domains like this to save one (1) line
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.
Since it's an internal function, it's not leaking implementation detail
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 dunno, it feels like a natural choice for me...
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.
You know, other than your weird new obsession with saving single lines of code, the maths and the changes look good
I'm not obsessed with saving single lines of code, I'm lazy to change something unless I see a good motivation for that change :) |
when instantiated with certain curves, and may also enable attacker to perform DoS attack by
finding derivation path that results into very long computation