Open mesh networking over LoRa

Off-grid text chat done right.

Long-range radio instead of cell towers. Group chats that cover a region, with replies, reactions, and edits. And encryption that was the starting point of the design, not an afterthought.

Open source, and open to anyone who wants to build on it.

A SenseCAP T1000-E radio beside an iPhone showing a UMSH group conversation
Technology preview

UMSH works today, and it is not finished. The protocol will keep changing for the next several months while it settles, and the apps are still being built out around it. Expect breaking changes, and expect to reflash your radios when they land.

You can take part right now: flash a supported board, and join the iOS beta. An Android app is planned but has not been started. Much of this project was written with heavy help from large language models, which is documented openly rather than quietly.

What makes it different

Few of the ideas here are new. The contribution is putting them together cleanly: stronger cryptography, composable routing, and layers that stay in their lane.

Encryption came first

Your messages are encrypted — a channel conversation as much as a private one — using a construction that stays safe even when a node reboots and loses track of its counters. A private message is authenticated against your contact's own key as well, so it cannot be forged or quietly altered on the way.

Security model →

A chat that behaves like a chat

Replies, reactions, edits, and deletes — the things you stop noticing until they are missing. Messages run to 1,600 bytes, so you can say what you mean instead of compressing it into a telegram.

Text messages →

Forward secrecy that costs nothing

Two nodes can agree on a pair of ephemeral addresses and simply talk to those instead. At the link layer the result is indistinguishable from any other conversation, so it needs no special handling by repeaters, no changes to application protocols, and adds no per-packet overhead at all.

PFS sessions →

Private channels are like VPNs

A private channel is more than encrypted group chat: the shared key protects everything inside it, not just the group thread. To anyone without it the traffic is unreadable, unalterable, and does not disclose which member is speaking. Sharing a key is a QR code away.

Planned: one-to-one messages carried under the channel key, so they look like ordinary group traffic — plus key rotation and member removal.

Channels →

Sent means carried, not just transmitted

After transmitting, your radio listens for the mesh to pick the message up, and tries again if it does not hear that happen. Along a known path each hop confirms the next one the same way, so a message that stalls partway through gets another chance instead of vanishing without trace.

Forwarding confirmation →

Nothing depends on the time

Replay protection counts frames rather than reading a clock, so nothing about the security of a message rests on knowing the time. A radio that has sat in a drawer for a year, or has never seen a GPS fix, can start talking securely the moment you switch it on — and there is no clock skew for an attacker to work with.

Replay protection →

Understanding UMSH

How the thing works underneath, for anyone who wants to look. None of it is required reading to use a radio.

Your key is your address

A node is identified by its Ed25519 public key, and that key is the address other nodes send to — no node numbers to collide, no registration, no authority handing out identifiers. On air, most packets carry a three-byte hint instead of the full key, which keeps frames small. A hint is still a stable pseudonym that a patient listener could follow; only an encrypted channel conceals the sender outright.

Strict layers, tight frames

The link layer moves opaque payloads and never inspects them, so it can carry UMSH's own chat protocols, CoAP, or something you invent. Typical authenticated overhead runs 16 to 28 bytes, and every packet fits in a single LoRa frame.

Designed for amateur radio

Amateur rules bar encryption that obscures the meaning of a message, and UMSH keeps the two separable: a message can carry authentication without carrying encryption, so a licensed operator does not have to give up integrity to stay legal. Operator and station callsigns ride along as compact options, and a repeater rewrites the station callsign as it forwards.

Built to be debugged

A Wireshark dissector, a capture tool, and published test vectors ship with the protocol. Being able to read a packet trace is treated as a requirement, not a nicety — a protocol nobody can troubleshoot does not survive contact with a real deployment.

Read the full specification →

How it compares

UMSH owes a great deal to the projects it is measured against here, MeshCore especially. These tables are condensed from the specification's own comparison chapters, which aim to be accurate rather than flattering — if something here is unfair or wrong, please say so.

Against MeshCore

Aspect UMSH MeshCore
Address on the wire 3-byte hint, or the full public key when the receiver may not know it 1-byte hash, with a dedicated packet type for first contact
Encryption AES-128-CTR in a SIV construction AES-128-ECB
Authentication AES-CMAC, 4 to 16 bytes HMAC-SHA256 truncated to 2 bytes
Key derivation HKDF-SHA256, with separate encryption and authentication keys The ECDH secret used directly for both
Replay protection Monotonic frame counters, no clock involved A 128-entry duplicate cache, with timestamps above
Routing Independent options that combine freely A path field and route-mode bits
Layering The link layer never inspects payloads Link, network, and application concerns combined

Read the full comparison →

Against Meshtastic

Aspect UMSH Meshtastic
Identity An Ed25519 public key, which is also the address A 32-bit node number derived from the Bluetooth address
Spoofing The address is a cryptographic credential Node numbers are not bound to any key
Authentication Private messages bound to the sender's key; channel traffic carries an integrity tag None on channel traffic; direct messages only, since v2.5
Header privacy Compact hints, and the sender is concealed entirely in encrypted multicast A 16-byte cleartext header on every packet
Typical overhead 16 to 28 bytes, authentication included About 22 bytes for channel traffic, about 42 for direct messages
Forward secrecy Available, at no per-packet cost Not available
Maturity Experimental, one app, six boards Mature, huge community, dozens of devices, a rich application layer

Read the full comparison →

Getting started

You need one radio to listen, and two to have a conversation.

  1. Get a radio

    Six boards are supported, from a sealed pocket tracker to a solar-powered node you can bolt to a roof. The T1000-E is the one most of this was developed against.

    Supported hardware →

  2. Flash it

    One command builds and installs the firmware for your board. A browser-based flasher that needs no toolchain at all is on the way.

    Flashing instructions →

  3. Pair your phone

    The iPhone app connects to your radio over Bluetooth and gives you conversations, contacts, and a map. It is in beta.

    About the app →