An independent implementation of the KEYM v1 container format, written in
Python from ../docs/FORMAT.md alone.
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.
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.
pip install -r reference/requirements.txt
python3 reference/keym.py selftest # round-trip against itself
npm run test:conformance # bidirectional vs the TypeScriptThe conformance test covers:
- The frozen JS fixtures, decrypted by this implementation
- JS encrypt → Python decrypt, all 6 KDF × cipher combos, with and without a key file
- Python encrypt → JS decrypt, same matrix
- Payload shapes: single byte, ASCII, Unicode, binary, block boundary
- Tamper rejection agreeing across both, with an untampered control
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.