Skip to content

Commit 067b646

Browse files
author
sammyne
committed
feature: extra works
2 parents 6112731 + 5b11ddb commit 067b646

21 files changed

+216
-1232
lines changed

README.md

+15-21
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
hdkeychain
1+
# bip32
2+
23
==========
34

4-
[![CircleCI](https://circleci.com/gh/sammyne/bip32.svg?style=svg)](https://circleci.com/gh/sammyne/bip32)
5-
[![codecov](https://codecov.io/gh/sammyne/bip32/branch/master/graph/badge.svg)](https://codecov.io/gh/sammyne/bip32)
6-
[![Go Report Card](https://goreportcard.com/badge/github.com/sammyne/bip32)](https://goreportcard.com/report/github.com/sammyne/bip32)
7-
[![LICENSE](https://img.shields.io/badge/license-ISC-blue.svg)](LICENSE)
5+
[![CircleCI](https://circleci.com/gh/sammyne/bip32.svg?style=svg)](https://circleci.com/gh/sammyne/bip32)
6+
[![codecov](https://codecov.io/gh/sammyne/bip32/branch/master/graph/badge.svg)](https://codecov.io/gh/sammyne/bip32)
7+
[![Go Report Card](https://goreportcard.com/badge/github.com/sammyne/bip32)](https://goreportcard.com/report/github.com/sammyne/bip32)
8+
[![LICENSE](https://img.shields.io/badge/license-ISC-blue.svg)](LICENSE)
89

9-
Package hdkeychain provides an API for bitcoin hierarchical deterministic
10+
Package `bip32` provides an API for bitcoin hierarchical deterministic
1011
extended keys (BIP0032).
1112

12-
A comprehensive suite of tests is provided to ensure proper functionality. See
13-
`test_coverage.txt` for the gocov coverage report. Alternatively, if you are
14-
running a POSIX OS, you can run the `cov_report.sh` script for a real-time
15-
report.
13+
A comprehensive suite of tests is provided to ensure proper functionality. See
14+
[codecov](https://codecov.io/gh/sammy00/bip32) for the coverage report.
1615

1716
## Feature Overview
1817

@@ -25,7 +24,7 @@ report.
2524
keys
2625
- Support for custom networks by registering them with chaincfg
2726
- Obtaining the underlying EC pubkeys, EC privkeys, and associated bitcoin
28-
addresses ties in seamlessly with existing btcec and btcutil types which
27+
address public key hashes ties in seamlessly with existing btcec and btcutil types which
2928
provide powerful tools for working with them to do things like sign
3029
transations and generate payment scripts
3130
- Uses the btcec package which is highly optimized for secp256k1
@@ -35,26 +34,21 @@ report.
3534
- Default HD wallet layout as described by BIP0032
3635
- Audits use case as described by BIP0032
3736
- Comprehensive test coverage including the BIP0032 test vectors
38-
- Benchmarks
37+
- Benchmarks [WIP]
3938

4039
## Installation and Updating
4140

4241
```bash
43-
$ go get -u github.com/btcsuite/btcutil/hdkeychain
42+
$ go get -u github.com/sammy00/bip32
4443
```
4544

4645
## Examples
4746

48-
* [NewMaster Example](http://godoc.org/github.com/btcsuite/btcutil/hdkeychain#example-NewMaster)
47+
- [NewMaster Example](http://godoc.org/github.com/btcsuite/btcutil/hdkeychain#example-NewMaster)
4948
Demonstrates how to generate a cryptographically random seed then use it to
5049
create a new master node (extended key).
51-
* [Default Wallet Layout Example](http://godoc.org/github.com/btcsuite/btcutil/hdkeychain#example-package--DefaultWalletLayout)
50+
- [Default Wallet Layout Example](http://godoc.org/github.com/btcsuite/btcutil/hdkeychain#example-package--DefaultWalletLayout)
5251
Demonstrates the default hierarchical deterministic wallet layout as described
5352
in BIP0032.
54-
* [Audits Use Case Example](http://godoc.org/github.com/btcsuite/btcutil/hdkeychain#example-package--Audits)
53+
- [Audits Use Case Example](http://godoc.org/github.com/btcsuite/btcutil/hdkeychain#example-package--Audits)
5554
Demonstrates the audits use case in BIP0032.
56-
57-
## License
58-
59-
Package hdkeychain is licensed under the [copyfree](http://copyfree.org) ISC
60-
License.

bytes.go

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package bip32
22

3+
// ReverseCopy works in the opposite direction as the built-in copy()
34
func ReverseCopy(dst, src []byte) {
45
for i, j := len(dst)-1, len(src)-1; i >= 0 && j >= 0; i, j = i-1, j-1 {
56
dst[i] = src[j]

conf.go

-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package bip32
22

3-
// masterKey is the master key used along with a random seed used to generate
4-
// the master node in the hierarchical tree.
5-
var masterKey = []byte("Bitcoin seed")
6-
73
// masterHMACKey is the key used along with a random seed used to generate
84
// the master key in the hierarchical tree.
95
var masterHMACKey = []byte("Bitcoin seed")

constant.go

+5-10
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,6 @@ const (
1818
// MaxSeedBytes is the maximum number of bytes allowed for a seed to
1919
// a master node.
2020
MaxSeedBytes = 64 // 512 bits
21-
22-
// serializedKeyLen is the length of a serialized public or private
23-
// extended key. It consists of 4 bytes version, 1 byte depth, 4 bytes
24-
// fingerprint, 4 bytes child number, 32 bytes chain code, and 33 bytes
25-
// public/private key data.
26-
serializedKeyLen = 4 + 1 + 4 + 4 + 32 + 33 // 78 bytes
27-
28-
// maxUint8 is the max positive integer which can be serialized in a uint8
29-
maxUint8 = 1<<8 - 1
3021
)
3122

3223
// length constants about fields of key serialization
@@ -37,6 +28,10 @@ const (
3728
ChildIndexLen = 4
3829
ChainCodeLen = 32
3930
KeyDataLen = 33
40-
KeyLen = VersionLen + DepthLen + FingerprintLen +
31+
// KeyLen is the length of a serialized public or private
32+
// extended key. It consists of 4 bytes version, 1 byte depth, 4 bytes
33+
// fingerprint, 4 bytes child number, 32 bytes chain code, and 33 bytes
34+
// public/private key data.
35+
KeyLen = VersionLen + DepthLen + FingerprintLen +
4136
ChildIndexLen + ChainCodeLen + KeyDataLen
4237
)

cov_report.sh

-17
This file was deleted.

doc.go

+18-15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Copyright (c) 2018 sammy00
12
// Copyright (c) 2014 The btcsuite developers
23
// Use of this source code is governed by an ISC
34
// license that can be found in the LICENSE file.
@@ -12,39 +13,41 @@ The ability to implement hierarchical deterministic wallets depends on the
1213
ability to create and derive hierarchical deterministic extended keys.
1314
1415
At a high level, this package provides support for those hierarchical
15-
deterministic extended keys by providing an ExtendedKey type and supporting
16-
functions. Each extended key can either be a private or public extended key
17-
which itself is capable of deriving a child extended key.
16+
deterministic extended keys specified as the ExtendedKey interface, which is
17+
implemented by PrivateKey and PublicKey.Therefore, each extended key can either
18+
be a private or public extended key which itself is capable of deriving a child
19+
extended key.
1820
1921
Determining the Extended Key Type
2022
21-
Whether an extended key is a private or public extended key can be determined
22-
with the IsPrivate function.
23+
Whether an extended key is a private or public extended key can be type assertion against the PrivateKey type.
2324
2425
Transaction Signing Keys and Payment Addresses
2526
2627
In order to create and sign transactions, or provide others with addresses to
2728
send funds to, the underlying key and address material must be accessible. This
28-
package provides the ECPubKey, ECPrivKey, and Address functions for this
29-
purpose.
29+
package provides the ECPubKey, ECPrivKey, and AddressPubKeyHash functions for
30+
this purpose.
3031
3132
The Master Node
3233
3334
As previously mentioned, the extended keys are hierarchical meaning they are
3435
used to form a tree. The root of that tree is called the master node and this
35-
package provides the NewMaster function to create it from a cryptographically
36-
random seed. The GenerateSeed function is provided as a convenient way to
37-
create a random seed for use with the NewMaster function.
36+
package provides the NewMasterKey function to create it from a cryptographically
37+
random seed. The GenerateMasterKey function is provided as a convenient way to
38+
create a random extended private key for use where the seed would be read from
39+
the provided rand entropy reader.
3840
3941
Deriving Children
4042
4143
Once you have created a tree root (or have deserialized an extended key as
4244
discussed later), the child extended keys can be derived by using the Child
4345
function. The Child function supports deriving both normal (non-hardened) and
4446
hardened child extended keys. In order to derive a hardened extended key, use
45-
the HardenedKeyStart constant + the hardened key number as the index to the
46-
Child function. This provides the ability to cascade the keys into a tree and
47-
hence generate the hierarchical deterministic key chains.
47+
the mapping function HardenIndex(i) to get the corresponding index for
48+
generating harden child to the Child function. This provides the ability to
49+
cascade the keys into a tree and hence generate the hierarchical deterministic
50+
key chains.
4851
4952
Normal vs Hardened Child Extended Keys
5053
@@ -69,8 +72,8 @@ public extended keys.
6972
Serializing and Deserializing Extended Keys
7073
7174
Extended keys are serialized and deserialized with the String and
72-
NewKeyFromString functions. The serialized key is a Base58-encoded string which
73-
looks like the following:
75+
ParsePrivateKey/ParsePublicKey functions. The serialized key is a
76+
Base58-encoded string which looks like the following:
7477
public key: xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw
7578
private key: xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7
7679

errors.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ var (
1616
ErrDeriveBeyondMaxDepth = errors.New("cannot derive a key with more than " +
1717
"255 indices in its path")
1818

19-
// ErrNotPrivExtKey describes an error in which the caller attempted
20-
// to extract a private key from a public extended key.
21-
ErrNotPrivExtKey = errors.New("unable to create private keys from a " +
22-
"public extended key")
23-
2419
// ErrInvalidChild describes an error in which the child at a specific
2520
// index is invalid due to the derived key falling outside of the valid
2621
// range for secp256k1 private keys. This error indicates the caller
@@ -48,5 +43,6 @@ var (
4843
ErrInvalidKeyLen = errors.New("the provided serialized extended key " +
4944
"length is invalid")
5045

46+
// ErrNoEnoughEntropy signals more entropy is needed
5147
ErrNoEnoughEntropy = errors.New("more entropy is needed")
5248
)

extended_key.go

+57
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,72 @@ package bip32
22

33
import "github.com/btcsuite/btcd/btcec"
44

5+
// References:
6+
// [BIP32]: BIP0032 - Hierarchical Deterministic Wallets
7+
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
8+
9+
// ExtendedKey specifies the basic api for a extended private or public key.
10+
// TODO: add the Zero method manually clears all fields and bytes in the
11+
// extended key. This can be used to explicitly clear key material from memory
12+
// for enhanced security against memory scraping. This function only clears
13+
// this particular key and not any children that have already been derived.
514
type ExtendedKey interface {
15+
// AddressPubKeyHash returns the public key hash (20 bytes) derived from the
16+
// key, which would be itself for public keys and the extended public key
17+
// bound to it for private keys
618
AddressPubKeyHash() []byte
19+
// Child returns a derived child extended key at the given index. When this
20+
// extended key is a private extended key (as determined by the IsPrivate
21+
// function), a private extended key will be derived. Otherwise, the derived
22+
// extended key will be also be a public extended key.
23+
//
24+
// When the index is greater to or equal than the HardenedKeyStart constant,
25+
// the derived extended key will be a hardened extended key. It is only
26+
// possible to derive a hardended extended key from a private extended key.
27+
// Consequently, this function will return ErrDeriveHardFromPublic if a
28+
// hardened child extended key is requested from a public extended key.
29+
//
30+
// A hardened extended key is useful since, as previously mentioned, it
31+
// requires a parent private extended key to derive. In other words, normal
32+
// child extended public keys can be derived from a parent public extended
33+
// key (no knowledge of the parent private key) whereas hardened extended
34+
// keys may not be.
35+
//
36+
// NOTE: There is an extremely small chance (< 1 in 2^127) the specific child
37+
// index does not derive to a usable child. The ErrInvalidChild error should
38+
// be returned if this should occur, and the caller is expected to ignore the
39+
// invalid child and simply increment to the next index.
740
Child(i uint32) (ExtendedKey, error)
41+
// Depth returns the current derivation level with respect to the root.
42+
//
43+
// The root key has depth zero, and the field has a maximum of 255 due to
44+
// how depth is serialized.
845
Depth() uint8
46+
// Hardened tells if the key of interest is hardened, whose index is greater
47+
// than HardenedKeyStart.
948
Hardened() bool
49+
// Index returns the index of the key seen from its parent.
1050
Index() uint32
51+
// IsForNet checks if this key is in use for a given net specified by keyID
1152
IsForNet(keyID Magic) bool
53+
54+
// Neuter returns a new extended public key from a extended private key. The
55+
// same extended key will be returned unaltered if it is already an extended
56+
// public key.
57+
//
58+
// As the name implies, an extended public key does not have access to the
59+
// private key, so it is not capable of signing transactions or deriving
60+
// child extended private keys. However, it is capable of deriving further
61+
// child extended public keys.
62+
Neuter() (*PublicKey, error)
63+
// ParentFingerprint returns a fingerprint of the parent extended key from
64+
// which this one was derived.
1265
ParentFingerprint() uint32
66+
// Public converts the extended key to a btcec public key and returns it.
1367
Public() (*btcec.PublicKey, error)
68+
// SetNet associates the extended key, and any child keys yet to be derived
69+
// from it, with the passed network.
1470
SetNet(keyID Magic)
71+
// String returns the extended key as a human-readable base58-encoded string.
1572
String() string
1673
}

0 commit comments

Comments
 (0)