Skip to main content

KRANSX

CI Python 3.10+ License: MIT

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
  • --aad accepts hex-encoded bytes
  • --max-output-size caps 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-256 over 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=False when this is a concern.
  • Resource limitsmax_output_size bounds decompressed output. For untrusted inputs, also bound the encrypted input size before calling open_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

kransx-0.1.0.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kransx-0.1.0-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

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

Hashes for kransx-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d436979d2b23c8fc38232cc4530efd37b238791b0489d6c95065c1a946f731cd
MD5 db31d8ecd18d4cb120b7f44a4cd3d8e6
BLAKE2b-256 1ec37d8696b35bf7ae2cc6bc1f26b782ada2be5c289d34c2db9034d39c109e39

See more details on using hashes here.

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

Hashes for kransx-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f4891bf6d8d1a97e844eaed911f08bed47fd2cfdc9f7122589f87d97e1e87b22
MD5 0f65ceca32814c9cb6a3bc8343c276f2
BLAKE2b-256 0921ed8f733fcb9d1b99cddd939f9a5059d20dd100ddf18a884ba244aa88c53e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page