KRANSX
Authenticated encryption with adaptive compression for Python.
KRANSX seals arbitrary bytes into a compact, authenticated envelope. It applies Zstandard compression only when it reduces size, otherwise stores the payload as-is, and protects both with AES-256-GCM-SIV. The result is a single self-contained binary with 29 bytes of overhead.
Features
- Adaptive compression — Zstandard when beneficial, raw otherwise
- Authenticated encryption — AES-256-GCM-SIV (nonce-misuse resistant)
- Small fixed overhead — 29 bytes (
suite+nonce+tag) - Simple API —
seal/open_data, fully typed - Dictionary support — optional Zstandard dictionaries for structured data
- CLI —
keygen,seal,open,train - No background services or async dependencies
Installation
pip install kransx
For development:
uv sync --locked --extra dev
Requires Python 3.10+, cryptography >= 42, zstandard >= 0.22.
Usage
Python API
import secrets
from kransx import open_data, seal
key = secrets.token_bytes(32) # 32 uniformly random bytes
aad = b"record-42" # associated data, authenticated but not encrypted
sealed = seal(b"hello world", key, aad=aad)
assert open_data(sealed, key, aad=aad) == b"hello world"
Authentication failures raise cryptography.exceptions.InvalidTag (wrong key, AAD, dictionary, or modified bytes). Structural errors raise ValueError.
With a shared dictionary (non-secret, improves compression on similar payloads):
from kransx import train_dict
dictionary = train_dict([b'{"user":1,"action":"login"}'] * 300)
sealed = seal(b'{"user":1,"action":"login"}', key, dict_obj=dictionary)
assert open_data(sealed, key, dict_obj=dictionary) == b'{"user":1,"action":"login"}'
API reference:
seal(data: bytes, key: bytes, *, dict_obj=None, aad=b"", compress=True, level=3) -> bytes
open_data(blob: bytes, key: bytes, *, dict_obj=None, aad=b"", max_output_size=64*1024*1024) -> bytes
train_dict(samples: Iterable[bytes], dict_size=16384) -> ZstdCompressionDict
save_dict(dictionary, path) / load_dict(path)
compress=True retains the Zstandard frame only when strictly smaller than the input. max_output_size limits the decompressed output size.
CLI
kransx keygen key.bin
kransx seal plain.bin sealed.bin --key-file key.bin --aad 7265636f72642d3432
kransx open sealed.bin restored.bin --key-file key.bin --aad 7265636f72642d3432
kransx train 'samples/*.json' --output model.dict
kransx seal plain.bin out.bin --key-file key.bin --dict model.dict
kransx open out.bin restored.bin --key-file key.bin --dict model.dict --max-output-size 1048576
--aadaccepts hex-encoded bytes--max-output-sizecaps plaintext size on open- Output files are created exclusively and never overwritten
Design
Envelope layout: suite (1) | nonce (12) | ciphertext | tag (16)
| Suite | Payload | Authenticated associated data |
|---|---|---|
0x21 |
Zstandard frame | suite + dictionary binding + aad |
0x22 |
raw bytes | suite + aad |
- The dictionary binding is
SHA-256over the dictionary bytes (or a constant for no dictionary), ensuring a mismatched dictionary fails authentication before decompression. - Keys are 32 random bytes expanded via HKDF-SHA256 to the AEAD key. A fresh 12-byte nonce is generated per seal.
- Opening validates the envelope before decryption: size and suite checks, then AEAD authentication, then — for compressed payloads — single-frame Zstandard validation and bounded decompression.
Security considerations
This library implements the envelope only. Key generation, distribution, storage, rotation, and encrypted-input size bounding are the caller's responsibility.
- Keys must be 32 uniformly random bytes. Passwords are not valid keys.
- Nonces are generated with
os.urandom(12)per seal. AES-GCM-SIV is nonce-misuse resistant, but reuse should still be avoided. - Compression oracles — the sealed size reveals whether compression was used. Do not compress data that mixes secrets with attacker-controlled input without application-level separation. Use
compress=Falsewhen this is a concern. - Resource limits —
max_output_sizebounds decompressed output. For untrusted inputs, also bound the encrypted input size before callingopen_data.
Development
uv sync --locked --extra dev
uv run ruff check .
uv run mypy kransx
uv run pytest -q
Pre-commit hooks are configured for ruff and mypy (see .pre-commit-config.yaml).
kransx/ seal, open_data, dicts, cli
tests/ conformance vectors, tamper checks, resource limits
License
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kransx-0.1.0.tar.gz.
File metadata
- Download URL: kransx-0.1.0.tar.gz
- Upload date:
- Size: 11.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.8 {"installer":{"name":"uv","version":"0.12.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d436979d2b23c8fc38232cc4530efd37b238791b0489d6c95065c1a946f731cd
|
|
| MD5 |
db31d8ecd18d4cb120b7f44a4cd3d8e6
|
|
| BLAKE2b-256 |
1ec37d8696b35bf7ae2cc6bc1f26b782ada2be5c289d34c2db9034d39c109e39
|
File details
Details for the file kransx-0.1.0-py3-none-any.whl.
File metadata
- Download URL: kransx-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.8 {"installer":{"name":"uv","version":"0.12.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4891bf6d8d1a97e844eaed911f08bed47fd2cfdc9f7122589f87d97e1e87b22
|
|
| MD5 |
0f65ceca32814c9cb6a3bc8343c276f2
|
|
| BLAKE2b-256 |
0921ed8f733fcb9d1b99cddd939f9a5059d20dd100ddf18a884ba244aa88c53e
|