1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-12-23 15:18:11 +00:00
bitcoinbook/ch04.asciidoc
David A. Harding 91eae20099 CH04::P2SH: remove multisig, describe p2sh rationale, give examples
- Start with a description of the problem that P2SH helps solve, the
  ability for the receiver to specify a script without having to
  communicate all the details of that script to the spender (and having
  the spender pay the tx fees for it).

- Mention that P2SH uses base58check.  Provide the prefix and continue
  using an existing example, but don't go into too much detail since
  bech32m addresses are now the preferred format
2023-02-09 20:58:47 -10:00

1616 lines
69 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[[ch04_keys_addresses]]
== Keys and Addresses
Alice wants to pay Bob, but the the thousands of Bitcoin full nodes who
will verify her transaction don't know who Alice or Bob are--and we want
to keep it that way to protect their privacy. Alice needs to
communicate that Bob should receive some of her bitcoins without tying
any aspect of that transaction to Bob's real-world identity or to other
Bitcoin payments that Bob receives. The method Alice uses must ensure
that only Bob can further spend the bitcoins he receives.
The original Bitcoin paper describes a very simple scheme for achieving
those goals, shown in <<pay-to-pure-pubkey>>. A receiver like Bob
accepts bitcoins to a public key in a transaction which is signed by the
spender (like Alice). The bitcoins which Alice is spending had been
previously received to one her public keys, and she uses the
corresponding private key to generate her signature. Full nodes can
verify that Alice's signature commits to the output of a hash function
that itself commits to Bob's public key and other transaction details.
[[pay-to-pure-pubkey]]
.Transaction chain from original Bitcoin paper
image::images/mbc2_abin01.png["Transaction chain from original Bitcoin paper"]
We'll examine public keys, private keys, signatures, and hash functions
in the following sections, and then use all of them together to describe
the addresses used by modern Bitcoin software.
==== Public Key Cryptography and Cryptocurrency
((("keys and addresses", "overview of", "public key
cryptography")))((("digital currencies", "cryptocurrency")))Public key
cryptography was invented in the 1970s and is a mathematical foundation
for computer and information security.
Since the invention of public key cryptography, several suitable
mathematical functions, such as prime number exponentiation and elliptic
curve multiplication, have been discovered. These mathematical functions
are practically irreversible, meaning that they are easy to calculate in
one direction and infeasible to calculate in the opposite direction.
Based on these mathematical functions, cryptography enables the creation
of digital secrets and unforgeable digital signatures. Bitcoin uses
elliptic curve multiplication as the basis for its cryptography.
In bitcoin, we use public key cryptography to create a key pair that
controls access to bitcoin. The key pair consists of a private key
and--derived from it--a unique public key. The public key is used to
receive funds, and the private key is used to sign transactions to spend
the funds.
There is a mathematical relationship between the public and the private
key that allows the private key to be used to generate signatures on
messages. This signature can be validated against the public key without
revealing the private key.
When spending bitcoin, the current bitcoin owner presents her public key
and a signature (different each time, but created from the same private
key) in a transaction to spend those bitcoin. Through the presentation
of the public key and signature, everyone in the Bitcoin network can
verify and accept the transaction as valid, confirming that the person
transferring the bitcoin owned them at the time of the transfer.
[TIP]
====
((("keys and addresses", "overview of", "key pairs")))In most wallet
implementations, the private and public keys are stored together as a
_key pair_ for convenience. However, the public key can be calculated
from the private key, so storing only the private key is also possible.
====
[[private_public_keys]]
==== Private and Public Keys
((("keys and addresses", "overview of", "private and public key
pairs")))((("elliptic curve cryptography")))((("cryptography", "elliptic
curve cryptography")))A bitcoin wallet contains a collection of key
pairs, each consisting of a private key and a public key. The private
key (k) is a number, usually derived from a number picked at random.
From the private key, we
use elliptic curve multiplication, a one-way cryptographic function, to
generate a public key (K). From the public key (K), we use a one-way
cryptographic hash function to generate a Bitcoin address (A). In this
section, we will start with generating the private key, look at the
elliptic curve math that is used to turn that into a public key, and
finally, generate a Bitcoin address from the public key. The
relationship between private key, public key, and Bitcoin address is
shown in <<k_to_K_to_A>>.
[[k_to_K_to_A]]
.Private key, public key, and Bitcoin address
image::images/mbc2_0401.png["privk_to_pubK_to_addressA"]
.Why Use Asymmetric Cryptography (Public/Private Keys)?
****
((("cryptography", "asymmetric")))((("digital signatures", "asymmetric
cryptography and")))((("asymmetric cryptography")))Why is asymmetric
cryptography used in bitcoin? It's not used to "encrypt" (make secret)
the transactions. Rather, the useful property of asymmetric cryptography
is the ability to generate _digital signatures_. A private key can be
applied to the digital fingerprint of a transaction to produce a
numerical signature. This signature can only be produced by someone with
knowledge of the private key. However, anyone with access to the public
key and the transaction fingerprint can use them to _verify_ the
signature. This useful property of asymmetric cryptography makes it
possible for anyone to verify every signature on every transaction,
while ensuring that only the owners of private keys can produce valid
signatures.
****
[[private_keys]]
==== Private Keys
((("keys and addresses", "overview of", "private key
generation")))((("warnings and cautions", "private key protection")))A
private key is simply a number, picked at random. Ownership and control
over the private key is the root of user control over all funds
associated with the corresponding Bitcoin address. The private key is
used to create signatures that are required to spend bitcoin by proving
ownership of funds used in a transaction. The private key must remain
secret at all times, because revealing it to third parties is equivalent
to giving them control over the bitcoin secured by that key. The private
key must also be backed up and protected from accidental loss, because
if it's lost it cannot be recovered and the funds secured by it are
forever lost, too.
[TIP]
====
The bitcoin private key is just a number. You can pick your private keys
randomly using just a coin, pencil, and paper: toss a coin 256 times and
you have the binary digits of a random private key you can use in a
bitcoin wallet. The public key can then be generated from the private
key.
====
===== Generating a private key from a random number
The first and most important step in generating keys is to find a secure
source of entropy, or randomness. Creating a bitcoin key is essentially
the same as "Pick a number between 1 and 2^256^." The exact method you
use to pick that number does not matter as long as it is not predictable
or repeatable. Bitcoin software uses cryptographically-secure random
number generators to produce 256 bits of entropy (randomness).
More precisely, the private key can be any number between +0+ and +n -
1+ inclusive, where n is a constant (n = 1.1578 * 10^77^, slightly less
than 2^256^) defined as the order of the elliptic curve used in bitcoin
(see <<elliptic_curve>>). To create such a key, we randomly pick a
256-bit number and check that it is less than +n+. In programming terms,
this is usually achieved by feeding a larger string of random bits,
collected from a cryptographically secure source of randomness, into the
SHA256 hash algorithm, which will conveniently produce a 256-bit number.
If the result is less than +n+, we have a suitable private key.
Otherwise, we simply try again with another random number.
[WARNING]
====
((("random numbers", "random number generation")))((("entropy", "random
number generation")))Do not write your own code to create a random
number or use a "simple" random number generator offered by your
programming language. Use a cryptographically secure pseudorandom number
generator (CSPRNG) with a seed from a source of sufficient entropy.
Study the documentation of the random number generator library you
choose to make sure it is cryptographically secure. Correct
implementation of the CSPRNG is critical to the security of the keys.
====
The following is a randomly generated private key (k) shown in
hexadecimal format (256 bits shown as 64 hexadecimal digits, each 4
bits):
----
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
----
[TIP]
====
The size of bitcoin's private key space, (2^256^) is an unfathomably
large number. It is approximately 10^77^ in decimal. For comparison, the
visible universe is estimated to contain 10^80^ atoms.
====
((("dumpprivkey command")))To generate a new key with the Bitcoin Core
client (see <<ch03_bitcoin_client>>), use the +getnewaddress+ command.
For security reasons it displays the public key only, not the private
key. To ask +bitcoind+ to expose the private key, use the +dumpprivkey+
command. The +dumpprivkey+ command shows the private key in a Base58
checksum-encoded format called the _Wallet Import Format_ (WIF), which
we will examine in more detail in <<priv_formats>>. Here's an example of
generating and displaying a private key using these two commands:
----
$ bitcoin-cli getnewaddress
1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
$ bitcoin-cli dumpprivkey 1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
----
The +dumpprivkey+ command opens the wallet and extracts the private key
that was generated by the +getnewaddress+ command. It is not possible
for +bitcoind+ to know the private key from the public key unless they
are both stored in the wallet.
[TIP]
=====================================================================
The +dumpprivkey+ command does not generate a private key from a public
key, as this is impossible. The command simply reveals the private key
that is already known to the wallet and which was generated by the
+getnewaddress+ command.
=====================================================================
[role="pagebreak-before"]
You can also use the Bitcoin Explorer command-line tool (see
<<appdx_bx>>) to generate and display private keys with the commands
+seed+, +ec-new+, and +ec-to-wif+:
----
$ bx seed | bx ec-new | bx ec-to-wif
5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
----
[[pubkey]]
==== Public Keys
((("keys and addresses", "overview of", "public key
calculation")))((("generator point")))The public key is calculated from
the private key using elliptic curve multiplication, which is
irreversible: _K_ = _k_ * _G_, where _k_ is the private key, _G_ is a
constant point called the _generator point_, and _K_ is the resulting
public key. The reverse operation, known as "finding the discrete
logarithm"—calculating _k_ if you know __K__—is as difficult as trying
all possible values of _k_, i.e., a brute-force search. Before we
demonstrate how to generate a public key from a private key, let's look
at elliptic curve cryptography in a bit more detail.
[TIP]
====
Elliptic curve multiplication is a type of function that cryptographers
call a "trap door" function: it is easy to do in one direction
(multiplication) and impossible to do in the reverse direction
(division). The owner of the private key can easily create the public
key and then share it with the world knowing that no one can reverse the
function and calculate the private key from the public key. This
mathematical trick becomes the basis for unforgeable and secure digital
signatures that prove ownership of bitcoin funds.
====
[[elliptic_curve]]
==== Elliptic Curve Cryptography Explained
((("keys and addresses", "overview of", "elliptic curve
cryptography")))((("elliptic curve cryptography",
id="eliptic04")))((("cryptography", "elliptic curve cryptography",
id="Celliptic04")))Elliptic curve cryptography is a type of asymmetric
or public key cryptography based on the discrete logarithm problem as
expressed by addition and multiplication on the points of an elliptic
curve.
<<ecc-curve>> is an example of an elliptic curve, similar to that used
by bitcoin.
[[ecc-curve]]
[role="smallerthirty"]
.An elliptic curve
image::images/mbc2_0402.png["ecc-curve"]
Bitcoin uses a specific elliptic curve and set of mathematical
constants, as defined in a standard called +secp256k1+, established by
the National Institute of Standards and Technology (NIST). The
+secp256k1+ curve is defined by the following function, which produces
an elliptic curve:
[latexmath]
++++
\begin{equation}
{y^2 = (x^3 + 7)}~\text{over}~(\mathbb{F}_p)
\end{equation}
++++
or
[latexmath]
++++
\begin{equation}
{y^2 \mod p = (x^3 + 7) \mod p}
\end{equation}
++++
The _mod p_ (modulo prime number p) indicates that this curve is over a
finite field of prime order _p_, also written as latexmath:[\(
\mathbb{F}_p \)], where p = 2^256^ 2^32^ 2^9^ 2^8^ 2^7^ 2^6^
2^4^ 1, a very large prime number.
Because this curve is defined over a finite field of prime order instead
of over the real numbers, it looks like a pattern of dots scattered in
two dimensions, which makes it difficult to visualize. However, the math
is identical to that of an elliptic curve over real numbers. As an
example, <<ecc-over-F17-math>> shows the same elliptic curve over a much
smaller finite field of prime order 17, showing a pattern of dots on a
grid. The +secp256k1+ bitcoin elliptic curve can be thought of as a much
more complex pattern of dots on a unfathomably large grid.
[[ecc-over-F17-math]]
[role="smallersixty"]
.Elliptic curve cryptography: visualizing an elliptic curve over F(p), with p=17
image::images/mbc2_0403.png["ecc-over-F17-math"]
So, for example, the following is a point P with coordinates (x,y) that
is a point on the +secp256k1+ curve:
----
P = (55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424)
----
<<example_4_1>> shows how you can check this yourself using Python:
[[example_4_1]]
.Using Python to confirm that this point is on the elliptic curve
====
[source, pycon]
----
Python 3.4.0 (default, Mar 30 2014, 19:23:13)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
>>> x = 55066263022277343669578718895168534326250603453777594175500187360389116729240
>>> y = 32670510020758816978083085130507043184471273380659243275938904335757337482424
>>> (x ** 3 + 7 - y**2) % p
0
----
====
In elliptic curve math, there is a point called the "point at infinity,"
which roughly corresponds to the role of zero in addition. On computers,
it's sometimes represented by x = y = 0 (which doesn't satisfy the
elliptic curve equation, but it's an easy separate case that can be
checked).
There is also a pass:[+] operator, called "addition," which has some
properties similar to the traditional addition of real numbers that
gradeschool children learn. Given two points P~1~ and P~2~ on the
elliptic curve, there is a third point P~3~ = P~1~ + P~2~, also on the
elliptic curve.
Geometrically, this third point P~3~ is calculated by drawing a line
between P~1~ and P~2~. This line will intersect the elliptic curve in
exactly one additional place. Call this point P~3~' = (x, y). Then
reflect in the x-axis to get P~3~ = (x, y).
There are a couple of special cases that explain the need for the "point
at infinity."
If P~1~ and P~2~ are the same point, the line "between" P~1~ and P~2~
should extend to be the tangent on the curve at this point P~1~. This
tangent will intersect the curve in exactly one new point. You can use
techniques from calculus to determine the slope of the tangent line.
These techniques curiously work, even though we are restricting our
interest to points on the curve with two integer coordinates!
In some cases (i.e., if P~1~ and P~2~ have the same x values but
different y values), the tangent line will be exactly vertical, in which
case P3 = "point at infinity."
If P~1~ is the "point at infinity," then P~1~ + P~2~ = P~2~. Similarly,
if P~2~ is the point at infinity, then P~1~ + P~2~ = P~1~. This shows
how the point at infinity plays the role of zero.
It turns out that pass:[+] is associative, which means that (A pass:[+]
B) pass:[+] C = A pass:[+] (B pass:[+] C). That means we can write A
pass:[+] B pass:[+] C without parentheses and without ambiguity.
Now that we have defined addition, we can define multiplication in the
standard way that extends addition. For a point P on the elliptic curve,
if k is a whole number, then kP = P + P + P + ... + P (k times). Note
that k is sometimes confusingly called an "exponent" in this case.((("",
startref="eliptic04")))((("", startref="Celliptic04")))
[[public_key_derivation]]
==== Generating a Public Key
((("keys and addresses", "overview of", "public key
generation")))((("generator point")))Starting with a private key in the
form of a randomly generated number _k_, we multiply it by a
predetermined point on the curve called the _generator point_ _G_ to
produce another point somewhere else on the curve, which is the
corresponding public key _K_. The generator point is specified as part
of the +secp256k1+ standard and is always the same for all keys in
bitcoin:
[latexmath]
++++
\begin{equation}
{K = k * G}
\end{equation}
++++
where _k_ is the private key, _G_ is the generator point, and _K_ is the
resulting public key, a point on the curve. Because the generator point
is always the same for all bitcoin users, a private key _k_ multiplied
with _G_ will always result in the same public key _K_. The relationship
between _k_ and _K_ is fixed, but can only be calculated in one
direction, from _k_ to _K_. That's why a Bitcoin address (derived from
_K_) can be shared with anyone and does not reveal the user's private
key (_k_).
[TIP]
====
A private key can be converted into a public key, but a public key
cannot be converted back into a private key because the math only works
one way.
====
Implementing the elliptic curve multiplication, we take the private key
_k_ generated previously and multiply it with the generator point G to
find the public key _K_:
----
K = 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD * G
----
Public key _K_ is defined as a point +K = (x,y)+:
----
K = (x, y)
where,
x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
----
To visualize multiplication of a point with an integer, we will use the
simpler elliptic curve over real numbers&#x2014;remember, the math is
the same. Our goal is to find the multiple _kG_ of the generator point
_G_, which is the same as adding _G_ to itself, _k_ times in a row. In
elliptic curves, adding a point to itself is the equivalent of drawing a
tangent line on the point and finding where it intersects the curve
again, then reflecting that point on the x-axis.
<<ecc_illustrated>> shows the process for deriving _G_, _2G_, _4G_, as a
geometric operation on the curve.
[TIP]
====
((("OpenSSL cryptographic library")))Many Bitcoin implementations use
the https://github.com/bitcoin-core/secp256k1[libsecp256k1 crytographic
library] to do the elliptic curve math.
====
[[ecc_illustrated]]
.Elliptic curve cryptography: visualizing the multiplication of a point G by an integer k on an elliptic curve
image::images/mbc2_0404.png["ecc_illustrated"]
=== ScriptPubKey and ScriptSig
Although the illustration from the original Bitcoin paper, <<pay-to-pure-pubkey>>,
shows public keys (pubkeys) and signatures (sigs) being used directly,
the first version of Bitcoin instead had payments sent to a field called
_scriptPubKey_ and had them authorized by a field called _scriptSig_.
These fields allow additional operations to be performed in addition to
(or instead of) verifying that a signature corresponds to a public key.
For example, a scriptPubKey can contain two public keys and require two
corresponding signatures be placed in the spending scriptSig.
Later, in <<tx_script>>, we'll learn about scripts in detail. For now,
all we need to understand is that bitcoins are received to a
scriptPubKey which acts like a public key, and bitcoin spending is
authorized by a scriptSig which acts like a signature.
[[p2pk]]
=== IP Addresses: The Original Address For Bitcoin
We've established that Alice can pay Bob by assigning some of her
bitcoins to one of Bob's public keys. But how does Alice get one of
Bob's public keys? Bob could just give her a copy, but let's look again
at the public key we worked with in <<public_key_derivation>>. Notice
that it's quite long. Imagine Bob trying to read that to Alice over the
phone.
----
x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
----
Instead of direct public key entry, the earliest version of Bitcoin
software allowed a spender to enter the receiver's IP address. This
feature was later removed--there are many problems
with using IP addresses--but a quick description of it will help us
better understand why certain features may have been added to the
Bitcoin protocol.
[[bitcoin_01_send]]
.Early send screen for Bitcoin via http://web.archive.org/web/20090722011820/https://bitcoin.org/[The Internet Archive]
image::images/bitcoin-01-send.png["Early Bitcoin send screen"]
If Alice entered Bob's IP address in Bitcoin 0.1, her full node would
establish a connection with his full node and receive a new public key
from Bob's wallet that his node had never previously given anyone. This
being a new public key was important to ensure that different
transactions paying Bob couldn't be connected together by someone
looking at the blockchain and noticing that all of the transactions paid
the same public key.
Using the public key her node received from Bob's node, Alice's wallet
would construct a transaction output paying a very simple scriptPubKey:
----
<Bob's public key> OP_CHECKSIG
----
Bob would later be able to spend that output with a scriptSig consisting
entirely of his signature:
----
<Bob's signature>
----
To figure out what a scriptPubKey and scriptSig are doing, you can
combine them together (scriptSig first) and then note that each piece of
data (shown in angle brackets) is placed at the top of a list of items,
called a stack. When an operation code (opcode) is encountered, it uses
items from the stack, starting with the topmost items. Let's look at
how that works by beginning with the combined script:
----
<Bob's signature> <Bob's public key> OP_CHECKSIG
----
For this script, Bob's signature is put on the stack, then Bob's public
key is placed on top of it. The +OP_CHECKSIG+ operation consumes two
elements, starting with the public key and followed by the signature,
removing them from the stack. It verifies the signature corresponds to
the public key and also commits to (signs) the various fields in the
transaction. If the signature is correct, OP_CHECKSIG replaces itself
on the stack with the value 1; if the signature was not correct, it
replaces itself with a 0. If the top of the stack is non-zero at the
end of evaluation, the script passes. If all scripts in a transaction
pass, and all of the other details about the transaction are valid, then
full nodes will consider the transaction to be valid.
In short, the script above uses the same public key and signature
described in the original paper but adds in the complexity of two script
fields and an opcode. That seems like extra work here, but we'll begin
to see the benefits when we look at <<p2pkh>>.
This type of output is known today as _Pay-to-Public-Key_, or _P2PK_ for
short. It was never widely used for payments, and no widely-used
program has supported IP address payments for almost a decade.
[[p2pkh]]
=== Legacy Addresses for P2PKH
Entering the IP address of the person you want to pay has a number of
advantages, but it also has a number of downsides. One particular
downside is that the receiver needs their wallet to be online at their
IP address, and it needs to be accessible from the outside world. For
a lot of people, that isn't an option. They turn their computers off at
night, their laptops go to sleep, they're behind firewalls, or they're
using Network Address Translation (NAT).
This brings us back to the problem of receivers like Bob having to give
spenders like Alice a long public key. The shortest version of Bitcoin
public keys known to the developers of early Bitcoin were 65 bytes, or
about 130 characters when written in hexadecimal. However, Bitcoin
already contained several data structures much larger than 65 bytes
which needed to be securely referenced in other parts of Bitcoin using the
smallest amount of data that was secure.
Bitcoin accomplishes that with a _hash function_, a function which takes
a potentially large amount of data and scrambles (hashes) it into a
fixed amount of data. A cryptographic hash function will always produce
the same output when given the same input, and a secure function will
also make it impractical for somebody to choose a different input that
produces a previously-seen output. That makes the output a _commitment_
to the input. It's a promise that, in practice, only input _x_ will
produce output _X_.
For example, imagine I want to ask you a question and also give you my
answer in a form that you can't read immediately. Let's say the
question is, "in what year did Satoshi Nakamoto start working on
Bitcoin?" I'll give you my commitment to the answer in the form of
output from the SHA256 hash function, the function most commonly used in
Bitcoin:
----
94d7a772612c8f2f2ec609d41f5bd3d04a5aa1dfe3582f04af517d396a302e4e
----
Later, after you tell me your guess to the answer of the question, I can
reveal my answer and prove to you that my answer, as input to the hash
function, produces exactly the same output I gave you earlier:
----
$ echo "2007. He said about a year and a half before Oct 2008" | sha256sum
94d7a772612c8f2f2ec609d41f5bd3d04a5aa1dfe3582f04af517d396a302e4e
----
Now imagine that we ask Bob the question, "what is your public key?" Bob
can use a hash function to give us a cryptographically secure commitment
to his public key. If he later reveals his key, and we verify it
produces the same commitment he previously gave us, we can be sure it
was the exact same key that was used to create that earlier commitment.
The SHA256 hash function is considered to be very secure and produces
256 bits (32 bytes) of output, less than half the size of original
Bitcoin public keys. However, there are other slightly less secure hash
functions that produce smaller output, such as the RIPEMD160 hash
function whose output is 160 bits (20 bytes). For reasons Satoshi
Nakamoto never stated, the original version of Bitcoin made commitments
to public keys by first hashing the key with SHA256 and then hashing
that output with RIPEMD160; this produced a 20-byte commitment to the
public key.
We can look at that algorithmically.
Starting with the public key _K_, we compute the SHA256 hash and then
compute the RIPEMD160 hash of the result, producing a 160-bit (20-byte)
number:
[latexmath]
++++
\begin{equation}
{A = RIPEMD160(SHA256(K))}
\end{equation}
++++
where _K_ is the public key and _A_ is the resulting commitment.
Now that we understand how to make a commitment to a public key, we need
to figure out how to use it in a transaction. Consider the following
scriptPubKey:
----
OP_DUP OP_HASH160 <Bob's commitment> OP_EQUAL OP_CHECKSIG
----
And also the following scriptSig:
----
<Bob's signature> <Bob's public key>
----
Together, they form the following script:
----
<sig> <pubkey> OP_DUP OP_HASH160 <commitment> OP_EQUALVERIFY OP_CHECKSIG
----
As we did in <<p2pk>>, we start putting items on the stack. Bob's
signature goes on first; his public key is then placed on top of the
stack. The +OP_DUP+ operation duplicates the top item, so the top and
second-to-top item on the stack are now both Bob's public key. The
+OP_HASH160+ operation consumes (removes) the top public key and
replaces it with the result of hashing it with +RIPEMD160(SHA256(K))+,
so now the top of the stack is a hash of Bob's public key. Next, the
commitment to Bob's public key is added to the top of the stack. The
+OP_EQUALVERIFY+ operation consumes the top two items and verifies that
they are equal; that should be the case if the public key Bob provided
in the scriptSig is the same public key used to create the commitment in
the scriptPubKey that Alice paid. If +OP_EQUALVERIFY+ fails, the whole
script fails. Finally, we're left with a stack containing just Bob's
signature and his public key; the +OP_CHECKSIG+ opcode verifies they
correspond with each other and that the signature commits to the
transaction.
Although this process of Paying To a Public Key Hash (_P2PKH_) may seem
convoluted, it allows Alice's payment to
Bob to contain only a 20 byte commitment to his public key instead of
the key itself, which would've been 65 bytes in the original version of
Bitcoin. That's a lot less data for Bob to have to communicate to
Alice.
However, we haven't yet discussed how Bob gets those 20 bytes from his
Bitcoin wallet to Alice's wallet. There are commonly used encodings for
byte values, such as hexadecimal, but any mistake made in copying a
commitment would result in the bitcoins being sent to an unspendable
output, causing them to be lost forever. In <<base58>>, we'll
look at compact encoding and reliable checksums.
[[base58]]
==== Base58 and Base58Check Encoding
((("keys and addresses", "Bitcoin addresses", "Base58 and Base58check
encoding")))((("Base58 and Base58check encoding",
id="base5804")))((("addresses", "Base58 and Base58check encoding",
id="Abase5804")))In order to represent long numbers in a compact way,
using fewer symbols, many computer systems use mixed-alphanumeric
representations with a base (or radix) higher than 10. For example,
whereas the traditional decimal system uses the 10 numerals 0 through 9,
the hexadecimal system uses 16, with the letters A through F as the six
additional symbols. A number represented in hexadecimal format is
shorter than the equivalent decimal representation. Even more compact,
Base64 representation uses 26 lowercase letters, 26 capital letters, 10
numerals, and 2 more characters such as &#x201c;`+`&#x201d; and "/" to
transmit binary data over text-based media such as email. Base64 is most
commonly used to add binary attachments to email. Base58 is a text-based
binary-encoding format developed for use in bitcoin and used in many
other cryptocurrencies. It offers a balance between compact
representation, readability, and error detection and prevention. Base58
is a subset of Base64, using upper- and lowercase letters and numbers,
but omitting some characters that are frequently mistaken for one
another and can appear identical when displayed in certain fonts.
Specifically, Base58 is Base64 without the 0 (number zero), O (capital
o), l (lower L), I (capital i), and the symbols &#x201c;`+`&#x201d; and
"/". Or, more simply, it is a set of lowercase and capital letters and
numbers without the four (0, O, l, I) just mentioned. <<base58alphabet>>
shows the full Base58 alphabet.
[[base58alphabet]]
.Bitcoin's Base58 alphabet
====
----
123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
----
====
To add extra security against typos or transcription errors, Base58Check
is a Base58 encoding format, frequently used in bitcoin, which has a
built-in error-checking code. The checksum is an additional four bytes
added to the end of the data that is being encoded. The checksum is
derived from the hash of the encoded data and can therefore be used to
detect and prevent transcription and typing errors. When presented with
Base58Check code, the decoding software will calculate the checksum of
the data and compare it to the checksum included in the code. If the two
do not match, an error has been introduced and the Base58Check data is
invalid. This prevents a mistyped Bitcoin address from being accepted by
the wallet software as a valid destination, an error that would
otherwise result in loss of funds.
To convert data (a number) into a Base58Check format, we first add a
prefix to the data, called the "version byte," which serves to easily
identify the type of data that is encoded. For example, in the case of a
Bitcoin address the prefix is zero (0x00 in hex), whereas the prefix
used when encoding a private key is 128 (0x80 in hex). A list of common
version prefixes is shown in <<base58check_versions>>.
Next, we compute the "double-SHA" checksum, meaning we apply the SHA256
hash-algorithm twice on the previous result (prefix and data):
----
checksum = SHA256(SHA256(prefix+data))
----
From the resulting 32-byte hash (hash-of-a-hash), we take only the first
four bytes. These four bytes serve as the error-checking code, or
checksum. The checksum is concatenated (appended) to the end.
The result is composed of three items: a prefix, the data, and a
checksum. This result is encoded using the Base58 alphabet described
previously. <<base58check_encoding>> illustrates the Base58Check
encoding process.
[[base58check_encoding]]
.Base58Check encoding: a Base58, versioned, and checksummed format for unambiguously encoding bitcoin data
image::images/mbc2_0406.png["Base58CheckEncoding"]
In bitcoin, most of the data presented to the user is
Base58Check-encoded to make it compact, easy to read, and easy to detect
errors. The version prefix in Base58Check encoding is used to create
easily distinguishable formats, which when encoded in Base58 contain
specific characters at the beginning of the Base58Check-encoded payload.
These characters make it easy for humans to identify the type of data
that is encoded and how to use it. This is what differentiates, for
example, a Base58Check-encoded Bitcoin address that starts with a 1 from
a Base58Check-encoded private key WIF that starts with a 5. Some example
version prefixes and the resulting Base58 characters are shown in
<<base58check_versions>>.
[[base58check_versions]]
.Base58Check version prefix and encoded result examples
[options="header"]
|=======
|Type| Version prefix (hex)| Base58 result prefix
| Bitcoin Address | 0x00 | 1
| Pay-to-Script-Hash Address | 0x05 | 3
| Bitcoin Testnet Address | 0x6F | m or n
| Private Key WIF | 0x80 | 5, K, or L
| BIP-38 Encrypted Private Key | 0x0142 | 6P
| BIP-32 Extended Public Key | 0x0488B21E | xpub
|=======
==== Key Formats
[[pubkey_to_address]]
.Public key to Bitcoin address: conversion of a public key into a Bitcoin address
image::images/mbc2_0405.png["pubkey_to_address"]
===== Decode from Base58Check
The Bitcoin Explorer commands (see <<appdx_bx>>) make it easy to write
shell scripts and command-line "pipes" that manipulate bitcoin keys,
addresses, and transactions. You can use Bitcoin Explorer to decode the
Base58Check format on the command line.
We use the +base58check-decode+ command to decode the uncompressed key:
----
$ bx base58check-decode 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
wrapper
{
checksum 4286807748
payload 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
version 128
}
----
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+, signaling that the derived public key is to be compressed:
----
$ bx base58check-decode KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
wrapper
{
checksum 2339607926
payload 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd01
version 128
}
----
FIXME:HERE
[[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 in
<<public_key_derivation>>.
----
x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
----
Here's the same public key shown as a 520-bit number (130 hex digits)
with the prefix +04+ followed by +x+ and then +y+ coordinates, as +04 x
y+:
++++
<pre data-type="programlisting">
K = 04F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A&#x21b5;
07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
</pre>
++++
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
is __y__^2^, the solution for _y_ is a square root, which can have a
positive or negative value. Visually, this means that the resulting _y_
coordinate can be above or below the x-axis. As you can see from the
graph of the elliptic curve in <<ecc-curve>>, the curve is symmetric,
meaning it is reflected like a mirror by the x-axis. So, while we can
omit the _y_ coordinate we have to store the _sign_ of _y_ (positive or
negative); or in other words, we have to remember if it was above or
below the x-axis because each of those options represents a different
point and a different public key. When calculating the elliptic curve in
binary arithmetic on the finite field of prime order p, the _y_
coordinate is either even or odd, which corresponds to the
positive/negative sign as explained earlier. Therefore, to distinguish
between the two possible values of _y_, we store a compressed public key
with the prefix +02+ if the _y_ is even, and +03+ if it is odd, allowing
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 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:
----
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 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
addresses. However, the private key is identical for both Bitcoin
addresses.
[[pubkey_compression]]
[role="smallerseventy"]
.Public key compression
image::images/mbc2_0407.png["pubkey_compression"]
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.
[[p2sh]]
=== Legacy Pay-to-Script-Hash (P2SH)
As we've seen in preceding sections, someone receiving Bitcoins (like
Bob) can require payments to him contain certain constraints in their
scriptPubKeys. Bob will need to fulfill those constraints using a
scriptSig when he spends those bitcoins. In <<p2pk>>, the constraint
was simply that the scriptSig needed to provide an appropriate
signature. In <<p2pkh>>, an appropriate public key also needed to be
provided.
In order for a spender (like Alice) to place the constraints Bob wants
in the scriptPubKey she uses to pay him, Bob needs to communicate those
constraints to her. This is similar to the problem of Bob needing to
communicate his public key to her. Like that problem, where
public keys can be fairly large, the constraints Bob uses can also be
quite large---potentially thousands of bytes. That's not only thousands
of bytes which need to be communicated to Alice, but thousands of bytes
for which she needs to pay transaction fees every time she wants to spend
money to Bob. However, the solution of using hash functions to create
small commitments to large amounts of data also applies here.
The BIP16 upgrade to the Bitcoin protocol in 2013 allows a
scriptPubKey to commit to a _redemption script_ (_redeemScript_). When
Bob spends his bitcoins, his scriptSig need to provide a redeemScript
that matches the commitment and also any data necessary to satisfy the
redeemScript (such as signatures). Let's start by imagining Bob wants
to require two signatures from different wallets he controls in
order to spend his bitcoins. He puts those conditions into a
redeemScript:
----
<pubkey1> OP_CHECKSIGVERIFY <pubkey2> OP_CHECKSIG
----
He then creates a commitment to the redeemScript using the same
HASH160 mechanism used for P2PKH commitments, +RIPEMD160(SHA256(script))+.
That commitment is placed into the scriptPubKey using a special
template:
----
OP_HASH160 <commitment> OP_EQUAL
----
[WARNING]
====
Payments to Script Hashes (P2SH) must use the specific P2SH template
with no extra data or conditions in the scriptPubKey. If the
scriptPubKey is not exactly +OP_HASH160 <20 bytes> OP_EQUAL+, the
redeemScript will not be used and any bitcoins may either be unspendable
or spendable by anyone (meaning anyone can take them).
====
When Bob goes to spend the payment he received to the commitment for his
script, he uses a scriptSig that includes the redeemScript, with it
serialized as a single data element. He also provides the signatures
he needs to satisfy the redeemScript, putting them in the order that
they will be consumed by the opcodes:
----
<signature2> <signature1> <redeemScript>
----
When Bitcoin full nodes receive Bob's spend, they'll verify that the
serialized redeemScript will hash to the same value as the commitment.
Then they'll replace it on the stack with its deserialized value:
----
<signature2> <signature1> <pubkey1> OP_CHECKSIGVERIFY <pubkey2> OP_CHECKSIG
----
The script is executed and, if it passes and all of the other
transaction details are correct, the transaction is valid.
Addresses for Pay-to-Script-Hash (P2SH) are also created with
Base58Check. The version prefix is set to 5, which results in an
encoded address starting with a +3+. An example of a P2SH address is
+3F6i6kwkevjR7AsAd4te2YB2zZyASEm1HM+, which can be derived using the
Bitcoin Explorer commands +script-encode+, +sha256+, +ripemd160+, and
+base58check-encode+ (see <<appdx_bx>>) as follows:
----
$ echo \
'DUP HASH160 [89abcdefabbaabbaabbaabbaabbaabbaabbaabba] EQUALVERIFY CHECKSIG' > script
$ bx script-encode < script | bx sha256 | bx ripemd160 \
| bx base58check-encode --version 5
3F6i6kwkevjR7AsAd4te2YB2zZyASEm1HM
----
[TIP]
====
P2SH is not necessarily the same as a multisignature
transaction. A P2SH address _most often_ represents a multisignature
script, but it might also represent a script encoding other types of
transactions.
====
P2PKH and P2SH are the only two script templates used with Base58Check
encoding. They are now known as legacy addresses and, as of early 2023,
are only used in
https://transactionfee.info/charts/payments-spending-segwit/[about 10% of transactions].
Legacy addresses were supplanted by the bech32 family of addresses.
==== Key Formats
((("keys and addresses", "Bitcoin addresses", "key formats")))Both
private and public keys can be represented in a number of different
formats. These representations all encode the same number, even though
they look different. These formats are primarily used to make it easy
for people to read and transcribe keys without introducing errors.
[[priv_formats]]
===== Private key formats
((("public and private keys", "private key formats")))The private key
can be represented in a number of different formats, all of which
correspond to the same 256-bit number. <<table_4-2>> shows three common
formats used to represent private keys. Different formats are used in
different circumstances. Hexadecimal and raw binary formats are used
internally in software and rarely shown to users. The WIF is used for
import/export of keys between wallets and often used in QR code
(barcode) representations of private keys.
.Modern relevancy of private key formats
****
Early Bitcoin wallet software generated one or more independent private
keys when a new user wallet was initialized. When the initial set of
keys had all been used, the wallet might generate additional private
keys. Individual private keys could be exported or imported. Any time
new private keys were generated or imported, a new backup of the wallet
needed to be created.
Later Bitcoin wallets began using deterministic wallets where all
private keys are generated from a single seed value. These wallets only
ever need to be backed up once for typical onchain use. However, if a
user exports a single private key from one of these wallets and an
attacker acquires that key plus some non-private data about the wallet,
they can potentially derive any private key in the wallet--allowing the
attacker to steal all of the wallet funds. Additionally, keys cannot be
imported into deterministic wallets. This means almost no modern
wallets support the ability to export or import an individual key. The
information in this section is mainly of interest to anyone needing
compatibility with early Bitcoin wallets.
For more information, see <<hd_wallets>>.
****
[[table_4-2]]
.Private key representations (encoding formats)
[options="header"]
|=======
|Type|Prefix|Description
| Raw | None | 32 bytes
| Hex | None | 64 hexadecimal digits
| WIF | 5 | Base58Check encoding: Base58 with version prefix of 128- and 32-bit checksum
| WIF-compressed | K or L | As above, with added suffix 0x01 before encoding
|=======
<<table_4-3>> shows the private key generated in these three formats.
[[table_4-3]]
.Example: Same key, different formats
[options="header"]
|=======
|Format | Private key
| Hex | 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
| WIF | 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
| WIF-compressed | KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
|=======
All of these representations are different ways of showing the same
number, the same private key. They look different, but any one format
can easily be converted to any other format. Note that the "raw binary"
is not shown in <<table_4-3>> as any encoding for display here would, by
definition, not be raw binary data.
We use the +wif-to-ec+ command from Bitcoin Explorer (see <<appdx_bx>>)
to show that both WIF keys represent the same private key:
----
$ bx wif-to-ec 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
$ bx wif-to-ec KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
----
[[comp_priv]]
===== Compressed private keys
((("public and private keys", "compressed private keys")))Ironically,
the term "compressed private key" is a misnomer, because when a private
key is exported as WIF-compressed it is actually one byte _longer_ than
an "uncompressed" private key. That is because the private key has an
added one-byte suffix (shown as 01 in hex in <<table_4-4>>), which
signifies that the private key is from a newer wallet and should only be
used to produce compressed public keys. Private keys are not themselves
compressed and cannot be compressed. The term "compressed private key"
really means "private key from which only compressed public keys should
be derived," whereas "uncompressed private key" really means "private
key from which only uncompressed public keys should be derived." You
should only refer to the export format as "WIF-compressed" or "WIF" and
not refer to the private key itself as "compressed" to avoid further
confusion
<<table_4-4>> shows the same key, encoded in WIF and WIF-compressed formats.
[[table_4-4]]
.Example: Same key, different formats
[options="header"]
|=======
|Format | Private key
| Hex | 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
| WIF | 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
| Hex-compressed | 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD01
| WIF-compressed | KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
|=======
Notice that the hex-compressed private key format has one extra byte at
the end (01 in hex). While the Base58 encoding version prefix is the
same (0x80) for both WIF and WIF-compressed formats, the addition of one
byte on the end of the number causes the first character of the Base58
encoding to change from a 5 to either a _K_ or _L_. Think of this as the
Base58 equivalent of the decimal encoding difference between the number
100 and the number 99. While 100 is one digit longer than 99, it also
has a prefix of 1 instead of a prefix of 9. As the length changes, it
affects the prefix. In Base58, the prefix 5 changes to a _K_ or _L_ as
the length of the number increases by one byte.
Remember, these formats are _not_ used interchangeably. In a newer
wallet that implements compressed public keys, the private keys will
only ever be exported as WIF-compressed (with a _K_ or _L_ prefix). If
the wallet is an older implementation and does not use compressed public
keys, the private keys will only ever be exported as WIF (with a 5
prefix). The goal here is to signal to the wallet importing these
private keys whether it must search the blockchain for compressed or
uncompressed public keys and addresses.
If a bitcoin wallet is able to implement compressed public keys, it will
use those in all transactions. The private keys in the wallet will be
used to derive the public key points on the curve, which will be
compressed. The compressed public keys will be used to produce Bitcoin
addresses and those will be used in transactions. When exporting private
keys from a new wallet that implements compressed public keys, the WIF
is modified, with the addition of a one-byte suffix +01+ to the private
key. The resulting Base58Check-encoded private key is called a
"compressed WIF" and starts with the letter _K_ or _L_, instead of
starting with "5" as is the case with WIF-encoded (noncompressed) keys
from older wallets.
[TIP]
====
"Compressed private keys" is a misnomer! They are not compressed;
rather, WIF-compressed signifies that the keys should only be used to
derive compressed public keys and their corresponding Bitcoin addresses.
Ironically, a "WIF-compressed" encoded private key is one byte longer
because it has the added +01+ suffix to distinguish it from an
"uncompressed" one.((("", startref="KAaddress04")))
====
=== Implementing Keys and Addresses in Cpass:[++]
Let's look at the complete process of creating a Bitcoin address, from a
private key, to a public key (a point on the elliptic curve), to a
double-hashed address, and finally, the Base58Check encoding. The C++
code in <<addr_example>> shows the complete step-by-step process, from
private key to Base58Check-encoded Bitcoin address. The code example
uses the libbitcoin library introduced in <<alt_libraries>> for some
helper functions.
[[addr_example]]
.Creating a Base58Check-encoded Bitcoin address from a private key
====
[role="c_less_space"]
[source, cpp]
----
include::code/addr.cpp[]
----
====
The code uses a predefined private key to produce the same Bitcoin
address every time it is run, as shown in <<addr_example_run>>.((("",
startref="base5804")))((("", startref="Abase5804")))
[[addr_example_run]]
.Compiling and running the addr code
====
[source,bash]
----
# Compile the addr.cpp code
$ g++ -o addr addr.cpp -std=c++11 $(pkg-config --cflags --libs libbitcoin)
# Run the addr executable
$ ./addr
Public key: 0202a406624211f2abbdc68da3df929f938c3399dd79fac1b51b0e4ad1d26a47aa
Address: 1PRTTaJesdNovgne6Ehcdu1fpEdX7913CK
----
====
[TIP]
====
The code in <<addr_example_run>> produces a Bitcoin address (+1PRTT...+)
from a _compressed_ public key (see <<comp_pub>>). If you used the
uncompressed public key instead, it would produce a different Bitcoin
address (+14K1y...+).
====
=== Implementing Keys and Addresses in Python
((("keys and addresses", "implementing in Python",
id="KApython04")))((("pybitcointools")))The most comprehensive bitcoin
library in Python is
https://github.com/vbuterin/pybitcointools[pybitcointools] by Vitalik
Buterin. In <<key-to-address_script>>, we use the pybitcointools library
(imported as "bitcoin") to generate and display keys and addresses in
various formats.
[[key-to-address_script]]
.Key and address generation and formatting with the pybitcointools library
====
[source,python]
----
include::code/key-to-address-ecc-example.py[]
----
====
<<key-to-address_script_run>> shows the output from running this code.
[[key-to-address_script_run]]
.Running key-to-address-ecc-example.py
====
++++
<pre data-type="programlisting">
$ python key-to-address-ecc-example.py
Private Key (hex) is:
3aba4162c7251c891207b747840551a71939b0de081f85c4e44cf7c13e41daa6
Private Key (decimal) is:
26563230048437957592232553826663696440606756685920117476832299673293013768870
Private Key (WIF) is:
5JG9hT3beGTJuUAmCQEmNaxAuMacCTfXuw1R3FCXig23RQHMr4K
Private Key Compressed (hex) is:
3aba4162c7251c891207b747840551a71939b0de081f85c4e44cf7c13e41daa601
Private Key (WIF-Compressed) is:
KyBsPXxTuVD82av65KZkrGrWi5qLMah5SdNq6uftawDbgKa2wv6S
Public Key (x,y) coordinates is:
(41637322786646325214887832269588396900663353932545912953362782457239403430124L,
16388935128781238405526710466724741593761085120864331449066658622400339362166L)
Public Key (hex) is:
045c0de3b9c8ab18dd04e3511243ec2952002dbfadc864b9628910169d9b9b00ec&#x21b5;
243bcefdd4347074d44bd7356d6a53c495737dd96295e2a9374bf5f02ebfc176
Compressed Public Key (hex) is:
025c0de3b9c8ab18dd04e3511243ec2952002dbfadc864b9628910169d9b9b00ec
Bitcoin Address (b58check) is:
1thMirt546nngXqyPEz532S8fLwbozud8
Compressed Bitcoin Address (b58check) is:
14cxpo3MBCYYWCgF74SWTdcmxipnGUsPw3
</pre>
++++
====
<<ec_math>> is another example, using the Python ECDSA library for the
elliptic curve math and without using any specialized bitcoin libraries.
[[ec_math]]
.A script demonstrating elliptic curve math used for bitcoin keys
====
[source, python]
----
include::code/ec-math.py[]
----
====
<<ec_math_run>> shows the output produced by running this script.
[NOTE]
====
<<ec_math>> ((("random numbers", "os.urandom",
see="entropy")))((("entropy", "os.urandom", see="random
numbers")))((("random numbers", "random number
generation")))((("entropy", "random number generation")))uses
+os.urandom+, which reflects a cryptographically secure random number
generator (CSRNG) provided by the underlying operating system. Caution:
Depending on the OS, +os.urandom+ may _not_ be implemented with
sufficient security or seeded properly and may _not_ be appropriate for
generating production-quality bitcoin keys.((("",
startref="KApython04")))
====
[[ec_math_run]]
.Installing the Python ECDSA library and running the ec_math.py script
====
----
$ # Install Python PIP package manager
$ sudo apt-get install python-pip
$ # Install the Python ECDSA library
$ sudo pip install ecdsa
$ # Run the script
$ python ec-math.py
Secret: 38090835015954358862481132628887443905906204995912378278060168703580660294000
EC point: (70048853531867179489857750497606966272382583471322935454624595540007269312627, 105262206478686743191060800263479589329920209527285803935736021686045542353380)
BTC public key: 029ade3effb0a67d5c8609850d797366af428f4a0d5194cb221d807770a1522873
----
====
=== Advanced Keys and Addresses
((("keys and addresses", "advanced forms", id="KAadvanced04")))In the
following sections we will look at advanced forms of keys and addresses,
such as encrypted private keys, script and multisignature addresses,
vanity addresses, and paper wallets.
==== Vanity Addresses
((("keys and addresses", "advanced forms", "vanity
addresses")))((("vanity addresses", id="vanity04")))((("addresses",
"vanity addresses", id="Avanity04")))Vanity addresses are valid Bitcoin
addresses that contain human-readable messages. For example,
+1LoveBPzzD72PUXLzCkYAtGFYmK5vYNR33+ is a valid address that contains
the letters forming the word "Love" as the first four Base-58 letters.
Vanity addresses require generating and testing billions of candidate
private keys, until a bitcoin address with the desired pattern is found.
Although there are some optimizations in the vanity generation
algorithm, the process essentially involves picking a private key at
random, deriving the public key, deriving the Bitcoin address, and
checking to see if it matches the desired vanity pattern, repeating
billions of times until a match is found.
Once a vanity address matching the desired pattern is found, the private
key from which it was derived can be used by the owner to spend bitcoin
in exactly the same way as any other address. Vanity addresses are no
less or more secure than any other address. They depend on the same
Elliptic Curve Cryptography (ECC) and SHA as any other address. You can
no more easily find the private key of an address starting with a vanity
pattern than you can any other address.
In <<ch01_intro_what_is_bitcoin>>, we introduced Eugenia, a children's
charity director operating in the Philippines. Let's say that Eugenia is
organizing a bitcoin fundraising drive and wants to use a vanity Bitcoin
address to publicize the fundraising. Eugenia will create a vanity
address that starts with "1Kids" to promote the children's charity
fundraiser. Let's see how this vanity address will be created and what
it means for the security of Eugenia's charity.((("use cases",
"charitable donations", startref="eugeniafour")))
===== Generating vanity addresses
It's important to realize that a Bitcoin address is simply a number
represented by symbols in the Base58 alphabet. The search for a pattern
like "1Kids" can be seen as searching for an address in the range from
+1Kids11111111111111111111111111111+ to
+1Kidszzzzzzzzzzzzzzzzzzzzzzzzzzzzz+. There are approximately 58^29^
(approximately 1.4 * 10^51^) addresses in that range, all starting with
"1Kids." <<table_4-11>> shows the range of addresses that have the
prefix 1Kids.
[[table_4-11]]
.The range of vanity addresses starting with "1Kids"
|=======
| *From* | +1Kids11111111111111111111111111111+
| | +1Kids11111111111111111111111111112+
| | +1Kids11111111111111111111111111113+
| | +...+
| *To* | +1Kidszzzzzzzzzzzzzzzzzzzzzzzzzzzzz+
|=======
Let's look at the pattern "1Kids" as a number and see how frequently we
might find this pattern in a Bitcoin address (see <<table_4-12>>). An
average desktop computer PC, without any specialized hardware, can
search approximately 100,000 keys per second.
[[table_4-12]]
.The frequency of a vanity pattern (1KidsCharity) and average search time on a desktop PC
[options="header"]
|=======
| Length | Pattern | Frequency | Average search time
| 1 | 1K | 1 in 58 keys | < 1 milliseconds
| 2 | 1Ki| 1 in 3,364 | 50 milliseconds
| 3 | 1Kid | 1 in 195,000 | < 2 seconds
| 4 | 1Kids | 1 in 11 million | 1 minute
| 5 | 1KidsC | 1 in 656 million | 1 hour
| 6 | 1KidsCh | 1 in 38 billion | 2 days
| 7 | 1KidsCha | 1 in 2.2 trillion | 34 months
| 8 | 1KidsChar | 1 in 128 trillion | 1318 years
| 9 | 1KidsChari | 1 in 7 quadrillion | 800 years
| 10 | 1KidsCharit | 1 in 400 quadrillion | 46,000 years
| 11 | 1KidsCharity | 1 in 23 quintillion | 2.5 million years
|=======
As you can see, Eugenia won't be creating the vanity address
"1KidsCharity" anytime soon, even if she had access to several thousand
computers. Each additional character increases the difficulty by a
factor of 58. Patterns with more than seven characters are usually found
by specialized hardware, such as custom-built desktops with multiple
GPUs. These are often repurposed bitcoin mining "rigs" that are no
longer profitable for bitcoin mining but can be used to find vanity
addresses. Vanity searches on GPU systems are many orders of magnitude
faster than on a general-purpose CPU.
Another way to find a vanity address is to outsource the work to a pool
of vanity miners, such as the pool at
http://vanitypool.appspot.com[Vanity Pool]. A pool is a service that
allows those with GPU hardware to earn bitcoin searching for vanity
addresses for others. For a small payment (0.01 bitcoin or approximately
$5 at the time of this writing), Eugenia can outsource the search for a
seven-character pattern vanity address and get results in a few hours
instead of having to run a CPU search for months.
Generating a vanity address is a brute-force exercise: try a random key,
check the resulting address to see if it matches the desired pattern,
repeat until successful. <<vanity_miner_code>> shows an example of a
"vanity miner," a program designed to find vanity addresses, written in
C++. The example uses the libbitcoin library, which we introduced in
<<alt_libraries>>.
[[vanity_miner_code]]
.Vanity address miner
====
[source,cpp]
----
include::code/vanity-miner.cpp[]
----
====
[NOTE]
====
<<vanity_miner_run>> uses +std::random_device+. Depending on the
implementation it may reflect a CSRNG provided by the underlying
operating system. In the case of a Unix-like operating system such as
Linux, it draws from +/dev/urandom+. The random number generator used
here is for demonstration purposes, and it is _not_ appropriate for
generating production-quality bitcoin keys as it is not implemented with
sufficient security.
====
The example code must be compiled using a pass:[C++] compiler and linked
against the libbitcoin library (which must be first installed on that
system). To run the example, run the ++vanity-miner++ executable with no
parameters (see <<vanity_miner_run>>) and it will attempt to find a
vanity address starting with "1kid."
[[vanity_miner_run]]
.Compiling and running the vanity-miner example
====
[source,bash]
----
$ # Compile the code with g++
$ g++ -o vanity-miner vanity-miner.cpp $(pkg-config --cflags --libs libbitcoin)
$ # Run the example
$ ./vanity-miner
Found vanity address! 1KiDzkG4MxmovZryZRj8tK81oQRhbZ46YT
Secret: 57cc268a05f83a23ac9d930bc8565bac4e277055f4794cbd1a39e5e71c038f3f
$ # Run it again for a different result
$ ./vanity-miner
Found vanity address! 1Kidxr3wsmMzzouwXibKfwTYs5Pau8TUFn
Secret: 7f65bbbbe6d8caae74a0c6a0d2d7b5c6663d71b60337299a1a2cf34c04b2a623
# Use "time" to see how long it takes to find a result
$ time ./vanity-miner
Found vanity address! 1KidPWhKgGRQWD5PP5TAnGfDyfWp5yceXM
Secret: 2a802e7a53d8aa237cd059377b616d2bfcfa4b0140bc85fa008f2d3d4b225349
real 0m8.868s
user 0m8.828s
sys 0m0.035s
----
====
The example code will take a few seconds to find a match for the
three-character pattern "kid," as we can see when we use the +time+ Unix
command to measure the execution time. Change the +search+ pattern in
the source code and see how much longer it takes for four- or
five-character patterns!
===== Vanity address security
((("security", "vanity addresses")))Vanity addresses can be used to
enhance _and_ to defeat security measures; they are truly a double-edged
sword. Used to improve security, a distinctive address makes it harder
for adversaries to substitute their own address and fool your customers
into paying them instead of you. Unfortunately, vanity addresses also
make it possible for anyone to create an address that _resembles_ any
random address, or even another vanity address, thereby fooling your
customers.
Eugenia could advertise a randomly generated address (e.g.,
+1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy+) to which people can send their
donations. Or, she could generate a vanity address that starts with
1Kids, to make it more distinctive.
In both cases, one of the risks of using a single fixed address (rather
than a separate dynamic address per donor) is that a thief might be able
to infiltrate your website and replace it with his own address, thereby
diverting donations to himself. If you have advertised your donation
address in a number of different places, your users may visually inspect
the address before making a payment to ensure it is the same one they
saw on your website, on your email, and on your flyer. In the case of a
random address like +1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy+, the average
user will perhaps inspect the first few characters "1J7mdg" and be
satisfied that the address matches. Using a vanity address generator,
someone with the intent to steal by substituting a similar-looking
address can quickly generate addresses that match the first few
characters, as shown in <<table_4-13>>.
[[table_4-13]]
.Generating vanity addresses to match a random address
|=======
| *Original Random Address* | 1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
| *Vanity (4-character match)* | 1J7md1QqU4LpctBetHS2ZoyLV5d6dShhEy
| *Vanity (5-character match)* | 1J7mdgYqyNd4ya3UEcq31Q7sqRMXw2XZ6n
| *Vanity (6-character match)* | 1J7mdg5WxGENmwyJP9xuGhG5KRzu99BBCX
|=======
So does a vanity address increase security? If Eugenia generates the
vanity address +1Kids33q44erFfpeXrmDSz7zEqG2FesZEN+, users are likely to
look at the vanity pattern word _and a few characters beyond_, for
example noticing the "1Kids33" part of the address. That would force an
attacker to generate a vanity address matching at least six characters
(two more), expending an effort that is 3,364 times (58 &#x00D7; 58)
higher than the effort Eugenia expended for her 4-character vanity.
Essentially, the effort Eugenia expends (or pays a vanity pool for)
"pushes" the attacker into having to produce a longer pattern vanity. If
Eugenia pays a pool to generate an 8-character vanity address, the
attacker would be pushed into the realm of 10 characters, which is
infeasible on a personal computer and expensive even with a custom
vanity-mining rig or vanity pool. What is affordable for Eugenia becomes
unaffordable for the attacker, especially if the potential reward of
fraud is not high enough to cover the cost of the vanity address
generation.((("", startref="Avanity04")))((("",
startref="vanity04")))((("", startref="eugeniafour")))
[[paper_wallets]]
==== Paper Wallets
((("keys and addresses", "advanced forms", "paper wallets")))((("paper
wallets", id="paperw04")))((("wallets", "types of", "paper wallets",
id="Wpaper04")))Paper wallets are bitcoin private keys printed on paper.
Often the paper wallet also includes the corresponding Bitcoin address
for convenience, but this is not necessary because it can be derived
from the private key.
[WARNING]
====
Paper wallets are an OBSOLETE technology and are dangerous for most
users. There are many subtle pitfalls involved in generating them, not
least of which the possibility that the generating code is compromised
with a "back door". Hundreds of bitcoin have been stolen this way. Paper
wallets are shown here for informational purposes only and should not be
used for storing bitcoin. Use a recovery code to backup your
keys, possibly with a hardware signing device to store keys and sign transactions. DO NOT
USE PAPER WALLETS.
====
Paper wallets come in many shapes, sizes, and designs, but at a very
basic level are just a key and an address printed on paper.
<<table_4-14>> shows the simplest form of a paper wallet.
[[table_4-14]]
.Simplest form of a paper wallet—a printout of the Bitcoin address and private key
[options="header"]
|=======================
|Public address|Private key (WIF)
|1424C2F4bC9JidNjjTUZCbUxv6Sa1Mt62x|5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
|=======================
Paper wallets come in many designs and sizes, with many different
features. <<paper_wallet_simple>> shows a sample paper wallet.
[[paper_wallet_simple]]
.An example of a simple paper wallet
image::images/mbc2_0408.png[]
Some are intended to be given as gifts and have seasonal themes, such as
Christmas and New Year's themes. Others are designed for storage in a
bank vault or safe with the private key hidden in some way, either with
opaque scratch-off stickers, or folded and sealed with tamper-proof
adhesive foil. Other designs feature additional copies of the key and
address, in the form of detachable stubs similar to ticket stubs,
allowing you to store multiple copies to protect against fire, flood, or
other natural disasters.((("", startref="KAadvanced04")))((("",
startref="Wpaper04")))((("", startref="paperw04")))
[[paper_wallet_spw]]
.An example of a paper wallet with additional copies of the keys on a backup "stub"
image::images/mbc2_0412.png[]