-
Notifications
You must be signed in to change notification settings - Fork 267
k256: add Scalar::from_bytes_reduced #76
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
Codecov Report
@@ Coverage Diff @@
## master #76 +/- ##
==========================================
- Coverage 55.91% 55.49% -0.43%
==========================================
Files 15 15
Lines 2897 2919 +22
==========================================
Hits 1620 1620
- Misses 1277 1299 +22
Continue to review full report at Codecov.
|
This method is intended for use when implementing ECDSA, namely for computing a `Scalar` from the hash of the message: https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Signature_generation_algorithm > Let 𝐳 be the 𝐋𝑛 leftmost bits of 𝑒, where 𝐋𝑛 is the bit length of the > group order 𝑛
69a618b to
cac82e2
Compare
| let w7 = u32::from_be_bytes(bytes[0..4].try_into().unwrap()); | ||
| let w6 = u32::from_be_bytes(bytes[4..8].try_into().unwrap()); | ||
| let w5 = u32::from_be_bytes(bytes[8..12].try_into().unwrap()); | ||
| let w4 = u32::from_be_bytes(bytes[12..16].try_into().unwrap()); | ||
| let w3 = u32::from_be_bytes(bytes[16..20].try_into().unwrap()); | ||
| let w2 = u32::from_be_bytes(bytes[20..24].try_into().unwrap()); | ||
| let w1 = u32::from_be_bytes(bytes[24..28].try_into().unwrap()); | ||
| let w0 = u32::from_be_bytes(bytes[28..32].try_into().unwrap()); | ||
| let w = [w0, w1, w2, w3, w4, w5, w6, w7]; |
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.
A bit off-topic, but what is the motivation for this level of explicitness vs. loops or iterator approaches in cryptographic code? When I try this kind of thing, I tend to always get at least one index wrong :)
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 actually copypasta from both the from_bytes method as well as the from_overflow method.
I'd agree it could be simplified and potentially composed in terms of from_overflow too.
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.
Perhaps some time after rust-lang/rust#74060 is merged this could be:
let w: [u32; 8] = bytes.chunks(4).map(|chunk| u32::from_be_bytes(chunk).try_into().unwrap()).collect();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.
AIUI, in some cases the p256 arithmetic uses "many variables" to allow functions to be const, not in this case though. I was wondering if the use for this was motivated by consistency and subjective preference, or some kind of cryptographic reason, would you know?
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.
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.
There is a minor performance benefit as compared to loops, but that can be negated by using an unrolling macro (there are several packages available for that). I have plans to do that, but just didn't get to it yet.
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.
Ah, loop unrolling. Thanks!
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 far as macros for loop unrolling go, I've seen unroll, but that said so far in my usage of godbolt to optimize cryptographic code I still haven't seen a case where unrolling a loop by hand generates more efficient assembly.
(not saying they don't exist, especially in this kind of code, but I've generally seen LLVM's optimizer do a good job of unrolling loops on its own)
|
I'm going to go with #78 instead |
|
Haha, and now poking at implementing ECDSA this seems nice, especially in conjunction with the |
This method is intended for use when implementing ECDSA, namely for computing a
Scalarfrom the hash of the message:https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Signature_generation_algorithm
See related discussion here: https://github.com/RustCrypto/elliptic-curves/pull/56/files#diff-c8893dd2f9cf0dff9549c297fc437664R160-R176
cc @fjarri @nickray