Expand description
§Password-based authenticated encryption with multi-recipient key wrapping
Symmetric encryption for data that must be readable by one or more passwords. Used chiefly for at-rest protection of sensitive material (key lockers, encrypted persistence) and for payloads where a small group of recipients needs shared access without each receiving a copy.
§Construction
- A random 32-byte file key is generated per encryption.
- The body (plaintext) is encrypted in-place with
ChaCha20Poly1305using that file key and a fresh nonce — one authentication tag covers the whole body. - For each recipient password, an Argon2id KDF produces a wrap key; the file key is then wrapped (AEAD-encrypted) under that wrap key with its own nonce and tag and appended to the header as a “slot”.
On decrypt, the caller’s password is Argon2id-derived once and trial-decrypted against each slot until one authenticates; the recovered file key unwraps the body. Tampering anywhere after the Argon2 header is caught by one of the two AEAD tag layers.
§Strong vs weak
Both flavours use Argon2id / ChaCha20Poly1305 — they differ only in the memory cost of the KDF (encoded into the header):
encrypt_strong—m_cost = 19 MiB. For private, sensitive-at-rest data. Expensive enough to resist offline brute-force of weak passphrases.encrypt_weak—m_cost = 4 MiB. For public-at-rest data where throughput matters more than passphrase resistance (the secret itself is typically high-entropy).
decrypt reads the algorithm parameters from the header, so a single function
decrypts either flavour.
§DoS hardening
The header parser rejects absurd Argon2 parameters (m_cost > 256 MiB, t_cost > 16,
p_cost > 4) and absurd recipient counts (> MAX_RECIPIENTS) before running the KDF,
so a crafted ciphertext can’t make a peer burn gigabytes of RAM trying to validate it.
Functions§
- decrypt
- Decrypt ciphertext produced by
encrypt_strongorencrypt_weak(or any future variant) using the associated password. - encrypt_
strong - Strong encrypt data with one or more passwords – for private / sensitive data.
- encrypt_
weak - Weak encrypt data with one or more passwords - for public-at-rest data where speed matters more.