1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-12-23 07:08:13 +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.
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
@ -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
also presented in different ways, usually as either _compressed_ or
_uncompressed_ public keys.
//https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2011-November/000778.html
As we saw previously, the public key is a point on the elliptic curve
consisting of a pair of coordinates +(x,y)+. It is usually presented
with the prefix +04+ followed by two 256-bit numbers: one for the _x_
coordinate of the point, the other for the _y_ coordinate. The prefix
+04+ is used to distinguish uncompressed public keys from compressed
public keys that begin with a +02+ or a +03+.
((("public and private keys", "compressed public keys")))
When Bitcoin was first authored, its developers only knew how to create
65-byte public keys. However, a later developer became aware of an
alternative encoding for public keys that used only 33 bytes and which
was backwards compatible with all Bitcoin full nodes at the time,
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,
shown as the coordinates +x+ and +y+:
As we saw in the section <<public_key_derivation>>, 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!
Here's the public key generated by the private key we created in
<<public_key_derivation>>.
----
x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
@ -907,29 +921,6 @@ K = 04F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A&#x21b5;
</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
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
@ -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
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+
indicating the _y_ coordinate is odd:
@ -962,8 +953,9 @@ K = 03F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
This compressed public key corresponds to the same private key, meaning
it is generated from the same private key. However, it looks different
from the uncompressed public key. More importantly, if we convert this
compressed public key to a Bitcoin address using the double-hash
function (+RIPEMD160(SHA256(K))+) it will produce a _different_ Bitcoin
compressed public key to a commitment using the HASH160
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
key can produce a public key expressed in two different formats
(compressed and uncompressed) that produce two different Bitcoin
@ -975,30 +967,21 @@ addresses.
.Public key compression
image::images/mbc2_0407.png["pubkey_compression"]
Compressed public keys are gradually becoming the default across Bitcoin
clients, which is having a significant impact on reducing the size of
transactions and therefore the blockchain. However, not all clients
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!
Compressed public keys are now the default in almost all Bitcoin
software, and were made required when using certain new features added
in later protocol upgrades.
To resolve this issue, when private keys are exported from a wallet, the
WIF that is used to represent them is implemented differently in newer
bitcoin wallets, to indicate that these private keys have been used to
produce _compressed_ public keys and therefore _compressed_ Bitcoin
addresses. This allows the importing wallet to distinguish between
private keys originating from older or newer wallets and search the
blockchain for transactions with Bitcoin addresses corresponding to the
uncompressed, or the compressed, public keys, respectively. Let's look
at how this works in more detail, in the next section.
However, some software still needs to support uncompressed public keys,
such as a wallet application importing private keys from an older
wallet. When the new wallet scans the block chain for old P2PKH outputs
and inputs, it needs to know whether to scan the 65-byte keys (and
commitments to those keys) or 33-byte keys (and their commitments). Failure
to scan for the correct type can lead to the user not being able to
spend their full balance. To resolve this issue, when private keys are
exported from a wallet, the Wallet Import Format (WIF) that is used to
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]]
===== Compressed private keys