Core Concepts

How it works

Encra uses two layers of cryptography. X25519 establishes a shared secret between two parties. Double Ratchet ensures every message uses a unique key that is deleted after use.

Alice's device generates key pair

crypto_box_keypair() — private key never leaves device

Alice registers public key with server

POST /v1/keys — only the public key is sent

Alice fetches Bob's public key

GET /v1/keys/bob

Alice derives shared secret (locally)

ECDH(alicePriv, bobPub) — same as ECDH(bobPriv, alicePub)

Alice initialises Double Ratchet

DoubleRatchet.initSender(shared, bobPub)

Alice encrypts message

ratchet.encrypt('Hello!') — unique key per message

Server relays ciphertext blob to Bob

Server sees: { ciphertext, nonce, header } — nothing readable

Bob decrypts with his ratchet

ratchet.decrypt(msg) — message key deleted after use

Key generation

When a user first connects, Encra generates an X25519 key pair entirely on their device using libsodium's cryptographically secure random number generator. The private key is stored locally (in memory for the session, or IndexedDB for persistence) and is never transmitted anywhere.

// What happens on device

const { publicKey, privateKey } = crypto_box_keypair()

// publicKey → registered with server

// privateKey → stays on device FOREVER

Key exchange (X25519 ECDH)

To chat with Bob, Alice fetches his public key from the server. She then runs Elliptic Curve Diffie-Hellman (X25519) locally:

Alice's side

ECDH(alicePriv, bobPub)

→ sharedSecret

Bob's side

ECDH(bobPriv, alicePub)

→ same sharedSecret

Both sides arrive at the same 32-byte shared secret without ever transmitting it. This is the mathematical property of Diffie-Hellman. The server cannot compute this secret because it never has both private keys.

Why X25519?

X25519 is the Diffie-Hellman function over Curve25519. It's the same curve used by Signal, WhatsApp, and TLS 1.3. It's fast, constant-time (resistant to timing attacks), and has a 128-bit security level.

Message encryption

Messages are encrypted using XSalsa20-Poly1305 — a stream cipher combined with a message authentication code (MAC). Every message gets a randomly generated 24-byte nonce to ensure uniqueness.

encrypt(plaintext, key, nonce)

→ ciphertext (same length as plaintext + 16 byte MAC)

decrypt(ciphertext, key, nonce)

→ plaintext (or throws if MAC verification fails)

The MAC means any tampering with the ciphertext is detected and the decryption is rejected. The server cannot modify messages without Alice and Bob noticing.

Double Ratchet

The Double Ratchet is what makes Encra truly Signal-level. Without it, every message would use the same shared secret — compromise the key once and all messages are readable.

Symmetric Ratchet Chain

Root Key (RK)
Chain Key (CK₁)
Message Key 1
used → deleted
Chain Key (CK₂)
Message Key 2
used → deleted
continues indefinitely...

DH Ratchet (on direction change)

When the conversation direction flips (Alice→Bob becomes Bob→Alice), a new ephemeral key pair is exchanged and the Root Key is updated. This provides break-in recovery — even if an attacker compromises the current state, they lose access after the next DH step.

The two properties this gives you:

Forward secrecy

Message keys are deleted after use. Compromising state today cannot reveal past messages — their keys are gone forever.

Break-in recovery

After the next DH ratchet step, an attacker with compromised state loses access. Future messages are safe even after a breach.

What the server does (and doesn't do)

✓ Server stores

user_id → public_key mapping

Encrypted ciphertext blobs (offline delivery)

Timestamps and metadata

✗ Server never sees

Private keys

Shared secrets

Plaintext messages

Ratchet state

Zero trust

This is not a policy — it's a mathematical guarantee. Even if Encra's servers were fully compromised, an attacker would only see encrypted blobs they cannot decrypt.

Encra AI

Ask me anything · docs, code, troubleshooting

Hi, I'm Encra AI

I can explain concepts, generate starter code, troubleshoot errors, and guide your setup.

May make mistakes · verify critical crypto details