hdwallet

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2025 License: MIT Imports: 13 Imported by: 1

Documentation

Overview

Package hdwallet implements the BIP32 and BIP44 specifications for hierarchical deterministic wallets. BIP32 defines a method for creating a hierarchical deterministic wallet, where keys are derived from a single master key using a tree structure. BIP44 defines a specific derivation path structure for interoperability between wallets.

The implementation includes:

  • Creating master keys from seeds
  • Deriving child keys (normal and hardened)
  • Deriving keys using derivation paths
  • Support for BIP44 standard paths
  • Serialization to Base58Check format (xprv/xpub)
  • Conversion to Wallet Import Format (WIF)

For more information, see:

Index

Constants

View Source
const (
	// HardenedKeyStart is the index where hardened keys start
	HardenedKeyStart = 0x80000000

	// FirstHardenedChild is the index of the first hardened child
	FirstHardenedChild = HardenedKeyStart

	// PublicKeyCompressedLength is the length of a compressed public key
	PublicKeyCompressedLength = 33

	// PrivateKeyLength is the length of a private key
	PrivateKeyLength = 32
)

Variables

View Source
var (
	// ErrInvalidKey is returned when a key is invalid
	ErrInvalidKey = errors.New("hdwallet: invalid key")

	// ErrInvalidSeed is returned when a seed is invalid
	ErrInvalidSeed = errors.New("hdwallet: invalid seed")

	// ErrDerivingHardenedFromPublic is returned when trying to derive a hardened child from a public key
	ErrDerivingHardenedFromPublic = errors.New("hdwallet: cannot derive hardened child from public key")

	// ErrInvalidPath is returned when a derivation path is invalid
	ErrInvalidPath = errors.New("hdwallet: invalid derivation path")

	// ErrInvalidCurve is returned when the curve is invalid
	ErrInvalidCurve = errors.New("hdwallet: invalid curve")
)

Functions

This section is empty.

Types

type Key

type Key struct {

	// ChainCode is the 32-byte chain code used in key derivation.
	ChainCode []byte

	// Depth is the key derivation depth (0 for master key).
	Depth byte

	// Index is the child index of this key (0x80000000 or higher for hardened keys).
	Index uint32

	// ParentFingerprint is the first 4 bytes of the parent key's hash.
	ParentFingerprint []byte

	// IsPrivate indicates whether this Key holds a private key (true) or a public key (false).
	IsPrivate bool
	// contains filtered or unexported fields
}

Key represents a BIP32 hierarchical deterministic wallet key. It contains all the information needed to derive child keys and serialize the key in various formats.

func NewMasterKey

func NewMasterKey(seed []byte) (*Key, error)

NewMasterKey creates a new master key from a seed according to the BIP32 specification. The seed must be between 16 and 64 bytes as per BIP32 requirements.

This function implements the master key generation algorithm:

  1. Calculate I = HMAC-SHA512(Key = "Bitcoin seed", Data = S)
  2. Split I into two 32-byte sequences, IL and IR
  3. Use IL as master secret key, and IR as master chain code
  4. Verify that IL is in the range [1, n-1] where n is the curve order

Parameters:

seed: A cryptographically secure random seed between 16-64 bytes

Returns:

*Key: A new master key that can be used to derive child keys
error: ErrInvalidSeed if seed length is invalid, or ErrInvalidKey if the generated key is invalid

func (*Key) B58Serialize

func (k *Key) B58Serialize(isPublic bool) string

B58Serialize serializes the extended key into a Base58Check-encoded string. If isPublic is true, it serializes the extended public key; otherwise, it serializes the extended private key. The serialized format follows the BIP32 specification with version bytes:

  • xprv prefix for private keys (0x0488ADE4)
  • xpub prefix for public keys (0x0488B21E)

Parameters:

isPublic: If true, serialize as extended public key; if false, serialize as extended private key

Returns:

Base58Check-encoded string representation of the extended key

func (*Key) Derive

func (k *Key) Derive(index uint32) (*Key, error)

Derive derives a child key at the given index according to the BIP32 specification. The index can be a normal child (0-0x7FFFFFFF) or a hardened child (0x80000000-0xFFFFFFFF).

For normal child derivation:

  • Data = serP(Kpar) || ser32(i)
  • Uses the parent's public key

For hardened child derivation:

  • Data = 0x00 || ser256(kpar) || ser32(i)
  • Uses the parent's private key and can only be done with private keys

Parameters:

index: The child index to derive. Use HardenedKeyStart (0x80000000) or higher for hardened keys

Returns:

*Key: The derived child key
error: ErrDerivingHardenedFromPublic if trying to derive a hardened child from a public key,
       or ErrInvalidKey if the derived key is invalid

func (*Key) DerivePath

func (k *Key) DerivePath(path string) (*Key, error)

DerivePath derives a child key at the given path according to BIP32/BIP44 specifications. Path should be in the format "m/44'/0'/0'/0/0" where:

  • m: Master key
  • 44': BIP44 purpose (hardened)
  • 0': Coin type (hardened, 0 for Bitcoin)
  • 0': Account number (hardened)
  • 0: Change chain (0 for external, 1 for internal)
  • 0: Address index

Hardened indices are denoted with either an apostrophe (') or 'H'.

Parameters:

path: The derivation path string in BIP32/BIP44 format

Returns:

*Key: The derived child key at the specified path
error: ErrInvalidPath for invalid path formats, or errors from the Derive method

func (*Key) Fingerprint

func (k *Key) Fingerprint() []byte

Fingerprint returns the key fingerprint as the first 4 bytes of the RIPEMD-160 hash of the SHA-256 hash of the public key, as specified in BIP32. This fingerprint is used to identify the parent key in child key derivation.

The algorithm follows BIP32 specification:

  1. Serialize the public key in compressed format
  2. Perform SHA-256 hashing on the public key
  3. Perform RIPEMD-160 hashing on the SHA-256 hash
  4. Return the first 4 bytes of the RIPEMD-160 hash

Returns:

[]byte: The 4-byte key fingerprint

func (*Key) PrivateKey added in v1.0.1

func (k *Key) PrivateKey() ([]byte, error)

PrivateKey returns the raw 32-byte private key bytes if this Key is a private key. This method explicitly indicates that the key is intended for private operations.

Returns:

[]byte: The 32-byte private key.
error: An error if the Key is not a private key (i.e., IsPrivate is false).

func (*Key) PublicKey

func (k *Key) PublicKey() []byte

PublicKey returns the compressed public key for this key. If the key is already a public key, it returns the keyData directly. If the key is a private key, it derives and returns the corresponding compressed public key. This method ensures that a 33-byte compressed public key is always returned.

Returns:

[]byte: The 33-byte compressed public key.

func (*Key) SerializedSize

func (k *Key) SerializedSize() int

SerializedSize returns the size in bytes of the serialized extended key. Both private and public extended keys serialize to 78 bytes as per BIP32 specification. The serialization format consists of:

  • 4 bytes: version
  • 1 byte: depth
  • 4 bytes: parent fingerprint
  • 4 bytes: child number
  • 32 bytes: chain code
  • 33 bytes: key data (public key or 0x00 + private key)

func (*Key) String

func (k *Key) String() string

String returns a human-readable string representation of the key. It displays the type of key (private or public) along with its key data and chain code. This method is primarily intended for debugging and logging purposes.

func (*Key) ToECDSA added in v1.0.1

func (k *Key) ToECDSA() (*ecdsa.PrivateKey, error)

ToECDSA converts the private key to a standard *ecdsa.PrivateKey object. This method is useful for integrating with other Go cryptography functions that expect the standard library's ECDSA private key type.

Returns:

*ecdsa.PrivateKey: The standard library ECDSA private key.
error: An error if the Key is not a private key or if the conversion fails.

func (*Key) ToWIF

func (k *Key) ToWIF() (string, error)

ToWIF converts a private key to Wallet Import Format (WIF). WIF is a format for encoding Bitcoin private keys that includes a version byte, the private key, and a checksum.

This method only works on private keys. Attempting to convert a public key will return an error.

Returns:

string: The WIF-encoded private key with a '5' prefix for mainnet
error:  An error if the key is not a private key

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL