Skip to content

Latest commit

 

History

History
65 lines (47 loc) · 2.57 KB

File metadata and controls

65 lines (47 loc) · 2.57 KB

KEYM v1 reference implementation

An independent implementation of the KEYM v1 container format, written in Python from ../docs/FORMAT.md alone.

Why this exists

The frozen fixtures under scripts/fixtures/keymaker/ are append-only real ciphertexts, and they are genuinely load-bearing — they are what guarantees a file encrypted by a shipped release still opens today.

But they were all generated by the implementation that reads them back. A misreading of the specification would be encoded identically into the code and into the vectors, and the suite would report agreement forever without either side being right.

A second implementation, written only from the prose, is what converts those fixtures from a self-consistency check into a conformance test. When the two disagree, one of them has misread the specification — and the specification decides which.

It imports nothing from src/. The only contact between the two is bridge.mts, a thin CLI that lets the cross-test drive the TypeScript implementation as a black box.

It has already paid for itself

Writing it surfaced a defect in the specification, not in either implementation.

FORMAT.md described the KDF cost parameters but said nothing about bounding them. The TypeScript enforced bounds; the reference, written faithfully from the prose, did not — and during cross-testing a single flipped kdf_id byte caused it to attempt a ~2.5 GiB allocation. Flipping that byte makes a PBKDF2 container's iteration bytes be re-read as Argon2id parameters.

The TypeScript was already immune. The specification was not, so any new implementation built from it would have inherited the flaw. The bounds are now normative in FORMAT.md §3.1, and enforced here.

That is the whole argument for keeping this file: it tests the document, which nothing else does.

Usage

pip install -r reference/requirements.txt

python3 reference/keym.py selftest       # round-trip against itself
npm run test:conformance                 # bidirectional vs the TypeScript

The conformance test covers:

  1. The frozen JS fixtures, decrypted by this implementation
  2. JS encrypt → Python decrypt, all 6 KDF × cipher combos, with and without a key file
  3. Python encrypt → JS decrypt, same matrix
  4. Payload shapes: single byte, ASCII, Unicode, binary, block boundary
  5. Tamper rejection agreeing across both, with an untampered control

Scope

This is a specification oracle, not a product. It is not hardened, not constant-time beyond what its libraries provide, and not intended for encrypting anything real.