General Questions

What is ZelEn?

ZelEn (Zelen Quantum Encryption) is a post-quantum encryption platform built around NIST-standardised algorithms. It lets you generate quantum-safe key bundles, encrypt and decrypt text or files, and issue self-signed certificates — all without installing any software beyond a web browser.

The platform produces three portable key files: .zkey (encrypted private key), .zpub (public key), and .zcert (signed certificate). These files use a custom binary container format (.zelen) optimised for post-quantum key sizes.

Why do I need post-quantum encryption now?

Quantum computers capable of running Shor's algorithm will break RSA and ECC by solving the integer factorisation and discrete logarithm problems in polynomial time. While large-scale quantum computers don't exist yet, harvest-now, decrypt-later attacks are already happening: adversaries record encrypted traffic today and plan to decrypt it once quantum hardware matures.

Data that must remain confidential for more than 5–10 years should be encrypted with post-quantum algorithms today. NIST finalised its first PQC standards (FIPS 203, 204, 205) in August 2024.

Does ZelEn store my keys or data on the server?

No. All cryptographic operations happen in-process during your request and the results are returned directly to your browser. Nothing is written to disk, logged, or retained after the response is sent.

Your passphrase is used solely to derive the Argon2id key that protects your .zkey file and is never stored or transmitted beyond the single HTTP request that generates your key bundle.

Is ZelEn open source?

The ZelEn container format and key derivation specification are documented in the Whitepaper. The cryptographic core relies on liboqs (Open Quantum Safe), an open-source C library maintained by the OQS project.

Keys & File Formats

What are the three key files and what do I do with them?
FileContentsShare?Use for
.zkey Encrypted private key (KEM + signature). Protected with Argon2id + your passphrase. Never share Decrypting messages sent to you; signing documents
.zpub Public key pair — KEM public key and signature verification key. Share freely Others encrypt messages to you; verify your signatures
.zcert Your .zpub wrapped with an ML-DSA self-signature and metadata. Share freely Identity binding; verifiable certificate chain
What happens if I forget my passphrase?

Your private key is encrypted with a key derived from your passphrase using Argon2id (memory-hard KDF). There is no recovery mechanism, back door, or escrow — if you lose your passphrase, the .zkey file is permanently unrecoverable.

Best practice: store your passphrase in a password manager alongside your .zkey backup, or use the Generate Random button on the key generation page, which produces a memorable 5-word passphrase you can write down.

Why are ML-KEM keys so much larger than RSA or ECC keys?

Classical algorithms like RSA and ECC derive their security from a single large number (a modulus or a curve point). A 256-bit ECC key is all you need because the elliptic curve discrete logarithm problem is extremely hard.

Lattice-based schemes like ML-KEM derive security from the hardness of the Module Learning With Errors (MLWE) problem over polynomial rings. The public key encodes a structured matrix A plus a vector b = As + e, which requires significantly more bytes to represent — 1,568 bytes for the public key and 3,168 bytes for the private key at the ML-KEM-1024 (NIST Level 5) setting.

This is a known trade-off. The extra bytes are worth it for quantum resistance.

What is the ZELC marker at offset 0x7D?

The ZelEn binary container (.zelen) contains a four-byte brand marker ZELC at exact byte offset 0x7D (125 decimal). This is placed after the AES-GCM nonce and acts as an integrity anchor: any container that does not present the bytes 5A 45 4C 43 at exactly offset 0x7D is immediately rejected, regardless of whether other fields look valid.

The marker also serves as a parser-confusion defence — it is impossible to splice a valid ZelEn container into a foreign format that happens to pass the magic check. See the Binary Format section for the full byte map.

Can I inspect a key file to verify its contents?

Yes. Use the Inspect Key tool to paste or upload any .zpub or .zcert file. It will show the algorithm suite, fingerprint, expiry, key usage flags, and the full base64-encoded public keys — without requiring a passphrase.

Inspecting a .zkey file will show the encrypted wrapper metadata only; the private key material remains encrypted.

Security

What is the overall security model?

ZelEn provides authenticated encryption with associated data (AEAD) from sender to recipient. The security reduction is:

Advobj-secZelEn(A) ≤ AdvIND-CCAML-KEM(B) + AdvAEADGCM(C) + AdvPRFKDF(D) + AdvEUF-CMAML-DSA(E) + εCE + εparse

All terms are negligible at NIST Level 3/5 parameters. Full details are in the Formal Security section and the Whitepaper.

What is Argon2id and why is it used for the passphrase?

Argon2id is a memory-hard key derivation function (KDF) that won the Password Hashing Competition in 2015. "Memory-hard" means that deriving a key requires a configurable amount of RAM — making GPU and ASIC brute-force attacks proportionally more expensive than a simple hash function.

ZelEn uses Argon2id to stretch your passphrase into the AES-256 key that encrypts your private key. Even a short passphrase becomes expensive to brute-force because each guess requires allocating significant memory.

How does ZelEn prevent replay and tampering attacks?
  • Fresh nonce per message — a 12-byte random nonce is generated for every encryption; reuse is computationally impossible.
  • Header authentication tag — 16 bytes at offset 0x81 commit to the full header using a KDF-derived key, binding all metadata to the ciphertext.
  • KEM ciphertext digest — a SHA3-256 hash of the ML-KEM ciphertext is embedded in the header and verified before decapsulation.
  • AES-256-GCM authentication tag — every ciphertext carries a 16-byte GCM tag. Decryption fails closed on any mismatch.
  • Constant-time comparison — all tag comparisons use hash_equals() to prevent timing oracles.
Is the connection to this server secure?

ZelEn should be served exclusively over HTTPS with HSTS. The application sets Strict-Transport-Security, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, and a strict Content-Security-Policy on every response.

That said, the most sensitive operation — key generation — relies on your passphrase reaching the server. For maximum security, consider running ZelEn on-premises or generating keys offline using the CLI.

What NIST security levels does ZelEn target?
AlgorithmVariantNIST LevelClassical bitsQuantum bits
ML-KEMML-KEM-768Level 3~192~128
ML-KEMML-KEM-1024 (default)Level 5~256~128
ML-DSAML-DSA-65Level 3~192~128
ML-DSAML-DSA-87Level 5~256~128
AES-GCMAES-256256128 (Grover)

NIST Level 5 corresponds to roughly the security of AES-256 against classical adversaries. Quantum security of ~128 bits means even a quantum adversary running Grover's algorithm would need an astronomically large number of operations.

Algorithms & Standards

What is ML-KEM and how does it work?

ML-KEM (Module-Lattice Key Encapsulation Mechanism, FIPS 203) is a Key Encapsulation Mechanism based on the hardness of the Module Learning With Errors (MLWE) problem.

Key generation samples a random matrix A and short vectors s (secret) and e (noise), then computes b = As + e mod q. The public key is (A, b); the private key is s. Recovering s from (A, b) is the MLWE problem — believed hard for both classical and quantum computers.

Encapsulation generates a shared secret K and a ciphertext c. Only the holder of s can decapsulate c to recover K. This shared secret then feeds ZelEn's key schedule to derive the AES-256-GCM payload key.

What is ML-DSA and why is it needed alongside ML-KEM?

ML-DSA (Module-Lattice Digital Signature Algorithm, FIPS 204) is a post-quantum digital signature scheme. While ML-KEM handles confidentiality (only the intended recipient can read the message), ML-DSA handles authenticity (the recipient can verify the message came from you and was not modified).

In ZelEn, the sender's ML-DSA private key signs a canonical transcript of the ciphertext, header, and KEM output. The recipient verifies this signature using the sender's ML-DSA public key (from their .zpub or .zcert).

Why is AES-256-GCM still used if the scheme is post-quantum?

AES-256-GCM is a symmetric cipher. Grover's quantum algorithm can halve the effective key length of any symmetric cipher, reducing AES-256 from 256 bits to ~128 bits of quantum security — which is still considered secure.

The asymmetric part (ML-KEM key exchange) is where quantum computers pose a real threat, because Shor's algorithm can break RSA and ECC efficiently. ML-KEM replaces that component. AES-256-GCM remains appropriate for the symmetric bulk encryption layer.

What is HKDF and how is it used in ZelEn?

HKDF (HMAC-based Key Derivation Function, RFC 5869) is a two-step KDF: extract collapses entropy into a pseudorandom key (PRK), then expand produces multiple keying material outputs from that PRK.

ZelEn uses HKDF-SHA256 to derive three domain-separated keys from the ML-KEM shared secret:

  • k_enc — 32-byte AES-256 payload encryption key
  • k_hdr — 32-byte header authentication key
  • k_sigctx — signature transcript binding key

Domain separation (different info strings per key) ensures that compromise of one derived key reveals nothing about the others.

Has ML-KEM been standardised? Is it safe to use?

Yes. NIST published FIPS 203 (ML-KEM) and FIPS 204 (ML-DSA) as final standards in August 2024, after an 8-year public competition and multiple rounds of cryptanalysis by the global research community. These are the first post-quantum standards approved for use in US federal systems.

The underlying mathematical problem (MLWE) has been studied since the mid-2000s and no polynomial-time classical or quantum algorithm is known for it.

MTE

What does MTE stand for?

MTE stands for Morphological Topos Encryption. It is ZelEn’s governed-object layer for MTE-PQ5 encrypted objects.

What problem does MTE solve?

MTE solves the private-key-only decryption problem. In normal encryption, a stolen private key plus passphrase can often be enough to attempt decryption. With MTE, the encrypted object must also be reconstructed using the authorized .ztau datum before PQ5 decryption can begin.

The short version: the key decrypts, τ reconstructs, and policy governs.

Is MTE a replacement for PQ5 encryption?

No. MTE does not replace ML-KEM, ML-DSA, AES-256-GCM, Argon2id, or the ZELEN container. ZelEn PQ5 still protects the ciphertext. MTE wraps the already encrypted payload in a governed morphic envelope that must be reconstructed before decryption.

What is τ?

τ is the private morphic reconstruction datum used by ZelEn MTE. It acts like the hidden structural map required to reconstruct an MTE-governed encrypted object into the canonical encrypted body that PQ5 can decrypt.

In ZelEn, τ is stored in a private .ztau file.

Can I share a .ztau file?

No. Treat .ztau as sensitive private material. It should not be shared publicly, uploaded to GitHub, sent casually, or treated like a public key.

Can I decrypt an MTE object with only a .zkey file?

No. With MTE, the private key alone is not enough. You need the matching .zkey, passphrase, .ztau, valid object structure, valid MTE envelope, and passing PQ5 authentication checks.

What files does an MTE identity create?
FilePurposeShare?
.zkey Private key bundle used for cryptographic decryption and signing. Never share
.zpub Public key bundle used for encryption and verification. Share freely
.ztau Private MTE reconstruction datum required for MTE-governed objects. Never share
How do I create and use MTE from the CLI?
zelen keys generate --subject [email protected] --name Alice --suite mte-pq5 --out alice
zelen encrypt file --recipient alice.zpub --tau alice.ztau --suite mte-pq5 --input secret.pdf --out secret.mte.zelen
zelen decrypt file --key alice.zkey --tau alice.ztau --input secret.mte.zelen --out recovered.pdf

More details are available on the MTE page and the Developer downloads page.

What happens if an MTE object is tampered with?

ZelEn rejects it. MTE is fail-closed: missing τ, wrong τ, corrupted section maps, policy mismatch, tampered morphic bodies, bad AES-GCM tags, wrong private keys, and wrong passphrases all result in no plaintext being released.

What is the simplest way to describe MTE?

Encryption locks the data. MTE governs the locked object.

Usage & Compatibility

How do I encrypt a message for someone else?
  1. Ask the recipient to generate a key bundle and share their .zpub file with you.
  2. Go to Encrypt → Text (or File).
  3. Upload or paste the recipient's .zpub in the Recipient Public Key field.
  4. Optionally upload your own .zkey and enter your passphrase to sign the message.
  5. Click Encrypt. Download the .zelen ciphertext and send it to the recipient.
How does the recipient decrypt?
  1. Go to Decrypt → Text (or File).
  2. Upload or paste the .zelen ciphertext.
  3. Upload your .zkey private key file.
  4. Enter your passphrase. ZelEn decapsulates the ML-KEM shared secret, verifies all authentication tags, and returns the plaintext.
What file types can I encrypt?

Any file type. ZelEn treats the file as raw bytes — it doesn't inspect, compress, or modify the content before encryption. After decryption the original bytes are returned unchanged. The maximum upload size is determined by your server's PHP configuration (upload_max_filesize / post_max_size).

Can I encrypt for multiple recipients?

The current ZelEn v1 container format supports a single recipient per .zelen file. To send the same message to multiple recipients you encrypt once per recipient, each with their own .zpub. This keeps the key schedule independent for each recipient and avoids multi-recipient key reuse issues.

Multi-recipient support (header fan-out mode) is planned for a future container version.

What browsers are supported?

ZelEn's UI requires a modern browser with support for:

  • crypto.getRandomValues() — for the random passphrase generator
  • navigator.clipboard — for copy-to-clipboard (graceful fallback included)
  • ES6+ JavaScript — no legacy browser support

All cryptographic operations run server-side in PHP. The browser is used only for UI.

How strong should my passphrase be?

ZelEn requires a minimum of 12 characters. For protecting a long-lived private key, aim for at least 40 bits of entropy — the equivalent of a 5-word random passphrase from a ~200-word list, or a random 8-character string with mixed case, digits, and symbols.

The easiest approach: click 🎲 Random on the key generation page. It produces a 5-word hyphenated passphrase using crypto.getRandomValues() — memorable, easy to write down, and hard to brute-force.