WEBVTT

00:00.000 --> 00:07.280
All right, how many of you welcome Shane, everyone?

00:07.280 --> 00:20.760
Welcome, I'm Shane Perman, and I'm a developer contributor to the reticulum RS port of

00:20.760 --> 00:26.640
the reticulum, which is originally a Python, and I think it was presented here in at

00:26.640 --> 00:30.760
Boston maybe two or three years ago, but I think many people are familiar with it,

00:30.760 --> 00:38.800
already. The reticulum RS port was initially started by Maxime Austepinko, and

00:38.800 --> 00:44.720
Jokin Moller is another of the major contributors there. I think most people are

00:44.720 --> 00:49.400
familiar with mesh networking, but I'll just briefly touch on it as opposed to

00:49.400 --> 00:54.440
like an internet protocol where the networks are arranged more hierarchically. The

00:54.440 --> 00:59.280
mesh networks can be any general topology, and in this case, in the case of

00:59.280 --> 01:02.680
reticulum, any of the nodes are going to be relaying packets, whereas with

01:02.680 --> 01:07.160
traditional networks, you'll have usually a backbone or a routers, and then

01:07.160 --> 01:11.960
other devices are just going to be clients not necessarily during the relaying.

01:11.960 --> 01:21.200
The excuse me. I have some of the uses for mesh networking that are seen

01:21.200 --> 01:25.040
commonly are ad hoc networks that you need to set up, for example, in disaster

01:25.040 --> 01:29.000
scenarios. A couple of years or a last year, I think it was in Spain. There was a

01:29.000 --> 01:32.400
power outage nationwide, so you had no cell service, and that lasted about

01:32.400 --> 01:38.840
pay to 10 hours. So this would be a way to keep connected with your devices, as

01:38.840 --> 01:45.120
far as needing to keep connected with emergency services and response, and it's

01:45.120 --> 01:48.520
also sees applications with IoT deployments where you have a large number of

01:48.520 --> 01:56.120
nodes. So reticulum was created by Mark this, and he has actually a pretty good

01:56.120 --> 02:00.800
talk on YouTube, where he goes into detail about its design and the design

02:00.800 --> 02:07.000
philosophy. The best way to find information is the reticulum.network website, and

02:07.000 --> 02:13.400
then the community is based around the reticulum matrix.org chat, so that's the

02:13.400 --> 02:17.680
best place to get more information, and the reference implementation in Python is

02:17.680 --> 02:23.360
on GitHub. So reticulum, I guess what makes it different, or makes it stand out

02:23.360 --> 02:30.520
from other mesh networking solutions, would be that it was designed from the start,

02:30.520 --> 02:34.920
assuming that any peer or link or node in the network could be potentially

02:34.920 --> 02:39.040
compromised or hostile, but by default, everything is going to be in to end

02:39.040 --> 02:45.960
encrypted, and forward secrecy is available by default. The identities on the

02:45.960 --> 02:52.880
network are based around public keypairs. You have a X25519 key for key exchanges, and

02:52.880 --> 02:58.360
then you have a add25519 key for signatures, and each identity is going to be

02:58.360 --> 03:02.720
based around those keys. You don't have to appeal to any certificate authorities for

03:02.720 --> 03:08.480
authentication or validating. The API is message oriented already, so it's very easy

03:08.480 --> 03:13.200
to deploy to develop applications. Some of the more some additional points in

03:13.200 --> 03:21.000
reticulum, all packets do not have a source address. It improves privacy and

03:21.000 --> 03:25.400
censorship. It's more censorship resistant than that way. The addresses, whereas with

03:25.400 --> 03:31.200
the traditional IP and the net IP, addresses are going to be bound to your location,

03:31.200 --> 03:37.200
or depending on, for example, with reticulum, you're able to generate as many addresses

03:37.200 --> 03:42.080
as you want from that key pair, that is your identity, and another one of the benefits

03:42.080 --> 03:46.880
of reticulum is that it's designed to work very well in high latency environments and

03:46.880 --> 03:51.600
with a very low bandwidth. I think the bit rate that mark usually sites is you need about

03:51.600 --> 04:00.440
five bits per second to maintain a connection to appear. That's a trade-off based on how

04:00.440 --> 04:06.440
long you want the time out to be for the link, but they settled on about that, which

04:06.440 --> 04:15.680
is five bits per second. So the port to Rust was started based on performance issues with

04:15.680 --> 04:22.640
the Python implementation. There is a messaging app for reticulum already that supports

04:22.640 --> 04:28.200
mobile, but it's very slow on Android, running Python on Android is not very optimal. And

04:28.200 --> 04:33.800
in addition, CPU overhead prevents it from being used in very small devices. Microsoft

04:33.800 --> 04:45.240
processors, for example, with IOT devices. So, with regards to maybe keeping the Python implementation

04:45.240 --> 04:51.560
and trying to optimize it, that's, so that would be very challenging. I don't know if

04:51.560 --> 04:56.120
jit compilation would be very useful here. I know I've tried I've used number for some

04:56.120 --> 05:03.000
optimization in Python, but for a mature code based like reticulum, it could be very difficult

05:03.000 --> 05:09.560
or not maybe not too effective. Particularly the Python implementation uses, it links to sea

05:09.560 --> 05:16.360
libraries. There is the option to use Python native cryptography primitives, but mostly it's

05:16.360 --> 05:22.120
going to be linking to like open SSL. So that should already be very optimized, but the code

05:22.120 --> 05:28.120
around that, which is in Python, which would be like the routing logic, is going to be harder

05:28.120 --> 05:34.120
to optimize. And there's the issue of the interpreter lock with Python and also garbage collection.

05:34.120 --> 05:38.440
So this image here just is pointing to part of the object graph. When you're running

05:38.440 --> 05:43.000
reticulum, there are a lot of references, back references, and circular references. It can be

05:43.000 --> 05:50.840
difficult to really pin down like where data is getting used. So we've evaluated a few languages

05:50.840 --> 05:55.720
and looking at C++. C++ has cryptography libraries, but being C++, there are a lot of

05:55.720 --> 06:02.600
differences with the adult system. API can differ quite a bit and packaging and including dependencies

06:02.600 --> 06:09.160
in your C++ projects. Zig is a newer language, so it's still not quite a bit here. Another language

06:09.160 --> 06:15.240
that might fit here would be like go, go link. So I wasn't actually at the stage of this project,

06:15.240 --> 06:20.440
I wasn't on the project. I don't know if go was considered, but we settled on Rust for

06:20.440 --> 06:26.120
being a memory safe language and having a available cryptographic libraries and also cross

06:26.120 --> 06:31.640
compilation for Android, as well as being able to run on embedded targets. So that was the part of

06:31.640 --> 06:37.880
the impetus. There, just an overview of going from Python to Rust, getting rid of the circular

06:37.880 --> 06:45.240
dependencies, making it easier to test and scale. So the initial implementation there is on GitHub.

06:45.240 --> 06:51.720
This is just an outline of the public modules for the library. The so far for the interfaces,

06:51.720 --> 06:58.920
there's TCP and UDP and Keonic is a frequency hopping radio. That's being developed.

06:58.920 --> 07:05.160
This while I'm on this in reticulum, the connections between pairs are links that would be

07:06.040 --> 07:11.800
the upper right there and destinations are basically your addresses.

07:12.200 --> 07:20.360
One reticulum node is going to have to handle a lot of connections and IO from multiple sources

07:20.360 --> 07:25.400
depending on how many interfaces you're running. So for example, here is the, I believe this is

07:25.400 --> 07:33.080
from the UDP interface. So receiving data on the socket as well as sending data out at the bottom

07:33.080 --> 07:38.760
there. Each of these are going to be running in separate tasks. So the Python implementation does

07:38.840 --> 07:45.560
not use async whereas with Rust, we settle on using the async runtime. So that fits pretty well

07:46.440 --> 07:52.920
for helping the scale to async and having both input and output at the same time allows you to

07:52.920 --> 07:58.440
interleave that very well and makes it very efficient. But also I have to do packet routing at the same

07:58.440 --> 08:03.880
time, checking whether the packet needs to be forwarded or if it needs to be hand locally.

08:04.120 --> 08:10.440
Yeah, managing peer sessions so keeping track of the state of your links which are the connections

08:10.440 --> 08:16.520
to peers. So in Rust syntax, I think I don't really program JavaScript, but I think it's similar.

08:16.520 --> 08:24.040
We have the awake keyword are the async methods and link management is another example of

08:24.040 --> 08:29.160
something that needs to be done concurrently. So here, yeah, actually there's not too much to show here,

08:29.160 --> 08:33.880
but yeah. As far as the difference in the architecture goes between Python and the Rust

08:33.880 --> 08:40.040
implementation, the Python implementation, the like the public facing API is going to be using

08:40.040 --> 08:48.120
callbacks mostly for when data comes in and you want to read the message and reply as one example.

08:48.120 --> 08:52.520
That makes that means you have to go through setting up so for the destination when the

08:52.520 --> 08:56.360
connection gets established. You need to set a callback first for when it gets established.

08:57.320 --> 09:02.120
When it gets established, can you just set another callback for when the data comes in and then

09:02.120 --> 09:08.280
that's at the top there and even more like if you wanted to do something when the link drops,

09:08.280 --> 09:13.640
you'd have to set another callback there. Whereas with the Rust implementation, we're just going

09:13.640 --> 09:20.680
to have channels here. So you just subscribe to broadcast channel and this is also an async channel.

09:20.680 --> 09:25.160
It works well with async runtime and you're able to just wait for events and then

09:25.160 --> 09:30.440
depending on what it then happened and you can proceed from there. So yeah, I think Rust is also

09:30.440 --> 09:35.640
pretty well known at this point. It's been around for a while and it's fairly popular. Going from

09:35.640 --> 09:41.640
Python, which is not necessarily typed, there's a gradual types or type hinting available,

09:41.640 --> 09:46.680
but at least in the Python or a particular library, it's not really used. Moving to Rust,

09:46.680 --> 09:50.600
the type system helps quite a bit with making sure things are correct. These are just some of the

09:51.560 --> 09:57.080
design patterns that Rust allows with its types of systems. From the from the

09:57.080 --> 10:03.160
reticulum RS implementation at the top here, you have a few different, it's like a state machine.

10:04.520 --> 10:08.440
Depending on what state you're in, you're going to have a separate type. So it prevents errors

10:08.440 --> 10:14.040
whereas, for example, if you're just dealing with raw, does cipher text or something like that.

10:14.040 --> 10:18.040
And this is also an example of the new type pattern. So it's just a very light

10:18.120 --> 10:22.440
struck, wrapping some data. It's a little bit confusing because of the lifetimes,

10:22.440 --> 10:27.480
but the main thing to note is just the, it's a struck wrapping and array of bytes.

10:29.960 --> 10:34.360
The builder interface pattern actually, I don't think it's used in reticulum RS right now.

10:34.360 --> 10:40.200
You'd probably run into it like when you're initializing the logger and if you have some

10:40.200 --> 10:47.160
types, for example, in the Rust RS implementation, you have destinations and the parameterized by

10:48.200 --> 10:55.800
different types. And this allows you to, for example, have a type of method overloadings.

10:55.800 --> 10:59.880
Rust doesn't have method overloading, but it has a trade systems, you're able to

11:00.760 --> 11:05.240
depending on which type you plug in to these different type parameters. You can overload what the

11:05.240 --> 11:17.720
trade implementation does. So the benchmarks are not too surprising. The base number

11:17.720 --> 11:24.040
usage, going from Python to Rust was from 30 megabytes to four megabytes. I think that's pretty

11:24.040 --> 11:30.280
typical. And on the CPU task block from 51 milliseconds to four. And this is just like a basic

11:30.280 --> 11:36.360
curve test on Linux. The current state of the implementation, we have identity links,

11:36.360 --> 11:41.640
transport and channels are working progress. And the roadmap is getting this able to run in embedded

11:41.640 --> 11:46.680
environment. That's going to be a large one, configuring interfaces. So right now the Python

11:46.680 --> 11:52.520
implementation has a configuration format, like it has a, it's not tumble. It's similar to

11:52.520 --> 11:56.840
tumble. So there's some work being done right now on converting that to tumble. So it'll be standardized.

11:56.840 --> 12:03.240
And then maybe make that readable by the reticulum RS implementation. Another feature of the

12:03.240 --> 12:08.040
Python implementation that is missing in Rust right now is resources, which is a method for

12:08.040 --> 12:11.480
sending large files and key ratcheting. So that's the forward secrecy part.

12:11.480 --> 12:18.440
Yeah, I think embedded right, getting this on embedded is going to be one of the main challenges.

12:18.440 --> 12:23.240
So we have been running it on micro processor, small and micro processors, but to get it into

12:24.600 --> 12:31.480
the very smallest micro controllers will require some some rewriting. And there are available

12:31.480 --> 12:37.080
pacing runtimes. There are two that I'm aware of, which is the embassy and RTSC.

12:37.320 --> 12:42.760
Run times. It's sounding, yeah, embassy is more complete, but I'm not sure yet. So I think there's

12:42.760 --> 12:48.200
still remains challenges with concurrency in Rust. Even though it has memory safety and you avoid

12:48.200 --> 12:54.360
a lot of the pitfalls of CNC+. You can still run it to issues like deadlocks. So doing that

12:54.360 --> 12:59.320
correctly is going to be a challenge. As far as, because this is so motivated by performance,

12:59.320 --> 13:05.000
I'm not sure yet how profiling will be on Asik. So I've used, I've done profiling for rest,

13:05.000 --> 13:10.840
but not with the Asik runtime. Yeah, that'll be seen. And maintaining compatibility with the Python

13:10.840 --> 13:16.600
implementation. So we're testing against the Python reference implementation, but as that develops,

13:16.600 --> 13:23.480
it's, I think it's in 1.0 now, within last year. So hopefully it's relatively stable, but we'll

13:23.480 --> 13:30.360
want to maintain compatibility going forward. Some of the applications that we've been testing with.

13:30.440 --> 13:38.360
So this is a VPN application using virtual ton interface on Linux. And that allows you to basically

13:38.360 --> 13:42.840
route just at your standard TCP IP applications over a particular.

13:45.560 --> 13:51.240
Another application that we've been working on is using your particular with drones. So

13:51.240 --> 13:56.200
Mavlink is a standard for communication with drones. And this is what we've been testing on the

13:56.280 --> 14:07.000
SDM32 microprocessor with the Octolinics. We also have some development on a messenger for Android.

14:08.440 --> 14:15.480
And I think I'll leave it there for, yeah, GitHub repo link is there. If you want to reach out,

14:15.480 --> 14:26.120
there's email there. And that's it. Yeah. All right, we have time for a few questions.

14:26.120 --> 14:29.320
Here we go. I see a hand up here. And then I think there was a question here. Okay.

14:34.120 --> 14:39.640
Hi. Thank you for your talk. It's very interesting to see a rest implementation of

14:39.640 --> 14:45.480
the node and reticulum. I wanted to actually two questions. One is, do you plan to support

14:45.480 --> 14:51.960
our node on the URL as well? And the second one is that we did this be a different kind of

14:52.600 --> 14:58.600
compatible implementation with reticulum or since Markivist has altered public development,

14:58.600 --> 15:05.160
you're going to try to take over or continue his lineage. So you said the first part was about

15:05.240 --> 15:09.160
Laura, right, correct. So Laura, there is not currently as you saw. There was not currently

15:09.160 --> 15:13.800
at interface. As far as I know, it's not on me. It's not on a roadmap for me, but it's open source.

15:13.800 --> 15:17.240
So hopefully somebody can contribute. It's not very hard to implement the interfaces. And then,

15:17.240 --> 15:23.160
sorry, what was the second part of the question they did? I'm sorry. Yeah. Actually,

15:23.160 --> 15:28.600
partially answered this second question as well. This second question was, does it mean to be

15:28.680 --> 15:34.680
protocol compatible with the Python version or will be, since the Markivist has altered

15:34.680 --> 15:41.160
public development of the Python one, if you're going to take over his lineage. So you're referring

15:41.160 --> 15:47.000
to like, where recently he's stopped. It's like a mirror now. Yeah, it was expected somehow because

15:47.000 --> 15:54.200
already announced that I believe one year ago or something, they was completely tired. Was your question

15:54.280 --> 15:58.280
are we going to be taking that over? Yeah, something like, would you really implement the

15:58.280 --> 16:04.920
full stacking in Rust or just something like two separate implementations that are compatible

16:04.920 --> 16:09.400
each other? Right. Basically, two separate implementations that are compatible with each other.

16:09.400 --> 16:15.560
Right now, the Rust implementation is about 5,000 lines, whereas the Python has about 30,000 lines.

16:15.560 --> 16:19.640
So there's still quite a bit to do. We've just basically implemented what's necessary to get it working.

16:19.800 --> 16:27.960
So yeah. Thank you very much for your work. What were the biggest things you learned about

16:27.960 --> 16:36.120
reticulum, which were not documented anywhere, while you plotted it to Rust? So I'm not sure

16:36.120 --> 16:41.160
exactly specifically, but I remember mentioning 55,000 nodes or something with fit and like a

16:41.160 --> 16:45.880
megabyte or something like that. And then I tried doing the math on that, because I saw that

16:45.880 --> 16:51.480
comment in the code, and I looked at the like the path table. The sizes didn't really match up,

16:51.480 --> 16:55.000
so I don't know if that's still true. So that was just something that came out when I was looking

16:55.000 --> 17:03.320
at the code. So yeah. I've actually worked more on the application side, so I've contributed

17:03.320 --> 17:08.360
like an interface and I do like code review for the reticulum RS code, but I work closely on the

17:09.320 --> 17:17.320
application. Another question, reticulum 1.1-3, now depends on LXMF to do stamp verification

17:17.320 --> 17:23.400
for announced interfaces. Do you think it's a good idea that there's a circular dependency

17:23.400 --> 17:31.880
now between R and S and LXMF? So XMF is like the messaging? Yes, and LXM, LX stamp is what does the

17:31.880 --> 17:37.320
proof of work, and now in the newest release R and S depends on LXMF.

17:38.360 --> 17:41.960
Okay, yeah, it's a good point. I'm not too familiar with it, so I couldn't real say.

17:41.960 --> 17:48.200
Yep. All right, and if you're other questions, feel free to talk to him after, but we are

17:48.200 --> 17:51.080
going to keep things moving along now. Let's give another round of applause, everyone.

17:56.280 --> 18:00.200
Thank you very much. All right, we're going to get set up for the next talk now. Give us

18:00.200 --> 18:04.120
just like one minute, and we'll get going again. Okay, we'll be in there.

