DOCS / DETERMINISTIC AEAD
Deterministic AEAD
The problem
Standard AEAD ciphers (GCM, SIV) use a random nonce per encryption. This means encrypting the same plaintext twice produces different ciphertext. For CAS-based storage, this is a problem: the same content appears as two different blobs, defeating deduplication.
The solution
enprot's deterministic variants (aes-256-gcm-det, aes-256-gcm-siv-det) derive the nonce from the plaintext itself:
enc_key = HKDF-SHA256(master_key, "enprot-enc", 32)
iv_key = HKDF-SHA256(master_key, "enprot-iv", 32)
iv = HMAC-SHA256(iv_key, plaintext)[..12]Same (password, plaintext) pair → same iv → same ciphertext. This enables:
- CAS dedup on encrypted segments — identical secrets across files share the same CAS blob
- Git-friendly diffs — unchanged secrets produce unchanged ciphertext
- Idempotent transforms —
encrypt(encrypt(x)) = encrypt(x)
Security tradeoffs
Deterministic encryption leaks whether two ciphertexts encrypt the same plaintext. This is acceptable when:
- The same key is used for all instances of a given WORD (the common case)
- CAS dedup is a requirement (large-scale deployment)
- The adversary cannot mount chosen-plaintext attacks (offline file processing)
For maximum confidentiality, use aes-256-siv (random nonce per encryption). For CAS-friendly deployments, use aes-256-gcm-siv-det.
Usage
# Encrypt with deterministic AEAD
enprot encrypt -w SECRET --cipher aes-256-gcm-siv-det config.txt
# Same content always produces the same ciphertext:
enprot encrypt -w SECRET --cipher aes-256-gcm-siv-det config.txt
# → identical output (idempotent)
# Store encrypted content in CAS — dedup works:
enprot encrypt-store -w SECRET --cipher aes-256-gcm-siv-det config.txt
# → STORED pointer with deterministic hashWire format
The deterministic IV derivation is transparent to decryptors — the same key derivation runs during decryption. The cipher extfield records the algorithm:
// <( ENCRYPTED word pbkdf:$argon2id$... cipher:aes-256-gcm-siv-det )>No additional metadata is needed — the -det suffix in the algorithm name tells enprot to derive the IV.