|
|
|
@ -61,23 +61,56 @@ Modern wallet applications don't independently generate keys but instead
|
|
|
|
|
derive them from a single random seed using a repeatable (deterministic)
|
|
|
|
|
algorithm.
|
|
|
|
|
|
|
|
|
|
==== Deterministic (Seeded) Wallets
|
|
|
|
|
|
|
|
|
|
((("wallets", "types of", "deterministic (seeded)
|
|
|
|
|
wallets")))Deterministic, or "seeded," wallets are wallets that contain
|
|
|
|
|
private keys that are all derived from a common seed, through the use of
|
|
|
|
|
a one-way hash function. The seed is a randomly generated number that is
|
|
|
|
|
combined with other data, such as an index number or "chain code" (see
|
|
|
|
|
<<hd_wallets>>) to derive the private keys. In a deterministic wallet,
|
|
|
|
|
the seed is sufficient to recover all the derived keys, and therefore a
|
|
|
|
|
single backup at creation time is sufficient. The seed is also
|
|
|
|
|
sufficient for a wallet export or import, allowing for easy migration of
|
|
|
|
|
all the user's keys between different wallet implementations.
|
|
|
|
|
<<Type1_wallet>> shows a logical diagram of a deterministic wallet.
|
|
|
|
|
==== Deterministic Key Generation
|
|
|
|
|
|
|
|
|
|
A hash function will always produce the same output when given the same
|
|
|
|
|
input, but if the input is changed even slightly, the output will be
|
|
|
|
|
different. If the function is cryptographically secure, nobody should
|
|
|
|
|
be able to predict the new output--not even if they know the new input.
|
|
|
|
|
|
|
|
|
|
This allows us to take one random value and transform it into a
|
|
|
|
|
practically unlimited number of seemingly-random values. Even more
|
|
|
|
|
usefully, later using the same hash function with the same input
|
|
|
|
|
(called a _seed_) will produce the same seemingly-random values.
|
|
|
|
|
|
|
|
|
|
----
|
|
|
|
|
# Collect some entropy (randomness)
|
|
|
|
|
$ dd if=/dev/random count=1 status=none | sha256sum
|
|
|
|
|
f1cc3bc03ef51cb43ee7844460fa5049e779e7425a6349c8e89dfbb0fd97bb73 -
|
|
|
|
|
|
|
|
|
|
# Set our seed to the random value
|
|
|
|
|
$ seed=f1cc3bc03ef51cb43ee7844460fa5049e779e7425a6349c8e89dfbb0fd97bb73
|
|
|
|
|
|
|
|
|
|
# Deterministically generate derived values
|
|
|
|
|
$ for i in {0..2} ; do echo "$seed + $i" | sha256sum ; done
|
|
|
|
|
50b18e0bd9508310b8f699bad425efdf67d668cb2462b909fdb6b9bd2437beb3 -
|
|
|
|
|
a965dbcd901a9e3d66af11759e64a58d0ed5c6863e901dfda43adcd5f8c744f3 -
|
|
|
|
|
19580c97eb9048599f069472744e51ab2213f687d4720b0efc5bb344d624c3aa -
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
If we use the derived values as our private keys, we can later generate
|
|
|
|
|
exactly those same private keys by using our seed value with the
|
|
|
|
|
algorithm we used before. A user of deterministic key generation can
|
|
|
|
|
back up every key in their wallet by simply recording their seed and
|
|
|
|
|
a reference to the deterministic algorithm they used. For example, even
|
|
|
|
|
if Alice has a million bitcoins received to a million different
|
|
|
|
|
addresses, all she needs to back up in order to later recover access to
|
|
|
|
|
those bitcoins is:
|
|
|
|
|
|
|
|
|
|
----
|
|
|
|
|
f1cc 3bc0 3ef5 1cb4 3ee7 8444 60fa 5049
|
|
|
|
|
e779 e742 5a63 49c8 e89d fbb0 fd97 bb73
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
A logical diagram of basic sequential deterministic key generation is
|
|
|
|
|
shown in <<Type1_wallet>>. However, modern wallet applications have a
|
|
|
|
|
more clever way of accomplishing this that allows public keys to be
|
|
|
|
|
derived separately from their corresponding private keys, making it
|
|
|
|
|
possible to store private keys more securely than public keys.
|
|
|
|
|
|
|
|
|
|
[[Type1_wallet]]
|
|
|
|
|
[role="smallersixty"]
|
|
|
|
|
.Type-1 deterministic (seeded) wallet: a deterministic sequence of keys derived from a seed
|
|
|
|
|
.Deterministic key generation: a deterministic sequence of keys derived from a seed for a wallet database
|
|
|
|
|
image::images/mbc2_0502.png["Deterministic Wallet"]
|
|
|
|
|
|
|
|
|
|
[[hd_wallets]]
|
|
|
|
|