63

The standard Bitcoin client in version 0.6 apparently introduces compressed keys.

What are they? Are there any drawbacks to using them? Any incompatibilities with older software? Reductions in cryptographic strength?

54

A compressed key is just a way of storing a public key in fewer bytes (33 instead of 65). There are no compatibility or security issues because they are precisely the same keys, just stored in a different way. The original Bitcoin software didn't use compressed keys only because their use was poorly documented in OpenSSL. They have no disadvantages other than that a little bit of additional computation is needed before they can be used to validate a signature.

If you think of a public key as a point somewhere along a giant letter U, an uncompressed key is the x and y coordinates of the point. A compressed key is how high up on the U the point is along with a single bit indicating whether it's on the left or right side. As you can visualize, they both encode precisely the same thing, but the compressed form requires half as much space plus one bit. (Of course, they're really points on elliptic curve secp256k1, but the concept is the same.)

  • 3
    No, it can't. But it is always disallowed to try to read a wallet.dat file with an earlier version of the software. That's a permitted break. (You could still manually extract the case, uncompress them, and put them into the earlier form if you had to. But that kind of compatibility is not supported. You can't go back with a newer wallet file unless you translate the data.) – David Schwartz Mar 3 '12 at 10:42
  • 3
    To answer your other question, only in the wallet.dat. Compressed keys aren't yet supported anywhere else because that would be a protocol-breaking change. – David Schwartz Mar 3 '12 at 10:46
  • 4
    Old clients can validate transactions with compressed public keys because Bitcoin sends public keys to OpenSSL without checking their format and OpenSSL automatically processes the public key according to the leading byte (0x04 for uncompressed, 0x02/0x03 for compressed). – theymos Mar 3 '12 at 17:24
  • 2
    The advantage is mainly for the blockchain and the network, as transactions will be a bit smaller now. It's 33 bytes instead of 65, by the way. – Pieter Wuille Mar 3 '12 at 18:22
  • 1
    I have a problem understanding it : I have an uncompressed private key, I enter it in bitaddress.org, and I get two public addresses : one compressed and one uncompressed. On one I have one million dollar, on the other 0. And they both come from the same private key. How does that make sense? – Advanced May 13 '14 at 8:21
16

Format (private keys):

  • uncompressed: 0x80 + [32-byte secret] + [4 bytes of Hash() of previous 33 bytes], base58 encoded
  • compressed: 0x80 + [32-byte secret] + 0x01 + [4 bytes of Hash() previous 34 bytes], base58 encoded

case 1:

  • secret (hex): 1111111111111111111111111111111111111111111111111111111111111111
  • uncompressed:
    • secret (base58): 5HwoXVkHoRM8sL2KmNRS217n1g8mPPBomrY7yehCuXC1115WWsh
    • pubkey (hex): 044f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1
    • address (base58): 1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a
  • compressed:
    • secret (base58): KwntMbt59tTsj8xqpqYqRRWufyjGunvhSyeMo3NTYpFYzZbXJ5Hp
    • pubkey (hex): 034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
    • address (base58): 1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9

Obtained from the Bitcoin developer mailing list:

  • This answer is different from above where the first byte of compressed/uncompressed is (0x04 for uncompressed, 0x02/0x03 for compressed) – random65537 Dec 17 '12 at 12:12
  • 1
    It appears that this answer refers to the bitcoin specific import/export format of keys, vs the usage of compressed keys itself namely in OpenSSL. I hope this helps future readers contrast the two answers here. – random65537 Dec 17 '12 at 12:49
  • 1
    The quote is quite misleading. Since it is a quote, it probably should not be edited but “4 bytes of Hash() of previous […] bytes” should have been “4 bytes of Hash(Hash()) of previous […] bytes”. Hash function is applied twice. – Akater Jun 15 '15 at 20:38
  • @Akater hash applied twice is still a hash. Since it doesn't say which function Hash() corresponds to, the quote is correct. I don't know which function is used, so maybe e.g. Hash(x) = SHA256(SHA256(x)) – modular Sep 12 '17 at 12:23
6

It may help to break the fields apart.

04
4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1

03 [could be 02]
4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
[discarded value can be computed from above value]

There is more detail omitted above. The 03 can be 02 because the discarded value has to be derived from the preserved value and one extra bit of info is needed. That is because there are two roots [plus and minus] when taking a square root.

4

a good explanation is available in How can I test if a bitcoin address is compressed or not?

More specifically, a public key in Bitcoin is a pair integers (x,y). For uncompressed public keys, these integers are encoded as 256-bit unsigned big-endian ints, concatenated together, and then prepended with a single 0x04 byte. The result is 65 bytes long.

For compressed public keys, only the x coordinate is encoded (like above, as 256-bit unsigned big-endian int). It turns out that the y coordinate can only be one of two values, one even and one odd. Instead of prepending a single 0x04 byte, a single 0x02 or 0x03 byte is prepended depending on y's value (0x02 for even, 0x03 for odd). The result is 33 bytes long.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.