Skip to main content

Module encryption

Module encryption 

Source
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

  1. A random 32-byte file key is generated per encryption.
  2. The body (plaintext) is encrypted in-place with ChaCha20Poly1305 using that file key and a fresh nonce — one authentication tag covers the whole body.
  3. 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_strongm_cost = 19 MiB. For private, sensitive-at-rest data. Expensive enough to resist offline brute-force of weak passphrases.
  • encrypt_weakm_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_strong or encrypt_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.