-
Notifications
You must be signed in to change notification settings - Fork 191
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
New releases of elliptic curve crates #119
Comments
I've got some problems in my library that uses Also, there is a bug in
I can make a separate PR for this, but I wanted to figure out the remaining problems first. |
Okay, sounds good. I'll try to wrap up what I'm working on and let you have at it. If there's no pressing reason not to, I might cut releases of the |
Another way to fix that bug would be to force normalization in I'll try to have something more definite today - I guess I'll just start advancing commits from the working versions and see when my code starts failing. Can't eyeball anything suspicious at the moment. |
Perhaps use |
That's what I did, the difficulty was that I had to bisect Anyway, the issue is in commit 29e98d6 . When you moved Is it supposed to work this way? I'll probably use the high-level An unrelated question about the API: why is |
@fjarri There's a few complications here. The first is to efficiently compute the "recovery ID" for public key recovery (i.e. without doing a brute force search), the signer implementation needs to know if https://github.com/RustCrypto/elliptic-curves/blob/93f7ff9/k256/src/ecdsa/signer.rs#L76 Another option to solve this particular problem would be to pass through something closer to a full "recovery ID" as part of the 2-tuple return value from The second complication is hardware ECDSA accelerators and using
I could have it return a new value, sure. Everything was previously non-mutating when I had a module-level |
Thanks, I see. I'm not too familiar with the specifics of ECDSA, so if that's the expected behavior, it's fine by me. After all, it is in
My vote would be for a pure function (for the scalar; I guess, mutating |
@fjarri sure, that's fine. Perhaps we should consider putting it in |
Created RustCrypto/signatures#119 and #122 |
Hm, @tarcieri , could you explain briefly how to use the new high-level ECSDA API in a generic way? Namely, if I have a |
@fjarri I originally instantiated The implementation in #108 is a newtype around the original generic type though, with added functionality (namely support for Ethereum-style recoverable signatures). You can still use it generically as (Also a type alias vs newtype seems somewhat irrelevant to generic usage, so I'm not sure what concrete problem you're having. |
I must have misunderstood the intention for |
This is really the only thing that changed...
It does all of this and none of that changed in #108. The changes in #108 added a newtype which added support for recoverable signatures. To do this, as I outlined above in this comment, I had to remove "pre-normalization" of signatures within Also as I described above, I think this is good for reasons beyond supporting recoverable signatures, namely RustCrypto/signatures#115 made it possible to generically support low-S normalization, and I think that'd be great for signers. We could move low-S normalization into the All that said, aside from moving |
That's true. What I was hoping for is to ditch my whole implementation based on low-level traits from
Now I'm looking at |
The main reason the But that extension is just a newtype wrapper for ...but also, The alternative to a newtype would be making a special tl;dr:
|
That is exactly the problem. Using the generic To be more specific, the following compiles but fails the assertion:
|
@fjarri as I explained in this post, it's possible to normalize in the
It's a tricky set of concerns to square... but also note that just doing that would break using a secp256k1 So I guess we could normalize in both places? That would address your concerns for receiving low-S normalized signatures through the generic API, and my concerns about receiving them through a hardware accelerator which doesn't perform the normalization (which isn't just an academic concern: I'm targeting a device with an ECDSA accelerator which doesn't low-S normalize signatures, I'd like to use it, and such accelerators not low-S normalizing signatures is pretty much par for the course with all such devices). I'm thinking it might make sense to just have |
The way I understand it is that there is an implied contract in the high-level API (what's signed by Now, I admit, I currently have a very vague idea of what hardware acceleration involves. Is there a function that gets called? At what level and how do you substitute it? Can it just be wrapped to perform the normalization in software? If it is just a Secp256k1 thing, would it make sense to have a |
The problem is low-S normalization is a secp256k1-specific concern, and beyond that, a cryptocurrency-specific concern. Low-S normalization is specifically a concern of ECDSA/secp256k1 when following BIP 0062 rules, which were introduced in 2014 and target a cryptocurrency vertical (they were originally Bitcoin-specific, but have gained more widespread adoption in other cryptocurrencies). There are several implementations of ECDSA/secp256k1, including pretty much all of them in non-cryptowallet hardware, but also several in software, which will both produce and verify secp256k1 signatures without low-S normalization applied. I hope this makes it clear how this is a very specific complication which introduces rules beyond what the typical ECDSA standards require, which is difficult to work into a generic-across-curves ECDSA implementation. I think it's good to make sure a secp256k1 library is cryptocurrency-friendly, but I am a bit wary to let these concerns leak out into cross-curve abstractions.
EDIT: I take this back, there's a gross hack that will probably work here, which would be introspecting whatever generic property of the curve used to select the curve to pass the peripheral (e.g. the OID) at runtime, getting a generic signature type out of the peripheral, and if the e.g. OID is for secp256k1, parsing it as a secp256k1 signature (i.e. Another option would be adding some sort of curve-specific parsing logic for the signature type which would low-S normalize all secp256k1 signatures at the time they're parsed. All that said, I think having the |
Another option is to introduce traits specifically for consensus-critical signing applications which have different rules from the "regular" rules (e.g. This has also been discussed in the context of ZIP-215 rules for Ed25519 verification. |
I feel like we're going in circles and not understanding one another. I realize that normalization is a specific
Do you have some public code with an example of usage of such hardware accelerator? I honestly don't understand what problems might arise. We will have either a conditional compilation in In the end of the day, as a user, I expect the library to handle these issues internally. Today I find out that The high-level API should be hard, ideally impossible to misuse. If I absolutely can't use a |
Let me put it this way. To my knowledge, there is no implementation of ECDSA/secp256k1, in hardware or software form, that presently does both of these things simultaneously:
Perhaps there's one I haven't encountered yet, but otherwise I feel like squaring these concerns simultaneously does not exist in other implementations, or is at best exceedingly rare. I agree we should try to find a solution that produces a low-S normalized signature from We can add yet another trait specific to hardware accelerators, but these concerns also potentially apply to things like ASM implementations, so a "hardware accelerator trait" isn't necessarily the best solution to this particular problem (but that said, might be generally useful, particularly one which takes Another option is for |
I think this change makes it possible to apply normalization generically, by moving the full recoverable signature construction into the What form generic normalization would take is still up for debate, though. |
Well, someone has to be the first, right? I am not sure I understand at the moment how your solution will be reflected in specific implementations, but if it makes As an alternative solution, would it be such a big problem to simply always do the normalization in the |
That's what I was proposing here with The basic idea is consensus critical applications may want different rules from the typical rules: stricter signature construction rules, but also validation rules which are well-defined and universally agreed upon. |
@fjarri any other showstopper issues you can think of that need to be addressed prior to a release? |
I would love to have some kind of a |
Cool, yeah that sounds like something to work on next. I'd also like to make it possible for |
They're out: |
I'd like to cut releases of the following crates relatively soon (next few days / week):
elliptic-curve
v0.5.0ecdsa
v0.7.0k256
v0.4.0p256
v0.4.0p384
v0.3.0These will be the first releases supporting an integrated ECDSA implementation as well as initial (and rather rudimentary) support for implementing algorithms generically over elliptic curve groups.
If there's anything else you'd like to get into these releases, let me know, otherwise I plan on doing it soon.
When I say that, I'm also looking for small items rather than more significant changes. There's plenty of bigger issues to address (e.g. eliminating fallible APIs via eliminating the invalid representations that cause them in
PublicKey
/SecretKey
) but I'd rather not make any bigger items release blockers at this point and we can continue making large and breaking changes in the next release.cc @str4d @tuxxy @fjarri @nickray
The text was updated successfully, but these errors were encountered: