What is a compressed Bitcoin key?

70

18

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?

Thilo

Posted 2012-03-03T08:25:39.543

Reputation: 4 601

Answers

66

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.)

David Schwartz

Posted 2012-03-03T08:25:39.543

Reputation: 48 957

So, if I understand correctly, a single private key is always connected to a single public key representable in two different formats, which is connected to two addresses (from whether the compressed and uncompressed form of the key is hashed)? So somebody can send coins to either address, but to use those coins I need to use the right version of the public key (which the newer software will automatically handle and the older software won't?) – Daniel H – 2014-02-19T10:07:48.090

1I 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 – 2014-05-13T08:21:50.433

So if the older software encounters a compressed key (how would that happen? in wallet.dat? in the block chain? in a transaction broadcast?) can it handle it? – Thilo – 2012-03-03T10:39:10.920

3No, 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 – 2012-03-03T10:42:00.620

3To 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 – 2012-03-03T10:46:14.093

If this is only for wallet.dat, why bother about a few bytes? 31 bytes saved add up to a megabyte only if you have 33.825 keys. – Thilo – 2012-03-03T11:44:44.020

5Old 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 – 2012-03-03T17:24:46.930

3The 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 – 2012-03-03T18:22:49.177

@Advanced A single private key has a single corresponding public key. But that public key can be expressed in two forms, compressed and uncompressed. Each public key form has a corresponding Bitcoin address. Bitcoins can be sent to addresses without regard for how that address was formed. – David Schwartz – 2015-05-25T20:44:25.680

@DavidSchwartz The link to Secp256k1 in your post has become broken. But: What an excellent explanation of how this compression is archieved! – Qqwy – 2015-11-03T18:58:43.563

@Qqwy Thanks. I fixed the link to point to something that is at least a little relevant. – David Schwartz – 2015-11-03T19:00:28.323

17

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:

user479

Posted 2012-03-03T08:25:39.543

Reputation: 381

1The 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 – 2015-06-15T20:38:40.717

@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 – 2017-09-12T12:23:30.637

This answer is different from above where the first byte of compressed/uncompressed is (0x04 for uncompressed, 0x02/0x03 for compressed) – halfbit – 2012-12-17T12:12:11.047

1It 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. – halfbit – 2012-12-17T12:49:29.590

7

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.

Techno CAT

Posted 2012-03-03T08:25:39.543

Reputation: 71

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.

Badr Bellaj

Posted 2012-03-03T08:25:39.543

Reputation: 971

is it 0x02 for y > 0 and 0x03 for y < 0 – Cisco Mmu – 2020-07-10T07:29:46.697