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:
parent
e4c8d67956
commit
915b961d41
107
ch04.asciidoc
107
ch04.asciidoc
@ -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↵
|
||||
</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
|
||||
|
Loading…
Reference in New Issue
Block a user