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
Not for merge: quick n' dirty ECDSA #57
Conversation
80abf8f
to
cae6c2e
Compare
Awesome! Thanks for submitting this.
The traits you really need for a cross-curve abstraction don't exist yet, so don't worry about it (see #22), however this is great food for thought about it. I would agree "secret key is scalar, public key is an affine point" is the right starting point. |
#[cfg(feature = "expose-arithmetic")] | ||
pub mod field; | ||
#[cfg(not(feature = "expose-arithmetic"))] | ||
mod field; | ||
#[cfg(feature = "expose-arithmetic")] | ||
pub mod scalar; | ||
#[cfg(not(feature = "expose-arithmetic"))] | ||
mod scalar; | ||
#[cfg(feature = "expose-arithmetic")] | ||
pub mod util; | ||
#[cfg(not(feature = "expose-arithmetic"))] | ||
mod util; |
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'd be nice to figure out a better solution for this sort of gating.
One option would be to make the arithmetic module mod arithmetic
(no pub
), and then re-export the types it contains at the toplevel when the arithmetic
feature is enabled.
Since doc_cfg
tags everything with the requisite cargo features, I don't think this would be confusing:
https://docs.rs/p256/0.3.0/p256/arithmetic/index.html
I might open a separate PR for discussion on that idea (skipping the expose-arithmetic
stuff for now)
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 think the easiest solution will be to use the cfg_if
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.
Yeah, that would work too.
For what it's worth I opened a PR with my suggested refactoring and I like it:
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.
Mmh, agreed. This is just a hack to allow use of the arithmetic in an experimental/hazmat manner outside the crate while core pieces are missing. I actually think the arithmetic should be public, but that's another topic - this PR is just to exemplify a possible ECDSA implementation.
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'm not sure how many abstractions are actually needed (looking at the p256 implementation here). The only thing I'm aware of that's tricky is the "left-most bits" thing, which for p256 is just "subtract modulus if necessary", but e.g. for p521 requires a right shift to chop off some low bits. |
Do you need me to do anything here? I think it might have a more uniform look n' feel to k256 if you make whatever adjustments you deem necessary (and I'm a little low on time/energy right now). It would be good though to have the masking scalar / vartime inversion option, as things are horribly slow otherwise on microcontrollers. |
@nickray I'm pretty much just going to open a new PR and copy over the implementation from the (we don't have an optimized |
I checked the speed of vartime inversion from this PR in |
A generic implementation would be great, as it would make it possible to move handling of the masking scalar out of It could go into the |
Relevant parts of this were incorporated into #84, which implements ECDSA/P-256 (low-level) signing and verification |
This builds on #56 by implementing a signing method on Scalar. It outsources entropy concerns and error handling to the caller. There are no deterministic signatures and there is no "additional randomness".
The masking scalar approach I believe goes back to PolarSSL (mbed TLS), although I have found no clear story about it. It is also used by kmackay/micro-ecc.
I did not find myself capable of understanding how existing traits are intended to be used, which is why I opted for this very direct approach: A secret key is a scalar, a public key is an affine point.
This is not for merge, rather as input to the discussion mentioned in #54 (comment)