-
Notifications
You must be signed in to change notification settings - Fork 39
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
ecdsa public key format uncompressed vs compressed #1234
Comments
@kwantam do you have an opinion if ecdsa apis that output public keys should do so uncompressed or compressed? Any insight if this is okay as is or concerns we might not be considering? |
@leighmcculloch your summary of the tradeoffs here is on target. A few random thoughts:
In sum, there doesn't seem to be much of a disadvantage to working with compressed points; there's probably not even an efficiency hit. On the other hand, it's (potentially) a departure from the way folks are used to doing things in other ecosystems, and it's not clear there's any safety benefit if people are anyway going to be using public key recovery for signature verification. |
Thanks for the insight @kwantam. Sounds like this is okay as is then from a safety perspective. From a resource perspective the benefit would be 33 bytes vs 65 bytes being stored and transmitted. If we wanted to improve this later we could introduce a second recover fn that returns the compressed form, or add a host fn that converts a |
Yeah, I'm not too concerned with the size difference at the API level. If someone's making zillions of them and want to optimize, yeah they can transform to compressed manually (I expect they'll be compressing XDR long before, but whatever). I went with the uncompressed because as @kwantam originally pointed out it's what existing systems use. Less deviation. |
Reviewing the SDK and environments crypto functions and noticed that we're returning the public key from
secp256k1_recover
as 65-bytes uncompressed.I expected that this would have been the 33-byte compressed form.
The value returned will likely be == compared with a public key stored in contract storage, or passed in as an input into to a contract fn, and so the format returned by this function will likely influence how contract developers pass ecdsa public keys to contracts, and how they use keys in their own applications.
The reason I expected compressed form is that it's less data being passed around and stored, meaning more cost effective.
Also the uncompressed form has a quality that developers must be aware of: the points may not be on the curve, and may not be valid. The compressed form doesn't have this quality because developers must derive one of the points and so the points will always be valid. I don't think this quality would especially affect Soroban development directly, but if Soroban encourages the uncompressed form it's possible it encourages use of uncompressed form in the ecosystem outside contracts.
I'm not sure if compressed vs uncompressed was a conscious and intentional decision. Compressed form does require the Soroban environment to do more work and maybe we evaluated that was too expensive? I think we should reconsider though.
This is the function exposed in the Soroban SDK:
Ref: https://github.com/stellar/rs-soroban-sdk/blob/349cd57fc7f20c67730ff89762e99e64e280e4d5/soroban-sdk/src/crypto.rs#L50-L60
This is the code in the Soroban Environment that generates the public key. It appears that changing to compressed is a one line change not including updating tests and redoing calibration:
rs-soroban-env/soroban-env-host/src/host/crypto.rs
Lines 158 to 160 in 8e593ab
I started a conversation about this on Discord, but the issue can be discussed here on GitHub.
Related issue:
The text was updated successfully, but these errors were encountered: