An open API service indexing awesome lists of open source software.

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.

Awesome Lists containing this project

README

          

# Loom

Experimental local-first peer-to-peer messaging for desktop.

[![Repository](https://img.shields.io/badge/GitHub-sudoaanish%2Floom-181717?style=for-the-badge&logo=github)](https://github.com/sudoaanish/loom)
[![Website](https://img.shields.io/badge/Website-aanishfarrukh.com-0f766e?style=for-the-badge)](http://aanishfarrukh.com/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=for-the-badge)](LICENSE)
[![Status](https://img.shields.io/badge/Status-Experimental-orange?style=for-the-badge)](#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


Tauri 2
Rust
Tokio
JavaScript
HTML5
CSS3
SQLite
mDNS
Cryptography

- 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)