A decentralized, asynchronous Peer-to-Peer messaging network built entirely on top of Tor Onion Routing.
Unlike traditional P2P networks that expose participant IP addresses, this project routes all node-to-node communication through Tor Hidden Services (.onion addresses), ensuring that nodes cannot easily trace the physical location or IP address of their peers. Furthermore, it implements "Russian Nesting Doll" layered encryption (Onion Routing) within the application layer itself to securely multi-hop messages across the network.
- Tor Hidden Services: Every node automatically hosts an Express HTTP server exposed as a
.onionaddress, acting as a receiver for incoming packets. - Cryptographic Identity: Nodes are identified by a generated Ed25519 public key (
nodeID). All messages are cryptographically signed by the sender and verified by the receiver. - Application-Layer Onion Routing: Messages are wrapped in multiple layers of Curve25519 encryption (
sealedBox). Intermediate relays can only decrypt instructions for the next hop, blinding them to both the message content and the final destination. - Anti-Replay Protection: Packets contain freshness timestamps (
createdAt). The network enforces strict Time-To-Live (TTL) limits and clock skew rules to reject expired or replayed packets. - Reliable ACK System: Upon successful delivery, the destination node fires an Acknowledgment (ACK) packet back through a new random circuit. Failed ACKs are picked up by a background SQLite worker and aggressively retried using an exponential backoff policy.
- Signed Peer Announcements: Nodes announce themselves to the network using timestamped, cryptographically signed payloads to prevent spoofing and Sybil-like identity hijacking.
- Interactive CLI Controller: A local terminal interface to easily manage the node, view the inbox, and send messages securely over the network.
The system is designed with a strict separation of concerns, heavily utilizing background workers to handle unreliability in Tor connections.
- The Daemon (
server.ts): The core background process. It runs an Express HTTP server listening on the Tor proxy. It handles unwrapping encryption layers, routing, signature verification, and updating the local SQLite database. - The Crypto Engine (
crypto.ts): Wrapslibsodium-wrappersto handle Ed25519 signing and Curve25519 anonymous encryption. - The Router (
onion.ts): Handles dynamic circuit building (selectRoute) and the construction of the multi-layered encrypted packets (buildOnion). - The Peer Manager (
peer.ts): Maintains an active dictionary mapping knownnodeIDs to their respective.onionaddresses. - The Controller (
cli.ts): A lightweight Node.js script that communicates with the local daemon to provide a human-readable interface.
- Sending: Node A wants to message Node Z. Node A selects random relays (Node B and Node C). Node A encrypts the message for Node Z, wraps that in instructions for Node C, and wraps that in instructions for Node B.
- Relaying: Node A sends the package to Node B. Node B unlocks its layer, reads "Next hop: Node C", and forwards it. Node C does the same, forwarding to Node Z.
- Delivery & ACK: Node Z unlocks the final layer, verifies Node A's signature, and saves the message to its local SQLite DB. Node Z then builds a brand new circuit and sends an
ACKpacket back to Node A.
You will need the following installed on your machine:
- Node.js (v18+ recommended)
- Tor Daemon (Must be installed and running as a background service)
pnpm(ornpm)
The application expects Tor to run locally and expose a SOCKS5 proxy on port 9050. It also needs Tor to read from our local torrc configuration to generate the Hidden Service.
Depending on your OS, launch Tor pointing to the local torrc file provided in the repository:
tor -f ./torrc(Wait until Tor prints Bootstrapped 100% (done): Done before proceeding).
Open a new terminal window and navigate into the server directory:
cd server
pnpm installCopy the example environment file and configure it if necessary:
cp .env.example .env(By default, the .env settings are already configured for local testing).
Start the main application. This will generate your cryptographic identity, connect to the Tor network, and spin up the background workers:
pnpm run devNote: On first boot, check the server/hidden_service directory. Tor will automatically generate your .onion address and save it in hidden_service/hostname.
To actually send messages and interact with the node, open a third terminal window and run the CLI script:
cd server
npx tsx src/cli.tsFrom the CLI menu, you can:
- View your newly generated Public Key and Onion Address.
- View known peers on the network.
- Check your Inbox/Outbox for
PENDING,SENT, andDELIVEREDmessages. - Send an encrypted message to another node by pasting their Public Key.
To test the multi-hop routing locally, simply duplicate the entire project folder (e.g., nodeB, nodeC).
- In
nodeB/server/.envandnodeC/server/.env, ensure you assign differentHTTP_PORTs (e.g.,3001,3002). - Add
nodeA's newly generated.onionaddress to theBOOTSTRAP_ONIONSlist in their.envfiles. - Launch Tor and the Daemon for all three nodes. Node B and Node C will automatically discover Node A and sync peer tables!