Skip to content
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

Implement lexigraphic ordering for PubKey #248

Merged
merged 1 commit into from Nov 26, 2020

Conversation

justinmoon
Copy link
Contributor

@justinmoon justinmoon commented Nov 9, 2020

While implementing a feature in rust-miniscript I ran into surprising behavior with public key ordering in rust-bitcoin. I would expect pubkeys to be lexigraphically ordered by compressed serialization (used by BIP 67), but instead it was based on the internal 64-byte libsecp256k1 representation.

@apoelstra mentioned he was in favor of changing this so I attempted to implement it.

@justinmoon justinmoon force-pushed the pubkey-ordering branch 2 times, most recently from 1ba7317 to ba09c5d Compare November 9, 2020 17:46
@apoelstra
Copy link
Member

I expect this won't compile on Rust 1.29. I think using &self.serialize()[..] will work because slices are comparable even though [u8; 33]s are not.

@justinmoon
Copy link
Contributor Author

Tests pass on 1.29 on my machine:

$ cargo --version
cargo 1.29.0 (524a578d7 2018-08-05)

$ cargo test
running 33 tests
...
test result: ok. 33 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests secp256k1

running 5 tests
...
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

I see a Travis check here that's not "completed yet". Is this broken?

@apoelstra
Copy link
Member

Yeah, CI seems pretty broken :(

@apoelstra
Copy link
Member

Travis says "Abuse detected" https://travis-ci.org/github/rust-bitcoin/rust-secp256k1/requests

This is pretty stupid, let's just switch to github actions.

@apoelstra
Copy link
Member

Once we get #250 in you'll need to rebase and then we'll be rid of Travis once and for all.

@real-or-random
Copy link
Collaborator

I think this could break existing code. I don't think it will but we can't know for sure.

@elichai
Copy link
Member

elichai commented Nov 11, 2020

Should we also implement PartialEq in terms of the serialized key? (I remember talking on #secp256k1 if we allow users to assume secp256k1_* objects are comparable or not, I don't remember the answer though hehe)

@apoelstra
Copy link
Member

@elichai any such existing code was already buggy because it was violating the contract for the upstream public key type

@apoelstra
Copy link
Member

@elichai as for PartialEq ... it is true that the contract says we're not allowed to compare based on the underlying, so morally we should fix this. But it's also true that in our particular vendored version, comparing equality based or serialize will give identical results to comparing based on the underlying representation. So I guess, I'm indifferent.

@real-or-random
Copy link
Collaborator

@elichai as for PartialEq ... it is true that the contract says we're not allowed to compare based on the underlying, so morally we should fix this. But it's also true that in our particular vendored version, comparing equality based or serialize will give identical results to comparing based on the underlying representation. So I guess, I'm indifferent.

We could ask upstream to give us an equality function.

@apoelstra
Copy link
Member

@sipa informs me in bitcoin-core/secp256k1#850 (comment) that this PR is incorrect for sortedmulti in descriptors.

@sipa
Copy link

sipa commented Nov 23, 2020

See https://github.com/bitcoin/bitcoin/blob/v0.20.1/src/script/descriptor.cpp#L679. CPubKey's ordering is lexicographic (i.e., compressed keys will sort before uncompressed ones).

@apoelstra
Copy link
Member

@justinmoon can you try force-pushing this and see if that makes CI move?

@apoelstra
Copy link
Member

I think we should get this PR in even if it doesn't match Core. Our current Ord impl sorts on the internal representation of the keys which is definitely wrong, and it's useful to be able to sort keys without compressedness flag somehow..

@justinmoon
Copy link
Contributor Author

@apoelstra Done

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets do it

@apoelstra apoelstra merged commit 9083bab into rust-bitcoin:master Nov 26, 2020
@elichai
Copy link
Member

elichai commented Nov 26, 2020

@apoelstra We can implement Ord differently here, and in rust-bitcoin where we can take the compressed flag into account

@apoelstra
Copy link
Member

Yep. We should be sure to do both, because it's a footgun to use this Ord with Bitcoin keys in contexts where you may have uncompressed keys and you care about Core compat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants