larzcrypt
Batteries-included, pure-Python cryptography. Zero dependencies.
The primitives you actually reach for — hashing, HMAC, key derivation, password hashing, authenticated encryption, key agreement, and signatures — behind one small, hard-to-misuse import surface, with nothing to compile and nothing to install.
from larzcrypt import ed25519, seal, unseal, hash_password, check_password
# sign & verify
priv, pub = ed25519.generate_keypair()
sig = ed25519.sign(priv, b"ship it")
assert ed25519.verify(pub, b"ship it", sig)
# encrypt to someone's public key (they alone can open it)
blob = seal(their_x25519_pubkey, b"for your eyes only")
# store passwords safely
stored = hash_password("correct horse battery staple")
assert check_password("correct horse battery staple", stored)
What's inside
Everything is verified against the relevant standard's official test vectors.
| area | what | standard |
|---|---|---|
| hashing / HMAC | SHA-2/3, BLAKE2, RIPEMD-160, sha256d, hash160, constant-time compare |
FIPS / RFC 4231 |
| key derivation | HKDF, PBKDF2, scrypt | RFC 5869 |
| password hashing | scrypt → self-describing storable strings | — |
| AEAD | ChaCha20-Poly1305 | RFC 8439 |
| key agreement | X25519 Diffie-Hellman | RFC 7748 |
| signatures | Ed25519; ECDSA over secp256k1 (deterministic RFC 6979) | RFC 8032 / 6979 |
| public-key encryption | anonymous seal/unseal + authenticated Box |
— |
| tokens | CSPRNG tokens, URL-safe base64 | — |
| JWT | HS256/384/512, EdDSA, ES256K — with safe verify | RFC 7519 |
Install
pip install larzcrypt
Zero required dependencies. Optionally pip install larzcrypt[fast] to pull in
coincurve — larzcrypt will auto-use it for secp256k1 only after a self-test
proves it produces byte-identical signatures, so it speeds things up without ever
changing your output.
Highlights
Authenticated encryption that can't be silently tampered
from larzcrypt import chacha20poly1305 as aead, token_bytes
key, nonce = token_bytes(32), token_bytes(12) # nonce unique per message!
ct = aead.encrypt(key, nonce, b"secret", aad=b"header")
pt = aead.decrypt(key, nonce, ct, aad=b"header") # raises if tampered
Encrypt to a public key (sealed boxes)
from larzcrypt import x25519, seal, unseal
priv, pub = x25519.generate_keypair()
blob = seal(pub, b"hello") # anyone can seal to `pub`
unseal(priv, blob) # only `priv` can open it -> b"hello"
Or an authenticated two-way channel where each side knows the other:
from larzcrypt import x25519, Box
a_priv, a_pub = x25519.generate_keypair()
b_priv, b_pub = x25519.generate_keypair()
a, b = Box(a_priv, b_pub), Box(b_priv, a_pub)
b.decrypt(a.encrypt(b"ping")) # -> b"ping", and forgery is impossible
JWTs without the footguns
decode() takes the expected algorithm as a required argument and ignores
the token's own alg header — so the classic alg:none and RS256→HS256
confusion attacks simply can't happen.
from larzcrypt import jwt, ed25519
priv, pub = ed25519.generate_keypair()
token = jwt.encode({"sub": "42", "exp": 1893456000}, priv, alg="EdDSA")
jwt.decode(token, pub, alg="EdDSA") # {"sub": "42", ...}, or raises
Password storage you don't have to think about
from larzcrypt import hash_password, check_password
stored = hash_password("hunter2") # 'scrypt$16384$8$1$<salt>$<hash>'
check_password("hunter2", stored) # True — params are in the string
A note on trust
Pure-Python crypto is auditable and dependency-free, and every primitive
here matches its standard's test vectors. It is not, and does not claim to be,
side-channel hardened to the level of a C library like libsodium. Use it freely
for signing, tokens, KDFs, app-level encryption, JWTs, and blockchain keys. For
deployments where an attacker can measure precise timing of your secret-key
operations at scale, pair it with a hardened backend (secp256k1 already
auto-uses coincurve when available).
Don't invent protocols on top of these primitives without knowing what you're
doing — reach for the high-level seal/Box/jwt/hash_password helpers,
which compose them correctly for you.
Tests
python -m unittest discover -s tests -v # 37 tests incl. RFC vectors, zero deps
The Larz stack
Pure-Python, zero-dependency building blocks:
- larz — money-native web framework
- larzchain — from-scratch PoW blockchain
- larzmoney — exact, penny-perfect money
- larzcrypt — this library
License
MIT © larz-scripter
Metadata
Release files for larzcrypt 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| larzcrypt-0.1.1.tar.gz | 23.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| larzcrypt-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.9 kB
Release files / larzcrypt-0.1.1.tar.gz
| Download URL | larzcrypt-0.1.1.tar.gz |
|---|---|
| Size | 23.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c456499a06018b957f40e58320e9fc07020804282bd5acc36f4f9048c734f499
|
|
BLAKE2b-256 checksum How to use checksums |
7c48de6476f617dd4d0d2579193d60c7226b5f12a485ad8f6ad75ed6d862fa67
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / larzcrypt-0.1.1-py3-none-any.whl
| Download URL | larzcrypt-0.1.1-py3-none-any.whl |
|---|---|
| Size | 22.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9aa2bf451f2112e72f40ef6c0d5a4ea2d4130ab79f371695e3823eb9a29f83c2
|
|
BLAKE2b-256 checksum How to use checksums |
bb77d5d7e77c249cc0cbfcadabdaa51a27ff2e7ceab80bdb597e6b05880bd398
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for larzcrypt 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.