Security posture · v1 · 2026

Zero-knowledge messaging,
audited in the open.

Panthera is an end-to-end encrypted messenger built on the Double Ratchet protocol. Keys are generated and unlocked on your device — the server never sees plaintext, never holds a decryption key, and cannot be compelled to hand one over.

Encryption
XChaCha20-Poly1305
Key exchange
X25519 · X3DH
KDF
Argon2id
Server access
Zero

Zero-knowledge server

The backend stores only ciphertext, wrapped keys and routing metadata. Server operators, hosting providers and platform staff cannot read messages.

Keys never leave the device

Your identity private key is wrapped with a KEK derived from your passphrase via Argon2id and only ever unwrapped in memory.

Forward + post-compromise secrecy

Double Ratchet rotates message keys on every send. A compromised session key cannot decrypt past or future messages.

Trust-on-first-use pinning

Peer identity keys are pinned locally. Any change is surfaced as a visible warning and requires explicit re-trust.

01 — Cryptography

How your messages are sealed

Every primitive comes from libsodium. Nothing is hand-rolled. The server only ever handles opaque ciphertext.

PurposePrimitiveImplementation
Symmetric cipherXChaCha20-Poly1305 (AEAD)libsodium
Key exchangeX25519 (Curve25519 ECDH)libsodium
SignaturesEd25519libsodium
Message ratchetDouble Ratchet (Signal spec)in-house impl · frozen vectors
Session initX3DH with one-time prekeysin-house impl
Password KDFArgon2id (interactive params)libsodium
Session KDFHKDF-SHA-256libsodium
Randomnesscrypto.getRandomValues + libsodiumbrowser CSPRNG
FingerprintSHA-256 of identity public keysverifiable in-app
02 — Protocol

Double Ratchet + X3DH

Panthera implements the same protocol family used by Signal: X3DH for the initial handshake, Double Ratchet for forward secrecy and post-compromise recovery on every single message.

  1. 01

    Identity bootstrap

    On sign-up, a long-term Ed25519/X25519 identity keypair is generated locally. The private key is wrapped with Argon2id(passphrase) and stored encrypted.

  2. 02

    Prekey publication

    A signed prekey and a batch of one-time prekeys are published. The server refills them on demand — it only sees public bytes.

  3. 03

    X3DH handshake

    The initiator combines three or four DHs (identity, signed prekey, ephemeral, one-time) to derive a shared root key. TOFU pinning locks the peer identity.

  4. 04

    Double Ratchet

    Every send advances a symmetric chain; every reply performs a fresh DH to rotate the root. Message keys are used once and destroyed.

  5. 05

    Envelope encryption

    Ciphertext + ratchet header are stored on the server. Rows without a valid header are unreadable by design — the legacy sealed-box path has been fully removed.

03 — Threat model

What we defend against — and what we don't

Being explicit about the boundary is part of the guarantee.

Protected against

  • Passive network eavesdroppers (ISP, Wi-Fi, transit).
  • Server operator compromise, subpoena or seizure of ciphertext.
  • Database dump — all message rows are opaque without device keys.
  • Retroactive session key exposure — past traffic stays sealed (forward secrecy).
  • Single message key leak — future traffic re-secures (post-compromise recovery).
  • Silent peer-key substitution — TOFU pinning + visible re-trust prompt.
  • Idle-device theft — auto-lock wipes keys from memory.

Out of scope

  • A fully compromised endpoint (malware, screen readers, hostile OS).
  • A user who shares their passphrase or unlocked device.
  • Traffic-analysis metadata (who talks to whom, when, how often).
  • Recovery of a lost passphrase — there is no backdoor.
  • Third-party push notification content (we do not send message bodies to push services).
04 — Security audit

Control-by-control audit

Maintained by the Panthera team. This page lists app-visible controls that are currently enabled; it is not an independent certification.

End-to-end encryptionEnabled

Enabled on every conversation. Non-optional.

Zero-knowledge backendEnabled

Server holds ciphertext + wrapped keys only. Row-level security enforced on every table.

Client-side key derivationEnabled

Argon2id derives the KEK from your passphrase; identity keys are wrapped at rest.

Auto-lockEnabled

Configurable idle + background timers wipe the in-memory KEK and private key.

Full local wipeEnabled

Sign-out clears IndexedDB, CacheStorage, service worker and web storage.

Verifiable fingerprintsEnabled

Compare identity fingerprints in person or via QR to detect MITM.

QR-based contact addEnabled

Import a peer's identity by scanning their code — no server-side directory lookup needed.

No plaintext usernames on the serverEnabled

Usernames are SHA-256 hashed with a versioned domain tag before hitting auth.

Row-Level SecurityEnabled

Every public table has explicit GRANTs and policies scoped to the authenticated user.

HTTPS-only transportEnabled

All network calls use TLS. The service worker is disabled in dev/preview to avoid stale ciphertext caches.

Reproducible cryptoEnabled

Frozen test vectors + RFC vectors run on every build to catch regressions in the ratchet.

No anonymous sign-ups by defaultEnabled

Registration is passphrase-gated; anonymous auth is disabled.

05 — Feature specs

Everything the app ships with today

Messaging

  • End-to-end encrypted 1:1 chat
  • Double Ratchet forward + post-compromise secrecy
  • Message archive with local TTL
  • Contact list with per-peer key pinning
  • Peer key-change warnings with explicit re-trust

Identity & Auth

  • Anonymous username + passphrase — no email required
  • Client-side Argon2id passphrase derivation
  • Wrapped identity key stored encrypted
  • Multi-device unlock via passphrase (no key export)

Device hardening

  • In-memory-only session keys
  • Idle + background auto-lock
  • Full local wipe on sign-out
  • PWA install with offline shell
  • iOS-safe backgrounding via pagehide

Trust & verification

  • SHA-256 identity fingerprints
  • In-person QR fingerprint check
  • Trust-on-first-use with pinned local cache
  • Signed prekey rotation
06 — Disclosure

Responsible disclosure

Found a vulnerability? We want to hear from you. Report privately before publishing so we can protect users first.

Report suspected vulnerabilities privately to the maintainers before any public disclosure. Include reproduction steps, affected versions, and your preferred contact. We aim to acknowledge within 72 hours.

This page is maintained by the Panthera team to describe the app's current security posture. It is not an independent audit or certification.