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:
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.
|
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↵
|
|||||||
</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
|
||||||
|
Loading…
Reference in New Issue
Block a user