MurmurLRS is a fork of ExpressLRS that encrypts every packet between your transmitter and receiver. Nobody can sniff your stick inputs or inject commands into your link.
Works on all ELRS hardware. Same configurator. No performance loss.
git clone https://github.com/PotatoSpudowski/MurmurLRS- Open ELRS Configurator
- Go to Local tab, point it at the
srcfolder - Set your binding phrase (3-4 random words minimum, same on TX and RX)
- Flash TX, flash RX
Encryption turns on automatically when a binding phrase is set. You'll see in the build log:
MurmurLRS: encryption enabled
To verify, connect over USB (420000 baud) and check for:
MurmurLRS: encryption active (TX)
Both TX and RX must run MurmurLRS. A MurmurLRS device won't link with stock ELRS.
Your binding phrase becomes your encryption key. In stock ELRS it's just for pairing. In MurmurLRS it's fed through a key derivation function to produce real cryptographic keys.
TX: RC data -> encrypt + authenticate -> transmit
RX: receive -> verify -> decrypt -> output
Zero extra bytes. Same packet structure. Same air rate. The authentication tag replaces the CRC field.
Identical to stock ELRS. The encryption adds ~22 microseconds per packet. At 500 Hz that's 1.3% CPU. You won't notice it.
| MurmurLRS | Stock ELRS | |
|---|---|---|
| Latency added | ~22 us/pkt | -- |
| Packet size | Same | Same |
| Air rate | Same | Same |
| Range | Same | Same |
Both add encryption to ELRS. The difference is authentication.
| MurmurLRS | PrivacyLRS | |
|---|---|---|
| Cipher | ASCON-128 AEAD | ChaCha20 |
| Authentication | Yes (keyed) | No (CRC only) |
| Tampered packets | Rejected | Accepted silently |
| Replay protection | 64-packet window | 8-bit counter |
PrivacyLRS encrypts. MurmurLRS encrypts and authenticates. If someone flips bits in your encrypted packet, MurmurLRS rejects it. PrivacyLRS can't tell.
Everything ELRS supports. ESP32, ESP32-S3, ESP32-C3, ESP8285. 900 MHz and 2.4 GHz. Same radios, same modules.
cd src/lib/MurmurEncrypt
make test
29/29 tests pass, including official ASCON-128 test vectors.
Technical details
Cipher: ASCON-128 AEAD (NIST SP 800-232, lightweight crypto standard selected 2023)
Key derivation:
binding_phrase -> ASCON-XOF -> master_key -> ASCON-XOF -> enc_key (16B) + UID (6B)
Replay protection: 64-packet sliding window with 32-bit counter reconstructed from 8-bit OtaNonce
Nonce construction: counter + packet_type + direction (uplink=0, downlink=1)
What changed from stock ELRS:
| File | What |
|---|---|
src/lib/MurmurEncrypt/* |
Encryption module (~400 LOC, pure C) |
src/lib/OTA/OTA.cpp |
Encrypt/decrypt wrapping, counter tracking |
src/python/build_flags.py |
Auto-enable when binding phrase is set |
src/src/tx_main.cpp |
Init at boot, counter reset on rate change |
src/src/rx_main.cpp |
Init at boot, counter reset on SYNC/disconnect |
Known limitations:
- 14-bit MAC (forgery probability: 1/16384 per attempt)
- SYNC packets are cleartext (needed for connection establishment)
- No forward secrecy
- LCG hop sequence inherited from ELRS (see #3)
See CONTRIBUTING.md.
- Flash and test -- report what works and breaks
- Review the crypto -- under 500 lines of C in
src/lib/MurmurEncrypt/ - ESP8285/ESP32-S3/C3 testing -- primary dev is on ESP32
Started with a post on r/fpv (423+ upvotes, 155+ comments). Looking for testers.
See CHANGELOG.md.
Based on ExpressLRS. See README_ELRS.md for upstream docs.