-
Notifications
You must be signed in to change notification settings - Fork 26
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
RFC: Use EllSwift for ECDH #66
Conversation
One thing I haven't checked is how this impacts generating and verifying the certificate. In this proposal we encode public keys with 64 byte EllSwift instead of 32-byte x-only. The ECDH algorithm in libsecp256k1 can use this encoding directly which makes it more efficient. Signing the certificate involves only the private key, so that's not impacted. I'm assuming that we can just convert the EllSwift encoded server static key to x-only format for this purpose, but I haven't implemented this yet. |
64366a3
to
e36df67
Compare
I implemented certificate signing and verification in bitcoin/bitcoin#28983 so next week I should be able to test how that combines with EllSwift. |
e36df67
to
ccf6322
Compare
I added additional clarification on the fact that that we use three encodings for x-only:
I also further clarified that with EllSwift we do not assume anything about the y-coordinate parity. |
Rebased after #64 (footnote numbering). |
38e8953
to
be7f156
Compare
Just a small clarification. Here
I understand that the method .public_key() outputs an internal representation of ElligatorSwift encoding, and we use .serislizeEllSwift() for obtaining the 64-bytes serialization. But the here
should it be `e.public_key().serislizeEllSwift() ? |
That probably makes sense. So maybe:
And then:
|
Done. I also clarified which sections of BIP324 we refer to for EllSwift encoding and for EllSwift x-only ECDH. I don't think we should copy large portions of the BIP324 text here. The EllSwift stuff we use from it should be implemented in exactly the way described there. If we also described that here, implementers might think it's somehow different. We could even accidentally introduce an incompatibility if we decide to change the wording here. It's fine to provide a high level summary though. And it should be clear which parts of BIP324 are used, and that nothing else is used. |
be7f156
to
bcfeb3b
Compare
bcfeb3b
to
2dc86d8
Compare
I changed the protocol name to |
2dc86d8
to
fb03db5
Compare
The discussion above so far suggests more clarification is needed. Happy to copy-paste suggestions... But at least I think we agree the implementations are now correct. |
Co-authored-by: Jakub Trnka <jak3264@gmail.com>
@jakubtrnka I added your suggestion |
we use the 64 byte ElligatorSwift x-only encoding as defined in BIP324<sup>[7](#reference-7)</sup> under "ElligatorSwift encoding of curve X coordinates". This encoding uses 64-bytes instead of 32-bytes in order to produce a | ||
pseudo-random bytesteam. This is useful because the protocol handshake starts with | ||
each side sending ther public key in plain text. Additionally the use of X-only | ||
ElligatorSwift ECDH removes the need to grind or negate private keys. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is true apparently, but in detail seems not.
When ElligatorSwift is proposed in BIP340.
When it says "In what follows, we use the notation from BIP340", if we look at the lift_x()
function then it seems not x-only to me.
Indeed the last step is.
Return the unique point P such that x(P) = x and y(P) = y if y mod 2 = 0 or y(P) = p-y otherwise.
I am not familiar with the implementation in C++ so I cannot tell where in the precise implementation appears the pub key negation of y-coordinate
|
||
- for each keypair `(sk, bytes(P.x))` there is another keypair `(n - sk, bytes(P.x))`, where `n` is group order of secp256k1 curve | ||
- Each result of `ECDH(sk, Q)` is equal to `ECDH(n - sk, Q)` for some EC point `Q` where `n` is group order of secp256k1 curve | ||
To perform X-only ECDH we use ellswift_ecdh_xonly(ellswift_theirs, d) as described in BIP324<sup>[7](#reference-7)</sup> under "Shared secret computation". The result is 32 bytes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as above, I have some doubt that ElligatorSwift ecdh is x-only
As I remarked in a comment, I don't think that ECDH procedure in the ElligatorSwift module is really x-only. I mean, the encoding itself is x-only, but I have some reasons to think that the ECDH is not. This is because it uses the function
|
It's in secp256k1 which is used by Bitcoin Core, but also by SRI and many other projects. I also haven't looked at exactly what it does under the hood. I think the confusion here is what "x-only" means. The y-coordinate is not transmitted to the counterparty, and it has no effect on the result of the ECDH operation. If we don't mention that property at all, that seems confusing. Just using the term "EllSwift" doesn't communicate this either. But if anyone has a specific suggestion on an updated text, I can use that. |
The Python implementation that's used for Bitcoin Core tests may be useful as another reference: https://github.com/bitcoin/bitcoin/blob/master/test/functional/test_framework/crypto/ellswift.py |
This updates the spec to use ElligatorSwift encoded public keys. It's option 3 in #65.
Todo:
Bitcoin Core's BIP324 peer-to-peer encryption uses ElligatorSwift to encode the x-coordinate of a public key in 64 pseudorandom bytes. We currently encode the x-coordinate in 32 bytes which can be distinguished from random by a passive observer. This impact the first step of the handshake which uses plain text.
BIP324 also defines a method of x-only ECDH, whereas our current spec is ambiguous on how to perform ECDH and in practice implementations grind or negate the private key in order to use only an even y-coordinate. This won't be needed anymore.
https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki