-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
crypto/ecdsa: generate RFC 6979 signatures if rand is nil #64802
Comments
Unfortunately, for RFC 6979 we need to instantiate HMAC with the hash that was used to hash the message. In Sign and SignASN1, we don't have this information, only in PrivateKey.Sign. We could implement this only for PrivateKey.Sign, or take a pragmatic route and map hash lengths to SHA-256/SHA-512 in SignASN1. (We'd document that, and still do the right thing in PrivateKey.Sign.) Another wrinkle is that opts is currently ignored in PrivateKey.Sign, so we need to be prepared for current applications setting it wrong. |
Change https://go.dev/cl/552215 mentions this issue: |
Ok, since we can't do this properly in Sign and SignASN1, I propose
|
Actually, the top level functions might be worth rethinking in a v2 anyway, especially if we adopt some standard hedged signature scheme such as draft-irtf-cfrg-det-sigs-with-noise, maybe while doing FIPS work. What I'm proposing here then is just that when the rand parameter to Deterministic signatures are enough of an uncommon use case that it's ok if they are not super easy to access. |
Based on the discussion above, this proposal seems like a likely accept. The proposal is that ecdsa.PrivateKey.Sign start accepting rand==nil and in that case return a deterministic RFC 6979 signature. There is no new API, only the redefinition of that failure mode. A new GODEBUG setting will control the behavior. GODEBUG=ecdsarfc6979=1 (the new default for go 1.23+ main modules) means enable these deterministic signatures when rand==nil; GODEBUG=ecdsarfc6979=0 means don’t. |
Given rand==nil currently panics, do we need the GODEBUG? I can't imagine an application relying on a panic here. |
No change in consensus, so accepted. 🎉 The proposal is that ecdsa.PrivateKey.Sign start accepting rand==nil and in that case return a deterministic RFC 6979 signature. There is no new API, only the redefinition of that failure mode. A new GODEBUG setting will control the behavior. GODEBUG=ecdsarfc6979=1 (the new default for go 1.23+ main modules) means enable these deterministic signatures when rand==nil; GODEBUG=ecdsarfc6979=0 means don’t. |
@rsc Was this #64802 (comment) addressed? Is there a need for this GODEBUG? |
The previous behavior here ( |
Since we missed Go 1.23, let's land this at the start of Go 1.24 and wait for feedback before adding the GODEBUG. We will have the whole cycle for someone to point out a convoluted sequence that makes this a breaking change. |
Sounds good, will target early Go 1.24 for this. (I chose not to land it in Go 1.23 because it turned out to be a larger change than expected, touching very delicate parts of the code, and I didn't feel like we had enough review bandwidth or brewing time to do it safely.) |
This issue is currently labeled as early-in-cycle for Go 1.24. |
Change https://go.dev/cl/628681 mentions this issue: |
@FiloSottile Does this change need to covered in Go 1.24 release notes? |
crypto/ecdsa currently generates "hedged" signatures, by drawing the random nonce from an AES-CTR CSPRNG keyed by
SHA2-512(priv.D || entropy || hash)[:32]
. This is great, as it provides the best of both worlds: fault injection tolerance and RNG failure resistance.However, sometimes you do need deterministic signatures, not because they are more secure (as hedged signatures are even better) but because you actually need the signature not to change over time. I propose that when the
rand
parameter is nil (which currently panics), we produce RFC 6979 deterministic signatures.Morevoer, Section 3.6 of RFC 6979 specifies how to add additional data to the RNG input, so we can replace our AES-CTR construction with that. The advantage of this would be that although the RFC doesn't have test vectors for this variant, we can generate some and share them with other implementations.
(The CFRG has a forever-stalled draft on "deterministic with noise" ECDSA signatures, draft-irtf-cfrg-det-sigs-with-noise, but it's unclear to me why we'd want that instead of the existing RFC 6979 mechanism.)
The properties of signatures generated by current applications wouldn't change: they would still be hendged, randomized, and unpredictable (because we use MaybeReadByte, so we can change the internals, yay!).
/cc @golang/security
The text was updated successfully, but these errors were encountered: