Hopefully by now you have seen my articles on the 'Ripple' LoRa mesh system, so you have some background on where this is coming from, but essentially I have been creating various apps and firmwares for a simple LoRa mesh network, which uses pretty standard ECC (Curve25519) encryption for a private, personal network of your own.
Ripple has one main competitor called Meshtastic, which you've probably heard of. Both Ripple and Meshtastic, however, suffer from the same problem in that they have trouble scaling beyond a certain size of nodes, and cannot handle the congestion.
ResearchFor many months I researched for existing algorithms or libraries and found that the most promising was one called Reticulum, by Mark Qvist. I really have to tip my hat to Mark, as he designed a very advanced network stack, some of which I still have trouble getting my head around :-) I tried to find if there were any native C++ implementations, but sadly only some partial attempts which haven't panned out.
So, I made the decision to re-think Reticulum, and approach it from an embedded-first angle, whereas RNS (Reticulum Network Stack) was designed in a Python, desktop-first environment.
What I have come up with is a very stripped-down version, that can be run on extremely resource constrained devices. I made a number of compromises on the technical front, which I'm sure Mark and others could find questionable. I like the fact that RNS strives to be cryptographically secure as its primary objective, but I saw a lot of it as overkill for a simple LoRa mesh between parties who know each other, and are exchanging information which I wouldn't consider to be extremely sensitive, like financial transactions.
R2 is BornSo, I got on the tools and coded for months, and 'R2' was born. :-) It is, in essence, a C++ library which is, hopefully, fairly portable, ie. not just for Arduino targets, for instance, although it comes with some Arduino helper classes to make it super simple for that environment.
I will be releasing this library to Github very soon, but am still putting final touches, hopefully making it more presentable.
A high-level overview, more of a philosophical summary of the objectives I had in mind, when designing is:
- simple, understandable by most developers/integrators.
- 'pretty good' crypto fundamentals, balanced with performance
- Well suited to LoRa, and other extremely bandwidth-constrained packet radios
- Portable to different MPUs, packet radios, and software frameworks
- An open-ended/generic transport protocol.
For those interested in some of the technical details, please refer to/study RNS first, as I have borrowed the basic primitives/concepts. These include:
- 'Announce' packets, which propagate outwards from a 'Destination', and are cryptographically signed. They can also optionally contain a small (up to 32 byte) payload of data, eg. a 'callsign' for a Chat user.
- 'Identities', which are essentially an Ed25519 key-pair.
- 'Destinations', which are truncated SHA256 hashes of a name, or name+Identity. I am proposing 64-bit hashes, (ie. 'Addresses'), vs 128-bit in RNS.
- 'Transport nodes', which hold routing tables, ie. just the 'next hop' to a Destination. They also hold special tables for 'Reply' packets. These are called 'Proofs' in RNS.
- 'Datagrams', packets that get routed to a Destination. No MANDATORY encryption, vs mandatory ephemeral keys in RNS. Encryption/authentication is considered to be in the 'application' layer.
- 'Reply packets', which are special packets that follow 'bread crumbs' left in Transport nodes, and only have a short time-window that can be used, then the trail collapses. The replies can either be signed, and are more guaranteed to be carried by transport nodes, or can be 'plain' but less chance of securely making it back. (I'm still not sure about this last part, and whether to only support signed replies(?))
- 'Airtime Budgets', each node is configured with a budget of how much transmit airtime they can use. This is purely a cooperative mechanism, and isn't (prob can't be) enforced. Each of the packets has a priority, and lower priority outbound packets end up having to wait longer because of the airtime budget. This will hopefully attenuate many congestion problems, and also be a mechanism for frugality, ie. for nodes to not even try to pump out 'less important' packets.
Chat is naturally the first client to enter the scene, and require a protocol. The core C++ library has a 'simple-secure-chat' sample app, which effectively has a proposed protocol, built on top of the R2 basics. Each user has an Identity key-pair, and can potentially exchange public keys via whatever medium (eg. QR codes), or can use the Announce mechanism and put some identifying data into their Announce packets, like a 'callsign'.
The 'Destination' for a Chat datagram is the hash of "chat.msg" + Identity.public_key (of recipient)
An Announce packet must be sent at least on startup, to let the mesh know about this Destination, and to build up the next-hop tables in the Transport nodes.
Because encryption is considered to be in the application layer, for the first proposal, the chat Datagrams have a payload like so:
[8-byte hash of sender],[4-byte MAC],[encrypted data]
The encrypted data is AES-128 encoding of:
[32-bit timestamp],[message UTF-8]
The MAC is a SHA256 HMAC, truncated to 4 bytes.
And the key to both the HMAC and AES-128 is the ECDH key exchange, ie. 'shared secret', of the two party's Identities. (ie. keypair). (the Ed25519 public key is transposed to Ex25519)
(Recipient nodes send a signed Reply packet as an acknowledgement, with no reply data payload. ie. it's simply the packet-hash of the original Chat datagram signed with a digital signature by the recipient.)
Here is another divergence from RNS, which insists on separate signing key pair and encryption key pair. I understand that this is more secure, but for low-bandwidth environments, this can be a valid compromise. And, also no ephemeral key pair generation.
Some apps may opt to use a more secure application protocol, and use separate encryption keys, or generate ephemeral key pair and pad-out the payload with the extra fields needed. But, that is up to the application.
There are many potential applications that may pop up, and for the sake of interoperability, hopefully some standards will emerge.
The 'R2 beta'I have put together a set of firmwares and Android client apps to launch a beta trial 'kit'. (The download link is at the top of this article).
There is a more detailed explanation of this here: https://buymeacoffee.com/ripplebiz/wanted-r2-beta-testers
Like a lot of people, I also have bills to pay, and need to make a living. I am launching 'R2' as a combination of proprietary firmwares + Android apps, for a more 'consumer'-like user who just wants to get it all up and going with as little fuss as possible. So, I am selling the convenience, but also catering to the DIY/developer crowd by open sourcing the core C++ library.
I very much hope to see competition arise from 3rd parties. For instance, I have absolutely no iOS skills, so the door will be open for someone to develop an R2 Messenger app for iPhone. But, let me tell you, it's a lot of work! Whoever does the iPhone version deserves to be rewarded.
I'm also hoping/anticipating there could be several Repeater projects that emerge. Even though you can spin up a very simple one from the Arduino sample in the C++ library, it really is a no-frills thing, and being able to remotely 'tweak'/tune your repeaters, or do OTA firmware updates will be points-of-difference that some people may consider worth paying for.
But, back to the R2 beta. I am looking for people who maybe already have Meshtastic repeaters up in high places, who are willing to give R2 a try, and see how it performs. Am looking for as much feedback as possible--good or bad.
EDIT: The C++ libraryI have now published the RippleCore C++ library: https://github.com/ripplebiz/RippleCore
ConclusionOK, that's it for now. It has been a lot of work and imagination gone into this beta release, and I'm very much in need of some RNR now :-)
regards,
Scott Powell.
Comments
Please log in or sign up to comment.