Skip to content

Release 2.5.0: keyring ciphertext format with key IDs, field binding and padding; BlindIndex - #12

Merged
yuriizee merged 1 commit into
mainfrom
release-2.5.0
Oct 16, 2026
Merged

yuriizee merged 1 commit into
mainfrom
release-2.5.0

Conversation

@yuriizee

Copy link
Copy Markdown
Contributor

Added (opt-in)

  • EncryptedCast(keyring: AppKeyring::class) with the EncryptionKeyring contract writes v2:<key id>:… (XChaCha20-Poly1305-IETF):
    • key ID in every value — rotation without downtime (S1-02);
    • class + field (or context:) authenticated as associated data — a ciphertext moved to another field is rejected (S1-03);
    • plaintext padded to 32-byte blocks (S1-14);
    • keys must be 32 random bytes, raw or base64; subkey via sodium_crypto_kdf_derive_from_key (S1-01).
  • With a legacy key next to the keyring, both formats are read and only the new one is written. Without keyring: nothing changes.
  • needsReencryption() / forField() for migration scripts.
  • Support\BlindIndex — keyed HMAC-SHA256 for searching encrypted columns (S1-16).
  • Contracts\BindsToField — casts learn their class and field at metadata build time.

Verification

  • Docker: 817 tests, 100% line coverage (2101/2101).
  • Benchmarks: hydration/serialization within noise; legacy EncryptedCast::get() 804 → 816 ns, set() unchanged.

…and padding; BlindIndex

- EncryptedCast(keyring:) writes v2:<key id>:... with XChaCha20-Poly1305-IETF,
  class and field bound as associated data, plaintext padded to 32 bytes,
  32-byte keys only; legacy ciphertext stays readable with the old key
- needsReencryption() and forField() for rotation scripts
- BindsToField contract, bound at metadata build time
- Support\BlindIndex for searching encrypted columns
@yuriizee
yuriizee merged commit 2fa14a5 into main Oct 16, 2026
4 checks passed
@yuriizee
yuriizee deleted the release-2.5.0 branch October 16, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant