1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2025-01-11 00:01:03 +00:00

CH04::compressed pubkeys: merge with "pubkey formats"

This reduces repitive text, provides a better introducion to compressed
pubkeys, and updates adoption claims.
This commit is contained in:
David A. Harding 2023-02-07 16:19:03 -10:00
parent e4c8d67956
commit 915b961d41

View File

@ -862,7 +862,7 @@ wrapper
The result contains the key as payload, the WIF version prefix 128, and a checksum. The result contains the key as payload, the WIF version prefix 128, and a checksum.
Notice that the "payload" of the compressed key is appended with the Notice that the "payload" of the compressed key is appended with the
suffix +01+, signalling that the derived public key is to be compressed: suffix +01+, signaling that the derived public key is to be compressed:
---- ----
$ bx base58check-decode KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ $ bx base58check-decode KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
@ -874,22 +874,36 @@ wrapper
} }
---- ----
FIXME:HERE
===== Public key formats [[comp_pub]]
=== Compressed public keys
((("public and private keys", "public key formats")))Public keys are //https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2011-November/000778.html
also presented in different ways, usually as either _compressed_ or
_uncompressed_ public keys.
As we saw previously, the public key is a point on the elliptic curve ((("public and private keys", "compressed public keys")))
consisting of a pair of coordinates +(x,y)+. It is usually presented When Bitcoin was first authored, its developers only knew how to create
with the prefix +04+ followed by two 256-bit numbers: one for the _x_ 65-byte public keys. However, a later developer became aware of an
coordinate of the point, the other for the _y_ coordinate. The prefix alternative encoding for public keys that used only 33 bytes and which
+04+ is used to distinguish uncompressed public keys from compressed was backwards compatible with all Bitcoin full nodes at the time,
public keys that begin with a +02+ or a +03+. so there was no need to change the Bitcoin protocol. Those 33-byte
public keys are known as _compressed public keys_ and the original 65
byte keys are known as _uncompressed public keys_. Smaller public keys
was smaller transactions, allowing more payments to be made in the same
block.
Here's the public key generated by the private key we created earlier, As we saw in the section <<public_key_derivation>>, a public key is a point (x,y) on an
shown as the coordinates +x+ and +y+: elliptic curve. Because the curve expresses a mathematical function, a
point on the curve represents a solution to the equation and, therefore,
if we know the _x_ coordinate we can calculate the _y_ coordinate by
solving the equation y^2^ mod p = (x^3^ + 7) mod p. That allows us to
store only the _x_ coordinate of the public key point, omitting the _y_
coordinate and reducing the size of the key and the space required to
store it by 256 bits. An almost 50% reduction in size in every
transaction adds up to a lot of data saved over time!
Here's the public key generated by the private key we created in
<<public_key_derivation>>.
---- ----
x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
@ -907,29 +921,6 @@ K = 04F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A&#x21b5;
</pre> </pre>
++++ ++++
[[comp_pub]]
===== Compressed public keys
((("public and private keys", "compressed public keys")))Compressed
public keys were introduced to bitcoin to reduce the size of
transactions and conserve disk space on nodes that store the Bitcoin
blockchain database. Most transactions include the public key, which is
required to validate the owner's credentials and spend the bitcoin. Each
public key requires 520 bits (prefix + x + y), which when multiplied by
several hundred transactions per block, or tens of thousands of
transactions per day, adds a significant amount of data to the
blockchain.
As we saw in the section <<pubkey>>, a public key is a point (x,y) on an
elliptic curve. Because the curve expresses a mathematical function, a
point on the curve represents a solution to the equation and, therefore,
if we know the _x_ coordinate we can calculate the _y_ coordinate by
solving the equation y^2^ mod p = (x^3^ + 7) mod p. That allows us to
store only the _x_ coordinate of the public key point, omitting the _y_
coordinate and reducing the size of the key and the space required to
store it by 256 bits. An almost 50% reduction in size in every
transaction adds up to a lot of data saved over time!
Whereas uncompressed public keys have a prefix of +04+, compressed Whereas uncompressed public keys have a prefix of +04+, compressed
public keys start with either a +02+ or a +03+ prefix. Let's look at why public keys start with either a +02+ or a +03+ prefix. Let's look at why
there are two possible prefixes: because the left side of the equation there are two possible prefixes: because the left side of the equation
@ -951,7 +942,7 @@ the software to correctly deduce the _y_ coordinate from the _x_
coordinate and uncompress the public key to the full coordinates of the coordinate and uncompress the public key to the full coordinates of the
point. Public key compression is illustrated in <<pubkey_compression>>. point. Public key compression is illustrated in <<pubkey_compression>>.
Here's the same public key generated previously, shown as a compressed Here's the same public key generated in <<public_key_derivation>>, shown as a compressed
public key stored in 264 bits (66 hex digits) with the prefix +03+ public key stored in 264 bits (66 hex digits) with the prefix +03+
indicating the _y_ coordinate is odd: indicating the _y_ coordinate is odd:
@ -962,8 +953,9 @@ K = 03F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
This compressed public key corresponds to the same private key, meaning This compressed public key corresponds to the same private key, meaning
it is generated from the same private key. However, it looks different it is generated from the same private key. However, it looks different
from the uncompressed public key. More importantly, if we convert this from the uncompressed public key. More importantly, if we convert this
compressed public key to a Bitcoin address using the double-hash compressed public key to a commitment using the HASH160
function (+RIPEMD160(SHA256(K))+) it will produce a _different_ Bitcoin function (+RIPEMD160(SHA256(K))+) it will produce a _different_
commitment than the uncompressed public key, leading to a different
address. This can be confusing, because it means that a single private address. This can be confusing, because it means that a single private
key can produce a public key expressed in two different formats key can produce a public key expressed in two different formats
(compressed and uncompressed) that produce two different Bitcoin (compressed and uncompressed) that produce two different Bitcoin
@ -975,30 +967,21 @@ addresses.
.Public key compression .Public key compression
image::images/mbc2_0407.png["pubkey_compression"] image::images/mbc2_0407.png["pubkey_compression"]
Compressed public keys are gradually becoming the default across Bitcoin Compressed public keys are now the default in almost all Bitcoin
clients, which is having a significant impact on reducing the size of software, and were made required when using certain new features added
transactions and therefore the blockchain. However, not all clients in later protocol upgrades.
support compressed public keys yet. Newer clients that support
compressed public keys have to account for transactions from older
clients that do not support compressed public keys. This is especially
important when a wallet application is importing private keys from
another bitcoin wallet application, because the new wallet needs to scan
the blockchain to find transactions corresponding to these imported
keys. Which Bitcoin addresses should the bitcoin wallet scan for? The
Bitcoin addresses produced by uncompressed public keys, or the Bitcoin
addresses produced by compressed public keys? Both are valid Bitcoin
addresses, and can be signed for by the private key, but they are
different addresses!
To resolve this issue, when private keys are exported from a wallet, the However, some software still needs to support uncompressed public keys,
WIF that is used to represent them is implemented differently in newer such as a wallet application importing private keys from an older
bitcoin wallets, to indicate that these private keys have been used to wallet. When the new wallet scans the block chain for old P2PKH outputs
produce _compressed_ public keys and therefore _compressed_ Bitcoin and inputs, it needs to know whether to scan the 65-byte keys (and
addresses. This allows the importing wallet to distinguish between commitments to those keys) or 33-byte keys (and their commitments). Failure
private keys originating from older or newer wallets and search the to scan for the correct type can lead to the user not being able to
blockchain for transactions with Bitcoin addresses corresponding to the spend their full balance. To resolve this issue, when private keys are
uncompressed, or the compressed, public keys, respectively. Let's look exported from a wallet, the Wallet Import Format (WIF) that is used to
at how this works in more detail, in the next section. represent them is implemented slightly differently in newer Bitcoin
wallets, to indicate that these private keys have been used to produce
compressed public keys.
[[comp_priv]] [[comp_priv]]
===== Compressed private keys ===== Compressed private keys