Python bindings for selected RustCrypto post-quantum algorithms.
Lycan currently wraps:
- ML-KEM from RustCrypto
ml-kem - ML-DSA from RustCrypto
ml-dsa - SLH-DSA from RustCrypto
slh-dsa
The underlying RustCrypto implementations wrapped by Lycan have not all been independently audited.
USE AT YOUR OWN RISK.
Lycan also adds a Python FFI layer. Keep secret-key objects in their Rust-backed classes when possible. Export helpers such as to_seed() and to_private_bytes() create immutable Python bytes copies, and Lycan cannot reliably zeroize Python-managed memory after those copies exist.
You can install lycan using your preferred package manager:
# Using pip
pip install lycan
# Using uv
uv add lycan
## Install for development
uv run maturin developimport lycan
secret_key, public_key = lycan.ml_kem_keygen("ML-KEM-768")
ciphertext, sender_secret = lycan.ml_kem_encapsulate(public_key, "ML-KEM-768")
receiver_secret = secret_key.decapsulate(ciphertext)
assert sender_secret == receiver_secretAvailable ML-KEM algorithms:
lycan.ml_kem_algorithms()secret_key, public_key = lycan.ml_dsa_keygen("ML-DSA-65")
signature = secret_key.sign(b"message", context=b"example")
assert lycan.ml_dsa_verify(
"ML-DSA-65", public_key, b"message", signature, context=b"example"
)Available ML-DSA algorithms:
lycan.ml_dsa_algorithms()secret_key, public_key = lycan.slh_dsa_keygen("SLH-DSA-SHAKE-128f")
signature = secret_key.sign(b"message", context=b"example")
assert lycan.slh_dsa_verify(
"SLH-DSA-SHAKE-128f", public_key, b"message", signature, context=b"example"
)Available SLH-DSA algorithms:
lycan.slh_dsa_algorithms()