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.