ps-cypher
Convergent encryption with ChaCha20-Poly1305, zstd, and Reed-Solomon ECC.
Scheme
- The encryption key is the hash of the plaintext (
ps-hash): theChaCha20key is the hash's 32-byte digest, and the nonce is derived from the hash's parity bytes. - The plaintext is compressed deterministically (zstd level 7 via
ps-compress) before encryption. - The ciphertext is Reed-Solomon encoded (
ps-ecc), so up to 12 corrupted bytes per codeword are repaired transparently during decryption. - Identical inputs therefore always produce identical ciphertexts, keys, and hashes, which enables content-addressed deduplication of encrypted data.
decryptre-hashes the decrypted data and fails withKeyMismatchunless it hashes to the decryption key, so a successful decryption returns exactly the data that produced the key.
Example
use ;
let encrypted = encrypt?;
let decrypted = decrypt?;
assert_eq!;
# Ok::
Security caveats
Convergent encryption is deterministic by design, which leaks information that a randomized cipher would not:
- Plaintext equality: identical plaintexts encrypt to identical ciphertexts, so an observer learns when two stored objects are equal.
- Confirmation and dictionary attacks: anyone who can guess a plaintext can encrypt the guess and compare ciphertexts, confirming whether it is stored. Low-entropy data is therefore not confidential against an adversary who can enumerate candidates.
- Length leakage: the ciphertext length reveals the compressed size of the plaintext, i.e., its length and compressibility.
validate_eccis not authentication: it is an unkeyed checksum that detects accidental corruption only, and it returnsfalsefor corrupted-but-correctable data thatdecryptstill accepts. Tampering is detected by the Poly1305 tag duringdecrypt, and the decrypted data is additionally verified to hash to the decryption key.