1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-11-27 02:18:25 +00:00
bitcoinbook/selected BIPs/bip-0032.asciidoc

579 lines
24 KiB
Plaintext
Raw Normal View History

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.