rustywallet-hd 0.2.0

BIP32/BIP44/BIP85 Hierarchical Deterministic wallet for cryptocurrency key derivation
Documentation
# rustywallet-hd

[![Crates.io](https://img.shields.io/crates/v/rustywallet-hd.svg)](https://crates.io/crates/rustywallet-hd)
[![Documentation](https://docs.rs/rustywallet-hd/badge.svg)](https://docs.rs/rustywallet-hd)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Build Status](https://github.com/rustywallet/rustywallet-hd/workflows/CI/badge.svg)](https://github.com/rustywallet/rustywallet-hd/actions)

BIP32/BIP44 Hierarchical Deterministic wallet implementation for cryptocurrency key derivation in Rust.

## Features

- **BIP32 Compliance**: Full implementation of BIP32 hierarchical deterministic key derivation
- **BIP44 Support**: Standard derivation paths for multiple cryptocurrencies
- **Master Key Generation**: Create master keys from 64-byte seeds (typically from mnemonics)
- **Child Key Derivation**: Derive child keys using both normal and hardened derivation
- **Extended Keys**: Export/import extended keys (xprv/xpub, tprv/tpub) with Base58Check encoding
- **Public Key Derivation**: Derive public keys from extended public keys (non-hardened paths only)
- **Network Support**: Mainnet and testnet key generation
- **Security**: Secure memory handling with automatic zeroization on drop
- **No-std Compatible**: Works in embedded environments (with `no-std` feature)

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
rustywallet-hd = "0.1"
```

For `no-std` environments:

```toml
[dependencies]
rustywallet-hd = { version = "0.1", default-features = false }
```

## Quick Start

```rust
use rustywallet_hd::prelude::*;

// Create master key from seed (64 bytes, typically from mnemonic)
let seed = [0u8; 64];
let master = ExtendedPrivateKey::from_seed(&seed, Network::Mainnet)?;

// Derive BIP44 Bitcoin path: m/44'/0'/0'/0/0
let path = DerivationPath::bip44_bitcoin(0, 0, 0);
let child = master.derive_path(&path)?;

// Get keys
let private_key = child.private_key()?;
let public_key = child.public_key();

// Export as xprv/xpub
let xprv = child.to_xprv();
let xpub = child.extended_public_key().to_xpub();
```

## Master Key Derivation

Create master keys from seeds generated by mnemonic phrases:

```rust
use rustywallet_hd::prelude::*;

// From 64-byte seed (typically from BIP39 mnemonic)
let seed = [0u8; 64]; // Replace with actual seed
let master = ExtendedPrivateKey::from_seed(&seed, Network::Mainnet)?;

// Master key properties
println!("Master fingerprint: {:?}", master.fingerprint());
println!("Master chain code: {:?}", master.chain_code());
```

## Child Key Derivation

Derive child keys using BIP32 derivation:

```rust
use rustywallet_hd::prelude::*;

let master = ExtendedPrivateKey::from_seed(&seed, Network::Mainnet)?;

// Single derivation step
let child = master.derive_child(ChildNumber::Hardened(44))?;

// Multi-step derivation
let path = DerivationPath::from_str("m/44'/0'/0'/0/0")?;
let account_key = master.derive_path(&path)?;

// Hardened vs normal derivation
let hardened = master.derive_child(ChildNumber::Hardened(0))?;  // m/0'
let normal = master.derive_child(ChildNumber::Normal(0))?;      // m/0
```

## Derivation Paths (BIP32/BIP44)

### BIP32 Path Format

```text
m / level1 / level2 / level3 / level4 / level5
```

- `m`: Master key
- `'` (apostrophe): Indicates hardened derivation
- Numbers: Child key indices

### BIP44 Standard Paths

```text
m / purpose' / coin_type' / account' / change / address_index

Purpose: 44' (BIP44)
Coin Types:
  - Bitcoin: 0'
  - Ethereum: 60'
  - Litecoin: 2'
```

### Helper Methods

```rust
use rustywallet_hd::prelude::*;

// Bitcoin paths
let btc_account = DerivationPath::bip44_bitcoin(0, 0, 0);     // m/44'/0'/0'/0/0
let btc_change = DerivationPath::bip44_bitcoin(0, 1, 0);      // m/44'/0'/0'/1/0

// Ethereum paths  
let eth_path = DerivationPath::bip44_ethereum(0, 0);          // m/44'/60'/0'/0/0

// Custom paths
let custom = DerivationPath::from_str("m/44'/0'/0'/0/5")?;
```

## Extended Keys (xpub/xprv)

### Private Extended Keys (xprv)

```rust
use rustywallet_hd::prelude::*;

let master = ExtendedPrivateKey::from_seed(&seed, Network::Mainnet)?;

// Export as xprv string
let xprv_string = master.to_xprv();
println!("xprv: {}", xprv_string);

// Import from xprv string
let imported = ExtendedPrivateKey::from_xprv(&xprv_string)?;
```

### Public Extended Keys (xpub)

```rust
use rustywallet_hd::prelude::*;

let master = ExtendedPrivateKey::from_seed(&seed, Network::Mainnet)?;
let xpub = master.extended_public_key();

// Export as xpub string
let xpub_string = xpub.to_xpub();
println!("xpub: {}", xpub_string);

// Import from xpub string
let imported_xpub = ExtendedPublicKey::from_xpub(&xpub_string)?;

// Derive public keys (non-hardened only)
let child_pubkey = imported_xpub.derive_child(ChildNumber::Normal(0))?;
```

### Testnet Keys (tprv/tpub)

```rust
use rustywallet_hd::prelude::*;

let master = ExtendedPrivateKey::from_seed(&seed, Network::Testnet)?;

// Testnet keys use tprv/tpub prefixes
let tprv = master.to_xprv();  // Returns tprv... for testnet
let tpub = master.extended_public_key().to_xpub();  // Returns tpub... for testnet
```

## API Reference

### Core Types

#### `ExtendedPrivateKey`

```rust
impl ExtendedPrivateKey {
    // Create master key from seed
    pub fn from_seed(seed: &[u8], network: Network) -> Result<Self, Error>;
    
    // Import from xprv/tprv string
    pub fn from_xprv(xprv: &str) -> Result<Self, Error>;
    
    // Derive child key
    pub fn derive_child(&self, child_number: ChildNumber) -> Result<Self, Error>;
    
    // Derive using path
    pub fn derive_path(&self, path: &DerivationPath) -> Result<Self, Error>;
    
    // Get private key
    pub fn private_key(&self) -> Result<PrivateKey, Error>;
    
    // Get public key
    pub fn public_key(&self) -> PublicKey;
    
    // Get extended public key
    pub fn extended_public_key(&self) -> ExtendedPublicKey;
    
    // Export as xprv/tprv
    pub fn to_xprv(&self) -> String;
    
    // Key properties
    pub fn fingerprint(&self) -> Fingerprint;
    pub fn chain_code(&self) -> &ChainCode;
    pub fn depth(&self) -> u8;
    pub fn child_number(&self) -> ChildNumber;
}
```

#### `ExtendedPublicKey`

```rust
impl ExtendedPublicKey {
    // Import from xpub/tpub string
    pub fn from_xpub(xpub: &str) -> Result<Self, Error>;
    
    // Derive child (non-hardened only)
    pub fn derive_child(&self, child_number: ChildNumber) -> Result<Self, Error>;
    
    // Derive using path (non-hardened only)
    pub fn derive_path(&self, path: &DerivationPath) -> Result<Self, Error>;
    
    // Get public key
    pub fn public_key(&self) -> PublicKey;
    
    // Export as xpub/tpub
    pub fn to_xpub(&self) -> String;
}
```

#### `DerivationPath`

```rust
impl DerivationPath {
    // Parse from string
    pub fn from_str(path: &str) -> Result<Self, Error>;
    
    // BIP44 helpers
    pub fn bip44_bitcoin(account: u32, change: u32, index: u32) -> Self;
    pub fn bip44_ethereum(account: u32, index: u32) -> Self;
    
    // Path operations
    pub fn extend(&self, child_number: ChildNumber) -> Self;
    pub fn len(&self) -> usize;
    pub fn is_empty(&self) -> bool;
}
```

#### `ChildNumber`

```rust
pub enum ChildNumber {
    Normal(u32),    // Non-hardened derivation
    Hardened(u32),  // Hardened derivation (adds 2^31)
}
```

### Integration with rustywallet-mnemonic

```rust
use rustywallet_mnemonic::prelude::*;
use rustywallet_hd::prelude::*;

// Generate mnemonic
let mnemonic = Mnemonic::generate(WordCount::Words12);

// Get seed with optional passphrase
let seed = mnemonic.to_seed("optional_passphrase");

// Create HD wallet
let master = ExtendedPrivateKey::from_seed(seed.as_bytes(), Network::Mainnet)?;

// Derive Bitcoin account keys
let account_path = DerivationPath::bip44_bitcoin(0, 0, 0);
let account_key = master.derive_path(&account_path)?;

// Generate multiple addresses
for i in 0..10 {
    let addr_path = DerivationPath::bip44_bitcoin(0, 0, i);
    let addr_key = master.derive_path(&addr_path)?;
    println!("Address {}: {:?}", i, addr_key.public_key());
}
```

## Security Considerations

- **Memory Safety**: Private keys and chain codes are automatically zeroized when dropped
- **Debug Protection**: Sensitive data is masked in debug output
- **Hardened Derivation**: Use hardened paths for account-level keys to prevent key leakage
- **Seed Entropy**: Always use cryptographically secure random seeds (64 bytes from BIP39)
- **Key Storage**: Never store private keys in plain text; use secure key management

## License

Licensed under the MIT License. See [LICENSE](LICENSE) for details.