<linkrel="index"title="Index"href="genindex.html"><linkrel="search"title="Search"href="search.html"><linkrel="next"title="Communications Hardware"href="hardware.html"><linkrel="prev"title="Using Reticulum on Your System"href="using.html">
<spanid="understanding-main"></span><h1>Understanding Reticulum<aclass="headerlink"href="#understanding-reticulum"title="Link to this heading">¶</a></h1>
<p>The primary motivation for designing and implementing Reticulum has been the current lack of
reliable, functional and secure minimal-infrastructure modes of digital communication. It is my
belief that it is highly desirable to create a reliable and efficient way to set up long-range digital
communication networks that can securely allow exchange of information between people and
machines, with no central point of authority, control, censorship or barrier to entry.</p>
<p>Almost all of the various networking systems in use today share a common limitation: They
require large amounts of coordination and centralised trust and power to function. To join such networks, you need approval
of gatekeepers in control. This need for coordination and trust inevitably leads to an environment of
central control, where it’s very easy for infrastructure operators or governments to control or alter
traffic, and censor or persecute unwanted actors. It also makes it completely impossible to freely deploy
and use networks at will, like one would use other common tools that enhance individual agency and freedom.</p>
<p>Reticulum aims to require as little coordination and trust as possible. It aims to make secure,
anonymous and permissionless networking and information exchange a tool that anyone can just pick up and use.</p>
<p>Since Reticulum is completely medium agnostic, it can be used to build networks on whatever is best
suited to the situation, or whatever you have available. In some cases, this might be packet radio
links over VHF frequencies, in other cases it might be a 2.4 GHz
network using off-the-shelf radios, or it might be using common LoRa development boards.</p>
<p>At the time of release of this document, the fastest and easiest setup for development and testing is using
LoRa radio modules with an open source firmware (see the section <aclass="reference internal"href="#understanding-referencesystem"><spanclass="std std-ref">Reference Setup</span></a>),
connected to any kind of computer or mobile device that Reticulum can run on.</p>
<p>The ultimate aim of Reticulum is to allow anyone to be their own network operator, and to make it
cheap and easy to cover vast areas with a myriad of independent, interconnectable and autonomous networks.
Reticulum <strong>is not</strong><em>one network</em>, it <strong>is a tool</strong> to build <em>thousands of networks</em>. Networks without
kill-switches, surveillance, censorship and control. Networks that can freely interoperate, associate and disassociate
with each other, and require no central oversight. Networks for human beings. <em>Networks for the people</em>.</p>
<p>To be as widely usable and efficient to deploy as possible, the following goals have been used to
guide the design of Reticulum:</p>
<ulclass="simple">
<li><dlclass="simple">
<dt><strong>Fully useable as open source software stack</strong></dt><dd><p>Reticulum must be implemented with, and be able to run using only open source software. This is
critical to ensuring the availability, security and transparency of the system.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Hardware layer agnosticism</strong></dt><dd><p>Reticulum must be fully hardware agnostic, and shall be useable over a wide range of
physical networking layers, such as data radios, serial lines, modems, handheld transceivers,
wired Ethernet, WiFi, or anything else that can carry a digital data stream. Hardware made for
dedicated Reticulum use shall be as cheap as possible and use off-the-shelf components, so
it can be easily modified and replicated by anyone interested in doing so.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Very low bandwidth requirements</strong></dt><dd><p>Reticulum should be able to function reliably over links with a transmission capacity as low
as <em>5 bits per second</em>.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Encryption by default</strong></dt><dd><p>Reticulum must use strong encryption by default for all communication.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Initiator Anonymity</strong></dt><dd><p>It must be possible to communicate over a Reticulum network without revealing any identifying
information about oneself.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Unlicensed use</strong></dt><dd><p>Reticulum shall be functional over physical communication mediums that do not require any
form of license to use. Reticulum must be designed in a way, so it is usable over ISM radio
frequency bands, and can provide functional long distance links in such conditions, for example
by connecting a modem to a PMR or CB radio, or by using LoRa or WiFi modules.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Supplied software</strong></dt><dd><p>In addition to the core networking stack and API, that allows a developer to build
applications with Reticulum, a basic set of Reticulum-based communication tools must be
implemented and released along with Reticulum itself. These shall serve both as a
functional, basic communication suite, and as an example and learning resource to others wishing
to build applications with Reticulum.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Ease of use</strong></dt><dd><p>The reference implementation of Reticulum is written in Python, to make it easy to use
and understand. A programmer with only basic experience should be able to use
Reticulum to write networked applications.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Low cost</strong></dt><dd><p>It shall be as cheap as possible to deploy a communication system based on Reticulum. This
should be achieved by using cheap off-the-shelf hardware that potential users might already
own. The cost of setting up a functioning node should be less than $100 even if all parts
<spanid="understanding-basicfunctionality"></span><h2>Introduction & Basic Functionality<aclass="headerlink"href="#introduction-basic-functionality"title="Link to this heading">¶</a></h2>
<p>Reticulum is a networking stack suited for high-latency, low-bandwidth links. Reticulum is at its
core a <em>message oriented</em> system. It is suited for both local point-to-point or point-to-multipoint
scenarios where all nodes are within range of each other, as well as scenarios where packets need
to be transported over multiple hops in a complex network to reach the recipient.</p>
<p>Reticulum does away with the idea of addresses and ports known from IP, TCP and UDP. Instead
Reticulum uses the singular concept of <em>destinations</em>. Any application using Reticulum as its
networking stack will need to create one or more destinations to receive data, and know the
destinations it needs to send data to.</p>
<p>All destinations in Reticulum are _represented_ as a 16 byte hash. This hash is derived from truncating a full
SHA-256 hash of identifying characteristics of the destination. To users, the destination addresses
will be displayed as 16 hexadecimal bytes, like this example: <codeclass="docutils literal notranslate"><spanclass="pre"><13425ec15b621c1d928589718000d814></span></code>.</p>
<p>The truncation size of 16 bytes (128 bits) for destinations has been chosen as a reasonable trade-off
between address space
and packet overhead. The address space accommodated by this size can support many billions of
simultaneously active devices on the same network, while keeping packet overhead low, which is
essential on low-bandwidth networks. In the very unlikely case that this address space nears
congestion, a one-line code change can upgrade the Reticulum address space all the way up to 256
bits, ensuring the Reticulum address space could potentially support galactic-scale networks.
This is obviously complete and ridiculous over-allocation, and as such, the current 128 bits should
be sufficient, even far into the future.</p>
<p>By default Reticulum encrypts all data using elliptic curve cryptography and AES. Any packet sent to a
destination is encrypted with a per-packet derived key. Reticulum can also set up an encrypted
channel to a destination, called a <em>Link</em>. Both data sent over Links and single packets offer
<em>Initiator Anonymity</em>. Links additionally offer <em>Forward Secrecy</em> by default, employing an Elliptic Curve
Diffie Hellman key exchange on Curve25519 to derive per-link ephemeral keys. Asymmetric, link-less
packet communication can also provide forward secrecy, with automatic key ratcheting, by enabling
ratchets on a per-destination basis. The multi-hop transport, coordination, verification and reliability
layers are fully autonomous and also based on elliptic curve cryptography.</p>
<p>Reticulum also offers symmetric key encryption for group-oriented communications, as well as
unencrypted packets for local broadcast purposes.</p>
<p>Reticulum can connect to a variety of interfaces such as radio modems, data radios and serial ports,
and offers the possibility to easily tunnel Reticulum traffic over IP links such as the Internet or
<spanid="understanding-destinationnaming"></span><h4>Destination Naming<aclass="headerlink"href="#destination-naming"title="Link to this heading">¶</a></h4>
<p>Destinations are created and named in an easy to understand dotted notation of <em>aspects</em>, and
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 128 bits. The
top level aspect should always be a unique identifier for the application using the destination.
The next levels of aspects can be defined in any way by the creator of the application.</p>
<p>Aspects can be as long and as plentiful as required, and a resulting long destination name will not
impact efficiency, as names are always represented as truncated SHA-256 hashes on the network.</p>
<p>As an example, a destination for a environmental monitoring application could be made up of the
application name, a device type and measurement type, like this:</p>
<divclass="highlight-text notranslate"><divclass="highlight"><pre><span></span>app name : environmentlogger
aspects : remotesensor, temperature
full name : environmentlogger.remotesensor.temperature
hash : 4faf1b2e0a077e6a9d92fa051f256038
</pre></div>
</div>
<p>For the <em>single</em> destination, Reticulum will automatically append the associated public key as a
destination aspect before hashing. This is done to ensure only the correct destination is reached,
since anyone can listen to any destination name. Appending the public key ensures that a given
packet is only directed at the destination that holds the corresponding private key to decrypt the
packet.</p>
<p><strong>Take note!</strong> There is a very important concept to understand here:</p>
<ulclass="simple">
<li><p>Anyone can use the destination name <codeclass="docutils literal notranslate"><spanclass="pre">environmentlogger.remotesensor.temperature</span></code></p></li>
<li><p>Each destination that does so will still have a unique destination hash, and thus be uniquely
addressable, because their public keys will differ.</p></li>
</ul>
<p>In actual use of <em>single</em> destination naming, it is advisable not to use any uniquely identifying
features in aspect naming. Aspect names should be general terms describing what kind of destination
is represented. The uniquely identifying aspect is always achieved by appending the public key,
which expands the destination into a uniquely identifiable one. Reticulum does this automatically.</p>
<p>Any destination on a Reticulum network can be addressed and reached simply by knowing its
destination hash (and public key, but if the public key is not known, it can be requested from the
network simply by knowing the destination hash). The use of app names and aspects makes it easy to
structure Reticulum programs and makes it possible to filter what information and data your program
receives.</p>
<p>To recap, the different destination types should be used in the following situations:</p>
<ulclass="simple">
<li><dlclass="simple">
<dt><strong>Single</strong></dt><dd><p>When private communication between two endpoints is needed. Supports multiple hops.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Group</strong></dt><dd><p>When private communication between two or more endpoints is needed. Supports multiple hops
indirectly, but must first be established through a <em>single</em> destination.</p>
</dd>
</dl>
</li>
<li><dlclass="simple">
<dt><strong>Plain</strong></dt><dd><p>When plain-text communication is desirable, for example when broadcasting information, or for local discovery purposes.</p>
</dd>
</dl>
</li>
</ul>
<p>To communicate with a <em>single</em> destination, you need to know its public key. Any method for
obtaining the public key is valid, but Reticulum includes a simple mechanism for making other
nodes aware of your destinations public key, called the <em>announce</em>. It is also possible to request
an unknown public key from the network, as all transport instances serve as a distributed ledger
of public keys.</p>
<p>Note that public key information can be shared and verified in other ways than using the
built-in <em>announce</em> functionality, and that it is therefore not required to use the <em>announce</em> and <em>path request</em>
functionality to obtain public keys. It is by far the easiest though, and should definitely be used
if there is not a very good reason for doing it differently.</p>
<spanid="understanding-keyannouncements"></span><h3>Public Key Announcements<aclass="headerlink"href="#public-key-announcements"title="Link to this heading">¶</a></h3>
<p>Currently, Reticulum distinguishes between two types of network nodes. All nodes on a Reticulum network
are <em>Reticulum Instances</em>, and some are also <em>Transport Nodes</em>. If a system running Reticulum is fixed in
one place, and is intended to be kept available most of the time, it is a good contender to be a <em>Transport Node</em>.</p>
<p>Any Reticulum Instance can become a Transport Node by enabling it in the configuration.
This distinction is made by the user configuring the node, and is used to determine what nodes on the
network will help forward traffic, and what nodes rely on other nodes for wider connectivity.</p>
<p>If a node is an <em>Instance</em> it should be given the configuration directive <codeclass="docutils literal notranslate"><spanclass="pre">enable_transport</span><spanclass="pre">=</span><spanclass="pre">No</span></code>, which
is the default setting.</p>
<p>If it is a <em>Transport Node</em>, it should be given the configuration directive <codeclass="docutils literal notranslate"><spanclass="pre">enable_transport</span><spanclass="pre">=</span><spanclass="pre">Yes</span></code>.</p>
<spanid="understanding-announce"></span><h3>The Announce Mechanism in Detail<aclass="headerlink"href="#the-announce-mechanism-in-detail"title="Link to this heading">¶</a></h3>
<spanid="understanding-paths"></span><h3>Reaching the Destination<aclass="headerlink"href="#reaching-the-destination"title="Link to this heading">¶</a></h3>
<p>In networks with changing topology and trustless connectivity, nodes need a way to establish
<em>verified connectivity</em> with each other. Since the network is assumed to be trustless, Reticulum
must provide a way to guarantee that the peer you are communicating with is actually who you
expect. Reticulum offers two ways to do this.</p>
<p>For exchanges of small amounts of information, Reticulum offers the <em>Packet</em> API, which works exactly like you would expect - on a per packet level. The following process is employed when sending a packet:</p>
<ul>
<li><divclass="line-block">
<divclass="line">A packet is always created with an associated destination and some payload data. When the packet is sent
to a <em>single</em> destination type, Reticulum will automatically create an ephemeral encryption key, perform
an ECDH key exchange with the destination’s public key (or ratchet key, if available), and encrypt the information.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">It is important to note that this key exchange does not require any network traffic. The sender already
knows the public key of the destination from an earlier received <em>announce</em>, and can thus perform the ECDH
key exchange locally, before sending the packet.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">The public part of the newly generated ephemeral key-pair is included with the encrypted token, and sent
along with the encrypted payload data in the packet.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">When the destination receives the packet, it can itself perform an ECDH key exchange and decrypt the
packet.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">A new ephemeral key is used for every packet sent in this way.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">Once the packet has been received and decrypted by the addressed destination, that destination can opt
to <em>prove</em> its receipt of the packet. It does this by calculating the SHA-256 hash of the received packet,
and signing this hash with its Ed25519 signing key. Transport nodes in the network can then direct this
<em>proof</em> back to the packets origin, where the signature can be verified against the destination’s known
public signing key.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">In case the packet is addressed to a <em>group</em> destination type, the packet will be encrypted with the
destination type, the payload data will not be encrypted. Neither of these two destination types can offer
forward secrecy. In general, it is recommended to always use the <em>single</em> destination type, unless it is
strictly necessary to use one of the others.</div>
</div>
</li>
</ul>
<p>For exchanges of larger amounts of data, or when longer sessions of bidirectional communication is desired, Reticulum offers the <em>Link</em> API. To establish a <em>link</em>, the following process is employed:</p>
<ul>
<li><divclass="line-block">
<divclass="line">First, the node that wishes to establish a link will send out a special packet, that
traverses the network and locates the desired destination. Along the way, the Transport Nodes that
forward the packet will take note of this <em>link request</em>.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">Second, if the destination accepts the <em>link request</em> , it will send back a packet that proves the
authenticity of its identity (and the receipt of the link request) to the initiating node. All
nodes that initially forwarded the packet will also be able to verify this proof, and thus
accept the validity of the <em>link</em> throughout the network.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">When the validity of the <em>link</em> has been accepted by forwarding nodes, these nodes will
remember the <em>link</em> , and it can subsequently be used by referring to a hash representing it.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">As a part of the <em>link request</em>, an Elliptic Curve Diffie-Hellman key exchange takes place, that sets up an
efficiently encrypted tunnel between the two nodes. As such, this mode of communication is preferred,
even for situations when nodes can directly communicate, when the amount of data to be exchanged numbers
in the tens of packets, or whenever the use of the more advanced API functions is desired.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">When a <em>link</em> has been set up, it automatically provides message receipt functionality, through
the same <em>proof</em> mechanism discussed before, so the sending node can obtain verified confirmation
that the information reached the intended recipient.</div>
</div>
</li>
<li><divclass="line-block">
<divclass="line">Once the <em>link</em> has been set up, the initiator can remain anonymous, or choose to authenticate towards
the destination using a Reticulum Identity. This authentication is happening inside the encrypted
link, and is only revealed to the verified destination, and no intermediaries.</div>
</div>
</li>
</ul>
<p>In a moment, we will discuss the details of how this methodology is
implemented, but let’s first recap what purposes this methodology serves. We
first ensure that the node answering our request is actually the one we want to
communicate with, and not a malicious actor pretending to be so. At the same
time we establish an efficient encrypted channel. The setup of this is
relatively cheap in terms of bandwidth, so it can be used just for a short
exchange, and then recreated as needed, which will also rotate encryption keys.
The link can also be kept alive for longer periods of time, if this is more
suitable to the application. The procedure also inserts the <em>link id</em> , a hash
calculated from the link request packet, into the memory of forwarding nodes,
which means that the communicating nodes can thereafter reach each other simply
by referring to this <em>link id</em>.</p>
<p>The combined bandwidth cost of setting up a link is 3 packets totalling 297 bytes (more info in the
<aclass="reference internal"href="#understanding-packetformat"><spanclass="std std-ref">Binary Packet Format</span></a> section). The amount of bandwidth used on keeping
a link open is practically negligible, at 0.45 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 96% channel capacity for actual data.</p>
<p>For exchanging small amounts of data over a Reticulum network, the <aclass="reference internal"href="reference.html#api-packet"><spanclass="std std-ref">Packet</span></a> interface
is sufficient, but for exchanging data that would require many packets, an efficient way to coordinate
the transfer is needed.</p>
<p>This is the purpose of the Reticulum <aclass="reference internal"href="reference.html#api-resource"><spanclass="std std-ref">Resource</span></a>. A <em>Resource</em> can automatically
handle the reliable transfer of an arbitrary amount of data over an established <aclass="reference internal"href="reference.html#api-link"><spanclass="std std-ref">Link</span></a>.
Resources can auto-compress data, will handle breaking the data into individual packets, sequencing
the transfer, integrity verification and reassembling the data on the other end.</p>
<p><aclass="reference internal"href="reference.html#api-resource"><spanclass="std std-ref">Resources</span></a> are programmatically very simple to use, and only requires a few lines
of codes to reliably transfer any amount of data. They can be used to transfer data stored in memory,
<spanid="understanding-protocolspecifics"></span><h2>Protocol Specifics<aclass="headerlink"href="#protocol-specifics"title="Link to this heading">¶</a></h2>
<p>Reticulum can create named virtual networks, and networks that are only accessible by knowing a preshared
passphrase. The configuration of this is detailed in the <aclass="reference internal"href="interfaces.html#interfaces-options"><spanclass="std std-ref">Common Interface Options</span></a>
section. To implement these feature, Reticulum uses the concept of Interface Access Codes, that are calculated
and verified per packet.</p>
<p>An interface with a named virtual network or passphrase authentication enabled will derive a shared Ed25519
signing identity, and for every outbound packet generate a signature of the entire packet. This signature is
then inserted into the packet as an Interface Access Code before transmission. Depending on the speed and
capabilities of the interface, the IFAC can be the full 512-bit Ed25519 signature, or a truncated version.
Configured IFAC length can be inspected for all interfaces with the <codeclass="docutils literal notranslate"><spanclass="pre">rnstatus</span></code> utility.</p>
<p>Upon receipt, the interface will check that the signature matches the expected value, and drop the packet if it
does not. This ensures that only packets sent with the correct naming and/or passphrase parameters are allowed to
<spanid="understanding-announcepropagation"></span><h3>Announce Propagation Rules<aclass="headerlink"href="#announce-propagation-rules"title="Link to this heading">¶</a></h3>
<p>See the <aclass="reference internal"href="interfaces.html#interfaces-modes"><spanclass="std std-ref">Interface Modes</span></a> section for a conceptual overview
of the different interface modes, and how they are configured.</p>
<spanid="understanding-primitives"></span><h3>Cryptographic Primitives<aclass="headerlink"href="#cryptographic-primitives"title="Link to this heading">¶</a></h3>
primitives are provided by <aclass="reference external"href="https://www.openssl.org/">OpenSSL</a> (via the <aclass="reference external"href="https://github.com/pyca/cryptography">PyCA/cryptography</a>
package). The hashing functions <codeclass="docutils literal notranslate"><spanclass="pre">SHA-256</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">SHA-512</span></code> are provided by the standard
Python <aclass="reference external"href="https://docs.python.org/3/library/hashlib.html">hashlib</a>. The <codeclass="docutils literal notranslate"><spanclass="pre">HKDF</span></code>, <codeclass="docutils literal notranslate"><spanclass="pre">HMAC</span></code>,
<codeclass="docutils literal notranslate"><spanclass="pre">Token</span></code> primitives, and the <codeclass="docutils literal notranslate"><spanclass="pre">PKCS7</span></code> padding function are always provided by the