https://github.com/sudoaanish/loom
Local-first, serverless, peer-to-peer secure messaging client built on Tauri and Rust utilizing Double Ratchet encryption.
https://github.com/sudoaanish/loom
cryptography double-ratchet local-first mdns offline p2p rust secure-messaging serverless tauri
Last synced: about 20 hours ago
JSON representation
Local-first, serverless, peer-to-peer secure messaging client built on Tauri and Rust utilizing Double Ratchet encryption.
- Host: GitHub
- URL: https://github.com/sudoaanish/loom
- Owner: sudoaanish
- License: mit
- Created: 2026-06-26T20:48:44.000Z (8 days ago)
- Default Branch: main
- Last Pushed: 2026-06-26T21:27:27.000Z (8 days ago)
- Last Synced: 2026-06-26T22:19:17.055Z (8 days ago)
- Topics: cryptography, double-ratchet, local-first, mdns, offline, p2p, rust, secure-messaging, serverless, tauri
- Language: Rust
- Size: 96.7 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Loom
Experimental local-first peer-to-peer messaging for desktop.
[](https://github.com/sudoaanish/loom)
[](http://aanishfarrukh.com/)
[](LICENSE)
[](#experimental-security-warning)
## Overview
Loom is a Tauri and Rust desktop messaging client exploring local network discovery, direct peer-to-peer communication, cryptographic identity, and message exchange without a central messaging server.
The current implementation is designed around local-first operation. It does not use user accounts, telephone registration, a central messaging service, or cloud relay infrastructure. Peers exchange Loom identity tokens out of band, discover one another through mDNS when available, and communicate over direct TCP connections.
## Experimental Security Warning
Loom is experimental software. It has not been independently audited and should not be treated as production-ready security software.
The repository contains a custom cryptographic protocol implementation using X25519 key agreement, Ed25519 signatures, HKDF-SHA256 key derivation, ChaCha20-Poly1305 message encryption, and a custom Double Ratchet-style state machine. Loom should not be used for high-risk, sensitive, regulated, or adversarial communications.
## What Loom Does
- Generates a local cryptographic identity from a 32-byte master seed.
- Exports public identity material as a `LOOM-` token.
- Imports contacts from Loom tokens.
- Discovers local peers through mDNS using `_loom._tcp.local.`.
- Opens a direct TCP listener on an ephemeral local port.
- Supports manual peer address injection for loopback and local testing.
- Performs signed handshake messages before chat.
- Encrypts message payloads in transit after a ratchet session is established.
- Persists contacts, message history, local identity seed, and ratchet state in SQLite.
- Exposes a Tauri desktop UI for onboarding, contact management, peer discovery, handshakes, and chat.
## Architecture
Loom is split into three main layers.
### Frontend
The frontend lives in `src/` and is implemented with HTML, CSS, and JavaScript.
- `src/index.html` defines the single-page application shell.
- `src/style.css` defines the desktop UI styling.
- `src/main.js` handles UI state, Tauri command calls, contact rendering, peer rendering, chat rendering, and event listeners.
The frontend invokes Tauri commands such as `generate_new_identity`, `start_network`, `add_contact_token`, `initiate_chat_handshake`, `send_message`, and `get_messages`. It listens for backend events including `peer_discovered`, `message_received`, `session_established`, and `log`.
### Tauri Backend
The Tauri backend lives in `src-tauri/`.
- `src-tauri/src/main.rs` initializes the app, creates the `LoomEngine`, registers Tauri commands, and forwards core callbacks into frontend events.
- `src-tauri/tauri.conf.json` defines the desktop app configuration.
- `src-tauri/capabilities/default.json` defines the app capability permissions.
The backend stores the SQLite database under Tauri's app data directory. The default database filename is `loom.db`. A `LOOM_PROFILE` environment variable or `--profile` / `-p` argument changes the database filename to `loom_.db`.
### Core Engine
The Rust core lives in `crates/loom-core/`.
- `src/lib.rs` exposes the `LoomEngine` API and callback interface.
- `src/token.rs` implements Loom token serialization and parsing.
- `src/storage.rs` implements SQLite persistence.
- `src/network.rs` implements mDNS discovery, TCP transport, handshake handling, message send and receive paths, and connection tracking.
- `src/protocol.rs` defines handshake and encrypted envelope wire messages.
- `src/crypto.rs` implements key derivation, symmetric encryption helpers, and Double Ratchet-style session state.
## Security Model
Loom currently models identity as an Ed25519 public key and an X25519 public key encoded into an out-of-band Loom token. Private key material is derived from a locally generated master seed.
The implementation signs handshake payloads with Ed25519, derives shared session material from X25519 Diffie-Hellman outputs using HKDF-SHA256, initializes a Double Ratchet-style session, encrypts message payloads with ChaCha20-Poly1305, and signs encrypted chat envelopes with Ed25519.
These are implementation details, not audit results. The security model remains experimental.
## Current Limitations
- The protocol is custom and unaudited.
- Loom is not equivalent to Signal.
- SQLite stores plaintext message history after decryption.
- SQLite stores the local master seed and serialized ratchet state without application-level encryption.
- Tauri Content Security Policy is currently set to `null`.
- mDNS exposes local presence and network metadata on the local network.
- There is no documented identity revocation, key rotation, or recovery model.
- There is no documented key verification ceremony beyond out-of-band token exchange.
- TCP frame lengths are accepted from the network without an explicit maximum in the current implementation.
## Tech Stack
- Desktop shell: Tauri 2
- Frontend: HTML, CSS, JavaScript
- Backend: Rust
- Async runtime: Tokio
- Storage: SQLite through `rusqlite`
- Peer discovery: `mdns-sd`
- Cryptography crates: `ed25519-dalek`, `x25519-dalek`, `chacha20poly1305`, `hkdf`, `sha2`, `blake2`, `rand`
- Serialization: `serde`, `serde_json`
- Message identifiers: `uuid`
## Development
The repository is a Rust workspace with two members:
- `crates/loom-core`
- `src-tauri`
Prerequisites:
- Rust toolchain
- Node.js and npm for invoking the Tauri CLI through `npx`
Run the Rust test suite:
```bash
cargo test
```
Start the Tauri app in development mode:
```bash
npx @tauri-apps/cli dev
```
For local multi-instance testing, run separate profiles:
```powershell
$env:LOOM_PROFILE="peer1"
npx @tauri-apps/cli dev
```
Open a second terminal in the same repository directory. If you use [twin](https://github.com/sudoaanish/twin), you can open a matching terminal session from the current working directory:
```powershell
twin
```
Then run the second profile:
```powershell
$env:LOOM_PROFILE="peer2"
.\target\debug\loom-backend.exe
```
## Security Documentation
Additional security documentation:
- [SECURITY.md](SECURITY.md)
- [THREAT_MODEL.md](THREAT_MODEL.md)
## License
Loom is licensed under the [MIT License](LICENSE).
## Author
Built by [Aanish Farrukh](http://aanishfarrukh.com/).
Repository: [github.com/sudoaanish/loom](https://github.com/sudoaanish/loom)