Pure Python cryptocurrency address generation and cryptographic utilities.
Project description
libcrypto
A lightweight, dependency-free Python library for deterministic cryptocurrency key and address generation.
libcrypto is designed for developers who need a clean, portable, and auditable cryptographic address engine without unnecessary runtime dependencies. It provides pure Python implementations for core wallet operations, including private key handling, public key derivation, address encoding, WIF conversion, mnemonic-based HD wallets, and multi-chain address generation.
The library focuses on predictable output, compatibility with established address formats, and a stable public API suitable for production tools, research utilities, wallet infrastructure, offline generators, and blockchain automation systems.
Key Features
- Pure Python implementation
- No required runtime dependencies
- Deterministic private key to public address conversion
- secp256k1 public key derivation
- Real Keccak-256 implementation for Ethereum and TRON
- RIPEMD-160 support with internal fallback
- Base58Check, Bech32, Bech32m, and CashAddr support
- Bitcoin legacy, nested SegWit, native SegWit, and Taproot addresses
- Ethereum-compatible EVM address generation
- TRON Base58 and hex address generation
- WIF import and export
- Public key based address generation
- BIP39 mnemonic utilities
- BIP32/BIP44-style HD wallet support
- Clean API for single-wallet and batch generation workflows
- Suitable for offline and local-first key/address operations
Installation
pip install libcrypto
Upgrade to the latest version:
pip install --upgrade libcrypto
Examples
Practical usage examples are available in the examples/ directory.
The Examples Cover Multi-chain Address Generation, Secure Wallet Creation, WIF import/export, Public-key-only Workflows, HD wallet Derivation, Batch CSV Generation, and Deterministic Address Test Vectors.
See More Details for the Full Example Guide.
Basic Usage
Generate multiple blockchain addresses from a single private key:
from libcrypto import Wallet
private_key = "0000000000000000000000000000000000000000000000000000000000000001"
wallet = Wallet(private_key)
print("Bitcoin P2PKH:", wallet.get_address("bitcoin", "p2pkh"))
print("Bitcoin P2SH-P2WPKH:", wallet.get_address("bitcoin", "p2sh-p2wpkh"))
print("Bitcoin P2WPKH:", wallet.get_address("bitcoin", "p2wpkh"))
print("Bitcoin Taproot:", wallet.get_address("bitcoin", "p2tr"))
print("Ethereum:", wallet.get_address("ethereum"))
print("TRON:", wallet.get_address("tron"))
print("TRON Hex:", wallet.get_address("tron", "hex"))
Expected deterministic output for private key 1:
Bitcoin P2PKH: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
Bitcoin P2SH-P2WPKH: 3JvL6Ymt8MVWiCNHC7oWU6nLeHNJKLZGLN
Bitcoin P2WPKH: bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
Bitcoin Taproot: bc1pmfr3p9j00pfxjh0zmgp99y8zftmd3s5pmedqhyptwy6lm87hf5sspknck9
Ethereum: 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf
TRON: TMVQGm1qAQYVdetCeGRRkTWYYrLXuHK2HC
TRON Hex: 417E5F4552091A69125D5DFCB7B8C2659029395BDF
Generate a New Wallet
from libcrypto import Wallet
wallet = Wallet.generate()
print("Private key:", wallet.private_key.hex)
print("WIF:", wallet.private_key.to_wif(compressed=True))
print("Bitcoin:", wallet.get_address("bitcoin", "p2pkh"))
print("Ethereum:", wallet.get_address("ethereum"))
print("TRON:", wallet.get_address("tron"))
Security note: never expose, log, upload, or commit real private keys.
Supported Address Types
Bitcoin
from libcrypto import Wallet
wallet = Wallet.generate()
print(wallet.get_address("bitcoin", "p2pkh"))
print(wallet.get_address("bitcoin", "p2sh-p2wpkh"))
print(wallet.get_address("bitcoin", "p2wpkh"))
print(wallet.get_address("bitcoin", "p2tr"))
Supported Bitcoin formats:
| Type | Description | Prefix |
|---|---|---|
p2pkh |
Legacy Pay-to-Public-Key-Hash | 1 |
p2sh-p2wpkh |
Nested SegWit | 3 |
p2wpkh |
Native SegWit v0 | bc1q |
p2tr |
Taproot / Native SegWit v1 | bc1p |
Ethereum and EVM Networks
Ethereum and EVM-compatible chains use the same address derivation method.
from libcrypto import Wallet
wallet = Wallet.generate()
print("Ethereum:", wallet.get_address("ethereum"))
print("BSC:", wallet.get_address("bsc"))
print("Polygon:", wallet.get_address("polygon"))
print("Avalanche:", wallet.get_address("avalanche"))
print("Arbitrum:", wallet.get_address("arbitrum"))
print("Optimism:", wallet.get_address("optimism"))
print("Base:", wallet.get_address("base"))
print("Ethereum Classic:", wallet.get_address("ethereum_classic"))
EVM addresses are generated using Keccak-256 and returned with EIP-55 checksum formatting.
TRON
from libcrypto import Wallet
wallet = Wallet.generate()
print("TRON Base58:", wallet.get_address("tron"))
print("TRON Hex:", wallet.get_address("tron", "hex"))
TRON addresses are generated from the same secp256k1 public key model used by Ethereum, but encoded with TRON's 0x41 address prefix and Base58Check representation.
Litecoin, Dogecoin, Dash, Bitcoin Cash, DigiByte, and Namecoin
from libcrypto import Wallet
wallet = Wallet.generate()
print("Litecoin:", wallet.get_address("litecoin", "p2pkh"))
print("Dogecoin:", wallet.get_address("dogecoin", "p2pkh"))
print("Dash:", wallet.get_address("dash", "p2pkh"))
print("Bitcoin Cash:", wallet.get_address("bitcoin_cash", "cashaddr"))
print("DigiByte:", wallet.get_address("digibyte", "p2pkh"))
print("Namecoin:", wallet.get_address("namecoin", "p2pkh"))
Get All Addresses for a Coin
from libcrypto import Wallet
wallet = Wallet.generate()
addresses = wallet.get_all_addresses("bitcoin")
for address_type, address in addresses.items():
print(address_type, address)
Example output:
p2pkh 1...
p2sh-p2wpkh 3...
p2wpkh bc1q...
p2tr bc1p...
Private Key Handling
Create a private key from hex:
from libcrypto import PrivateKey
private_key = PrivateKey(
"0000000000000000000000000000000000000000000000000000000000000001"
)
print(private_key.hex)
Generate a secure private key:
from libcrypto import PrivateKey
private_key = PrivateKey.generate()
print(private_key.hex)
Export to WIF:
from libcrypto import PrivateKey
private_key = PrivateKey.generate(network="bitcoin")
print(private_key.to_wif(compressed=True))
print(private_key.to_wif(compressed=False))
Import from WIF:
from libcrypto import PrivateKey, Wallet
wif = "your_wif_private_key_here"
private_key = PrivateKey(wif)
wallet = Wallet(private_key)
print(wallet.get_address("bitcoin", "p2pkh"))
Public Key Usage
Generate addresses directly from public keys:
from libcrypto import PrivateKey, PublicKey
private_key = PrivateKey(
"0000000000000000000000000000000000000000000000000000000000000001"
)
compressed_public_key = private_key.get_public_key(compressed=True)
uncompressed_public_key = private_key.get_public_key(compressed=False)
bitcoin_public_key = PublicKey(compressed_public_key.hex)
ethereum_public_key = PublicKey(uncompressed_public_key.hex)
print(bitcoin_public_key.get_address("p2pkh", "bitcoin"))
print(bitcoin_public_key.get_address("p2wpkh", "bitcoin"))
print(ethereum_public_key.get_address("default", "ethereum"))
HD Wallets and Mnemonics
Generate a mnemonic phrase:
from libcrypto import generate_mnemonic, validate_mnemonic
mnemonic = generate_mnemonic(12)
print(mnemonic)
print(validate_mnemonic(mnemonic))
Create an HD wallet from a mnemonic:
from libcrypto import HDWallet, Wallet, generate_mnemonic
mnemonic = generate_mnemonic(12)
hd_wallet = HDWallet.from_mnemonic(
mnemonic,
passphrase="",
network="mainnet",
)
node = hd_wallet.derive_from_path("m/44'/60'/0'/0/0")
if node.private_key is None:
raise RuntimeError("Derived node does not contain a private key.")
wallet = Wallet(node.private_key)
print(wallet.get_address("ethereum"))
Bitcoin derivation example:
from libcrypto import HDWallet, Wallet, generate_mnemonic
mnemonic = generate_mnemonic(12)
hd_wallet = HDWallet.from_mnemonic(
mnemonic,
passphrase="",
network="mainnet",
)
node = hd_wallet.derive_from_path("m/84'/0'/0'/0/0")
if node.private_key is None:
raise RuntimeError("Derived node does not contain a private key.")
wallet = Wallet(node.private_key)
print(wallet.get_address("bitcoin", "p2wpkh"))
TRON derivation example:
from libcrypto import HDWallet, Wallet, generate_mnemonic
mnemonic = generate_mnemonic(12)
hd_wallet = HDWallet.from_mnemonic(
mnemonic,
passphrase="",
network="mainnet",
)
node = hd_wallet.derive_from_path("m/44'/195'/0'/0/0")
if node.private_key is None:
raise RuntimeError("Derived node does not contain a private key.")
wallet = Wallet(node.private_key)
print(wallet.get_address("tron"))
Batch Wallet Generation
import csv
from pathlib import Path
from libcrypto import Wallet
output_path = Path("wallets.csv")
fieldnames = [
"index",
"private_key_hex",
"bitcoin_p2pkh",
"bitcoin_p2wpkh",
"bitcoin_p2tr",
"ethereum",
"tron",
]
with output_path.open("w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
for index in range(1, 11):
wallet = Wallet.generate()
writer.writerow(
{
"index": index,
"private_key_hex": wallet.private_key.hex,
"bitcoin_p2pkh": wallet.get_address("bitcoin", "p2pkh"),
"bitcoin_p2wpkh": wallet.get_address("bitcoin", "p2wpkh"),
"bitcoin_p2tr": wallet.get_address("bitcoin", "p2tr"),
"ethereum": wallet.get_address("ethereum"),
"tron": wallet.get_address("tron"),
}
)
print(f"Wallets written to {output_path.resolve()}")
Warning: this CSV file contains private keys. Store it offline and protect it carefully.
Deterministic Test Vector
This example verifies that the library produces deterministic and standard addresses from a known secp256k1 private key.
from libcrypto import Wallet
private_key = "0000000000000000000000000000000000000000000000000000000000000001"
wallet = Wallet(private_key)
assert wallet.get_address("bitcoin", "p2pkh") == "1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH"
assert wallet.get_address("bitcoin", "p2sh-p2wpkh") == "3JvL6Ymt8MVWiCNHC7oWU6nLeHNJKLZGLN"
assert wallet.get_address("bitcoin", "p2wpkh") == "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"
assert wallet.get_address("bitcoin", "p2tr") == "bc1pmfr3p9j00pfxjh0zmgp99y8zftmd3s5pmedqhyptwy6lm87hf5sspknck9"
assert wallet.get_address("ethereum") == "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf"
assert wallet.get_address("tron") == "TMVQGm1qAQYVdetCeGRRkTWYYrLXuHK2HC"
assert wallet.get_address("tron", "hex") == "417E5F4552091A69125D5DFCB7B8C2659029395BDF"
print("All deterministic address vectors passed.")
Command Line Usage
If installed with console script support:
libcrypto --help
Example usage:
libcrypto generate
Depending on the installed version, CLI commands may expose wallet generation, address conversion, and inspection utilities.
Design Goals
libcrypto is built around a few strict design principles:
- Keep the public API simple and stable.
- Avoid unnecessary runtime dependencies.
- Provide deterministic and reproducible address generation.
- Use correct cryptographic primitives for each chain.
- Keep private key operations local and offline-friendly.
- Make the implementation easy to inspect, test, and package.
Security Considerations
libcrypto performs local cryptographic key and address operations. It does not protect users from unsafe operational practices.
Follow these rules carefully:
- Never use demo private keys for real funds.
- Never commit private keys, mnemonic phrases, WIF keys, or seed material.
- Never log private keys in production systems.
- Never send private keys to remote APIs unless your application explicitly requires it and users fully understand the risk.
- Prefer offline execution for sensitive key generation workflows.
- Always verify address output with independent test vectors before integrating into high-value systems.
- Use secure backups for mnemonic phrases and private keys.
- Treat generated CSV, JSON, and text files containing private keys as highly sensitive data.
This library is intended for developers who understand the responsibility of handling private keys and wallet material.
Testing
Run the test suite:
python -m pytest -q
Build the package locally:
python -m pip install --upgrade build twine
python -m build --sdist --wheel
python -m twine check dist/*
Install locally from source:
pip install .
Packaging
The package is designed to be distributed as a pure Python wheel:
python -m build --wheel
Generated distributions are placed in:
dist/
Project Links
- Repository: https://gitlab.com/0xmdrza/libcrypto
- PyPI: https://pypi.org/project/libcrypto/
License
This project is distributed under the MIT License.
Disclaimer
This software is provided for development, research, and infrastructure use. Cryptocurrency private key handling is security-critical. The authors and contributors are not responsible for lost funds, insecure deployments, compromised keys, incorrect integrations, or misuse of the library.
Always test carefully before using any cryptographic tool in production.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file libcrypto-1.6.3.tar.gz.
File metadata
- Download URL: libcrypto-1.6.3.tar.gz
- Upload date:
- Size: 48.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
910e22d201e85f1013767ec9166a71b2d3402ddf24d4d42aec2d8908ad932b78
|
|
| MD5 |
f7271f226a6aa3a6852e612e533140cf
|
|
| BLAKE2b-256 |
2b696a14fa9714468dc1703bc7f59ee7cbac91e809d09497b811653e514f9b04
|
File details
Details for the file libcrypto-1.6.3-py3-none-any.whl.
File metadata
- Download URL: libcrypto-1.6.3-py3-none-any.whl
- Upload date:
- Size: 38.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d403fb3677fd415453b0fd5e2f9b0c2cfb5d0d26f88c779cb63866960f36949
|
|
| MD5 |
76c40bf493868780c1209548a3e4fd64
|
|
| BLAKE2b-256 |
02b444fa41956caf591d12965564b0d4296409f800d0ebd61d36b9c62ce9680b
|