Author

Topic: Converting public keys to compressed public keys (Read 4429 times)

newbie
Activity: 15
Merit: 0
Keep in mind that the compressed and uncompressed public keys have different hashes, and thus result in different Bitcoin addresses.  You need the right one to unlock a Txout.
kjj
legendary
Activity: 1302
Merit: 1026
Yup, you have it right, at least functionally.

The pubkey is structured data with a eight bit header followed by one or two fields of 256 bits each.  The first field is X and is always present.  The second field is Y, and is only present when the header is 0x04.  Stripping off the 0x04 and taking the first half is the same operation as unpacking the X value, so what you are doing is exactly right.  I just like to explain it in detail so that other people reading this thread will understand what that operation represents logically.

You just need to keep track of whether you are compressing or not.  If you are using the compressed form, you must use the compression flag in the WIF.  Even though they represent the exact same idea, the compressed WIF won't work with the uncompressed pubkey, nor the reverse.
hero member
Activity: 651
Merit: 501
My PGP Key: 92C7689C
This is just a quick sanity check, as I didn't find much on the matter that was definitive, but I want to make sure I'm doing the right thing with my deterministic wallet manager.

I wanted to implement support for compressed addresses.  I figured out compressed private WIF keys quickly enough: tack on 01 to the end of the private hexadecimal key and base58-encode it.  Handling of the public key wasn't as well-documented.  I tried looking at bitaddress.org and the Casascius address utility source for some clues, but the latter calls a library not available for this project and I couldn't quite make sense of the former.

If I have it right, it turned out to be nearly as simple:  split the public key (less the leading 04) in half and look at the last digit of the second half.  If that digit is even, prepend the first half with 02; if odd, prepend the first half with 03.  Push the result through the same hash and base58-encoding process to get the compressed address. 

Does this sound right?

Going the other way (from a compressed public key to an uncompressed public key) looks like it'd be much more involved, but I don't need that functionality for what I'm doing.

(If anyone's interested, the aforementioned deterministic wallet manager includes some Python code with no bignum or ECDSA dependencies that calculates addresses and private keys from hexadecimal private keys.  In its current form, it decodes to Bitcoin or Litecoin addresses, in either compressed or uncompressed format.)
Jump to: