Skip to main content

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:

  1. Keep the public API simple and stable.
  2. Avoid unnecessary runtime dependencies.
  3. Provide deterministic and reproducible address generation.
  4. Use correct cryptographic primitives for each chain.
  5. Keep private key operations local and offline-friendly.
  6. 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


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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

libcrypto-1.6.1.tar.gz (48.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

libcrypto-1.6.1-py3-none-any.whl (38.5 kB view details)

Uploaded Python 3

File details

Details for the file libcrypto-1.6.1.tar.gz.

File metadata

  • Download URL: libcrypto-1.6.1.tar.gz
  • Upload date:
  • Size: 48.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for libcrypto-1.6.1.tar.gz
Algorithm Hash digest
SHA256 6c4b930bec0b7675050fde99ee6927148e05a3f4f31ae17c81a9aa6b63d00038
MD5 801faf26d174c672df884bdbfca4e5a2
BLAKE2b-256 bfdccf703fd862cb485e2b075ce924cf9722d99ceed968a887956ce89017875d

See more details on using hashes here.

File details

Details for the file libcrypto-1.6.1-py3-none-any.whl.

File metadata

  • Download URL: libcrypto-1.6.1-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

Hashes for libcrypto-1.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f4832f01041a541fc9414ee9471994b50bcbefddd3a04db409756911a333806f
MD5 3072561544651157b17e39579c1efcd4
BLAKE2b-256 099538bd17ff947e1de95ed7465f9f4e9b6f8db2f4fcbd5ad19589261920abc1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page