test(vectors): pin empty-file framing across impls (FIL-518) - #2
Merged
Conversation
The empty object is its own STREAM framing case: it encodes as one empty final chunk, so the body is a bare 16-byte tag with nothing to authenticate. Until now that case was only covered by Go-internal tests, so a divergence from the foc-encryption reference on the case most likely to diverge would have gone unnoticed (FIL-518 AC3). - Add empty-file-go (Go seals, the reference decrypts) and empty-file-ts (the reference seals, Go decrypts). - Assert the ciphertext length against aesstream.EncryptedSize for every fixture, so the one-tag-per-chunk framing is pinned rather than implied by a successful decrypt. - Make the TS driver table-driven and skip a fixture already on disk unless FEE_VECTORS_REGEN=1, so generating a new TS fixture no longer rewrites a committed blob (the reference draws a random base nonce per encrypt). The pinned reference decrypts both new fixtures: all six fixtures pass under ./vectors/pull-foc-encryption.sh. Signed-off-by: Miroslav Bajtoš <oss@bajtos.net> Assisted-by: Claude:claude-opus-5
Contributor
There was a problem hiding this comment.
🟢 Ready to approve
Changes are isolated to test vectors/tooling and the added assertions/fixtures align with the documented STREAM framing rules, with only a minor optional robustness improvement noted for TS fixture regeneration skipping.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
Adds cross-implementation test vectors to pin the AES-256-GCM-STREAM empty-plaintext framing case (tag-only body) in both Go→TS and TS→Go directions, and strengthens vector validation by asserting ciphertext sizing/framing.
Changes:
- Add new empty-file fixtures (
empty-file-go,empty-file-ts) and document the empty-file framing rule. - In
TestVectors, assert ciphertext length viaaesstream.EncryptedSize(...)for every fixture to pin “one tag per chunk” framing (including empty plaintext → 1 empty final chunk). - Refactor the TS vector generator to be table-driven and avoid rewriting committed blobs unless
FEE_VECTORS_REGEN=1.
File summaries
| File | Description |
|---|---|
| vectors/vectors_test.go | Adds empty-file vectors and asserts ciphertext framing via aesstream.EncryptedSize. |
| vectors/ts/driver.ts | Makes TS fixture generation table-driven and adds “skip existing unless regen” behavior. |
| vectors/testdata/empty-file-ts/meta.json | Adds metadata for the TS-produced empty-file fixture. |
| vectors/testdata/empty-file-ts/plaintext.bin | Adds empty plaintext fixture payload (0 bytes). |
| vectors/testdata/empty-file-go/meta.json | Adds metadata for the Go-produced empty-file fixture. |
| vectors/testdata/empty-file-go/plaintext.bin | Adds empty plaintext fixture payload (0 bytes). |
| vectors/README.md | Documents empty-file framing and updates fixture/regeneration instructions. |
Review details
- Files reviewed: 5/9 changed files
- Comments generated: 1
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
The generate skip check only looked for the fixture directory, so an aborted generation left a partial fixture that was never rewritten, and verify skipped it for lacking meta.json. Require all three files. Signed-off-by: Miroslav Bajtoš <oss@bajtos.net> Assisted-by: Claude:claude-opus-5[1m]
alanshaw
approved these changes
Aug 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
While reviewing the acceptance criteria for FIL-518, Claude flagged a missing test. This pull request is adding it.
The empty object is its own STREAM framing case: it encodes as one empty final chunk, so the body is a bare 16-byte tag with nothing to authenticate. Until now that case was only covered by Go-internal tests, so a divergence from the foc-encryption reference on the case most likely to diverge would have gone unnoticed (FIL-518 AC3).
FEE_VECTORS_REGEN=1, so generating a new TS fixture no longer rewrites a committed blob (the reference draws a random base nonce per encrypt).The pinned reference decrypts both new fixtures: all six fixtures pass under
./vectors/pull-foc-encryption.sh.