Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bitcoin Keygen

Pure-Python Bitcoin key and address utilities. Zero runtime dependencies.

Every operation — secp256k1 scalar multiplication, RIPEMD-160, base58check — is implemented inside this package, so the whole codebase is auditable line by line and does not depend on any compiled extension or third-party library.

Install

pip install git+https://github.com/cheran-senthil/bitcoin-keygen.git

Or clone and pip install -e . for a working copy. Requires Python 3.9+.

Usage

from bitcoin_keygen import PrivateKey, PublicKey, base58

# Generate a fresh random key.
k = PrivateKey.generate()

k.hex()                                     # 64-char lowercase hex
k.wif(compressed=True)                      # WIF string
k.address(compressed=True)                  # P2PKH mainnet address
k.address(compressed=True, mainnet=False)   # testnet address
k.public_key()                              # PublicKey instance

# Import from other formats.
PrivateKey.from_hex("0c28fc...aa1d")
PrivateKey.from_bytes(b"\\x0c...")          # exactly 32 bytes
decoded = PrivateKey.from_wif("5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ")
decoded.private_key   # PrivateKey
decoded.compressed    # bool, taken from the WIF payload — never a caller argument
decoded.mainnet       # bool, taken from the WIF version byte

# Public keys.
pub = PublicKey.from_hex("04d0de0aae...648cb0a")
pub.hex(compressed=True)
pub.address(mainnet=True)

# Base58Check codec (bytes-native).
base58.encode(b"\\x00" + b"\\x11" * 20)     # → str
base58.decode(some_address)                  # → bytes, raises ValueError on bad checksum

Design

  • PrivateKey / PublicKey validate at construction. There is no path to a derivation method with an invalid, out-of-range, or wrong-shape key.
  • WIF decoding takes compression and network from the payload itself. There is no compressed argument to from_wif that could disagree with the string.
  • base58.decode verifies the double-SHA256 checksum and raises ValueError on any tampered or mistyped string, so a single-character typo in a WIF is caught rather than silently producing a different private key.
  • secp256k1 scalar multiplication uses a Montgomery ladder (one add + one double per bit regardless of key bits) rather than double-and-add-only. Python's arbitrary-precision int operations are not themselves constant-time, so this is defense in depth, not a cryptographic guarantee.
  • RIPEMD-160 is a pure-Python implementation of the FIPS-published algorithm, independent of OpenSSL — the library behaves identically on every Python build, including recent ones where OpenSSL's legacy provider is disabled.

Testing

pip install -e ".[test]"
pytest

Covers: base58check round-trips and error paths, secp256k1 arithmetic, RIPEMD-160 against the spec's published vectors (including the 1M-a stress test), the PrivateKey / PublicKey API surface, Bitcoin-wiki end-to-end test vectors, and one regression test per pre-1.0 API bug.

License

GNU General Public License v3.0 (c) 2019 Cheran Senthilkumar

Releases

Packages

Used by

Contributors

Languages