Bitcoin Forum
May 11, 2024, 08:01:23 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Need help on dealing with compressed keys  (Read 4116 times)
cjp (OP)
Full Member
***
Offline Offline

Activity: 210
Merit: 124



View Profile WWW
October 18, 2014, 10:51:55 AM
 #1

I made a piece of software which
* retrieves the private key of a given address with the dumpprivkey command
* decodes the private key according to the Wallet Import Format
* gives the private key to OpenSSL (based on what the Bitcoin source code does), and gets the corresponding public key
* encodes the public key to a Bitcoin address
* checks whether given and resulting Bitcoin addresses are the same.

This works fine for some keys, but not for others. Further investigation showed that it works for keys generated with an old version of BOTG (imported into Bitcoin-Qt), and fails for keys generated by Bitcoin-Qt itself (version 0.8.6). The addresses for which it works have a private key (as returned by dumpprivkey) that starts with a '5', and when it doesn't work, it starts with an 'L'. I've read that the ones that start with an 'L' correspond to "compressed public keys", so that's probably what causes the problem.

Note that my code did not generate any errors: it just returned an address that was different from the original. Among other things, this means the version number in the private key format is the same.

I couldn't find good documentation on how to go from private key to public key, either for compressed or for non-compressed keys, so I'll use the Bitcoin source code again to help me. I'd appreciate it if somebody could document this (also, just in case I can't figure it out from the code). Apparently, just saying "this is the private key, and this is the ECDSA curve you should use" is not enough.

Donate to: 1KNgGhVJx4yKupWicMenyg6SLoS68nA6S8
http://cornwarecjp.github.io/amiko-pay/
Be very wary of relying on JavaScript for security on crypto sites. The site can change the JavaScript at any time unless you take unusual precautions, and browsers are not generally known for their airtight security.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
cjp (OP)
Full Member
***
Offline Offline

Activity: 210
Merit: 124



View Profile WWW
October 18, 2014, 12:12:51 PM
 #2

For those of you with the same problem: I think I've figured it out. Apparently, private keys that correspond to compressed public keys can be recognized because Bitcoin adds a single (unused) byte to them (value: 0x01), making them 33 bytes long instead of 32 bytes. See CBitcoinSecret in base58.h. Somehow the appended byte causes the first Base58 character to become 'L' instead of '5' (probably there is some endianness inversion in the pipeline).

For the exact differences in behavior, see key.cpp. The essence is in CKey::SetCompressedPubKey, which calls EC_KEY_set_conv_form. Compressed public keys can be recognized because they're smaller (they're 33 bytes) than non-compressed keys. The corresponding Bitcoin addresses can not be distinguished from each other, since they're secure hashes of public keys.

Donate to: 1KNgGhVJx4yKupWicMenyg6SLoS68nA6S8
http://cornwarecjp.github.io/amiko-pay/
hhanh00
Sr. Member
****
Offline Offline

Activity: 467
Merit: 266


View Profile
October 18, 2014, 12:57:10 PM
 #3

Glad you figured it out. If you'd like some background info, here's a thread explaining the subtle differences.

https://bitcointalk.org/index.php?topic=129652.0

cjp (OP)
Full Member
***
Offline Offline

Activity: 210
Merit: 124



View Profile WWW
October 18, 2014, 01:59:25 PM
 #4

Thanks.

Here is my implementation in Python:
https://github.com/cornwarecjp/amiko-pay/commit/40ad1f844bad6c74223d13bc71a4812e8b24e9db

Interestingly, no changes to other parts of the software were needed. They just need to pass key data to this class, and this class will figure out the distinction between compressed/uncompressed automatically.

Donate to: 1KNgGhVJx4yKupWicMenyg6SLoS68nA6S8
http://cornwarecjp.github.io/amiko-pay/
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!