1. Uncompressed Public Key vs. Compressed Public Key
Since the inception of Bitcoin in 2009, the public key generated by the wallet is a 512-bit (64-byte) binary number. We will find that this public key connects the x and y coordinates together. However, once x is determined, the value of y will also be fixed, so as long as the value of x is collected, it also contains the information of y. This can significantly reduce the size of the data and lighten the storage burden (it will be mentioned later that every Bitcoin transaction must be encrypted using the public key, which will be stored on the blockchain), hence it is also referred to as 'compressed public key'. The earliest public key is called 'uncompressed public key'. To distinguish these two formats of public keys, the wallet adds a prefix '0x04' in front of the 'uncompressed public key', resulting in a 520-bit (65-byte) public key. Therefore, in 2012, after the Bitcoin wallet upgrade, support for compressed public keys began.
2. Uncompressed Private Key vs. Compressed Private Key
So the question arises, after the wallet generates a private key (or imports a private key), how does it tell the wallet which form of public key to generate? Simple, just add a 'tag' to the private key.
A. Do not add 'Compression Tag' to Private Key | Uncompressed Private Key
Assuming we have a 256-bit (32-byte) private key:
0x1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD (hexadecimal representation, each character occupies 4 bits, a total of 64 characters).
First, as described in the previous article, prepend the prefix 0x80 to the private key, indicating that this is a Bitcoin private key: 0x801E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
If up to this point, the format after Base58Check encoding would be: 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn, known as the 'WIF' format, which is the 'uncompressed wallet import format'.
In other words, after importing this format of the private key, the wallet first decodes it into 0x801E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD, then finds the prefix 0x80 to know it's a Bitcoin private key, and then discovers that there is no 'compression tag', indicating that this is an uncompressed private key. Finally, by extracting the hexadecimal string after 0x80, the actual private key to be used is restored. Based on this private key, a 512-bit public key can be calculated, which is then prefixed with '0x04' to indicate that this is an 'uncompressed public key'.
B. Add 'Compression Tag' to Private Key | Compressed Private Key
After adding the 0x80 prefix, add another 0x01 compression flag, i.e., 0x801E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD01. Then, perform two SHA-256 hashes on this private key format to obtain the checksum. Finally, the format after Base58Check encoding (refer to the previous article on Base58Check encoding process) would be: KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ, known as the 'WIF-Compressed' format, which is the 'compressed wallet import format'.
In other words, after importing this format of the private key, the wallet first decodes it into 0x801E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD01, then finds the prefix 0x80 to know it's a Bitcoin private key. It then discovers the 0x01 'compression tag', indicating that this is a compressed private key. Finally, by extracting the hexadecimal string between 0x80 and 0x01, the actual private key to be used is restored, allowing the calculation of the 'compressed public key'.
3. Calculate Public Key
Smart students have already noticed the problem; just determining the x coordinate of the public key is not enough because y can have both positive and negative values. How does the wallet know which one to take? Simple, just prepend a prefix to the x coordinate to tell the wallet. If the prefix is 0x02, it indicates that y is even, representing the negative value. If the prefix is 0x03, it indicates that y is odd, representing the positive value. Here’s a complete example.
Figure 1, Steps to Calculate Compressed Public Key
A. Obtain Private Key
We imported a private key of some format (it could be WIF format or WIF-Compressed) and extracted the original private key:
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
B. Calculate Public Key Coordinates
0xF028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
0x07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
C. Public Key Format Selection
If the imported private key is in WIF format, the public key is in uncompressed format: 0x04F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
If the imported private key is in WIF-Compressed format, the public key is in compressed format: 0x03F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A