-
Notifications
You must be signed in to change notification settings - Fork 112
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
[WIP]Add dsa encryption and decryption algorithm #223
Conversation
Hi, thanks for opening this PR! As a few general points, it doesn't look like you added the When they do, it looks like there are some non-idiomatic things you're doing like CamelCase function names. You can either have CI check for them or install Also please set up a GitHub Actions workflow: you can do this by copying e.g. |
Thank you very much for your suggestions and responses, I have made changes according to your suggestions. But there is one conflict that has not been resolved. Your response is very detailed, I am very grateful, but I have been too busy recently, I will slowly complete the submission of this algorithm. Please give me time. |
Hi, I was working in rPGP and to get some compatibility tests working I decided to do a simple DSA implementation. It has become a little too large and I thought this functionality should probably live in its own crate, and then I found this PR. Even though we have worked on the same thing I think there is actually not that much duplicated. In particular my code implements signing with full RFC6979 (deterministic signatures) support, and uses the test vectors from that RFC (which also test the basic DSA functionality, of course). It uses the Of course the code style is different and it is missing some tricks like the fermat inverse, and it does not have key generation at all. It is written to be simple to understand. The code is here: https://github.com/rpgp/rpgp/pull/124/files If I can help you with anything, please let me know. I am not in a huge hurry and don't mind if you continue when you have time. |
Sorry, just saw your message. My work is too busy, I have not had time to finish this, I almost forgot. I am very sorry about this PR, I may need to work on other things recently. If you have any ideas to discuss, I will try to spare the time to complete it. |
Hi, no problem, and thanks for the quick response! If you expect to be busy for a long time I can probably continue work on this PR, I do not mind doing it. But as I said I do not mind waiting either, if you want to finish it yourself later. |
Welcome to participate in the encryption and decryption algorithm, you can complete this algorithm. |
@rvolgers if you have a mostly complete DSA implementation, it'd be great if you can upstream it, so long as you're okay with licensing the code under MIT+Apache2.0 which is SOP for all of the crates in this organization. Regarding RFC6979, as you noted the As for the |
I'm actually kind of happy to hear an external crate won't be used. This is just my professional paranoia, but due to the role of HMAC DRBG it is ideally suited for inserting subtle bugs which instantly leak the DSA private key during normal use of (EC)DSA and having precisely that crate live elsewhere makes me a little itchy. The HMAC DRBG code currently in ecdsa causes the test suite to fail if I use it though (the external crate works). It assumes that a single hash output block is sufficient to produce the requested output size, and this does not hold for the dsa 2048 + sha1 and dsa 2048 + sha2-224 testcases (i.e. big DSA key, small hash). So, this needs to be fixed, besides splitting the code to a separate crate. I'm definitely planning on upstreaming it, but I may work on the code a little more before transplanting it because I currently have it all hooked up nicely. Is there any "idiomatic" code I can reference for how error handling should look? And are there any standards at all with regard to trying to avoid allocations and secret-dependent timing differences in BigInt expressions, or is it fine if it just works? I expect those to be the main complications, once I have key generation working. |
Yeah, I have similar feelings, in addition to it being a blocker on upgrades
Aah, interesting. It is somewhat specialized to the ECDSA use case at the moment.
For cryptographic errors, we generally use unit structs as error types. The intent is to avoid things like sidechannel attacks based on an attacker's ability to differentiate various error cases.
We don't have any crates at the moment which use a more general-purpose bigint library and support It would definitely be nice to align the bigint implementation used by I feel like a |
Posting here because it's the best place for now. My work remains in the rPGP PR I linked earlier. Key generation is now fully implemented including two unit tests with official test vectors. Signing and validation were already finished and covered by tests using official test vectors. DSA supports quite a few hash algorithms for key generation and signing. The general approach in RustCrypto seems to be static dispatch for everything, but I'm worried about the effect on code size. Any thoughts on using dynamic dispatch to parameterize by hash function for DSA key generation and hashing? Or clever hybrid solutions? I'm currently at " Things that remain to be done:
|
We are currently working on a big breaking update to Also I don't think static dispatch of hash functions will bloat the final code too much. If anything it could reduce code size a bit, since compiler will be able to remove dead code more efficiently. |
What would be a good place to discuss this? |
You can simply open an issue in the traits repository with your thoughts and proposals. |
It is my understanding that because |
It would be problematic if you wanted to use the traits in the I'm curious to what extent you think there's excessive monomorphization overhead for using generics instead of trait objects for digests. I'm a big fan of trait objects, but to me it seems like such overhead would be a drop-in-the-bucket compared to the code for the hash functions themselves. Have you measured to determine if this is actually a problem in practice? All that said, if you do use
Unless I'm missing something, it sounds like you should refactor these functions to take a raw digest output, rather than making them generic over the hash function. |
This is not about hashing input data to be signed. In key generation the hash function needs to be invoked multiple times because it is used as a key expansion / entropy extraction mechanism, to produce keys in a deterministic way from a seed. It is similar for signing. The hash function is used with HMAC DBRG, which is seeded and used in a specific way defined by the standard to produce a deterministic value for k. |
Aah, RFC6979's usage of HMAC-DRBG is a concern, if you have an excessive number of hash functions. FWIW the Note that the ...but the flipside is |
Isn't heapless pretty much a dream for now anyway because the bigint implementation uses allocation? It's not just an implementation detail either, it would have to move to fixed size bigints to support heapless and this is a major change. Unless I'm missing something. I understand const generics makes a fixed size bigint implementation seem close, but it seems a little premature. |
Yeah, as I said for DSA I think a hard The |
As a temporary solution I think you can create an object-safe wrapper trait with only necessary functionality and pass to your functions
I plan to implement stack-based bigint library using |
That's very cool. Hope somebody does a similar library for modular arithmetic including Montgomery representation, I'd be happy to adjust the DSA code to be properly zero allocation and constant time -ish. |
@rvolgers I believe that code implements Montgomery representation (the code I believe it's based on did, anyway) |
This is actually part of the |
@rvolgers that sounds like something good to address before the next |
@rvolgers another way to avoid monomorphizing HMAC-DRBG over several hash functionsis to pick a single hash function to always use for RFC6979 (e.g. SHA-256) and instantiate HMAC-DRBG with that, regardless of what hash function is used for the message digest. That sort of approach would work with ECDSA at least, so I assume it would work with DSA unless there are specific RFC6979 test vectors you're trying to match which work otherwise. |
@tarcieri RFC6979 specifies that the hash for HMAC-DRBG should be the same as used for signing. I don't see any real security downside in always using SHA256, but it does mean taking on a bit more responsibility for the overall security picture (which I'm trying to avoid). We could also use only two of the test vectors from the RFC then. |
@rvolgers it suggests it but doesn't mandate it (although as it were, the From RFC 6979 Section 3.6:
|
@tarcieri ah, interesting. I'll give it some thought, but I still don't expect to take that direction though. |
FYI, we now own the |
Going to close this PR as stale. It'd be great to have a DSA implementation if anyone wants to pick it up again. Note that to use the |
The rough outline of the algorithm is now completed. There is also a lack of test files and detailed modifications. Rust is too difficult. If there is something wrong, please point it out.