Skip to content

Cryptography in Detail

This page documents the cryptographic primitives BrightBlur uses, how they fit together, and what they protect against — including estimates of resistance to both classical and quantum attacks.

BrightBlur has three distinct cryptographic layers, each protecting a different thing:

  1. Photo encryption — protects photos and face slices at rest on the server
  2. Seed wrapping — protects your master seed at rest on the server
  3. Mnemonic recovery — allows you to regenerate your master seed from a 12-word phrase

Each layer uses different primitives and has different security properties.


Every photo and face slice is encrypted with a hybrid scheme combining classical and post-quantum cryptography. An attacker must break both to read the data.

ComponentPrimitivePurpose
Key agreement (classical)X25519 (Curve25519 ECDH)Establishes a shared secret between sender and recipient
Key agreement (post-quantum)ML-KEM-768 (NIST FIPS 203)Establishes a second shared secret resistant to quantum attacks
Key combinationHKDF-SHA-256Combines both shared secrets into a single content encryption key
Content encryptionXSalsa20-Poly1305 (libsodium)Encrypts the actual photo/face data with authentication

When you upload a photo, your browser:

  1. Generates a fresh random content encryption key (DEK) for the photo.
  2. Encrypts the base image and each face slice with the DEK using XSalsa20-Poly1305.
  3. For each recipient (circle members, person controllers), wraps the DEK using both X25519 and ML-KEM-768 key exchanges, combined via HKDF.
  4. Uploads only the encrypted blobs and wrapped keys. The server never sees the DEK or the plaintext.
AttackOperations requiredEstimated time
Classical (break X25519 via ECDLP)~2^128~10^16 years (a million times the age of the universe)
Classical (break ML-KEM-768 via core SVP)~2^187Effectively infinite
Quantum (break X25519 via Shor’s algorithm)Polynomial — effectively instantMinutes to hours with ~2,500 logical qubits
Quantum (break ML-KEM-768 via quantum SVP)~2^93~300 billion years at 10^9 quantum ops/second

An attacker with a quantum computer can break X25519 instantly using Shor’s algorithm — but they still can’t read the data because ML-KEM-768 holds. The hybrid scheme ensures that classical security is maintained today, and post-quantum security is maintained in the future.


Your master seed (96 bytes) is the root of all your encryption keys. It’s stored on the server, wrapped (encrypted) by a secret that only your passkey can produce.

ComponentPrimitivePurpose
Wrapping key sourceWebAuthn PRF extensionProduces a 32-byte secret from your passkey’s biometric prompt
WrappingAES-256-GCM (WebCrypto)Encrypts the master seed with authentication
IV12 bytes, randomPrepended to the ciphertext
  1. When you log in with your passkey, the authenticator (your phone, laptop, or security key) runs an HMAC internally using a device-bound secret and a salt from BrightBlur.
  2. The HMAC output (the PRF secret) is returned to your browser over the local CTAP2 channel (USB, NFC, or Bluetooth).
  3. Your browser uses this PRF secret as an AES-256-GCM key to unwrap your master seed.
  4. The PRF secret never touches the network. The server stores only the wrapped blob.
AttackOperations requiredEstimated time
Classical (brute-force AES-256 key)2^256~10^52 years — more operations than atoms in the observable universe
Quantum (Grover’s on AES-256)2^128~10^22 years (a trillion times the age of the universe)

AES-256 is considered post-quantum safe by NIST. Grover’s algorithm halves the effective key length to 128 bits, which remains far beyond feasible computation.

The PRF secret is transmitted from the authenticator to your browser over the local CTAP2 channel, encrypted with ECDH (P-256). This ECDH is theoretically quantum-vulnerable (Shor’s algorithm), but exploiting it requires:

  • Physical proximity to the device during the exact moment of authentication
  • Interception of the local bus (USB/NFC/BLE) communication
  • A quantum computer to break the P-256 ECDH in real time

This is not a “harvest now, decrypt later” attack — the PRF secret is never transmitted over the internet or stored on the server. An attacker who breaches the database gets only the AES-256-GCM wrapped blob, which is quantum-safe.


If you lose access to your passkey, you can recover your master seed using a 12-word recovery phrase (BIP39 mnemonic).

ComponentPrimitivePurpose
Mnemonic generationBIP39 (128-bit entropy, 2048-word list)Produces a human-readable recovery phrase
Key derivationArgon2id (libsodium)Derives the 96-byte master seed from the mnemonic
Argon2id parametersOPSLIMIT_MODERATE (3 passes), MEMLIMIT_MODERATE (256 MB)Makes each derivation attempt slow and memory-intensive
  1. During account setup, BrightBlur generates 128 bits of randomness and encodes it as a 12-word phrase.
  2. The phrase is shown once. You write it down. BrightBlur does not store it.
  3. To recover, you enter the phrase. Your browser runs Argon2id to derive the master seed, then re-wraps it with your new passkey’s PRF secret.
AttackOperations requiredEstimated time
Classical (enumerate all 12-word mnemonics)2^128, each requiring Argon2id~10^23 years with 1 million dedicated devices
Quantum (Grover’s on mnemonic space)2^64 sequential Argon2id evaluations~585,000 years at 1 eval/microsecond (generous)

Grover’s algorithm is inherently sequential — it cannot be parallelised effectively. Each oracle call must implement the full Argon2id function (256 MB of memory, 3 passes) as a reversible quantum circuit, which is enormously expensive in qubits. The 585,000-year estimate assumes a quantum computer that evaluates Argon2id a million times faster than any classical hardware, running continuously without error.

This is the “weakest” link in BrightBlur’s cryptographic chain — but ~585,000 years of continuous quantum computation targeting a single user’s mnemonic is firmly in state-level-actor territory with technology that does not yet exist.


BrightBlur uses an epoch-based key rotation scheme for groups (circles and persons).

  1. Each group has an asymmetric keypair (X25519 + ML-KEM-768) per epoch generation.
  2. When a member is added, the current epoch’s private key is wrapped to their public key and stored on the server.
  3. When a member is removed, a new epoch is created with a fresh keypair. The new private key is wrapped only to remaining members. The removed member’s wrapped keys for the new epoch are never created.
  4. Photos are encrypted to the epoch key that was current at the time of upload.

Removed members lose access to all content created after their removal — they never receive the new epoch’s private key, and the server refuses to serve blobs to non-members.

A removed member who cached both the epoch keys AND the ciphertext before removal retains access to that historical content. This is inherent to any end-to-end encryption system — you cannot un-show data someone has already decrypted.


LayerClassical resistancePost-quantum resistanceHarvest-now-decrypt-later safe?
Photo encryption (X25519 + ML-KEM-768)~10^16 years~300 billion yearsYes — hybrid PQ by design
Seed wrapping (AES-256-GCM)~10^52 years~10^22 yearsYes — AES-256 is PQ-safe
Mnemonic recovery (Argon2id, 128-bit)~10^23 years~585,000 yearsN/A — mnemonic is not stored

Every layer exceeds any realistic attack budget by many orders of magnitude, both today and against foreseeable quantum computers.