rust-bitcoin / rust-secp256k1

Rust language bindings for Bitcoin secp256k1 library.
Creative Commons Zero v1.0 Universal
346 stars 267 forks source link

Support for loading uncompressed public keys #43

Closed tarcieri closed 6 years ago

tarcieri commented 6 years ago

From what I can tell PublicKey can serialize_uncompressed public keys but I can't figure out a corresponding way to deserialize one.

I tried what I think is the only option: from_slice with the uncompressed key and that didn't work: I get InvalidPublicKey.

If you're curious where I'm getting an uncompressed key from: the YubiHSM2 supports ECDSA with several curves including the NIST curves and Brainpool in addition to secp256k1. It always returns an uncompressed key regardless of the curve type.

apoelstra commented 6 years ago

Can you post such a public key? I'm surprised that from_slice doesn't work because it passes directly to the ffi bindings.

We have a unit test pubkey_from_slice which checks parsing of uncompressed keys. Maybe the yubikey is producing keys with the wrong first byte?

tarcieri commented 6 years ago

Aah, it's a raw fixed-width key (64-bytes). I guess it needs a DER tag? (BIT STRING?)

apoelstra commented 6 years ago

It needs a 0x04, then the raw 64 bytes. I don't think this is DER because there aren't lengths encoded anywhere.

tarcieri commented 6 years ago

You appear to be correct, and this is a deeper rabbit hole than I realized. They appear to be a non-ASN.1-related magic tag.

Specifically the source of the mystery 0x04 appears be the Octet-String-to-Elliptic-Curve-Point encoding described in this document:

http://www.secg.org/sec2-v2.pdf

screen shot 2018-07-30 at 5 49 52 pm

Anyway, after adding the 0x04 this appears to be working as intended so I'll go ahead and close it.