Research preview LatticeLink v0.1.0 runs ML-KEM-768 (NIST FIPS 203) entirely in your browser. ML-KEM-768, in your browser. Read the specificationRead the spec →

How a message is established, protected and verified.

ML-KEM-768 establishes a fresh shared secret for every message. HKDF-SHA-256 turns it into a single-use key, and AES-256-GCM encrypts and authenticates. All of it runs in the browser, in isolated workers, with no server component.

Envelope v1v0.1.0Updated 2026-10-10

Overview

LatticeLink is a message envelope built on key encapsulation. The recipient publishes an ML-KEM-768 public key. The sender encapsulates to it, which produces a shared secret only the recipient can reproduce. The sender then derives an AES-256 key from that secret and seals the message into a versioned JSON envelope that can travel over any channel: a page, a file, or a paste.

Design note. Many production deployments pair ML-KEM with a classical key exchange such as X25519, so that security does not rest on a single assumption. LatticeLink version 1 deliberately uses ML-KEM alone, so the post-quantum component can be exercised and inspected in isolation.

Primitives

RoleAlgorithmStandardParametersImplementation
Key encapsulationML-KEM-768NIST FIPS 203Public key 1,184 B, secret key 2,400 B, ciphertext 1,088 B, shared secret 32 B. Security category 3.@noble/post-quantum 0.7.1
Key derivationHKDF-SHA-256RFC 5869Empty salt; info binds a label and the recipient fingerprint; 32-byte output.Browser WebCrypto
EncryptionAES-256-GCMNIST SP 800-38D96-bit random nonce, 128-bit tag, header as associated data.Browser WebCrypto
FingerprintSHA-256NIST FIPS 180-4Over the raw 1,184-byte public key, shown as 64 hex digits.Browser WebCrypto
RandomnessgetRandomValuesWeb Crypto APIKey-generation seeds, ML-KEM message randomness, nonces.Browser / operating-system CSPRNG

No primitive is implemented by hand. Every cryptographic operation calls either the maintained noble-post-quantum library or the browser’s built-in WebCrypto.

Message sequence

LatticeLink message sequence Agent B generates an ML-KEM-768 key pair and sends the public key to Agent A. A compares the fingerprint, encapsulates, derives a key with HKDF and seals the message with AES-256-GCM, then sends the envelope over the public channel. B parses, decapsulates, derives the key and verifies the tag: it either returns the message or rejects and releases nothing. public channel · may be read, delayed or altered Agent A sender Agent B recipient ML-KEM-768.KeyGen() → ek (public) · dk (secret) ek · 1,184 bytes fingerprint = SHA-256(ek) compare fingerprint over a channel A trusts Encaps(ek) → ss, kem_ct k = HKDF-SHA-256(ss, info) ct = AES-GCM(k, n, m, AAD) envelope · header, kem_ct, nonce, ct every header field is bound into the tag parse → Decaps(dk) → verify ✓ tag valid: message ✗ otherwise: release nothing

One message, end to end. The channel is assumed hostile: it may read, delay or alter anything it carries.

Key schedule

ss, kem_ct  = ML-KEM-768.Encaps(ek)                  // fresh for every message
info        = "LatticeLink/v1 message key" ‖ 0x00 ‖ SHA-256(ek)
k           = HKDF-SHA-256(IKM = ss, salt = ∅, info, L = 32)
AAD         = UTF-8(JSON[format, v, kem, kdf, aead, recipient, kem_ct, nonce])
ct ‖ tag    = AES-256-GCM(k, nonce, plaintext, AAD)  // nonce: 12 random bytes

The shared secret is wiped as soon as the AES key has been derived, and the AES key is created non-extractable inside WebCrypto. Because every message has its own encapsulation, every message has its own key. The random nonce is a second safeguard.

Verification pipeline

On receipt, B runs each step in order. The first failure ends the attempt, and no plaintext exists at any point before the tag verifies.

  1. Strict parse. Unknown or missing fields, other versions or algorithms, non-canonical base64url and wrong lengths are rejected before any cryptography runs.
  2. Recipient check. Whether the recipient field names B’s key is recorded, but does not end the attempt, so a wrong key is caught by the cryptography itself.
  3. Decapsulation. ML-KEM never reports failure here. A foreign or altered ciphertext yields an unrelated secret (implicit rejection).
  4. Key derivation. HKDF re-derives the AES key from the decapsulated secret.
  5. Tag verification. AES-GCM checks the 128-bit tag over the ciphertext and the full header. On failure WebCrypto returns no bytes at all.
  6. Recipient rule. A verified envelope whose header names a different key is still refused.
  7. Strict decoding. The plaintext must be valid UTF-8.

Isolation architecture

Isolation architecture Inside the browser tab, the page talks to three separate workers: Agent A (encapsulate and seal), Agent B (holds the secret key, which no request returns) and an optional local AI worker that receives only drafting requests or plain facts. Model weights come from huggingface.co, outside the tab, only after you opt in. your browser tab Agent A worker encapsulate · seal recipient public key Page interface · channel public event log Agent B worker holds dk (secret key) no request returns it message envelope envelope verdict Local AI worker optional · loads on request request · facts labelled text huggingface.co model weights, after opt-in

Each agent runs in a dedicated Web Worker with its own memory. A worker accepts exactly six requests: generate a key pair, generate a decoy key, import a recipient key, encrypt, decrypt and discard keys. None of them returns a secret key. The test suite drives a complete exchange through this protocol and searches every response for any part of the secret key.

Keys are ephemeral. They exist only in worker memory, are never written to storage, and are destroyed when the tab is closed or refreshed.

On-device AI

The optional assistant is SmolLM2-360M-Instruct (Apache-2.0), pinned to a fixed revision and run with Transformers.js 4.3.1 on ONNX Runtime Web 1.31.0-dev.20260914-8d85527a0. Its weights are about 275 MB with WebGPU (4-bit, 16-bit float) or about 390 MB on the CPU path. They download directly from Hugging Face only after the visitor presses Enable live AI.

  • The runtime’s WebAssembly binary is served by this site and checked against its SHA-256 before use. No code is loaded from a third-party CDN.
  • It receives a drafting request typed by the visitor, or a few sentences of facts derived by ordinary code from public event records. The exact prompt is shown under every answer.
  • It never receives keys, shared secrets, envelopes, fingerprints or decrypted text, and it cannot influence a verdict.

Platform

The site is a set of static files with no backend, database or accounts. Every page is served with a Content-Security-Policy that permits scripts only from this origin and network connections only to this origin and to Hugging Face’s hosts (for the opt-in model download). Cross-origin isolation (COOP and COEP) is enabled, which gives the benchmark finer timers and lets the AI runtime use threads.

default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self' blob:;
connect-src 'self' https://huggingface.co https://*.huggingface.co https://*.hf.co;
img-src 'self' data:; style-src 'self'; font-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'

Browser support

CapabilityRequiresTested
Encryption demoModule Web Workers, WebCrypto HKDF and AES-GCM. Current Chrome, Edge, Firefox or Safari 16.4+Chrome 154 (Windows 11), desktop and phone-width layouts
Two-browser exchangeThe above, plus file download and uploadTwo isolated Chrome profiles
Local AI, GPUWebGPU: Chrome or Edge 113+ on desktop, about 1.5 GB free memoryChrome 154 with an NVIDIA RTX 4070
Local AI, CPUWebAssembly SIMD and DecompressionStream. Much slowerChrome 154 with the CPU path forced: 3.4 tokens per second

How it is verified

  • Every build: 52 of 52 unit tests passed in this build, covering empty and Unicode messages, every tamper position, wrong keys, altered headers and malformed envelopes.
  • Independent implementation: the test suite contains a second implementation of the format written against Node’s own crypto module. Each implementation must open the other’s envelopes.
  • Published vector: an envelope sealed to a key from a published seed, reproducible byte for byte. Download it.
  • In your browser: the home page runs a six-check self-test on every visit, and the benchmark measures each operation on your device.