Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

About

Batteries-included pure-Python cryptography: hashing, HKDF, ChaCha20-Poly1305, X25519, Ed25519, ECDSA, JWT, sealed boxes. Zero dependencies.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages