Python package: metamui-crypto
Side-channel claim limit. Nothing on this page claims constant-time behaviour or side-channel resistance for any target: the side-channel harness covers nothing (finding A48) and no measurement exists. The Rust and C cores are designed for constant time and unmeasured; managed runtimes (JIT, GC, bounds checks) make no timing claim. Where this page names constant-time or side-channel techniques, in prose or in code, they are design intent or recommendations, not measured properties.
Version: 1.0.0rc7 (the 1.0.0-rc.7 release line in PyPI form; no package is published on PyPI yet)
Python: 3.10, 3.11, 3.12 (requires-python >= 3.10)
Licence: Apache-2.0
Distribution: one package, metamui-crypto, importing as metamui_crypto. The wheel carries compiled extensions (SHA-2, SHA-3, SHAKE and HMAC compiled from metamui-crypto-c, and the post-quantum cores), one wheel per interpreter; the sdist builds them with a C compiler. Nothing in the package wraps an external cryptography library.
This page is the package summary; the Python API Reference and the Python platform guide carry the installation and build detail.
Installation
pip install metamui-crypto==1.0.0rc7
Until the package is published, install the wheel of a locally built candidate or the source directory itself (pip install metamui-crypto-python/ from a checkout).
The facade
metamui_crypto.facade names every post-quantum profile of the release catalog by its identifier and holds each to the public API contract (explicit selection, validated byte boundaries, no boolean verify, required context strings, OS randomness only; see the Public API Reference). The block below was run on 2026-10-16 against this source tree: pip install metamui-crypto-python/ into a fresh Python 3.12 virtual environment, then python -I on the file; it exited 0.
from metamui_crypto.facade import profile
sig = profile("ml-dsa-65")
keys = sig.generate_keypair()
signature = sig.sign(keys.secret_key, b"message", context=b"my-app")
sig.verify(keys.public_key, b"message", signature, context=b"my-app") # raises InvalidSignatureError on failure
kem = profile("ml-kem-768")
ek, dk = kem.generate_keypair()
ct, ss = kem.encapsulate(ek)
assert kem.decapsulate(dk, ct) == ss
A family name is refused rather than substituted (also run on 2026-10-16; it printed refused: unsupported profile 'ml-kem'):
from metamui_crypto.facade import profile, UnsupportedProfileError
try:
profile("ml-kem") # a family name is not a profile
except UnsupportedProfileError as e:
print("refused:", e)
Profile objects: falcon512_compressed, falcon512_padded, falcon1024_compressed, falcon1024_padded, mlkem512, mlkem768, mlkem1024, mldsa44, mldsa65, mldsa87, the twelve SLH-DSA sets, smaugt modes 1/3/5, haetae2, haetae3, haetae5, aimer128s … aimer256f, ntruplus768, ntruplus864, ntruplus1152 — the 37 profiles the facade admits. Every error is a MetaMuiCryptoError subclass: UnsupportedProfileError, InvalidLengthError, InvalidHeaderError, MalformedKeyError, InvalidSignatureError, SigningFailedError, KeyGenerationFailedError, EntropyUnavailableError, EncapsulationFailedError, DecapsulationFailedError (NTRU+ only).
Modules in the package
Classical and supporting primitives are modules of metamui_crypto: sha2, sha3, shake, keccak, blake2b, blake2s, blake3, siphash, flathash, hmac, hkdf, pbkdf2, argon2, cmac, poly1305, aes256, aes_ctr_drbg, hmac_drbg, chacha20, chacha20_poly1305, camellia, aria256, ascon, deoxys, ed25519, ed25519zip215, rsa2048, mnemonic, hdwallet; the post-quantum families are falcon, mlkem, dilithium, slhdsa, smaug_t, haetae, aimer, ntru_plus. The catalog records the classical profiles blake3, sha3-256, shake-256, keccak-256, aes-256-gcm, hkdf-sha256, ed25519 and sr25519 as validated on the Python target; the other modules are present with their own tests and no catalog claim.
metamui_crypto.DEFERRED_FAMILIES names the families the release catalog defers (Classic McEliece, FrodoKEM, HQC, LMS, NTRU Prime, XMSS); their modules are present for evaluation and no cell of the catalog claims them.
Testing
python3 -m pytest
The suite replays the upstream answer files under test-vectors/ through the public API; a missing vector file fails the run. (Not re-run for this page; the command is the package’s own, from its README.)
What is not claimed
- Side channels: not claimed. CPython gives no timing guarantee and nothing is measured (A48).
- Certification: the NIST vectors are replayed in the test suite; no CMVP or CAVP certificate exists.
- Performance: no figure is published for this package.
- Audit: no independent audit has been performed.