Files
pyhdwallet/playbook.md
LC mac 4933168ae4 docs: update for multi-platform vendor support (v1.1.0)
- Update README.md with 6 vendor directories (macOS/Linux x86/ARM + dev)
- Update playbook.md with complete air-gapped workflow
- Document auto-detection in install_offline.sh
- Add dev mode documentation (--dev flag)
- Add platform-specific checksum verification commands
- Add operational security checklist
- Add vendor architecture diagram
- Document macOS native vs Docker build requirements

Complete support for:
- macOS ARM64 (Apple Silicon)
- Linux x86_64 (Intel/AMD)
- Linux aarch64 (ARM64/Raspberry Pi/Mac containers)
2026-01-12 18:22:57 +08:00

15 KiB
Raw Blame History

pyhdwallet v1.1.0 (hdwalletpy)

Deterministic BIP32/BIP39/BIP44 HD wallet generator for Bitcoin, Ethereum, and other cryptocurrencies. Designed for offline, air-gapped use with complete multi-platform support.

Features

  • BIP39 24-word mnemonic generation with configurable entropy
  • BIP32 hierarchical deterministic wallet derivation
  • BIP44 multi-account structure (Bitcoin, Ethereum, Litecoin, etc.)
  • Air-gapped operation with vendored dependencies for 3 platforms
  • AES-256 encrypted ZIP artifacts with password protection
  • PGP encryption support for at-rest storage
  • Deterministic output for reproducible wallet generation
  • Multi-platform offline support:
    • macOS ARM64 (Apple Silicon)
    • Linux x86_64 (Intel/AMD servers)
    • Linux aarch64 (ARM64 servers, Raspberry Pi, Mac containers)
  • Regression test suite with BIP test vectors
  • Checksum verification for all vendored wheels

Installation

Prerequisites

  • Python 3.12 (required for all platforms)
  • macOS: brew install python@3.12
  • Debian/Ubuntu: apt-get install python3.12 python3.12-venv
  • Docker (optional, for building Linux wheels on macOS)

Quick Installation (macOS/Linux with Internet)

# Clone repository
git clone https://github.com/yourusername/hdwalletpy.git
cd hdwalletpy

# Run automated installer (auto-detects your platform)
./install_offline.sh

The installer automatically detects:

  • macOS ARM64 → uses vendor/macos-arm64/
  • Linux x86_64 → uses vendor/linux-x86_64/
  • Linux aarch64/arm64 → uses vendor/linux-aarch64/

Air-Gapped Installation (No Internet)

The project includes pre-built vendored wheels for offline installation on all supported platforms.

On Internet-Connected Machine

# Clone and verify
git clone https://github.com/yourusername/hdwalletpy.git
cd hdwalletpy

# Verify checksums for your target platform
cd vendor/macos-arm64 && shasum -a 256 -c SHA256SUMS       # macOS ARM64
cd vendor/linux-x86_64 && sha256sum -c SHA256SUMS          # Linux x86_64
cd vendor/linux-aarch64 && sha256sum -c SHA256SUMS         # Linux ARM64

# Transfer entire repo to USB/CD
cp -r hdwalletpy /Volumes/USB/

On Air-Gapped Machine

# Ensure Python 3.12 is installed
python3.12 --version

# Navigate to repository
cd /path/to/hdwalletpy

# Run installer (auto-detects platform, creates venv, installs offline)
./install_offline.sh

# Activate environment
source .venv/bin/activate

# Generate wallet
python src/pyhdwallet.py gen --help

Development Installation (with pytest)

For development with full test suite on air-gapped machines:

# Install with dev dependencies (includes pytest)
./install_offline.sh --dev

Platform-specific dev wheels are located in:

  • vendor/macos-arm64-dev/
  • vendor/linux-x86_64-dev/
  • vendor/linux-aarch64-dev/

Manual Installation (Without Script)

If you prefer manual control:

# Create venv
python3.12 -m venv .venv
source .venv/bin/activate

# Install from vendored wheels
# For macOS ARM64:
pip install --no-index --find-links=vendor/macos-arm64 -r requirements.txt

# For Linux x86_64:
pip install --no-index --find-links=vendor/linux-x86_64 -r requirements.txt

# For Linux aarch64:
pip install --no-index --find-links=vendor/linux-aarch64 -r requirements.txt

# Verify installation
python src/pyhdwallet.py test

Dependencies (Top-Level Intent)

  • bip-utils BIP32/39/44 cryptographic operations
  • base58 Bitcoin address encoding
  • cbor2 CBOR serialization for Cardano
  • ecdsa Elliptic curve cryptography
  • pynacl NaCl cryptography library
  • pyzipper AES-256 encrypted ZIP archives
  • pytest (dev only) Test framework

Quick Start

1) Generate (debug/test; prints mnemonic)

python src/pyhdwallet.py gen

Output: Mnemonic, master keys, and derived addresses to stdout.

2) Generate and save AES ZIP artifact to .wallet/

python src/pyhdwallet.py gen --file --zip
# Enter password when prompted

Output: Encrypted ZIP in .wallet/wallet-YYYYMMDD-HHMMSS.zip

python src/pyhdwallet.py gen --file --zip --pgp recipient@example.com

Output:

  • .wallet/wallet-YYYYMMDD-HHMMSS.zip (AES encrypted)
  • .wallet/wallet-YYYYMMDD-HHMMSS.zip.gpg (PGP encrypted)

4) Recover (addresses) from mnemonic

python src/pyhdwallet.py recover
# (then paste mnemonic and press Ctrl-D)

5) Recover with interactive input + ZIP artifact

python src/pyhdwallet.py recover --file --zip

6) Run built-in smoke test

python src/pyhdwallet.py test

7) Run full regression test suite

# Requires dev installation
./install_offline.sh --dev
source .venv/bin/activate
pytest -v tests/test_vectors.py

Testing

Regression Test Suite

Test Coverage

  • BIP39 Mnemonic Generation: Entropy, word list, checksum validation
  • BIP32 Key Derivation: Master key, child key derivation paths
  • BIP44 Multi-Currency: Bitcoin, Ethereum, Litecoin address generation
  • Known Test Vectors: Official BIP39/BIP32 test cases

Running Tests

# Run all tests
pytest -v tests/test_vectors.py

# Run specific test
pytest -v tests/test_vectors.py::test_bip39_generation

# Run with detailed output
pytest -vv tests/test_vectors.py

Test Artifacts (Committed)

  • tests/vectors.json Official BIP test vectors
  • tests/test_vectors.py Regression test suite

When to Regenerate Test Vectors

Only if:

  • Upgrading bip-utils library
  • Adding new BIP implementations
  • Changing derivation paths

Vendored Dependencies

What is Vendoring?

Pre-compiled Python wheels stored in vendor/ for offline installation without PyPI access.

Vendor Directory Structure

vendor/
├── macos-arm64/          # macOS Apple Silicon (runtime)
├── macos-arm64-dev/      # macOS dev wheels (pytest)
├── linux-x86_64/         # Linux Intel/AMD (runtime)
├── linux-x86_64-dev/     # Linux x86_64 dev wheels
├── linux-aarch64/        # Linux ARM64 (runtime)
├── linux-aarch64-dev/    # Linux ARM64 dev wheels
└── PROVENANCE.md         # Build information

Building Vendor Wheels (Maintainers)

Using Makefile (recommended):

# Build runtime wheels for all platforms
make vendor-all

# Build dev wheels for all platforms (includes pytest)
make vendor-all-dev

# Build specific platform
make vendor-macos          # macOS ARM64
make vendor-macos-dev      # macOS dev
make vendor-linux          # Linux x86_64 via Docker
make vendor-linux-dev      # Linux x86_64 dev
make vendor-linux-arm      # Linux ARM64 via Docker
make vendor-linux-arm-dev  # Linux ARM64 dev

# Commit updated wheels
git add vendor/
git commit -m "vendor: update wheels to latest versions"

Platform-specific notes:

  • macOS wheels: Must build on native macOS (uses .venv312)
  • Linux wheels: Built via Docker (works on any platform)
  • ARM64 wheels: Built with --platform linux/arm64 in Docker

Verifying Vendor Integrity

# Check checksums before using on air-gapped machine
cd vendor/macos-arm64 && shasum -a 256 -c SHA256SUMS
cd vendor/linux-x86_64 && sha256sum -c SHA256SUMS
cd vendor/linux-aarch64 && sha256sum -c SHA256SUMS

Outputs and File Structure

Stdout Behavior

When running gen without --file, output goes to stdout (terminal).
Security warning: Use --file to avoid exposing mnemonic in shell history or logs.

--file Behavior (Deterministic, Secured Output)

  • Creates .wallet/ directory
  • Generates timestamped file: wallet-YYYYMMDD-HHMMSS.txt
  • With --zip: Creates AES-256 encrypted ZIP
  • With --pgp: Adds GPG encryption layer

Password Handling for ZIP

  • Interactive prompt (hidden input)
  • Minimum 8 characters enforced
  • Used for AES-256 encryption of ZIP archive

Commands

fetchkey (online)

python src/pyhdwallet.py fetchkey keyserver.ubuntu.com recipient@example.com

Downloads PGP public key for encryption. Requires internet.

gen (offline)

python src/pyhdwallet.py gen [--file] [--zip] [--pgp EMAIL] [--force]

Generates new HD wallet. Fully offline after dependencies installed.

recover (offline)

python src/pyhdwallet.py recover [--file] [--zip]

Recovers wallet from existing mnemonic. Reads from stdin.

test (offline)

python src/pyhdwallet.py test

Runs built-in smoke test (quick validation).

When to Use --force

# This redirects stdout to a file (non-TTY). The tool will refuse unless forced.
python src/pyhdwallet.py gen > output.txt  # ❌ Blocked by default

# Explicitly override the safety guard (dangerous).
python src/pyhdwallet.py gen --force > output.txt  # ✅ Allowed but discouraged

Recommendation: Use --file instead of shell redirection.

Security Notes (Practical)

Offline Security Best Practices

Air-Gapped Setup (Highest Security)

An air-gapped machine has:

  • No network interfaces (WiFi, Ethernet disabled/removed)
  • No Bluetooth
  • No USB devices except for initial setup
  • Physically isolated environment

Setup steps:

  1. Build/verify on trusted internet machine:

    git clone https://github.com/yourusername/hdwalletpy.git
    cd hdwalletpy
    
    # Verify checksums for target platform
    cd vendor/linux-x86_64 && sha256sum -c SHA256SUMS
    
  2. Transfer via USB/CD:

    # Copy entire repo to USB
    cp -r hdwalletpy /media/USB/
    
    # On air-gapped machine, verify checksums again
    cd /media/USB/hdwalletpy/vendor/linux-x86_64
    sha256sum -c SHA256SUMS
    
  3. Install offline:

    ./install_offline.sh
    source .venv/bin/activate
    
  4. Generate wallet:

    python src/pyhdwallet.py gen --file --zip --pgp recipient@example.com
    
  5. Store encrypted artifacts on separate USB (not the air-gapped machine)

Threats Air-Gapping Mitigates

Network-based attacks: Malware, keyloggers, remote exploitation
Supply chain attacks: Compromised PyPI packages (using vendored wheels)
Clipboard hijacking: If using --file mode

Threats Air-Gapping Does NOT Fully Mitigate

⚠️ Hardware keyloggers (physical security required)
⚠️ Side-channel attacks (electromagnetic, acoustic)
⚠️ Physical access (disk imaging, cold boot attacks)
⚠️ Compromised build environment (verify checksums, inspect code)

Physical Security

  • 🔒 Boot from read-only media (Live USB/CD)
  • 🔒 Full disk encryption on air-gapped machine
  • 🔒 Store encrypted wallet artifacts separately from air-gapped machine
  • 🔒 Destroy USB media after wallet generation (or keep offline)

Verification Through Testing

# On the air-gapped machine, before generating your wallet:
python src/pyhdwallet.py test
pytest -v tests/test_vectors.py  # If dev mode installed

Entropy Sources

The tool uses Python's secrets.token_bytes() which relies on:

  • Linux: /dev/urandom (kernel CSPRNG)
  • macOS: Security.framework randomness
  • Windows: CryptGenRandom()

Additional entropy sources:

  • System uptime
  • Process IDs
  • Hardware interrupts

PGP Key Fingerprint Pinning

# First, get and verify the fingerprint of your recipient key
gpg --fingerprint recipient@example.com

# Manually verify fingerprint matches what you expect (check via another channel)

# Then use it with pinning:
python src/pyhdwallet.py gen --file --zip --pgp recipient@example.com

Operational Checklist

Before generating a production wallet:

  • Verified Python 3.12 installation
  • Verified vendored wheel checksums
  • Tested smoke test (python src/pyhdwallet.py test)
  • Tested recovery process with test mnemonic
  • Disabled all network interfaces on air-gapped machine
  • Prepared encrypted storage media for wallet artifacts
  • Have PGP recipient key ready (if using --pgp)
  • Have strong password ready for ZIP encryption

Lower-Risk Scenarios

If full air-gapping is impractical:

  • Use a dedicated laptop (factory reset, minimal software)
  • Boot from Live USB (Tails, Ubuntu Live)
  • Disconnect network before wallet generation
  • Use hardware wallets for signing (this tool generates seeds only)

Trust But Verify

  • Inspect the source code before trusting
  • Build vendor wheels yourself instead of using pre-built
  • Run test suite to ensure cryptographic correctness
  • Compare generated addresses with other tools (Ian Coleman's BIP39 tool)

Troubleshooting

"Permission denied" running ./src/pyhdwallet.py

chmod +x src/pyhdwallet.py
# or
python3.12 src/pyhdwallet.py gen

Python 3.12 not found

# macOS
brew install python@3.12

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install python3.12 python3.12-venv

# Verify
python3.12 --version

"Missing dependency" errors

# Check your platform
uname -sm

# Install for macOS ARM64
pip install --no-index --find-links=vendor/macos-arm64 -r requirements.txt

# Install for Linux x86_64
pip install --no-index --find-links=vendor/linux-x86_64 -r requirements.txt

# Install for Linux aarch64
pip install --no-index --find-links=vendor/linux-aarch64 -r requirements.txt

Checksum verification failures

# If failures occur, re-download from trusted source
git clone --depth=1 https://github.com/yourusername/hdwalletpy.git

# DO NOT use corrupted wheels for production wallets

Unzipping AES ZIP issues

# Use pyzipper (installed with vendored deps)
python -c "import pyzipper; pyzipper.AESZipFile('wallet.zip').extractall(pwd=b'password')"

Test failures after code changes

# Regenerate test vectors if you changed derivation logic
python src/pyhdwallet.py gen > tests/expected_output.txt

# Re-run tests
pytest -v tests/test_vectors.py

Development

Building Vendor Wheels

# Clean old wheels
make clean-vendor

# Build for all platforms
make vendor-all          # Runtime only
make vendor-all-dev      # Runtime + dev (pytest)

# Build specific platform
make vendor-macos
make vendor-linux
make vendor-linux-arm

# Verify and commit
git add vendor/
git commit -m "vendor: update wheels for v1.1.0"

Running Tests (Dev)

# Quick test
python src/pyhdwallet.py test

# Full regression suite
pytest -v tests/test_vectors.py

# Specific test
pytest -v tests/test_vectors.py::test_bip39_generation

# With coverage
pytest --cov=src tests/

Docker Development Environment

# Build image
make build-image

# Start warm container
make up

# Inside container
make shell
python src/pyhdwallet.py test

Changelog

v1.1.0 (2026-01-12)

  • Added multi-platform vendor support (macOS ARM64, Linux x86_64, Linux aarch64)
  • Added dev wheel packages for all platforms (includes pytest)
  • Added automatic platform detection in install_offline.sh
  • Added checksum verification for all vendor wheels
  • Updated Makefile with vendor-all and vendor-all-dev targets
  • 📚 Updated documentation for air-gapped multi-platform setup

v1.0.5 (Previous)

  • Initial vendoring support for macOS and Linux x86_64
  • BIP32/BIP39/BIP44 implementation
  • PGP encryption support
  • AES-256 ZIP encryption