Whisper
your secrets.
A terminal-based, end-to-end encrypted messenger that operates entirely on your Local Area Network. No internet connection required, no cloud servers, and zero telemetry. Built for security researchers and privacy advocates.
Why choose LANMess?
The modern internet is built on centralization and data harvesting. LANMess is a return to localized, peer-to-peer communication where you control the infrastructure.
| Requirement | LANMess | Cloud Messengers |
|---|---|---|
| Internet Connection Required | No (if LAN Only) | Yes |
| Data Leaves Your Network | Never | Always |
| Account / Phone Number Required | None | Usually |
| End-to-End Encryption | Yes (X25519) | Mostly |
| Terminal User Interface (TUI) | Native | None |
| Auditable Open Source Code | 100% | Rarely |
How everything works.
From installation to encrypted message delivery.
Vault Creation
Upon first launch, you set a strong PIN. LANMess generates a random 32-byte master key and encrypts it using Argon2id derived from your PIN.
Peer Discovery
The app broadcasts a UDP packet on port 50505. Other instances on the LAN hear this and cache your IP, port, and public keys automatically.
Secure Adding
To add a peer, you exchange an 8-digit TOTP code. This proves you share the same local network and are intentionally connecting to each other.
Encrypted Chat
A chat request triggers an X25519 ephemeral handshake. Once established, messages are encrypted with AES-GCM and signed with Ed25519.
Cryptographic
Architecture
LANMess does not rely on proprietary security through obscurity. It uses battle-tested, standard cryptographic primitives. Here is how a message is secured:
X25519 Handshake
An ephemeral key exchange creates a shared secret that is never sent over the network.
HKDF Derivation
The shared secret is expanded into independent send and receive hash chains using HKDF-SHA256.
AES-GCM & Hash Ratchet
Each message uses a fresh key from the ratchet, encrypts the padded payload with AES-GCM, and immediately advances the chain.
Ed25519 Signatures
Every control frame and message is signed with your long-term identity key to prevent tampering.
async def send_chat_message(
self, contact_name, text,
reply_to=0, react_to=0
):
async with self._get_contact_lock(contact_name):
contact = self.db.get_contact(contact_name)
send_chain_hex = contact.get(
"send_chain_key_hex", ""
)
send_chain = bytes.fromhex(send_chain_hex)
counter = contact.get(
"send_counter", 0
) + 1
msg_key = chain_message_key(send_chain)
padded = pad_message(text.encode("utf-8"))
nonce = os.urandom(12)
aad = f"{self.user_name}:{counter}".encode("utf-8")
ct = aes_gcm_encrypt(
msg_key, padded, nonce, aad
)
signed_data = (
self.user_name.encode("utf-8")
+ counter.to_bytes(8, "big")
+ nonce + ct
)
sig = sign_bytes(self.ed_private, signed_data)
new_chain = chain_advance(send_chain)
self.db.set_contact_state(
contact_name,
send_chain_key_hex=new_chain.hex(),
send_counter=counter
)
Engineered for Privacy.
A complete suite of security features designed for hostile network environments.
Terminal Native
Built with Python and Textual. No web views, no Electron. A highly responsive, keyboard-driven interface.
PIN Lockout
Brute-forcing the vault is impractical. 5 failed attempts trigger a 30-second lockout. 50 attempts trigger a 24-hour lockout.
Audit Log
Security events are chained with HMAC-SHA256. The database cannot be silently modified without breaking the cryptographic chain.
Auto Discovery
UDP broadcast finds peers instantly. No need to manually configure IP addresses for peers on the same subnet.
Safety Numbers
Compare a 60-digit fingerprint out-of-band to verify your contact's identity and prevent man-in-the-middle attacks.
Secure Deletion
SQLite PRAGMA secure_delete is enabled. Symmetric keys are zeroed out in memory upon app lock or termination.
Deep Dive FAQ
Everything you need to know about LANMess. Mined directly from the source code.
1. App Setup & The Vault
What is the "Group Code" used for during setup?
Why must my PIN be at least 12 characters long?
What encryption is used for my local database?
What happens if I fail my PIN multiple times?
2. Networking & Discovery
Can I use LANMess over a VPN like Tailscale or ZeroTier?
What happens if my peer's IP address changes?
How does the 8-digit "Add Code" work?
What ports do I need to open in my firewall?
Does LANMess work across VLANs or subnets?
3. Cryptography & Security
What exactly are "Safety Numbers"?
How does the "Forward Secrecy" hash ratchet work?
What does "Verified-only" mode do?
What happens if a message signature fails to verify?
How does replay protection work?
4. TUI Interface & Commands
What is the difference between "/clear" and "/clearall"?
How do I completely reset LANMess?
What do the contact statuses mean?
What is the maximum message length I can send?
How do I accept a chat request or clear request?
5. Troubleshooting
Why does it say "Message not delivered: no response"?
Why is my peer showing as offline?
Why did I get blocked by a contact?
What does the "Audit Log" warning mean?
6. Platform & Compatibility
Which CPUs are supported by the pre-built installers?
What Python version do I need for a manual install?
Why does my antivirus flag the Windows installer?
Is there a mobile app?
7. General
Is LANMess free?
What happens if I lose my PIN?
Can I send files, images, or group chats?
How do I update LANMess?
Can I export my chat history?
What happens to an active chat if the network drops?
Does LANMess read my keystrokes or other files?
Take back control.
No accounts. No subscriptions. No telemetry. Pick your platform below to choose how you'd like to download.