This page presents a high-level overview of the cryptography used by our software and is intended for technical people that want to evaluate our design decisions.

If you want to report a vulnerability in our code or a library we use please see the security page.

Symmetric Ciphers

We use authenticated encryption with additional data (AEAD) symmetric ciphers AES GCM 256 or XChaCha20Poly1305 for data at rest; each encrypted block in our file formats uses a random nonce.

Because we are generating nonces at random we prefer the extended 192-bit nonce of the XChaCha20Poly1305 cipher so this is the default algorithm for data at rest.

Key Derivation Functions

To make brute force attacks harder we use modern key derivation functions in combination with symmetric ciphers; the default key derivation function is Argon2id.

Asymmetric Ciphers

For asymmetric encryption where data needs to be shared securely between multiple parties we use the AGE encryption standard.


The identity for an account uses an ECDSA signing key (Secp256k1 curve); this signature scheme was chosen for the ability to recover the public key from a signature allowing us to identify an account holder solely from a signature.

When syncing directly between devices we use Ed25519 signatures to verify trusted devices.

Secret Sharing

When we need to split secrets for social recovery we use Shamir's Secret Sharing.

Noise Protocol

For the self-hosted service to protect data in transit we use the Noise protocol. All data transferred is already encrypted on the client using a symmetric cipher however this adds an extra layer of protection that can help prevent replay and other MITM attacks.

Post-Quantum Cryptography

This is an active area of research for us and we are evaluating using CRYSTALS-kyber to augment the existing symmetric encryption for data at rest taking inspiration from the Signal Team.