|
|
|
@ -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
|
|
|
|
|
|
|
|
|
|
((("public and private keys", "public key formats")))Public keys are
|
|
|
|
|
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
|
|
|
|
|
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+.
|
|
|
|
|
[[comp_pub]]
|
|
|
|
|
=== Compressed public keys
|
|
|
|
|
|
|
|
|
|
//https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2011-November/000778.html
|
|
|
|
|
|
|
|
|
|
((("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.
|
|
|
|
|
|
|
|
|
|
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 earlier,
|
|
|
|
|
shown as the coordinates +x+ and +y+:
|
|
|
|
|
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!
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|