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.
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.
I think the easiest solution will be to use the cfg_if crate.
There was a problem hiding this comment.
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.
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.
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)