# Bitcoin Address Generator (btcaddr)
A secure, type-safe, and high-performance Rust library for Bitcoin address generation.
[](https://crates.io/crates/btcaddr)
[](https://docs.rs/btcaddr)
[](LICENSE)
[](https://www.rust-lang.org)
## Overview
`btcaddr` provides a clean, well-documented implementation of Bitcoin address generation following the BIP32 (Hierarchical Deterministic Wallets) specification. It emphasizes security, type safety, and zero-cost abstractions for performance-critical applications like vanity address generation.
## Features
- **Cryptographically Secure Entropy Generation**: Uses OS-provided CSPRNG for secure randomness
- **BIP32-Compliant Seed Derivation**: HMAC-SHA512-based deterministic key derivation
- **Bitcoin Address Generation**: Support for P2PKH addresses (mainnet and testnet)
- **Type-Safe Address Handling**: Compile-time guarantees prevent mixing address types
- **Memory Safety**: Automatic zeroization of sensitive data using the `zeroize` crate
- **Zero-Cost Abstractions**: High performance through Rust's type system and inlining
- **Comprehensive Documentation**: Every function thoroughly documented with examples
## Security Guarantees
This library is designed with security as the primary concern:
- **Cryptographically Secure Random Number Generation**: All entropy is sourced from `OsRng`, which uses platform-specific secure random sources (`/dev/urandom` on Linux, `getrandom()` syscall, etc.)
- **Memory Zeroization**: Sensitive data (`Entropy`, `Seed`) is automatically zeroed when dropped, preventing sensitive data from lingering in memory
- **No Copy Trait for Secrets**: Prevents untracked duplication of sensitive key material
- **Constant-Time Cryptographic Operations**: Uses industry-standard cryptographic libraries (SHA-256, RIPEMD-160, HMAC) with timing attack resistance
- **BIP32 Standard Compliance**: Follows Bitcoin Improvement Proposal 32 for deterministic key derivation
## Installation
Add `btcaddr` to your `Cargo.toml`:
```toml
[dependencies]
btcaddr = "0.1.0"
```
Or use cargo add:
```bash
cargo add btcaddr
```
## Quick Start
### Generate a Bitcoin Address
```rust
use btcaddr::address::public_key_ext::PublicKeyExt;
use btcaddr::seed::Seed;
use secp256k1::{Secp256k1, PublicKey};
// Generate a BIP32 seed directly (combines entropy generation and derivation)
let seed = Seed::generate()
.expect("Failed to generate seed");
// Extract master secret key (first 32 bytes of HMAC-derived seed)
let secret_key = seed.secret_key()
.expect("Failed to derive secret key");
// Generate public key from secret key
let secp = Secp256k1::new();
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
// Create Bitcoin address (P2PKH format on mainnet)
let address = public_key.to_p2pkh_address(btcaddr::network::Network::Mainnet);
// Display the address
println!("Bitcoin address: {}", address);
// Output example: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
```
#### Alternative: Two-Step Generation
If you need more control over the entropy generation, you can use the two-step approach:
```rust
use btcaddr::address::public_key_ext::PublicKeyExt;
use btcaddr::seed::Seed;
use secp256k1::{Secp256k1, PublicKey};
// Step 1: Create cryptographically secure entropy
let entropy = btcaddr::entropy::Entropy::new()
.expect("Failed to generate entropy");
// Step 2: Derive BIP32 seed from entropy
let seed = Seed::from(entropy);
// Extract master secret key and continue as above
let secret_key = seed.secret_key()
.expect("Failed to derive secret key");
let secp = Secp256k1::new();
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
let address = public_key.to_p2pkh_address(btcaddr::network::Network::Mainnet);
println!("Bitcoin address: {}", address);
```
### Generate Addresses for Different Networks
```rust
use btcaddr::address::public_key_ext::PublicKeyExt;
use btcaddr::seed::Seed;
use secp256k1::{Secp256k1, PublicKey};
// Generate seed once
let seed = Seed::generate().unwrap();
let secp = Secp256k1::new();
let secret_key = seed.secret_key().unwrap();
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
// Generate addresses for different networks
let mainnet_addr = public_key.to_p2pkh_address(btcaddr::network::Network::Mainnet);
let testnet_addr = public_key.to_p2pkh_address(btcaddr::network::Network::Testnet);
println!("Mainnet: {}", mainnet_addr); // Starts with '1'
println!("Testnet: {}", testnet_addr); // Starts with 'm' or 'n'
```
## Architecture
The library follows a modular architecture with clear separation of concerns:
```mermaid
%%{init: {'theme':'neutral', 'themeVariables': { 'fontSize':'14px'}}}%%
flowchart TD
A["🔐 OS CSPRNG"] -->|"rand::OsRng"| B["📦 Entropy<br/>64 bytes random"]
B -->|"HMAC-SHA512<br/>key: 'Bitcoin seed'"| C["🌱 Seed<br/>64 bytes derived"]
C -->|"Split bytes"| D["🔑 SecretKey<br/>bytes 0..32"]
C -->|"Split bytes"| E["⛓️ ChainCode<br/>bytes 32..64"]
D -->|"secp256k1<br/>EC multiplication"| F["🔓 PublicKey<br/>33/65 bytes"]
F -->|"SHA256"| G["#️⃣ SHA256 Hash<br/>32 bytes"]
G -->|"RIPEMD160"| H["#️⃣ HASH160<br/>20 bytes"]
H -->|"Add version byte<br/>Network: Mainnet/Testnet"| I["📋 Address Payload<br/>21 bytes"]
I -->|"Base58Check<br/>+ 4-byte checksum"| J["✅ Bitcoin Address<br/>1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"]
classDef entryPoint stroke:#666,stroke-width:2px
classDef keyMaterial stroke:#666,stroke-width:2.5px
classDef hashOp stroke:#888,stroke-width:2px
classDef finalAddr stroke:#333,stroke-width:3px
class A,B,C entryPoint
class D,F keyMaterial
class E,G,H,I hashOp
class J finalAddr
```
### Alternate Entry Point
You can also use the convenience method `Seed::generate()` which combines entropy generation and seed derivation:
```mermaid
%%{init: {'theme':'neutral', 'themeVariables': { 'fontSize':'14px'}}}%%
flowchart TD
A["⚡ Seed::generate"] -->|"Internally calls<br/>Entropy::new + Seed::from"| B["🌱 Seed<br/>64 bytes"]
B -->|"Continue flow"| C["🔑 SecretKey + ⛓️ ChainCode"]
classDef entryPoint stroke:#666,stroke-width:2px
classDef keyMaterial stroke:#666,stroke-width:2.5px
class A,B entryPoint
class C keyMaterial
```
## Module Organization
### Public Modules
#### `address`
Bitcoin address generation and representation system. Provides type-safe address handling with support for P2PKH (Pay-to-Public-Key-Hash) format.
- `Address<T>`: Generic address type with compile-time format enforcement
- `PublicKeyExt`: Extension trait for converting public keys to addresses
- Base58Check encoding and checksum calculation
- HASH160 computation (SHA256 followed by RIPEMD160)
#### `seed`
BIP32-compliant seed derivation and key extraction.
- `Seed`: 512-bit seed derived from entropy using HMAC-SHA512
- `generate()`: Convenience method that generates entropy and derives seed in one step
- `secret_key()`: Extracts master secret key (first 256 bits)
- `chain_code()`: Extracts chain code for hierarchical key derivation (last 256 bits)
- Automatic memory zeroization for sensitive data
#### `entropy`
Cryptographically secure random number generation using `OsRng`.
- `Entropy`: 512-bit cryptographically secure random data
- Automatic zeroization on drop
- CSPRNG-based random generation
#### `network`
Bitcoin network type definitions (Mainnet, Testnet). Determines address version bytes and prefixes.
## Supported Address Formats
### Currently Implemented
**P2PKH (Pay-to-Public-Key-Hash)**: Original Bitcoin address format
- Mainnet prefix: '1' (version byte 0x00)
- Testnet prefix: 'm' or 'n' (version byte 0x6F)
- Example: `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa`
### Future Support (Planned)
- **P2SH (Pay-to-Script-Hash)**: Multisig and complex scripts
- **P2WPKH (Pay-to-Witness-Public-Key-Hash)**: Native SegWit
- **P2WSH (Pay-to-Witness-Script-Hash)**: Native SegWit scripts
- **P2TR (Pay-to-Taproot)**: Taproot addresses with Schnorr signatures
## Type Safety
The library leverages Rust's type system to provide compile-time guarantees:
```rust
use btcaddr::address::Address;
use btcaddr::address::types::{P2PKH, P2SH};
let p2pkh: Address<P2PKH> = /* ... */;
let p2sh: Address<P2SH> = /* ... */;
// Compile error: mismatched types!
// let wrong: Address<P2PKH> = p2sh;
```
Address type markers (P2PKH, P2SH, etc.) are zero-sized types that exist only at compile time, providing type safety with zero runtime cost.
## Performance Characteristics
The library is optimized for high-performance applications like vanity address generation:
- **Zero heap allocations** in the critical path (key generation → address)
- **Inline functions** throughout for aggressive optimization
- **Stack-allocated fixed-size arrays** for deterministic performance
- **No virtual dispatch** - all polymorphism is compile-time
Typical performance on modern hardware (3+ GHz CPU):
- HASH160 computation: ~100-300 nanoseconds
- Address generation: ~150-500 nanoseconds
- Base58 encoding: ~5-10 microseconds
## Cryptographic Dependencies
This library relies on battle-tested cryptographic implementations:
- **secp256k1** (v0.31.1): Bitcoin's elliptic curve implementation
- **sha2** (v0.10.9): SHA-256 cryptographic hash function
- **ripemd** (v0.1.3): RIPEMD-160 hash function
- **hmac** (v0.12.1): HMAC (Hash-based Message Authentication Code)
- **zeroize** (v1.8.2): Secure memory zeroization
- **bs58** (v0.5.1): Base58 encoding/decoding
- **rand** (v0.9.2): Random number generation (using OsRng)
## Bitcoin Improvement Proposals (BIPs)
This library implements or is compatible with the following BIPs:
- **BIP32**: Hierarchical Deterministic Wallets
- **BIP13**: Address Format for pay-to-script-hash (future)
- **BIP16**: Pay to Script Hash (future)
- **BIP141**: Segregated Witness (future)
- **BIP173**: Base32 address format for native v0-16 witness outputs (future)
## Thread Safety
All public types are `Send + Sync` when appropriate:
- `Entropy`: Send (not Sync - interior mutability)
- `Seed`: Send + Sync
- `Address<T>`: Send + Sync
- `Network`: Copy + Send + Sync
This makes the library suitable for concurrent vanity address generation and parallel key derivation.
## Error Handling
This library uses Rust's `Result` type for error handling:
- `Entropy::new()` returns `Result<Entropy, rand::Error>` (CSPRNG failure)
- `Seed::secret_key()` returns `Result<SecretKey, secp256k1::Error>` (invalid key)
In practice, these errors are extremely rare (probability < 1 in 2^127) when using proper CSPRNG. They exist to handle edge cases and maintain API safety.
## Examples
Check out the [examples](examples/) directory for more comprehensive examples:
- Basic address generation
- Batch address generation
- Vanity address searching
## Documentation
Full API documentation is available on [docs.rs](https://docs.rs/btcaddr).
For more details on the implementation and design decisions, see the extensive inline documentation in the source code.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
### Development Guidelines
- Follow Rust best practices and idiomatic code
- Maintain comprehensive documentation
- Add tests for new functionality
- Ensure all tests pass with `cargo test`
- Run `cargo clippy` and address any warnings
- Format code with `cargo fmt`
## Security
This library handles cryptographic key material. If you discover a security vulnerability, please email the maintainers directly instead of using the public issue tracker.
## References
- [Bitcoin Developer Guide](https://developer.bitcoin.org/devguide/)
- [BIP32 Specification](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
- [Bitcoin Address Wiki](https://en.bitcoin.it/wiki/Address)
- [Base58Check Encoding](https://en.bitcoin.it/wiki/Base58Check_encoding)
- [secp256k1 Curve](https://en.bitcoin.it/wiki/Secp256k1)
## Acknowledgments
This library follows Bitcoin protocol specifications and builds upon the excellent work of:
- The Bitcoin Core development team
- The rust-bitcoin community
- The secp256k1 library maintainers
- All contributors to Bitcoin Improvement Proposals