Features
X25519 Key Exchange
Ephemeral keys per submission, forward secrecy
ChaCha20-Poly1305
Authenticated encryption of form payload
Browser WASM
Encryption happens client-side before any network request
MITM Proof
Server compromise doesn't expose form data in transit
Installation
<script src="wasm_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(fetch('stmf.wasm'), go.importObject)
.then(result => go.run(result.instance));
</script>
Usage
Protocol Flow
Setup (one-time):
Server generates X25519 keypair
Public key embedded in page
Submission:
Browser generates ephemeral keypair
Shared secret = X25519(ephemeral_private, server_public)
Key = SHA-256(shared_secret)
Encrypted = ChaCha20-Poly1305(form_data, key)
Send: ephemeral_public + encrypted
Decryption:
Shared secret = X25519(server_private, ephemeral_public)
Key = SHA-256(shared_secret)
form_data = Decrypt(encrypted, key)
Quick Links
More from Lethean R&D Labs
Fancy helping out?
Spotted a bug? Got an idea? We'd love to hear from you.
Read the contributing guide →