-
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/rsa: rsa.PrivateKey with json.Unmarshal and Go1.20 results in slow keys #59695
Comments
It seems like any of the obvious solutions involve satisfying the json.Unmarshaler interface, which will require adding a new API, and therefore needs to go through the proposal process. Unless @FiloSottile you had another idea? |
@rolandshoemaker How about atomic.Pointer? Is it fine to use it in crypto/rsa? |
What if |
We discussed this at the time with @rsc and found no good solution because any write, even by a sync.Once or sync/atomic, to PrivateKey could be detected by the race detector if it happened at the same time as a copy, which so far was allowed. The good news though is that https://go.dev/cl/632478 now mostly reuses the public precomputed values if they are available, so the penalty of missing the private result of Precompute is down to 7.5% of a signature.
(I am using ParsePKCS8PrivateKey as an indicative benchmark of "taking a PrivateKey with public precomputed values and filling out the rest".) I think this effectively resolves this issue. |
Change https://go.dev/cl/632478 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
If you create an
rsa.PrivateKey
, then calljson.Marshal
, then calljson.Unmarshal
, the resulting key "works" but is 3X slower for signing operations. The problem is that Go 1.20 added private fields torsa.PrecomputedValues
which do not get round-tripped. The resulting keys need to havekey.Precompute()
called to restore their performance. The following test fails on Go 1.20, but works on Go 1.19. The included benchmark demonstrates the performance problem.From Issue #59442 , it seems like we may want to preserve the existing behavior: #59442 (comment)
What did you expect to see?
The test should pass, and the benchmark should show the two cases have approximately the same performance, like on Go 1.19:
What did you see instead?
The test fails, showing that the round tripped key has nil fields:
The benchmark shows ~3X slower signing until calling
Precompute()
:The text was updated successfully, but these errors were encountered: