mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-12-23 15:18:11 +00:00
579 lines
24 KiB
Plaintext
579 lines
24 KiB
Plaintext
RECENT CHANGES:
|
|
|
|
* (16 Apr 2013) Added private derivation for i ≥ 0x80000000 (less risk
|
|
of parent private key leakage)
|
|
* (30 Apr 2013) Switched from multiplication by I~L~ to addition of I~L~
|
|
(faster, easier implementation)
|
|
* (25 May 2013) Added test vectors
|
|
* (15 Jan 2014) Rename keys with index ≥ 0x8000000 to hardened keys, and
|
|
add explicit conversion functions.
|
|
|
|
-------------------------------------------
|
|
BIP: 32
|
|
Title: Hierarchical Deterministic Wallets
|
|
Author: Pieter Wuille
|
|
Status: Accepted
|
|
Type: Informational
|
|
Created: 2012-02-11
|
|
-------------------------------------------
|
|
|
|
[[abstract]]
|
|
Abstract
|
|
~~~~~~~~
|
|
|
|
This document describes hierarchical determinstic wallets (or "HD
|
|
Wallets"): wallets which can be shared partially or entirely with
|
|
different systems, each with or without the ability to spend coins.
|
|
|
|
The specification is intended to set a standard for deterministic
|
|
wallets that can be interchanged between different clients. Although the
|
|
wallets described here have many features, not all are required by
|
|
supporting clients.
|
|
|
|
The specification consists of two parts. In a first part, a system for
|
|
deriving a tree of keypairs from a single seed is presented. The second
|
|
part demonstrates how to build a wallet structure on top of such a tree.
|
|
|
|
[[motivation]]
|
|
Motivation
|
|
~~~~~~~~~~
|
|
|
|
The Bitcoin reference client uses randomly generated keys. In order to
|
|
avoid the necessity for a backup after every transaction, (by default)
|
|
100 keys are cached in a pool of reserve keys. Still, these wallets are
|
|
not intended to be shared and used on several systems simultaneously.
|
|
They support hiding their private keys by using the wallet encrypt
|
|
feature and not sharing the password, but such "neutered" wallets lose
|
|
the power to generate public keys as well.
|
|
|
|
Deterministic wallets do not require such frequent backups, and elliptic
|
|
curve mathematics permit schemes where one can calculate the public keys
|
|
without revealing the private keys. This permits for example a webshop
|
|
business to let its webserver generate fresh addresses (public key
|
|
hashes) for each order or for each customer, without giving the
|
|
webserver access to the corresponding private keys (which are required
|
|
for spending the received funds).
|
|
|
|
However, deterministic wallets typically consist of a single "chain" of
|
|
keypairs. The fact that there is only one chain means that sharing a
|
|
wallet happens on an all-or-nothing basis. However, in some cases one
|
|
only wants some (public) keys to be shared and recoverable. In the
|
|
example of a webshop, the webserver does not need access to all public
|
|
keys of the merchant's wallet; only to those addresses which are used to
|
|
receive customer's payments, and not for example the change addresses
|
|
that are generated when the merchant spends money. Hierarchical
|
|
deterministic wallets allow such selective sharing by supporting
|
|
multiple keypair chains, derived from a single root.
|
|
|
|
[[specification-key-derivation]]
|
|
Specification: Key derivation
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
[[conventions]]
|
|
Conventions
|
|
^^^^^^^^^^^
|
|
|
|
In the rest of this text we will assume the public key cryptography used
|
|
in Bitcoin, namely elliptic curve cryptography using the field and curve
|
|
parameters defined by secp256k1
|
|
(http://www.secg.org/index.php?action=secg,docs_secg). Variables below
|
|
are either:
|
|
|
|
* Integers modulo the order of the curve (referred to as n).
|
|
* Coordinates of points on the curve.
|
|
* Byte sequences.
|
|
|
|
Addition (+) of two coordinate pair is defined as application of the EC
|
|
group operation. Concatenation (||) is the operation of appending one
|
|
byte sequence onto another.
|
|
|
|
As standard conversion functions, we assume:
|
|
|
|
* point(p): returns the coordinate pair resulting from EC point
|
|
multiplication (repeated application of the EC group operation) of the
|
|
secp256k1 base point with the integer p.
|
|
* ser~32~(i): serialize a 32-bit unsigned integer i as a 4-byte
|
|
sequence, most significant byte first.
|
|
* ser~256~(p): serializes the integer p as a 32-byte sequence, most
|
|
significant byte first.
|
|
* ser~P~(P): serializes the coordinate pair P = (x,y) as a byte sequence
|
|
using SEC1's compressed form: (0x02 or 0x03) || ser~256~(x), where the
|
|
header byte depends on the parity of the omitted y coordinate.
|
|
* parse~256~(p): interprets a 32-byte sequence as a 256-bit number, most
|
|
significant byte first.
|
|
|
|
[[extended-keys]]
|
|
Extended keys
|
|
^^^^^^^^^^^^^
|
|
|
|
In what follows, we will define a function that derives a number of
|
|
child keys from a parent key. In order to prevent these from depending
|
|
solely on the key itself, we extend both private and public keys first
|
|
with an extra 256 bits of entropy. This extension, called the chain
|
|
code, is identical for corresponding private and public keys, and
|
|
consists of 32 bytes.
|
|
|
|
We represent an extended private key as (k, c), with k the normal
|
|
private key, and c the chain code. An extended public key is represented
|
|
as (K, c), with K = point(k) and c the chain code.
|
|
|
|
Each extended key has 2^31^ normal child keys, and 2^31^ hardened child
|
|
keys. Each of these child keys has an index. The normal child keys use
|
|
indices 0 through 2^31^-1. The hardened child keys use indices 2^31^
|
|
through 2^32^-1. To ease notation for hardened key indices, a number
|
|
i~H~ represents i+2^31^.
|
|
|
|
[[child-key-derivation-ckd-functions]]
|
|
Child key derivation (CKD) functions
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Given a parent extended key and an index i, it is possible to compute
|
|
the corresponding child extended key. The algorithm to do so depends on
|
|
whether the child is a hardened key or not (or, equivalently, whether i
|
|
≥ 2^31^), and whether we're talking about private or public keys.
|
|
|
|
[[private-parent-key-private-child-key]]
|
|
Private parent key → private child key
|
|
++++++++++++++++++++++++++++++++++++++
|
|
|
|
The function CKDpriv((k~par~, c~par~), i) → (k~i~, c~i~) computes a
|
|
child extended private key from the parent extended private key:
|
|
|
|
* Check whether i ≥ 2^31^ (whether the child is a hardened key).
|
|
** If so (hardened child): let I = HMAC-SHA512(Key = c~par~, Data = 0x00
|
|
|| ser~256~(k~par~) || ser~32~(i)). (Note: The 0x00 pads the private key
|
|
to make it 33 bytes long.)
|
|
** If not (normal child): let I = HMAC-SHA512(Key = c~par~, Data =
|
|
ser~P~(point(k~par~)) || ser~32~(i)).
|
|
* Split I into two 32-byte sequences, I~L~ and I~R~.
|
|
* The returned child key k~i~ is parse~256~(I~L~) + k~par~ (mod n).
|
|
* The returned chain code c~i~ is I~R~.
|
|
* In case parse~256~(I~L~) ≥ n or k~i~ = 0, the resulting key is
|
|
invalid, and one should proceed with the next value for i. (Note: this
|
|
has probability lower than 1 in 2^127^.)
|
|
|
|
The HMAC-SHA512 function is specified in
|
|
http://tools.ietf.org/html/rfc4231[RFC 4231].
|
|
|
|
[[public-parent-key-public-child-key]]
|
|
Public parent key → public child key
|
|
++++++++++++++++++++++++++++++++++++
|
|
|
|
The function CKDpub((K~par~, c~par~), i) → (K~i~, c~i~) computes a child
|
|
extended public key from the parent extended public key. It is only
|
|
defined for non-hardened child keys.
|
|
|
|
* Check whether i ≥ 2^31^ (whether the child is a hardened key).
|
|
** If so (hardened child): return failure
|
|
** If not (normal child): let I = HMAC-SHA512(Key = c~par~, Data =
|
|
ser~P~(K~par~) || ser~32~(i)).
|
|
* Split I into two 32-byte sequences, I~L~ and I~R~.
|
|
* The returned child key K~i~ is point(parse~256~(I~L~)) + K~par~.
|
|
* The returned chain code c~i~ is I~R~.
|
|
* In case parse~256~(I~L~) ≥ n or K~i~ is the point at infinity, the
|
|
resulting key is invalid, and one should proceed with the next value for
|
|
i.
|
|
|
|
[[private-parent-key-public-child-key]]
|
|
Private parent key → public child key
|
|
+++++++++++++++++++++++++++++++++++++
|
|
|
|
The function N((k, c)) → (K, c) computes the extended public key
|
|
corresponding to an extended private key (the "neutered" version, as it
|
|
removes the ability to sign transactions).
|
|
|
|
* The returned key K is point(k).
|
|
* The returned chain code c is just the passed chain code.
|
|
|
|
To compute the public child key of a parent private key:
|
|
|
|
* N(CKDpriv((k~par~, c~par~), i)) (works always).
|
|
* CKDpub(N(k~par~, c~par~), i) (works only for non-hardened child keys).
|
|
|
|
The fact that they are equivalent is what makes non-hardened keys useful
|
|
(one can derive child public keys of a given parent key without knowing
|
|
any private key), and also what distinguishes them from hardened keys.
|
|
The reason for not always using non-hardened keys (which are more
|
|
useful) is security; see further for more information.
|
|
|
|
[[public-parent-key-private-child-key]]
|
|
Public parent key → private child key
|
|
+++++++++++++++++++++++++++++++++++++
|
|
|
|
This is not possible.
|
|
|
|
[[the-key-tree]]
|
|
The key tree
|
|
^^^^^^^^^^^^
|
|
|
|
The next step is cascading several CKD constructions to build a tree. We
|
|
start with one root, the master extended key m. By evaluating
|
|
CKDpriv(m,i) for several values of i, we get a number of level-1 derived
|
|
nodes. As each of these is again an extended key, CKDpriv can be applied
|
|
to those as well.
|
|
|
|
To shorten notation, we will write CKDpriv(CKDpriv(CKDpriv(m,3~H~),2),5)
|
|
as m/3~H~/2/5. Equivalently for public keys, we write
|
|
CKDpub(CKDpub(CKDpub(M,3),2,5) as M/3/2/5. This results in the following
|
|
identities:
|
|
|
|
* N(m/a/b/c) = N(m/a/b)/c = N(m/a)/b/c = N(m)/a/b/c = M/a/b/c.
|
|
* N(m/a~H~/b/c) = N(m/a~H~/b)/c = N(m/a~H~)/b/c.
|
|
|
|
However, N(m/a~H~) cannot be rewritten as N(m)/a~H~, as the latter is
|
|
not possible.
|
|
|
|
Each leaf node in the tree corresponds to an actual key, while the
|
|
internal nodes correspond to the collections of keys that descend from
|
|
them. The chain codes of the leaf nodes are ignored, and only their
|
|
embedded private or public key is relevant. Because of this
|
|
construction, knowing an extended private key allows reconstruction of
|
|
all descendant private keys and public keys, and knowing an extended
|
|
public keys allows reconstruction of all descendant non-hardened public
|
|
keys.
|
|
|
|
[[key-identifiers]]
|
|
Key identifiers
|
|
^^^^^^^^^^^^^^^
|
|
|
|
Extended keys can be identified by the Hash160 (RIPEMD160 after SHA256)
|
|
of the serialized public key, ignoring the chain code. This corresponds
|
|
exactly to the data used in traditional Bitcoin addresses. It is not
|
|
advised to represent this data in base58 format though, as it may be
|
|
interpreted as an address that way (and wallet software is not required
|
|
to accept payment to the chain key itself).
|
|
|
|
The first 32 bits of the identifier are called the key fingerprint.
|
|
|
|
[[serialization-format]]
|
|
Serialization format
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Extended public and private keys are serialized as follows:
|
|
|
|
* 4 byte: version bytes (mainnet: 0x0488B21E public, 0x0488ADE4 private;
|
|
testnet: 0x043587CF public, 0x04358394 private)
|
|
* 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 derived keys,
|
|
....
|
|
* 4 bytes: the fingerprint of the parent's key (0x00000000 if master
|
|
key)
|
|
* 4 bytes: child number. This is ser~32~(i) for i in x~i~ = x~par~/i,
|
|
with x~i~ the key being serialized. (0x00000000 if master key)
|
|
* 32 bytes: the chain code
|
|
* 33 bytes: the public key or private key data (ser~P~(K) for public
|
|
keys, 0x00 || ser~256~(k) for private keys)
|
|
|
|
This 78 byte structure can be encoded like other Bitcoin data in Base58,
|
|
by first adding 32 checksum bits (derived from the double SHA-256
|
|
checksum), and then converting to the Base58 representation. This
|
|
results in a Base58-encoded string of up to 112 characters. Because of
|
|
the choice of the version bytes, the Base58 representation will start
|
|
with "xprv" or "xpub" on mainnet, "tprv" or "tpub" on testnet.
|
|
|
|
Note that the fingerprint of the parent only serves as a fast way to
|
|
detect parent and child nodes in software, and software must be willing
|
|
to deal with collisions. Internally, the full 160-bit identifier could
|
|
be used.
|
|
|
|
When importing a serialized extended public key, implementations must
|
|
verify whether the X coordinate in the public key data corresponds to a
|
|
point on the curve. If not, the extended public key is invalid.
|
|
|
|
[[master-key-generation]]
|
|
Master key generation
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The total number of possible extended keypairs is almost 2^512^, but the
|
|
produced keys are only 256 bits long, and offer about half of that in
|
|
terms of security. Therefore, master keys are not generated directly,
|
|
but instead from a potentially short seed value.
|
|
|
|
* Generate a seed byte sequence S of a chosen length (between 128 and
|
|
512 bits; 256 bits is advised) from a (P)RNG.
|
|
* Calculate I = HMAC-SHA512(Key = "Bitcoin seed", Data = S)
|
|
* Split I into two 32-byte sequences, I~L~ and I~R~.
|
|
* Use parse~256~(I~L~) as master secret key, and I~R~ as master chain
|
|
code.
|
|
|
|
In case I~L~ is 0 or ≥n, the master key is invalid.
|
|
|
|
[[specification-wallet-structure]]
|
|
Specification: Wallet structure
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The previous sections specified key trees and their nodes. The next step
|
|
is imposing a wallet structure on this tree. The layout defined in this
|
|
section is a default only, though clients are encouraged to mimick it
|
|
for compatibility, even if not all features are supported.
|
|
|
|
[[the-default-wallet-layout]]
|
|
The default wallet layout
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
An HDW is organized as several 'accounts'. Accounts are numbered, the
|
|
default account ("") being number 0. Clients are not required to support
|
|
more than one account - if not, they only use the default account.
|
|
|
|
Each account is composed of two keypair chains: an internal and an
|
|
external one. The external keychain is used to generate new public
|
|
addresses, while the internal keychain is used for all other operations
|
|
(change addresses, generation addresses, ..., anything that doesn't need
|
|
to be communicated). Clients that do not support separate keychains for
|
|
these should use the external one for everything.
|
|
|
|
* m/i~H~/0/k corresponds to the k'th keypair of the external chain of
|
|
account number i of the HDW derived from master m.
|
|
* m/i~H~/1/k corresponds to the k'th keypair of the internal chain of
|
|
account number i of the HDW derived from master m.
|
|
|
|
[[use-cases]]
|
|
Use cases
|
|
^^^^^^^^^
|
|
|
|
[[full-wallet-sharing-m]]
|
|
Full wallet sharing: m
|
|
++++++++++++++++++++++
|
|
|
|
In cases where two systems need to access a single shared wallet, and
|
|
both need to be able to perform spendings, one needs to share the master
|
|
private extended key. Nodes can keep a pool of N look-ahead keys cached
|
|
for external chains, to watch for incoming payments. The look-ahead for
|
|
internal chains can be very small, as no gaps are to be expected here.
|
|
An extra look-ahead could be active for the first unused account's
|
|
chains - triggering the creation of a new account when used. Note that
|
|
the name of the account will still need to be entered manually and
|
|
cannot be synchronized via the block chain.
|
|
|
|
[[audits-nm]]
|
|
Audits: N(m/*)
|
|
++++++++++++++
|
|
|
|
In case an auditor needs full access to the list of incoming and
|
|
outgoing payments, one can share all account public extended keys. This
|
|
will allow the auditor to see all transactions from and to the wallet,
|
|
in all accounts, but not a single secret key.
|
|
|
|
[[per-office-balances-mih]]
|
|
Per-office balances: m/i~H~
|
|
+++++++++++++++++++++++++++
|
|
|
|
When a business has several independent offices, they can all use
|
|
wallets derived from a single master. This will allow the headquarters
|
|
to maintain a super-wallet that sees all incoming and outgoing
|
|
transactions of all offices, and even permit moving money between the
|
|
offices.
|
|
|
|
[[recurrent-business-to-business-transactions-nmih0]]
|
|
Recurrent business-to-business transactions: N(m/i~H~/0)
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
In case two business partners often transfer money, one can use the
|
|
extended public key for the external chain of a specific account (M/i
|
|
h/0) as a sort of "super address", allowing frequent transactions that
|
|
cannot (easily) be associated, but without needing to request a new
|
|
address for each payment. Such a mechanism could also be used by mining
|
|
pool operators as variable payout address.
|
|
|
|
[[unsecure-money-receiver-nmih0]]
|
|
Unsecure money receiver: N(m/i~H~/0)
|
|
++++++++++++++++++++++++++++++++++++
|
|
|
|
When an unsecure webserver is used to run an e-commerce site, it needs
|
|
to know public addresses that are used to receive payments. The
|
|
webserver only needs to know the public extended key of the external
|
|
chain of a single account. This means someone illegally obtaining access
|
|
to the webserver can at most see all incoming payments, but will not
|
|
(trivially) be able to distinguish outgoing transactions, nor see
|
|
payments received by other webservers if there are several ones.
|
|
|
|
[[compatibility]]
|
|
Compatibility
|
|
~~~~~~~~~~~~~
|
|
|
|
To comply with this standard, a client must at least be able to import
|
|
an extended public or private key, to give access to its direct
|
|
descendants as wallet keys. The wallet structure
|
|
(master/account/chain/subchain) presented in the second part of the
|
|
specification is advisory only, but is suggested as a minimal structure
|
|
for easy compatibility - even when no separate accounts or distinction
|
|
between internal and external chains is made. However, implementations
|
|
may deviate from it for specific needs; more complex applications may
|
|
call for a more complex tree structure.
|
|
|
|
[[security]]
|
|
Security
|
|
~~~~~~~~
|
|
|
|
In addition to the expectations from the EC public-key cryptography
|
|
itself:
|
|
|
|
* Given a public key K, an attacker cannot find the corresponding
|
|
private key more efficiently than by solving the EC discrete logarithm
|
|
problem (assumed to require 2^128^ group operations).
|
|
|
|
the intended security properties of this standard are:
|
|
|
|
* Given a child extended private key (k~i~,c~i~) and the integer i, an
|
|
attacker cannot find the parent private key k~par~ more efficiently than
|
|
a 2^256^ brute force of HMAC-SHA512.
|
|
* Given any number (2 ≤ N ≤ 2^32^-1) of (index, extended private key)
|
|
tuples (i~j~,(k~i~j~~,c~i~j~~)), with distinct i~j~'s, determining
|
|
whether they are derived from a common parent extended private key
|
|
(i.e., whether there exists a (k~par~,c~par~) such that for each j in
|
|
(0..N-1) CKDpriv((k~par~,c~par~),i~j~)=(k~i~j~~,c~i~j~~)), cannot be
|
|
done more efficiently than a 2^256^ brute force of HMAC-SHA512.
|
|
|
|
Note however that the following properties does not exist:
|
|
|
|
* Given a parent extended public key (K~par~,c~par~) and a child public
|
|
key (K~i~), it is hard to find i.
|
|
* Given a parent extended public key (K~par~,c~par~) and a non-hardened
|
|
child private key (k~i~), it is hard to find k~par~.
|
|
|
|
[[implications]]
|
|
Implications
|
|
^^^^^^^^^^^^
|
|
|
|
Private and public keys must be kept safe as usual. Leaking a private
|
|
key means access to coins - leaking a public key can mean loss of
|
|
privacy.
|
|
|
|
Somewhat more care must be taken regarding extended keys, as these
|
|
correspond to an entire (sub)tree of keys.
|
|
|
|
One weakness that may not be immediately obvious, is that knowledge of
|
|
the extended public key + any non-hardened private key descending from
|
|
it is equivalent to knowing the extended private key (and thus every
|
|
private and public key descending from it). This means that extended
|
|
public keys must be treated more carefully than regular public keys. It
|
|
is also the reason for the existence of hardened keys, and why they are
|
|
used for the account level in the tree. This way, a leak of
|
|
account-specific (or below) private key never risks compromising the
|
|
master or other accounts.
|
|
|
|
[[test-vectors]]
|
|
Test Vectors
|
|
~~~~~~~~~~~~
|
|
|
|
[[test-vector-1]]
|
|
Test vector 1
|
|
^^^^^^^^^^^^^
|
|
|
|
Master (hex): 000102030405060708090a0b0c0d0e0f
|
|
|
|
* Chain m
|
|
** ext pub:
|
|
xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8
|
|
** ext prv:
|
|
xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi
|
|
* Chain m/0~H~
|
|
** ext pub:
|
|
xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw
|
|
** ext prv:
|
|
xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7
|
|
* Chain m/0~H~/1
|
|
** ext pub:
|
|
xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ
|
|
** ext prv:
|
|
xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs
|
|
* Chain m/0~H~/1/2~H~
|
|
** ext pub:
|
|
xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5
|
|
** ext prv:
|
|
xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM
|
|
* Chain m/0~H~/1/2~H~/2
|
|
** ext pub:
|
|
xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV
|
|
** ext prv:
|
|
xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334
|
|
* Chain m/0~H~/1/2~H~/2/1000000000
|
|
** ext pub:
|
|
xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy
|
|
** ext prv:
|
|
xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76
|
|
|
|
[[test-vector-2]]
|
|
Test vector 2
|
|
^^^^^^^^^^^^^
|
|
|
|
Master (hex):
|
|
fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542
|
|
|
|
* Chain m
|
|
** ext pub:
|
|
xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB
|
|
** ext prv:
|
|
xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U
|
|
* Chain m/0
|
|
** ext pub:
|
|
xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH
|
|
** ext prv:
|
|
xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt
|
|
* Chain m/0/2147483647~H~
|
|
** ext pub:
|
|
xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a
|
|
** ext prv:
|
|
xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9
|
|
* Chain m/0/2147483647~H~/1
|
|
** ext pub:
|
|
xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon
|
|
** ext prv:
|
|
xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef
|
|
* Chain m/0/2147483647~H~/1/2147483646~H~
|
|
** ext pub:
|
|
xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
|
|
** ext prv:
|
|
xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc
|
|
* Chain m/0/2147483647~H~/1/2147483646~H~/2
|
|
** ext pub:
|
|
xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt
|
|
** ext prv:
|
|
xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j
|
|
|
|
[[implementations]]
|
|
Implementations
|
|
~~~~~~~~~~~~~~~
|
|
|
|
Two Python implementations exist:
|
|
|
|
PyCoin (https://github.com/richardkiss/pycoin) is a suite of utilities
|
|
for dealing with Bitcoin that includes BIP0032 wallet features.
|
|
BIP32Utils (https://github.com/jmcorgan/bip32utils) is a library and
|
|
command line interface specifically focused on BIP0032 wallets and
|
|
scripting.
|
|
|
|
A Java implementation is available at
|
|
https://github.com/bitsofproof/supernode/blob/1.1/api/src/main/java/com/bitsofproof/supernode/api/ExtendedKey.java
|
|
|
|
A C++ implementation is available at
|
|
https://github.com/CodeShark/CoinClasses/tree/master/tests/hdwallets
|
|
|
|
An Objective-C implementation is available at
|
|
https://github.com/oleganza/CoreBitcoin/blob/master/CoreBitcoin/BTCKeychain.h
|
|
|
|
A Ruby implementation is available at https://github.com/wink/money-tree
|
|
|
|
A Go implementation is available at
|
|
https://github.com/WeMeetAgain/go-hdwallet
|
|
|
|
A JavaScript implementation is available at
|
|
https://github.com/sarchar/brainwallet.github.com/tree/bip32
|
|
|
|
A PHP implemetation is available at
|
|
https://github.com/Bit-Wasp/bitcoin-lib-php
|
|
|
|
A C# implementation is available at
|
|
https://github.com/NicolasDorier/NBitcoin (ExtKey, ExtPubKey)
|
|
|
|
[[acknowledgements]]
|
|
Acknowledgements
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
* Gregory Maxwell for the original idea of type-2 deterministic wallets,
|
|
and many discussions about it.
|
|
* Alan Reiner for the implementation of this scheme in Armory, and the
|
|
suggestions that followed from that.
|
|
* Mike Caldwell for the version bytes to obtain human-recognizable
|
|
Base58 strings.
|
|
|