diff --git a/RNS/Transport.py b/RNS/Transport.py
index 398d09a..c5cb665 100755
--- a/RNS/Transport.py
+++ b/RNS/Transport.py
@@ -22,8 +22,6 @@ class Transport:
APP_NAME = "rnstransport"
- # TODO: Document the addition of random windows
- # and max local rebroadcasts.
PATHFINDER_M = 18 # Max hops
PATHFINDER_C = 2.0 # Decay constant
PATHFINDER_R = 1 # Retransmit retries
diff --git a/docs/Reticulum Manual.pdf b/docs/Reticulum Manual.pdf
index e61e007..3cc83c0 100644
Binary files a/docs/Reticulum Manual.pdf and b/docs/Reticulum Manual.pdf differ
diff --git a/docs/manual/_sources/understanding.rst.txt b/docs/manual/_sources/understanding.rst.txt
index 7c711e6..ecc106f 100644
--- a/docs/manual/_sources/understanding.rst.txt
+++ b/docs/manual/_sources/understanding.rst.txt
@@ -157,12 +157,16 @@ destinations. Reticulum uses three different basic destination types, and one sp
Destination Naming
^^^^^^^^^^^^^^^^^^
-Destinations are created and named in an easy to understand dotted notation of *aspects* , and
+Destinations are created and named in an easy to understand dotted notation of *aspects*, and
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 80 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. For example,
-a destination for a environmental monitoring application could be made up of the application name, a
-device type and measurement type, like this:
+The next levels of aspects can be defined in any way by the creator of the application.
+
+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.
+
+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:
.. code-block:: text
@@ -201,9 +205,8 @@ To recap, the different destination types should be used in the following situat
* **Single**
When private communication between two endpoints is needed. Supports multiple hops.
* **Group**
- When private communication between two or more endpoints is needed. More efficient in
- data usage than *single* destinations. Supports multiple hops indirectly, but must first be
- established through a *single* destination.
+ When private communication between two or more endpoints is needed. Supports multiple hops
+ indirectly, but must first be established through a *single* destination.
* **Plain**
When plain-text communication is desirable, for example when broadcasting information.
@@ -214,9 +217,9 @@ an unknown public key from the network, as all participating nodes serve as a di
of public keys.
Note that public key information can be shared and verified in many other ways than using the
-built-in methodology, and that it is therefore not required to use the announce/request functionality.
-It is by far the easiest though, and should definitely be used if there is not a good reason for
-doing it differently.
+built-in *announce* functionality, and that it is therefore not required to use the announce/request
+functionality to obtain public keys. It is by far the easiest though, and should definitely be used
+if there is not a good reason for doing it differently.
.. _understanding-keyannouncements:
@@ -235,7 +238,7 @@ contain the following information:
* The announcers public key
* Application specific data, in this case the users nickname and availability status
* A random blob, making each new announce unique
-* A signature of the above information, verifying authenticity
+* An Ed25519 signature of the above information, verifying authenticity
With this information, any Reticulum node that receives it will be able to reconstruct an outgoing
destination to securely communicate with that destination. You might have noticed that there is one
@@ -244,8 +247,9 @@ the aspect names of the destination. These are intentionally left out to save ba
will be implicit in almost all cases. If a destination name is not entirely implicit, information can be
included in the application specific data part that will allow the receiver to infer the naming.
-It is important to note that announcements will be forwarded throughout the network according to a
-certain pattern. This will be detailed later.
+It is important to note that announces will be forwarded throughout the network according to a
+certain pattern. This will be detailed in the section
+:ref:`The Announce Mechanism in Detail`.
Seeing how *single* destinations are always tied to a private/public key pair leads us to the next topic.
@@ -268,8 +272,8 @@ the identity first, and then link it to created destinations.
Building upon the simple messenger example, we could use an identity to represent the user of the
application. Destinations created will then be linked to this identity to allow communication to
-reach the user. In such a case it is of great importance to store the user’s identity securely and
-privately.
+reach the user. In all cases it is of great importance to store the private keys associated with any
+Reticulum Identity securely and privately.
.. _understanding-gettingfurther:
@@ -279,8 +283,9 @@ Getting Further
The above functions and principles form the core of Reticulum, and would suffice to create
functional networked applications in local clusters, for example over radio links where all interested
nodes can directly hear each other. But to be truly useful, we need a way to direct traffic over multiple
-hops in the network. In the next sections, two concepts that allow this will be introduced, *paths* and
-*links*.
+hops in the network.
+
+In the following sections, two concepts that allow this will be introduced, *paths* and *links*.
.. _understanding-transport:
@@ -298,85 +303,28 @@ useable over bandwidth-limited, high-latency links.
To overcome such challenges, Reticulum’s *Transport* system uses public-key cryptography to
implement the concept of *paths* that allow discovery of how to get information to a certain
-destination, and *resources* that help make reliable data transfer more efficient.
+destination. It is important to note that no single node in a Reticulum network knows the complete
+path to a destination. Every Transport node participating in a Reticulum network will only
+know what the most direct way to get a packet one hop closer to it's destination is.
-.. _understanding-paths:
+.. _understanding-announce:
-Reaching the Destination
-------------------------
+The Announce Mechanism in Detail
+--------------------------------
-In networks with changing topology and trustless connectivity, nodes need a way to establish
-*verified connectivity* 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.
-
-For exchanges of small amounts of information, Reticulum offers the *Packet* API, which works exactly like you would expect - on a per packet level. The following process is employed when sending a packet:
-
-* | A packet is always created with an associated destination and some payload data. When the packet is sent to a *single* destination type, Reticulum will automatically create an ephemeral encryption key, perform an ECDH key exchange with the destinations public key, and encrypt the information.
-
-* | 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 *announce*, and can thus perform the ECDH key exchange locally.
-
-* | The public key part of the newly generated ephemeral key is included with the encrypted token, and sent along with the encrypted payload data in the packet.
-
-* | When the destination receives the packet, it can itself perform an ECDH key exchange and decrypt the packet.
-
-* | A new ephemeral key is used for every packet sent in this way, and forward secrecy is guaranteed on a per packet level.
-
-* | In case the packet is addressed to a *group* destination type, the packet will be encrypted with the pre-shared AES-128 key associated with the destination. In case the packet is addressed to a *plain* destination type, the payload data will not be encrypted. Neither of these two destination types offer forward secrecy. In general, it is recommended to always use the *single* destination type, unless it is strictly necessary to use one of the others.
+When an *announce* is transmitted by a node, it will be forwarded by any node receiving it, but
+according to some specific rules:
-For exchanges of larger amounts of data, or when longer sessions of bidirectional communication is desired, Reticulum offers the *Link* API. To establish a *link*, the following process is employed:
+* | If this exact announce has already been received before, ignore it.
-* | 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 nodes that
- forward the packet will take note of this *link request*.
-
-* | Second, if the destination accepts the *link request* , it will send back a packet that proves the
- authenticity of it’s 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 *link* throughout the network.
-
-* | When the validity of the *link* has been accepted by forwarding nodes, these nodes will
- remember the *link* , and it can subsequently be used by referring to a hash representing it.
-
-* | As a part of the *link request* , a Diffie-Hellman key exchange takes place, that sets up an
- efficient symmetrically encrypted tunnel between the two nodes, using elliptic curve
- cryptography. 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.
-
-* | When a *link* has been set up, it automatically provides message receipt functionality, so the
- sending node can obtain verified confirmation that the information reached the intended
- recipient.
-
-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 *link id* , 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 *link id*.
-
-The total bandwidth cost of setting up a link is 409 bytes (more info in the :ref:`Binary Packet Format` section). The amount of bandwidth used on keeping a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
-
-Pathfinding in Detail
-^^^^^^^^^^^^^^^^^^^^^
-
-The pathfinding method builds on the *announce* functionality discussed earlier. When an announce
-is sent out by a node, it will be forwarded by any node receiving it, but according to some specific
-rules:
-
-
-* | If this announce has already been received before, ignore it.
-
-* | Record into a table which node the announce was received from, and how many times in
+* | If not, record into a table which node the announce was received from, and how many times in
total it has been retransmitted to get here.
* | If the announce has been retransmitted *m+1* times, it will not be forwarded. By default, *m* is
set to 18.
-* | The announce will be assigned a delay *d* = c\ :sup:`h` seconds, where *c* is a decay constant, by
- default 2, and *h* is the amount of times this packet has already been forwarded.
+* | The announce will be assigned a delay *d* = c\ :sup:`h` seconds, where *c* is a decay constant, and *h* is the amount of times this packet has already been forwarded.
* | The packet will be given a priority *p = 1/d*.
@@ -385,10 +333,11 @@ rules:
not utilized by other traffic, the announce will be forwarded.
* | If no other nodes are heard retransmitting the announce with a greater hop count than when
- it left this node, transmitting it will be retried *r* times. By default, *r* is set to 2. Retries follow
- same rules as above, with the exception that it must wait for at least *d* = c\ :sup:`h+1` + t seconds, ie.,
- the amount of time it would take the next node to retransmit the packet. By default, *t* is set to
- 10.
+ it left this node, transmitting it will be retried *r* times. By default, *r* is set to 1. Retries
+ follow same rules as above, with the exception that it must wait for at least *d* = c\ :sup:`h+1` +
+ t + rand(0, rw) seconds. This amount of time is equal to the amount of time it would take the next
+ node to retransmit the packet, plus a random window. By default, *t* is set to 10 seconds, and the
+ random window *rw* is set to 10 seconds.
* | If a newer announce from the same destination arrives, while an identical one is already in
the queue, the newest announce is discarded. If the newest announce contains different
@@ -407,14 +356,95 @@ distance of *Lavg =* 15 kilometers, an announce will be able to propagate outwar
kilometers in 34 minutes, and a *maximum announce radius* of 270 kilometers in approximately 3
days.
+.. _understanding-paths:
+
+Reaching the Destination
+------------------------
+
+In networks with changing topology and trustless connectivity, nodes need a way to establish
+*verified connectivity* 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.
+
+For exchanges of small amounts of information, Reticulum offers the *Packet* API, which works exactly like you would expect - on a per packet level. The following process is employed when sending a packet:
+
+* | A packet is always created with an associated destination and some payload data. When the packet is sent
+ to a *single* destination type, Reticulum will automatically create an ephemeral encryption key, perform
+ an ECDH key exchange with the destinations public key, and encrypt the information.
+
+* | 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 *announce*, and can thus perform the ECDH
+ key exchange locally, before sending the packet.
+
+* | 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.
+
+* | When the destination receives the packet, it can itself perform an ECDH key exchange and decrypt the
+ packet.
+
+* | A new ephemeral key is used for every packet sent in this way, and forward secrecy is guaranteed on a
+ per packet level.
+
+* | Once the packet has been received and decrypted by the addressed destination, that destination can opt
+ to *prove* its receipt of the packet. It does this by calculating the SHA-256 hash of the received packet,
+ and signing this hash with it's Ed25519 signing key. Transport nodes in the network can then direct this
+ *proof* back to the packets origin, where the signature can be verified against the destinations known
+ public signing key.
+
+* | In case the packet is addressed to a *group* destination type, the packet will be encrypted with the
+ pre-shared AES-128 key associated with the destination. In case the packet is addressed to a *plain*
+ destination type, the payload data will not be encrypted. Neither of these two destination types offer
+ forward secrecy. In general, it is recommended to always use the *single* destination type, unless it is
+ strictly necessary to use one of the others.
+
+
+For exchanges of larger amounts of data, or when longer sessions of bidirectional communication is desired, Reticulum offers the *Link* API. To establish a *link*, the following process is employed:
+
+* | 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 nodes that
+ forward the packet will take note of this *link request*.
+
+* | Second, if the destination accepts the *link request* , it will send back a packet that proves the
+ authenticity of it’s 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 *link* throughout the network.
+
+* | When the validity of the *link* has been accepted by forwarding nodes, these nodes will
+ remember the *link* , and it can subsequently be used by referring to a hash representing it.
+
+* | As a part of the *link request* , a Diffie-Hellman key exchange takes place, that sets up an
+ efficiently encrypted tunnel between the two nodes, using elliptic curve cryptography. 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.
+
+* | When a *link* has been set up, it automatically provides message receipt functionality, through
+ the same *proof* mechanism discussed before, so the sending node can obtain verified confirmation
+ that the information reached the intended recipient.
+
+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 *link id* , 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 *link id*.
+
+The combined bandwidth cost of setting up a link is 3 packets totalling 409 bytes (more info in the
+:ref:`Binary Packet Format` section). The amount of bandwidth used on keeping
+a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet
+radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
+
+
Link Establishment in Detail
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-After seeing how the conditions for finding a path through the network are created, we will now
-explore how two nodes can establish reliable communications over multiple hops. The *link* in
-Reticulum terminology should not be viewed as a direct node-to-node link on the physical layer, but
-as an abstract channel, that can be open for any amount of time, and can span an arbitrary number
-of hops, where information will be exchanged between two nodes.
+After exploring the basics of the announce mechanism, finding a path through the network, and an overview
+of the link establishment procedure, this section will go into greater detail about the Reticulum link
+establishment process.
+
+The *link* in Reticulum terminology should not be viewed as a direct node-to-node link on the
+physical layer, but as an abstract channel, that can be open for any amount of time, and can span
+an arbitrary number of hops, where information will be exchanged between two nodes.
* | When a node in the network wants to establish verified connectivity with another node, it
@@ -427,25 +457,25 @@ of hops, where information will be exchanged between two nodes.
considered as single public key for simplicity in this explanation.*
* | The *link request* is addressed to the destination hash of the desired destination, and
- contains the following data: The newly generated X25519 public key *LKi*. The contents
- are encrypted with the RSA public key of the destination and tramsitted over the network.
+ contains the following data: The newly generated X25519 public key *LKi*.
* | The broadcasted packet will be directed through the network according to the rules laid out
previously.
* | Any node that forwards the link request will store a *link id* in it’s *link table* , along with the
amount of hops the packet had taken when received. The link id is a hash of the entire link
- request packet. If the path is not *proven* within some set amount of time, the entry will be
- dropped from the *link table* again.
+ request packet. If the link request packet is not *proven* by the addressed destination within some
+ set amount of time, the entry will be dropped from the *link table* again.
-* | When the destination receives the link request packet, it will decrypt it and decide whether to
- accept the request. If it is accepted, the destination will also generate a new X25519 private/public
- key pair, and perform a Diffie Hellman Key Exchange, deriving a new symmetric key that will be used
- to encrypt the channel, once it has been established.
+* | When the destination receives the link request packet, it will decide whether to accept the request.
+ If it is accepted, the destination will also generate a new X25519 private/public key pair, and
+ perform a Diffie Hellman Key Exchange, deriving a new symmetric key that will be used to encrypt the
+ channel, once it has been established.
* | A *link proof* packet is now constructed and transmitted over the network. This packet is
addressed to the *link id* of the *link*. It contains the following data: The newly generated X25519
- public key *LKr* and an RSA-1024 signature of the *link id* and *LKr*.
+ public key *LKr* and an Ed25519 signature of the *link id* and *LKr* made by the signing key of
+ the addressed destination.
* | By verifying this *link proof* packet, all nodes that originally transported the *link request*
packet to the destination from the originator can now verify that the intended destination received
@@ -465,11 +495,6 @@ reveal any identifying information about itself. The link initiator remains comp
When using *links*, Reticulum will automatically verify all data sent over the link, and can also
automate retransmissions if *Resources* are used.
-Proven Delivery
-^^^^^^^^^^^^^^^
-
-TODO: Write
-
.. _understanding-resources:
Resources
diff --git a/docs/manual/index.html b/docs/manual/index.html
index 7d74524..4591372 100644
--- a/docs/manual/index.html
+++ b/docs/manual/index.html
@@ -69,6 +69,7 @@ the development of Reticulum itself.
diff --git a/docs/manual/searchindex.js b/docs/manual/searchindex.js
index 07b2761..3205bf9 100644
--- a/docs/manual/searchindex.js
+++ b/docs/manual/searchindex.js
@@ -1 +1 @@
-Search.setIndex({docnames:["examples","gettingstartedfast","index","reference","understanding","whatis"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["examples.rst","gettingstartedfast.rst","index.rst","reference.rst","understanding.rst","whatis.rst"],objects:{"RNS.Destination":{announce:[3,1,1,""],app_and_aspects_from_name:[3,1,1,""],clear_default_app_data:[3,1,1,""],create_keys:[3,1,1,""],decrypt:[3,1,1,""],encrypt:[3,1,1,""],full_name:[3,1,1,""],get_private_key:[3,1,1,""],hash:[3,1,1,""],hash_from_name_and_identity:[3,1,1,""],load_private_key:[3,1,1,""],set_default_app_data:[3,1,1,""],set_link_established_callback:[3,1,1,""],set_packet_callback:[3,1,1,""],set_proof_requested_callback:[3,1,1,""],set_proof_strategy:[3,1,1,""],sign:[3,1,1,""]},"RNS.Identity":{CURVE:[3,2,1,""],KEYSIZE:[3,2,1,""],TRUNCATED_HASHLENGTH:[3,2,1,""],decrypt:[3,1,1,""],encrypt:[3,1,1,""],from_bytes:[3,1,1,""],from_file:[3,1,1,""],full_hash:[3,1,1,""],get_private_key:[3,1,1,""],get_public_key:[3,1,1,""],get_random_hash:[3,1,1,""],load_private_key:[3,1,1,""],load_public_key:[3,1,1,""],recall:[3,1,1,""],recall_app_data:[3,1,1,""],sign:[3,1,1,""],to_file:[3,1,1,""],truncated_hash:[3,1,1,""],validate:[3,1,1,""]},"RNS.Link":{CURVE:[3,2,1,""],DEFAULT_TIMEOUT:[3,2,1,""],KEEPALIVE:[3,2,1,""],disable_encryption:[3,1,1,""],inactive_for:[3,1,1,""],no_inbound_for:[3,1,1,""],no_outbound_for:[3,1,1,""],set_packet_callback:[3,1,1,""],set_resource_callback:[3,1,1,""],set_resource_concluded_callback:[3,1,1,""],set_resource_started_callback:[3,1,1,""],set_resource_strategy:[3,1,1,""],teardown:[3,1,1,""]},"RNS.Packet":{ENCRYPTED_MDU:[3,2,1,""],PLAIN_MDU:[3,2,1,""],resend:[3,1,1,""],send:[3,1,1,""]},"RNS.PacketReceipt":{get_rtt:[3,1,1,""],get_status:[3,1,1,""],set_delivery_callback:[3,1,1,""],set_timeout:[3,1,1,""],set_timeout_callback:[3,1,1,""]},"RNS.Resource":{advertise:[3,1,1,""],cancel:[3,1,1,""],progress:[3,1,1,""]},"RNS.Reticulum":{should_allow_unencrypted:[3,1,1,""],should_use_implicit_proof:[3,1,1,""],transport_enabled:[3,1,1,""]},"RNS.Transport":{deregister_announce_handler:[3,1,1,""],has_path:[3,1,1,""],register_announce_handler:[3,1,1,""],request_path:[3,1,1,""]},RNS:{Destination:[3,0,1,""],Identity:[3,0,1,""],Link:[3,0,1,""],Packet:[3,0,1,""],PacketReceipt:[3,0,1,""],Resource:[3,0,1,""],Reticulum:[3,0,1,""],Transport:[3,0,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute"},terms:{"0":[0,3,4,5],"00":4,"000":[4,5],"00000000":4,"00000100":4,"00000111":4,"01":4,"01010000":4,"05":0,"1":[0,3,4,5],"10":[0,4],"100":[0,4],"1000":[0,4],"1024":[0,4],"11":4,"1200":4,"128":[4,5],"14":4,"141":4,"15":[3,4],"151":4,"18":4,"180":[3,4],"182":4,"2":[0,4],"20":[0,4],"205":[],"25":[0,5],"256":[3,4],"270":4,"2f":0,"3":[0,4,5],"323":[],"33":4,"34":4,"3600":0,"383":3,"3e12fc71692f8ec47bc5":1,"4":4,"409":[4,5],"430":4,"45":0,"477":[3,4],"5":[0,4],"500":[4,5],"512":3,"60":0,"62":[4,5],"7":4,"8":0,"80":[3,4],"80e29bf7cccaf31431b3":4,"86":4,"868":4,"900":4,"95":4,"abstract":4,"break":[4,5],"byte":[0,3,4,5],"case":[1,4],"class":[0,2,5],"default":[0,3,4],"do":[0,1,4,5],"float":[0,3],"function":[0,2,3,5],"import":[0,1,4],"int":0,"long":[0,4],"new":[0,3,4],"public":[0,2,3],"return":[0,3],"short":4,"static":3,"throw":3,"true":[0,3],"try":[0,2],"while":[0,3,4,5],A:[0,3,4,5],And:0,As:[3,4,5],At:4,Be:3,But:4,By:[0,4],For:[3,4],IN:[0,3],If:[0,1,3,4,5],In:[0,1,4,5],It:[0,3,4,5],No:[4,5],One:3,Or:4,That:4,The:[0,1,3,4,5],There:[4,5],These:4,To:[0,4,5],Will:3,With:4,_:4,__:4,______:4,_______:4,________:4,________________:4,__init__:0,__main__:0,__name__:0,_exit:0,ab:0,abl:[0,3,4],about:[0,3,4],abov:[1,4],accept:[3,4],accept_al:[0,3],accept_app:3,accept_non:3,access:[3,4],accord:4,accordingli:0,acheiv:4,achiev:[3,4],acknowledg:5,act:[3,4],action:0,activ:[0,3,4],actor:4,actual:[0,1,4],ad:[0,3,4,5],add:0,add_argu:0,addit:[4,5],addr1:4,addr2:4,address:[0,3,4,5],adress:[0,3,5],advantag:3,advertis:[0,3],advis:4,ae:[4,5],after:[0,4],again:[1,4],agent:4,agnost:4,agnostic:4,aim:[2,4],aliv:[3,4],all:[0,2,3,4,5],allow:[0,3,4,5],almost:4,along:[3,4],alreadi:[0,4],also:[0,3,4,5],alter:4,altern:0,although:5,alwai:[3,4],amateur:5,amount:[3,4,5],an:[0,1,3,4,5],ani:[0,1,3,4,5],announc:[2,3],announce_handl:0,announced_ident:[0,3],announceloop:0,announcesampl:0,anonym:4,anoth:[1,3,4],answer:4,anyon:[0,3,4],anyth:4,anywher:0,apart:4,api:[1,2,4,5],app:[0,3,4],app_and_aspects_from_nam:3,app_data:[0,3],app_nam:[0,3],app_timeout:0,append:[0,4],appli:4,applic:[0,3,4],approv:4,approxim:4,ar:[0,3,4,5],arbitrari:[3,4],arbritrari:5,area:5,arg:0,argon:0,argpars:0,argument:[0,3],argumentpars:0,around:4,arriv:[0,4],ask:[0,3],aspect:[0,3,4],aspect_filt:[0,3],assign:4,associ:[1,3,4],assum:4,asymmetr:5,attached_interfac:3,attribut:3,audit:5,authent:[4,5],author:4,auto:[3,4],auto_compress:3,autoconfigur:5,autom:4,automat:[0,3,4,5],autonom:4,autoomat:0,avail:[0,4,5],averag:4,avoid:4,awai:4,awar:4,ax:5,b:0,back:[0,4,5],band:4,bandwidth:[4,5],bare:0,barrier:4,base:[2,4,5],basi:[3,4,5],basic:[0,1,2],baud:4,becaus:4,becom:0,been:[0,3,4,5],befor:[0,3,4],begin:[0,3],begun:3,behind:4,being:4,belief:4,below:1,best:[1,4,5],beta:5,between:[0,3,4],bgp:4,bi:4,bidirect:4,binari:[0,2],bit:[3,4,5],blob:[0,4],both:[3,4,5],bp:4,briefli:4,broadcast:[2,3,4],broadcast_destin:0,broadcastloop:0,bug:5,build:[0,4,5],built:[1,4,5],bundl:0,c:[0,4],cad:4,calcul:4,call:[0,3,4,5],callabl:3,callback:[0,3],can:[0,1,2,3,4],cancel:3,cannot:0,capac:4,carambola:0,care:[3,4,5],carri:[3,4],carrier:5,caveat:2,cb:4,cbc:5,cd:1,censor:4,censorship:4,central:4,certain:[0,4],challeng:4,chang:[0,1,4,5],channel:[0,4,5],channelarg:0,chapter:[1,4],charact:0,characterist:4,cheap:4,check:0,checksum:[3,5],choos:0,chose:4,chunk:0,ciphertext:3,ciphertext_token:3,cl:0,clear:[0,3,4],clear_default_app_data:3,clear_screen:0,client:[0,1,3],client_connect:0,client_disconnect:0,client_loop:0,client_packet_receiv:0,client_request:0,clone:1,close:[0,3],cluster:4,code:[0,4],com:[0,1],come:4,command:[0,1],common:4,commun:[0,1,3,4,5],compat:4,complet:[0,1,3,4,5],compon:4,compos:4,compress:[0,3,4],comput:[1,4],concaten:3,concept:4,conclud:[0,3],concurr:4,condit:4,config:[0,1],configarg:0,configdir:3,configpath:0,configur:[0,3,4,5],confirm:[4,5],connect:[0,3,4,5],consequ:4,consid:[4,5],consist:4,constant:[3,4],construct:4,contact:4,contain:[0,3,4],content:4,context:[3,4],control:[0,3,4],conveni:0,convent:0,coordin:[3,4,5],core:[4,5],correct:[0,4],correctli:0,correspond:4,cost:[4,5],could:[0,3,4,5],count:4,counter:0,cover:5,cpu:0,creat:[0,1,3,4],create_kei:3,create_receipt:[0,3],creation:4,creator:4,critic:4,cryptograph:5,cryptographi:[1,4,5],ctrl:0,cull:3,current:[0,2,3,4],current_download:0,current_filenam:0,curv:[3,4,5],curve25519:[3,4,5],custom:4,d:4,daemon:3,dai:4,data:[0,3,4,5],date:0,debian:4,debug:3,decai:4,decid:[3,4],decod:0,decrypt:[3,4],dedic:4,def:0,default_timeout:3,defin:[0,4],definit:4,delai:4,deliv:[0,3],deliveri:[0,3,5],demand:3,demonstr:0,depend:1,deploi:4,deregist:3,deregister_announce_handl:3,deriv:[4,5],describ:[3,4],descript:0,design:[4,5],desir:[0,4],destin:[0,1,2],destination_1:0,destination_2:0,destination_clos:0,destination_hash:[0,3],destination_hexhash:0,detail:[0,3],detect:0,determin:[3,4],develop:[2,4],devic:[2,3,4],dh:3,did:0,differ:[0,1,3,4,5],diffi:[4,5],digit:[4,5],dir:0,direct:[0,3,4],directli:[3,4,5],directori:0,disable_encrypt:3,disappear:3,discard:4,disconnect:0,discoveri:4,discuss:4,disk:[0,3],displai:4,distanc:4,distinct:4,distribut:[0,3,4],divmod:0,document:4,doe:[0,2,3,4],don:[0,1],done:[0,4],dot:4,down:0,downgrad:3,download:0,download_began:0,download_conclud:0,download_finish:0,download_start:0,download_tim:0,driver:5,drop:4,duplex:[4,5],e:0,each:[0,4],earlier:4,eas:4,easi:[4,5],easiest:[1,4],easili:[4,5],ecdh:[4,5],echo:[1,2],echo_destin:0,echo_request:0,ed25519:5,effici:[0,4,5],ei:0,either:4,elif:0,ellipt:[3,4,5],els:[0,4],emploi:4,emptor:2,enabl:3,enable_transport:4,encapsul:5,encod:0,encrypt:[0,1,3,4,5],encrypted_mdu:3,encryptionless:3,end:[0,3,4,5],endpoint:[0,3,4],engin:4,ensur:4,enter:0,entir:4,entiti:4,entri:[0,4],enumer:0,environ:4,environment:4,environmentlogg:4,ephemer:[3,4,5],equal:4,equip:4,error:[0,3],essenti:4,establish:[0,3,5],ethernet:[4,5],even:[4,5],everi:[0,3,4],everyon:4,everyth:[0,4],exactli:[3,4],exampl:[1,2,3,4,5],example_util:0,exampleannouncehandl:0,exce:0,except:[0,4],exchang:[3,4,5],execut:[0,3],exhaust:4,exist:[0,4,5],exit:[0,1,3],exit_handl:0,expand:4,expect:[0,4],experi:[1,4],experiment:5,explain:3,explan:4,explicit:3,explicitli:3,explor:[0,4,5],expos:3,extend:[0,4],extern:[3,5],extrem:5,fa7ddfab5213f916dea:4,face:1,fact:[4,5],fail:[0,3],fals:[0,3],far:4,fast:2,featur:[4,5],feed:3,feedback:0,fernet:5,few:[4,5],field:4,file:[0,1,3,4,5],file_resourc:0,file_s:0,filelist:0,filelist_data:0,filelist_receiv:0,filelist_timeout_job:0,filenam:0,filetransf:[1,2,3],filter:[0,4],find:4,firmwar:4,first:[0,3,4],fit:0,five:0,fix:4,flag:[3,4],flush:0,folder:1,follow:[0,4,5],forcibl:3,foremost:5,form:[3,4],format:[0,2,5],forth:0,forward:[3,4,5],found:[0,1,4],free:5,frequenc:4,from:[0,1,3,4,5],from_byt:3,from_fil:3,fromhex:0,fruit:0,full:[3,4],full_hash:3,full_nam:3,fulli:[4,5],fundament:4,further:[1,2],futur:[3,4],g:0,ga:0,gatekeep:4,gener:[0,3,4,5],generalis:5,get:[0,2,3,5],get_private_kei:3,get_public_kei:3,get_random_hash:[0,3],get_rtt:[0,3],get_statu:3,gi:0,gigabyt:5,git:1,github:[0,1],give:4,given:4,global:[0,5],go:[0,1,4],goal:2,good:4,got:0,govern:4,grape:0,great:4,greater:4,group:[3,4],guarante:4,guid:[1,3,4],h:[1,4],ha:[0,3,4,5],had:4,half:[4,5],hand:0,handheld:4,handl:[0,3,4,5],handler:[0,3],happen:0,hardwar:[3,4,5],has_path:[0,3],hasattr:0,hash:[0,1,3,4],hash_from_name_and_ident:3,hashmap:0,have:[0,1,3,4],hazard:3,header:4,header_1:4,header_2:4,header_typ:3,hear:4,heard:[3,4],helium:0,hellman:[4,5],help:[0,4,5],here:[0,4],hexadecim:[0,4],high:[4,5],higher:[4,5],highli:4,hint:0,hit:0,hmac:5,hoc:5,hold:[3,4],hop:[4,5],host:[0,4,5],hour:0,how:[0,4,5],howev:4,http:[0,1],human:[0,3],i:0,id:4,idea:4,ident:[0,2],identif:5,identifi:4,identify:4,ie:4,ignor:[3,4],immedi:1,implement:[0,4,5],implicit:[3,4],inactive_for:3,inbound:3,includ:[0,3,4],incom:[0,3],incompat:[3,4],indefinit:4,independ:3,independt:5,index:[0,2],indirectli:4,individu:4,inevit:4,infer:4,info:[3,4],inform:[0,1,2,3,4],infrastructur:4,ingo:3,initi:4,initialis:[0,3],input:0,insert:4,instal:1,instanc:[0,3],instanti:3,instead:[0,4],integr:4,intend:4,intention:4,inter:3,interact:[0,4],interest:4,interfac:[0,2,3,4],intern:[3,4],internet:[4,5],interv:3,introduc:4,introduct:2,intuit:5,invalid:[0,3],investig:4,ip:[4,5],isdir:0,isfil:0,ism:4,its:[3,4],itself:[2,3,4],iv:5,job:0,join:[0,4],just:[0,4,5],k:0,kbp:4,keep:[0,3,4,5],keepal:[3,4],kei:[0,2,3,5],kept:[3,4],kernel:5,keyboardinterrupt:0,keyerror:3,keypair:4,keysiz:3,ki:0,kill:3,kilomet:4,kind:4,know:[0,3,4],knowledg:4,known:[0,3,4],krypton:0,lack:4,laid:4,larg:[0,4],larger:4,last:[0,3],last_unit:0,latenc:[4,5],later:[0,4],latest:[0,1],latest_client_link:0,launch:1,lavg:4,layer:[4,5],lead:4,learn:[0,4],least:[4,5],leav:4,ledger:4,left:4,len:0,length:[0,3],less:[4,5],let:[0,4],level:4,librari:1,licens:4,light:4,like:[1,3,4],limit:4,line:[0,1,4,5],link:[2,5],link_clos:0,link_establish:0,linkexampl:0,linux:4,list:[0,3,4],list_deliv:0,list_fil:0,list_packet:0,list_receipt:0,list_timeout:0,listdir:0,listen:[0,4],littl:4,lki:4,lkr:4,ll:[0,1,5],ln:1,load:[0,3],load_private_kei:3,load_public_kei:3,local:[0,3,4,5],locat:4,log:0,log_error:0,log_info:0,loglevel:0,longer:[0,4],look:[1,4],loop:0,lora:[4,5],lorawan:4,lot:4,low:[4,5],lxmf:1,m:[0,4],mac:4,machin:4,made:4,mai:4,main:0,maintain:4,make:[1,4],malici:4,manag:3,mani:[0,4,5],manipul:4,manual:[0,1,3],mark:4,markqvist:[0,1],master:[0,3],match:0,maximum:[3,4],mcu:4,mdu:0,mean:4,measur:4,mechan:4,medium:[4,5],memori:4,mention:4,menu:0,menu_mod:0,mesh:5,messag:[0,1,3,4],messeng:4,metavar:0,method:[0,3,4],methodolog:4,mhz:4,mi:0,microcontrol:4,microwav:4,might:4,millisecond:0,mind:5,minim:[2,4],minimalsampl:0,minimum:[0,4],minut:[0,4],mode:[0,1,4,5],modem:[3,4,5],modul:[0,4,5],moment:[4,5],monitor:4,more:[3,4,5],most:[1,4,5],motiv:2,move:1,mtu:[4,5],much:4,multi:[4,5],multilater:4,multipl:[0,4],multipoint:4,must:[0,3,4],my:4,n:0,name:[0,3],namespac:0,nano:1,narg:0,necessari:[1,3,4],necessarili:4,need:[0,2,4,5],neglig:4,neither:4,neon:0,network:[0,1,3,4,5],never:3,newer:4,newest:4,newli:4,next:[1,4],nicknam:4,no_inbound_for:3,no_outbound_for:3,nobl:0,noble_ga:0,noble_gas:0,node:[2,5],nomad:1,non:[3,4],none:[0,3,4],normal:0,notat:4,note:[0,4],noth:5,notic:4,notif:[0,3],now:[0,1,4],nt:0,num:0,number:[0,3,4],object:3,obtain:4,occur:5,off:[4,5],offer:[2,3,4],often:4,oganesson:0,old:4,onc:[4,5],one:[0,3,4,5],onli:[0,3,4,5],onlin:4,open:[0,3,4,5],openmodem:5,oper:[3,4,5],optic:5,option:[0,1],orient:4,origin:4,original_hash:3,os:[0,4,5],ospf:4,other:[3,4],otherwis:[3,4],our:[0,4],out:[0,3,4,5],outbound:3,outgo:[0,3,4],outlin:[1,4],outward:4,over:[0,3,4,5],overal:4,overcom:4,overhead:4,overrid:0,overview:4,own:[0,1,3,4],owner:3,p:[0,4],pack:0,packb:0,packet:[0,2,5],packet_callback:0,packet_deliv:0,packet_receipt:[0,3],packet_timed_out:0,packet_typ:3,packetreceipt:[0,3],pad:5,page:[2,4],pair:4,palm:0,paramet:3,pars:0,parse_arg:0,parser:0,part:[0,4],particip:[2,4],pass:[0,3,4],path:[0,1,3,4],path_respons:3,pattern:4,payload:[3,4],peach:0,peer:[3,4],peer_pub_byt:3,peer_sig_pub_byt:3,peopl:4,per:[4,5],percent:0,perfect:4,perform:4,period:4,persecut:4,person:4,philosophi:4,physic:4,pi:[0,4,5],piec:4,ping:1,pip3:1,pip:1,pkcs7:5,place:4,plain:[0,3,4],plain_mdu:3,plaintext:[0,3],platform:4,pleas:[0,5],pmr:4,point:4,pomelo:0,port:[4,5],possess:4,possibl:[4,5],potenti:[0,4],practic:[4,5],pre:[3,4],predict:4,prefer:4,prepar:0,presenc:3,press:0,pretend:4,pretti:4,prettyhexrep:0,previou:0,previous:[3,4],primari:4,principl:[4,5],print:0,print_filelist:0,print_help:0,print_menu:0,prioriti:4,prioritis:2,privaci:5,privat:[3,4,5],probabl:[0,4,5],procedur:4,process:[1,3,4],product:3,program:[0,2,3,4],program_setup:0,programm:4,programmat:4,progress:[0,3,5],progress_callback:3,project:1,prompt:0,proof:[0,3,4],proof_requested_callback:3,proof_strategi:3,propag:4,protocol:[1,2,5],prove:[0,4],prove_al:[0,3],prove_app:3,prove_non:3,proven:3,provid:[0,1,2,3,4,5],prv_byte:3,pub_byt:3,public_inform:0,purchas:[4,5],purg:3,purpos:[3,4],purposefulli:4,put:0,py:[0,1],pyseri:1,python3:1,python:[4,5],q:0,queri:0,queue:4,quinc:0,quit:0,r:[0,4],radio:[3,4,5],radiu:4,radon:0,rais:[0,3],randint:0,random:[0,3,4],randomli:[0,4],rang:[0,4,5],raspberri:[4,5],rate:0,rb:0,re:[0,3,4],reach:2,reachabl:[0,3,4],read:[0,1,4],readabl:[0,3,4],readi:[0,1],readili:5,real:5,reason:4,reassembl:4,recal:[0,3],recall_app_data:3,recap:4,receipt:[0,2,4],receiv:[0,3,4],received_announc:[0,3],recip:1,recipi:4,recommend:[0,4],reconstruct:4,record:4,recreat:4,refer:[0,1,2],regard:4,regist:[0,3],register_announce_handl:[0,3],rel:[4,5],releas:[1,4],relev:[0,3],reli:4,reliabl:[4,5],rem:0,remain:4,rememb:4,remot:[0,5],remotesensor:4,repeat:1,replac:[1,4],repli:0,replic:4,reply_data:0,reply_text:0,repositori:1,repres:4,represent:[0,4],request:[0,3,4],request_destin:0,request_packet:0,request_path:[0,3],requir:[0,4,5],research:5,resend:3,reserv:4,resili:5,resourc:[0,2],resource_callback:3,resource_sending_conclud:0,resource_strategi:3,respond:[0,3],rest:5,result:0,reticulum:0,retransmiss:4,retransmit:4,retri:4,reveal:4,review:5,right:[],rn:[0,1,3],rnode:[4,5],robot:4,rotat:4,round:[0,3],rout:[3,4,5],rprogress:0,rsa:4,rtt:[0,4],rttstring:0,rule:4,run:[0,1,3,4,5],runtim:4,s:[0,1,4,5],said:4,same:[1,3,4],satisfi:4,save:[3,4],save_error:0,saved_filenam:0,scenario:[1,4],screen:0,search:2,second:[0,3,4,5],secreci:[3,4,5],section:4,secur:[4,5],see:[0,3,4],seen:4,segment_index:3,select:0,self:[0,5],send:[0,3,4],sender:[0,4],sensibl:1,sensor:4,sent:[0,3,4],sentiment:4,separ:4,sequenc:[0,3,4,5],serial:[4,5],serv:[0,4],serve_path:0,server:[0,1],server_callback:0,server_destin:0,server_fil:0,server_ident:0,server_link:0,server_loop:0,server_packet_receiv:0,session:4,set:[0,3,4,5],set_default_app_data:3,set_delivery_callback:[0,3],set_link_closed_callback:0,set_link_established_callback:[0,3],set_packet_callback:[0,3],set_proof_requested_callback:3,set_proof_strategi:[0,3],set_resource_callback:3,set_resource_concluded_callback:[0,3],set_resource_started_callback:[0,3],set_resource_strategi:[0,3],set_timeout:[0,3],set_timeout_callback:3,setdaemon:0,setup:[0,2],sever:3,sha256:5,sha:[3,4],shall:4,share:[1,3,4],shelf:[4,5],shortest:4,should:[0,3,4,5],should_allow_unencrypt:3,should_quit:0,should_use_implicit_proof:3,shown:0,side:5,sign:[3,4],signatur:[3,4,5],similar:5,simpl:[0,4,5],simplest:4,simpli:[0,1,4],simplic:4,sinc:[0,3,4],singl:[0,3,4],singular:4,situat:4,size:[0,3,4],size_str:0,sleep:0,slice:0,slow:[0,4],small:[0,4],so:[0,1,4,5],softwar:[4,5],some:[0,1,4],someth:4,somethign:0,soon:3,sort:4,sourc:[0,1,4,5],space:[0,5],span:4,special:4,specif:[0,2,3,5],specifi:[0,3],spectrum:4,split:0,sponsor:5,stabl:[4,5],stack:[0,1,4,5],stage:4,standard:4,start:[0,2,3,4],startup:0,state:0,station:4,statist:0,statu:[0,2,3,4],stdout:0,step:1,still:[0,4],stop:5,store:[0,4],store_tru:0,str:0,strategi:3,stream:4,strength:5,strictli:4,string:[0,3],structur:4,subject:4,subsequ:4,successful:3,successfulli:0,sucessfulli:4,suffic:4,suffici:4,suffix:0,suit:[1,4],suitabl:[0,4],suppli:[3,4],support:[0,2,4],sy:0,symlink:1,symmetr:[3,4],system:[0,2,3,5],t:[0,1,4],tabl:4,take:[0,1,4,5],taken:[0,4],tangerin:0,target:0,tcp:[4,5],tdata:0,teardown:[0,3],teardown_reason:0,teffect:0,tell:0,temperatur:4,ten:4,term:4,termin:3,terminolog:4,test:4,text:[0,4],tfile:0,than:[0,4],thei:[0,3,4],them:[0,4],thereaft:4,therefor:[4,5],thi:[0,1,2,3,4],though:4,thourough:5,thread:0,three:4,through:[4,5],throughout:4,throughput:[4,5],thu:4,ti:[0,4],time:[0,1,3,4],timeout:[0,3],timeout_callback:0,timeoutarg:0,timestr:0,tnc:[3,5],to_fil:3,todai:4,todo:4,togeth:4,token:[3,4],too:[0,4],tool:5,top:4,topic:4,topolog:4,total:[4,5],total_s:0,touch:5,toward:[0,4],traffic:[0,3,4],tramsit:4,transceiv:[4,5],transfer:[0,3,4,5],transfer_s:0,transmiss:4,transmit:[0,4],transpar:4,transport:[0,2,5],transport_en:3,transport_id:3,transport_typ:3,travers:4,treat:4,tri:0,trip:[0,3],trivial:5,truli:4,truncat:[3,4],truncated_hash:3,truncated_hashlength:3,trust:4,trustless:[4,5],ttime:0,ttransfer:0,tunnel:[4,5],tupl:3,two:[0,4],type:[0,2,3],typeerror:3,udp:[4,5],umsgpack:0,uncencrypt:0,underli:5,understand:[1,2],unencrypt:[0,3,4],unequivoc:4,unforg:5,uninterest:0,uniqu:[4,5],unit:0,unknown:[0,3,4],unless:[1,3,4],unlicens:4,unpack:0,unpackb:0,unsupport:3,until:[0,3,4],unwant:4,up:[0,4,5],updat:[0,3],upon:[0,4],urandom:5,us:[0,2,3,4],usabl:4,usag:4,usb:[4,5],useabl:4,user:[0,1,3,4],user_input:0,userland:5,utf:0,util:[0,1,4],utilis:[4,5],valid:[0,3,4],valu:4,valueerror:[0,3],variabl:0,varieti:[4,5],variou:[0,4],ve:1,vendor:0,veri:[3,4,5],verif:[3,4],verifi:[0,4],versa:5,version:3,vhf:4,via:[1,4],vice:5,view:4,visibl:0,wa:[0,3,4,5],wai:[0,1,4],wait:[0,4],want:[0,1,4,5],warrant:5,wb:0,we:[0,4],well:[3,4,5],went:0,what:[0,1,2,3,4],whatev:4,when:[0,1,3,4],whenev:3,where:[2,3,4],whereupon:4,whether:[0,3,4],which:[0,1,3,4],who:4,wide:[4,5],wifi:[4,5],wildcard:0,wire:[4,5],wish:4,within:[0,3,4],won:0,work:[4,5],world:5,would:4,write:[0,3,4],written:4,wrong:0,x25519:[3,4,5],x:4,xenon:0,y:0,ye:4,year:4,yet:[0,4],yi:0,you:[0,1,2,3,4,5],your:[0,1,4,5],yourself:[4,5],z:0,zero:3,zi:0},titles:["Examples","Getting Started Fast","Reticulum Network Stack Manual","API Reference","Understanding Reticulum","What is Reticulum?"],titleterms:{"1":[],"2":[],"class":3,"function":4,"public":4,"try":1,announc:[0,4],api:3,base:1,basic:4,binari:4,broadcast:0,can:5,caveat:5,current:5,deliveri:4,destin:[3,4],detail:4,develop:1,devic:5,doe:5,echo:0,emptor:5,establish:4,exampl:0,fast:1,filetransf:0,format:4,further:4,get:[1,4],goal:4,ident:[3,4],indic:2,interfac:5,introduct:4,kei:4,link:[0,3,4],manual:2,minim:0,motiv:4,name:4,network:2,node:4,offer:5,packet:[3,4],particip:1,pathfind:4,prioritis:4,program:1,protocol:4,proven:4,reach:4,receipt:3,refer:[3,4],resourc:[3,4],reticulum:[1,2,3,4,5],setup:4,specif:4,stack:2,start:1,statu:5,step:[],support:5,system:4,tabl:2,transport:[3,4],type:[4,5],understand:4,us:[1,5],what:5,where:5}})
\ No newline at end of file
+Search.setIndex({docnames:["examples","gettingstartedfast","index","reference","understanding","whatis"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["examples.rst","gettingstartedfast.rst","index.rst","reference.rst","understanding.rst","whatis.rst"],objects:{"RNS.Destination":{announce:[3,1,1,""],app_and_aspects_from_name:[3,1,1,""],clear_default_app_data:[3,1,1,""],create_keys:[3,1,1,""],decrypt:[3,1,1,""],encrypt:[3,1,1,""],full_name:[3,1,1,""],get_private_key:[3,1,1,""],hash:[3,1,1,""],hash_from_name_and_identity:[3,1,1,""],load_private_key:[3,1,1,""],set_default_app_data:[3,1,1,""],set_link_established_callback:[3,1,1,""],set_packet_callback:[3,1,1,""],set_proof_requested_callback:[3,1,1,""],set_proof_strategy:[3,1,1,""],sign:[3,1,1,""]},"RNS.Identity":{CURVE:[3,2,1,""],KEYSIZE:[3,2,1,""],TRUNCATED_HASHLENGTH:[3,2,1,""],decrypt:[3,1,1,""],encrypt:[3,1,1,""],from_bytes:[3,1,1,""],from_file:[3,1,1,""],full_hash:[3,1,1,""],get_private_key:[3,1,1,""],get_public_key:[3,1,1,""],get_random_hash:[3,1,1,""],load_private_key:[3,1,1,""],load_public_key:[3,1,1,""],recall:[3,1,1,""],recall_app_data:[3,1,1,""],sign:[3,1,1,""],to_file:[3,1,1,""],truncated_hash:[3,1,1,""],validate:[3,1,1,""]},"RNS.Link":{CURVE:[3,2,1,""],DEFAULT_TIMEOUT:[3,2,1,""],KEEPALIVE:[3,2,1,""],disable_encryption:[3,1,1,""],inactive_for:[3,1,1,""],no_inbound_for:[3,1,1,""],no_outbound_for:[3,1,1,""],set_packet_callback:[3,1,1,""],set_resource_callback:[3,1,1,""],set_resource_concluded_callback:[3,1,1,""],set_resource_started_callback:[3,1,1,""],set_resource_strategy:[3,1,1,""],teardown:[3,1,1,""]},"RNS.Packet":{ENCRYPTED_MDU:[3,2,1,""],PLAIN_MDU:[3,2,1,""],resend:[3,1,1,""],send:[3,1,1,""]},"RNS.PacketReceipt":{get_rtt:[3,1,1,""],get_status:[3,1,1,""],set_delivery_callback:[3,1,1,""],set_timeout:[3,1,1,""],set_timeout_callback:[3,1,1,""]},"RNS.Resource":{advertise:[3,1,1,""],cancel:[3,1,1,""],progress:[3,1,1,""]},"RNS.Reticulum":{should_allow_unencrypted:[3,1,1,""],should_use_implicit_proof:[3,1,1,""],transport_enabled:[3,1,1,""]},"RNS.Transport":{deregister_announce_handler:[3,1,1,""],has_path:[3,1,1,""],register_announce_handler:[3,1,1,""],request_path:[3,1,1,""]},RNS:{Destination:[3,0,1,""],Identity:[3,0,1,""],Link:[3,0,1,""],Packet:[3,0,1,""],PacketReceipt:[3,0,1,""],Resource:[3,0,1,""],Reticulum:[3,0,1,""],Transport:[3,0,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute"},terms:{"0":[0,3,4,5],"00":4,"000":[4,5],"00000000":4,"00000100":4,"00000111":4,"01":4,"01010000":4,"05":0,"1":[0,3,4,5],"10":[0,4],"100":[0,4],"1000":[0,4],"1024":0,"11":4,"1200":4,"128":[4,5],"14":4,"141":4,"15":[3,4],"151":4,"18":4,"180":[3,4],"182":4,"2":[0,4],"20":[0,4],"205":[],"25":[0,5],"256":[3,4],"270":4,"2f":0,"3":[0,4,5],"323":[],"33":4,"34":4,"3600":0,"383":3,"3e12fc71692f8ec47bc5":1,"4":4,"409":[4,5],"430":4,"45":0,"477":[3,4],"5":[0,4],"500":[4,5],"512":3,"60":0,"62":[4,5],"7":4,"8":0,"80":[3,4],"80e29bf7cccaf31431b3":4,"86":4,"868":4,"900":4,"95":4,"abstract":4,"break":[4,5],"byte":[0,3,4,5],"case":[1,4],"class":[0,2,5],"default":[0,3,4],"do":[0,1,4,5],"float":[0,3],"function":[0,2,3,5],"import":[0,1,4],"int":0,"long":[0,4],"new":[0,3,4],"public":[0,2,3],"return":[0,3],"short":4,"static":3,"throw":3,"true":[0,3],"try":[0,2],"while":[0,3,4,5],A:[0,3,4,5],And:0,As:[3,4,5],At:4,Be:3,But:4,By:[0,4],For:[3,4],IN:[0,3],If:[0,1,3,4,5],In:[0,1,4,5],It:[0,3,4,5],No:[4,5],One:3,Or:4,That:4,The:[0,1,2,3,5],There:[4,5],These:4,To:[0,4,5],Will:3,With:4,_:4,__:4,______:4,_______:4,________:4,________________:4,__init__:0,__main__:0,__name__:0,_exit:0,ab:0,abl:[0,3,4],about:[0,3,4],abov:[1,4],accept:[3,4],accept_al:[0,3],accept_app:3,accept_non:3,access:[3,4],accord:4,accordingli:0,acheiv:4,achiev:[3,4],acknowledg:5,act:[3,4],action:0,activ:[0,3,4],actor:4,actual:[0,1,4],ad:[0,3,4,5],add:0,add_argu:0,addit:[4,5],addr1:4,addr2:4,address:[0,3,4,5],adress:[0,3,5],advantag:3,advertis:[0,3],advis:4,ae:[4,5],after:[0,4],again:[1,4],against:4,agent:4,agnost:4,agnostic:4,aim:[2,4],aliv:[3,4],all:[0,2,3,4,5],allow:[0,3,4,5],almost:4,along:[3,4],alreadi:[0,4],also:[0,3,4,5],alter:4,altern:0,although:5,alwai:[3,4],amateur:5,amount:[3,4,5],an:[0,1,3,4,5],ani:[0,1,3,4,5],announc:[2,3],announce_handl:0,announced_ident:[0,3],announceloop:0,announcesampl:0,anonym:4,anoth:[1,3,4],answer:4,anyon:[0,3,4],anyth:4,anywher:0,apart:4,api:[1,2,4,5],app:[0,3,4],app_and_aspects_from_nam:3,app_data:[0,3],app_nam:[0,3],app_timeout:0,append:[0,4],appli:4,applic:[0,3,4],approv:4,approxim:4,ar:[0,3,4,5],arbitrari:[3,4],arbritrari:5,area:5,arg:0,argon:0,argpars:0,argument:[0,3],argumentpars:0,around:4,arriv:[0,4],ask:[0,3],aspect:[0,3,4],aspect_filt:[0,3],assign:4,associ:[1,3,4],assum:4,asymmetr:5,attached_interfac:3,attribut:3,audit:5,authent:[4,5],author:4,auto:[3,4],auto_compress:3,autoconfigur:5,autom:4,automat:[0,3,4,5],autonom:4,autoomat:0,avail:[0,4,5],averag:4,avoid:4,awai:4,awar:4,ax:5,b:0,back:[0,4,5],band:4,bandwidth:[4,5],bare:0,barrier:4,base:[2,4,5],basi:[3,4,5],basic:[0,1,2],baud:4,becaus:4,becom:0,been:[0,3,4,5],befor:[0,3,4],begin:[0,3],begun:3,behind:4,being:4,belief:4,below:1,best:[1,4,5],beta:5,between:[0,3,4],bgp:4,bi:4,bidirect:4,binari:[0,2],bit:[3,4,5],blob:[0,4],both:[3,4,5],bp:4,briefli:4,broadcast:[2,3,4],broadcast_destin:0,broadcastloop:0,bug:5,build:[0,4,5],built:[1,4,5],bundl:0,c:[0,4],cad:4,calcul:4,call:[0,3,4,5],callabl:3,callback:[0,3],can:[0,1,2,3,4],cancel:3,cannot:0,capac:4,carambola:0,care:[3,4,5],carri:[3,4],carrier:5,caveat:2,cb:4,cbc:5,cd:1,censor:4,censorship:4,central:4,certain:[0,4],challeng:4,chang:[0,1,4,5],channel:[0,4,5],channelarg:0,chapter:[1,4],charact:0,characterist:4,cheap:4,check:0,checksum:[3,5],choos:0,chose:4,chunk:0,ciphertext:3,ciphertext_token:3,cl:0,clear:[0,3,4],clear_default_app_data:3,clear_screen:0,client:[0,1,3],client_connect:0,client_disconnect:0,client_loop:0,client_packet_receiv:0,client_request:0,clone:1,close:[0,3],closer:4,cluster:4,code:[0,4],com:[0,1],combin:4,come:4,command:[0,1],common:4,commun:[0,1,3,4,5],compat:4,complet:[0,1,3,4,5],compon:4,compos:4,compress:[0,3,4],comput:[1,4],concaten:3,concept:4,conclud:[0,3],concurr:4,condit:4,config:[0,1],configarg:0,configdir:3,configpath:0,configur:[0,3,4,5],confirm:[4,5],connect:[0,3,4,5],consequ:4,consid:[4,5],consist:4,constant:[3,4],construct:4,contact:4,contain:[0,3,4],content:[],context:[3,4],control:[0,3,4],conveni:0,convent:0,coordin:[3,4,5],core:[4,5],correct:[0,4],correctli:0,correspond:4,cost:[4,5],could:[0,3,4,5],count:4,counter:0,cover:5,cpu:0,creat:[0,1,3,4],create_kei:3,create_receipt:[0,3],creation:4,creator:4,critic:4,cryptograph:5,cryptographi:[1,4,5],ctrl:0,cull:3,current:[0,2,3,4],current_download:0,current_filenam:0,curv:[3,4,5],curve25519:[3,4,5],custom:4,d:4,daemon:3,dai:4,data:[0,3,4,5],date:0,debian:4,debug:3,decai:4,decid:[3,4],decod:0,decrypt:[3,4],dedic:4,def:0,default_timeout:3,defin:[0,4],definit:4,delai:4,deliv:[0,3],deliveri:[0,3,5],demand:3,demonstr:0,depend:1,deploi:4,deregist:3,deregister_announce_handl:3,deriv:[4,5],describ:[3,4],descript:0,design:[4,5],desir:[0,4],destin:[0,1,2],destination_1:0,destination_2:0,destination_clos:0,destination_hash:[0,3],destination_hexhash:0,detail:[0,2,3],detect:0,determin:[3,4],develop:[2,4],devic:[2,3,4],dh:3,did:0,differ:[0,1,3,4,5],diffi:[4,5],digit:[4,5],dir:0,direct:[0,3,4],directli:[3,4,5],directori:0,disable_encrypt:3,disappear:3,discard:4,disconnect:0,discoveri:4,discuss:4,disk:[0,3],displai:4,distanc:4,distinct:4,distribut:[0,3,4],divmod:0,document:4,doe:[0,2,3,4],don:[0,1],done:[0,4],dot:4,down:0,downgrad:3,download:0,download_began:0,download_conclud:0,download_finish:0,download_start:0,download_tim:0,driver:5,drop:4,duplex:[4,5],e:0,each:[0,4],earlier:4,eas:4,easi:[4,5],easiest:[1,4],easili:[4,5],ecdh:[4,5],echo:[1,2],echo_destin:0,echo_request:0,ed25519:[4,5],effici:[0,4,5],ei:0,either:4,elif:0,ellipt:[3,4,5],els:[0,4],emploi:4,emptor:2,enabl:3,enable_transport:4,encapsul:5,encod:0,encrypt:[0,1,3,4,5],encrypted_mdu:3,encryptionless:3,end:[0,3,4,5],endpoint:[0,3,4],engin:4,ensur:4,enter:0,entir:4,entiti:4,entri:[0,4],enumer:0,environ:4,environment:4,environmentlogg:4,ephemer:[3,4,5],equal:4,equip:4,equl:[],error:[0,3],essenti:4,establish:[0,3,5],ethernet:[4,5],even:[4,5],everi:[0,3,4],everyon:4,everyth:[0,4],exact:4,exactli:[3,4],exampl:[1,2,3,4,5],example_util:0,exampleannouncehandl:0,exce:0,except:[0,4],exchang:[3,4,5],execut:[0,3],exhaust:4,exist:[0,4,5],exit:[0,1,3],exit_handl:0,expand:4,expect:[0,4],experi:[1,4],experiment:5,explain:3,explan:4,explicit:3,explicitli:3,explor:[0,4,5],expos:3,extend:[0,4],extern:[3,5],extrem:5,fa7ddfab5213f916dea:4,face:1,fact:[4,5],fail:[0,3],fals:[0,3],far:4,fast:2,featur:[4,5],feed:3,feedback:0,fernet:5,few:[4,5],field:4,file:[0,1,3,4,5],file_resourc:0,file_s:0,filelist:0,filelist_data:0,filelist_receiv:0,filelist_timeout_job:0,filenam:0,filetransf:[1,2,3],filter:[0,4],find:4,firmwar:4,first:[0,3,4],fit:0,five:0,fix:4,flag:[3,4],flush:0,folder:1,follow:[0,4,5],forcibl:3,foremost:5,form:[3,4],format:[0,2,5],forth:0,forward:[3,4,5],found:[0,1,4],free:5,frequenc:4,from:[0,1,3,4,5],from_byt:3,from_fil:3,fromhex:0,fruit:0,full:[3,4],full_hash:3,full_nam:3,fulli:[4,5],fundament:4,further:[1,2],futur:[3,4],g:0,ga:0,gatekeep:4,gener:[0,3,4,5],generalis:5,get:[0,2,3,5],get_private_kei:3,get_public_kei:3,get_random_hash:[0,3],get_rtt:[0,3],get_statu:3,gi:0,gigabyt:5,git:1,github:[0,1],give:4,given:4,global:[0,5],go:[0,1,4],goal:2,good:4,got:0,govern:4,grape:0,great:4,greater:4,group:[3,4],guarante:4,guid:[1,3,4],h:[1,4],ha:[0,3,4,5],had:4,half:[4,5],hand:0,handheld:4,handl:[0,3,4,5],handler:[0,3],happen:0,hardwar:[3,4,5],has_path:[0,3],hasattr:0,hash:[0,1,3,4],hash_from_name_and_ident:3,hashmap:0,have:[0,1,3,4],hazard:3,header:4,header_1:4,header_2:4,header_typ:3,hear:4,heard:[3,4],helium:0,hellman:[4,5],help:[0,4,5],here:[0,4],hexadecim:[0,4],high:[4,5],higher:[4,5],highli:4,hint:0,hit:0,hmac:5,hoc:5,hold:[3,4],hop:[4,5],host:[0,4,5],hour:0,how:[0,4,5],howev:4,http:[0,1],human:[0,3],i:0,id:4,idea:4,ident:[0,2],identif:5,identifi:4,identify:4,ie:[],ignor:[3,4],immedi:1,impact:4,implement:[0,4,5],implicit:[3,4],inactive_for:3,inbound:3,includ:[0,3,4],incom:[0,3],incompat:[3,4],indefinit:4,independ:3,independt:5,index:[0,2],indirectli:4,individu:4,inevit:4,infer:4,info:[3,4],inform:[0,1,2,3,4],infrastructur:4,ingo:3,initi:4,initialis:[0,3],input:0,insert:4,instal:1,instanc:[0,3],instanti:3,instead:[0,4],integr:4,intend:4,intention:4,inter:3,interact:[0,4],interest:4,interfac:[0,2,3,4],intern:[3,4],internet:[4,5],interv:3,introduc:4,introduct:2,intuit:5,invalid:[0,3],investig:4,ip:[4,5],isdir:0,isfil:0,ism:4,its:[3,4],itself:[2,3,4],iv:5,job:0,join:[0,4],just:[0,4,5],k:0,kbp:4,keep:[0,3,4,5],keepal:[3,4],kei:[0,2,3,5],kept:[3,4],kernel:5,keyboardinterrupt:0,keyerror:3,keypair:4,keysiz:3,ki:0,kill:3,kilomet:4,kind:4,know:[0,3,4],knowledg:4,known:[0,3,4],krypton:0,lack:4,laid:4,larg:[0,4],larger:4,last:[0,3],last_unit:0,latenc:[4,5],later:0,latest:[0,1],latest_client_link:0,launch:1,lavg:4,layer:[4,5],lead:4,learn:[0,4],least:[4,5],leav:4,ledger:4,left:4,len:0,length:[0,3],less:[4,5],let:[0,4],level:4,librari:1,licens:4,light:4,like:[1,3,4],limit:4,line:[0,1,4,5],link:[2,5],link_clos:0,link_establish:0,linkexampl:0,linux:4,list:[0,3,4],list_deliv:0,list_fil:0,list_packet:0,list_receipt:0,list_timeout:0,listdir:0,listen:[0,4],littl:4,lki:4,lkr:4,ll:[0,1,5],ln:1,load:[0,3],load_private_kei:3,load_public_kei:3,local:[0,3,4,5],locat:4,log:0,log_error:0,log_info:0,loglevel:0,longer:[0,4],look:[1,4],loop:0,lora:[4,5],lorawan:4,lot:4,low:[4,5],lxmf:1,m:[0,4],mac:4,machin:4,made:4,mai:4,main:0,maintain:4,make:[1,4],malici:4,manag:3,mani:[0,4,5],manipul:4,manual:[0,1,3],mark:4,markqvist:[0,1],master:[0,3],match:0,maximum:[3,4],mcu:4,mdu:0,mean:4,measur:4,mechan:2,medium:[4,5],memori:4,mention:4,menu:0,menu_mod:0,mesh:5,messag:[0,1,3,4],messeng:4,metavar:0,method:[0,3,4],methodolog:4,mhz:4,mi:0,microcontrol:4,microwav:4,might:4,millisecond:0,mind:5,minim:[2,4],minimalsampl:0,minimum:[0,4],minut:[0,4],mode:[0,1,4,5],modem:[3,4,5],modul:[0,4,5],moment:[4,5],monitor:4,more:[3,4,5],most:[1,4,5],motiv:2,move:1,mtu:[4,5],much:4,multi:[4,5],multilater:4,multipl:[0,4],multipoint:4,must:[0,3,4],my:4,n:0,name:[0,3],namespac:0,nano:1,narg:0,necessari:[1,3,4],necessarili:4,need:[0,2,4,5],neglig:4,neither:4,neon:0,network:[0,1,3,4,5],never:3,newer:4,newest:4,newli:4,next:[1,4],nicknam:4,no_inbound_for:3,no_outbound_for:3,nobl:0,noble_ga:0,noble_gas:0,node:[2,5],nomad:1,non:[3,4],none:[0,3,4],normal:0,notat:4,note:[0,4],noth:5,notic:4,notif:[0,3],now:[0,1,4],nt:0,num:0,number:[0,3,4],object:3,obtain:4,occur:5,off:[4,5],offer:[2,3,4],often:4,oganesson:0,old:4,onc:[4,5],one:[0,3,4,5],onli:[0,3,4,5],onlin:4,open:[0,3,4,5],openmodem:5,oper:[3,4,5],opt:4,optic:5,option:[0,1],orient:4,origin:4,original_hash:3,os:[0,4,5],ospf:4,other:[3,4],otherwis:[3,4],our:[0,4],out:[0,3,4,5],outbound:3,outgo:[0,3,4],outlin:[1,4],outward:4,over:[0,3,4,5],overal:4,overcom:4,overhead:4,overrid:0,overview:4,own:[0,1,3,4],owner:3,p:[0,4],pack:0,packb:0,packet:[0,2,5],packet_callback:0,packet_deliv:0,packet_receipt:[0,3],packet_timed_out:0,packet_typ:3,packetreceipt:[0,3],pad:5,page:[2,4],pair:4,palm:0,paramet:3,pars:0,parse_arg:0,parser:0,part:[0,4],particip:[2,4],pass:[0,3,4],path:[0,1,3,4],path_respons:3,pathfind:[],pattern:4,payload:[3,4],peach:0,peer:[3,4],peer_pub_byt:3,peer_sig_pub_byt:3,peopl:4,per:[4,5],percent:0,perfect:4,perform:4,period:4,persecut:4,person:4,philosophi:4,physic:4,pi:[0,4,5],piec:4,ping:1,pip3:1,pip:1,pkcs7:5,place:4,plain:[0,3,4],plain_mdu:3,plaintext:[0,3],platform:4,pleas:[0,5],plenti:4,plu:4,pmr:4,point:4,pomelo:0,port:[4,5],possess:4,possibl:[4,5],potenti:[0,4],practic:[4,5],pre:[3,4],predict:4,prefer:4,prepar:0,presenc:3,press:0,pretend:4,pretti:4,prettyhexrep:0,previou:0,previous:[3,4],primari:4,principl:[4,5],print:0,print_filelist:0,print_help:0,print_menu:0,prioriti:4,prioritis:2,privaci:5,privat:[3,4,5],probabl:[0,4,5],procedur:4,process:[1,3,4],product:3,program:[0,2,3,4],program_setup:0,programm:4,programmat:4,progress:[0,3,5],progress_callback:3,project:1,prompt:0,proof:[0,3,4],proof_requested_callback:3,proof_strategi:3,propag:4,protocol:[1,2,5],prove:[0,4],prove_al:[0,3],prove_app:3,prove_non:3,proven:[3,4],provid:[0,1,2,3,4,5],prv_byte:3,pub_byt:3,public_inform:0,purchas:[4,5],purg:3,purpos:[3,4],purposefulli:4,put:0,py:[0,1],pyseri:1,python3:1,python:[4,5],q:0,queri:0,queue:4,quinc:0,quit:0,r:[0,4],radio:[3,4,5],radiu:4,radon:0,rais:[0,3],rand:4,randint:0,random:[0,3,4],randomli:[0,4],rang:[0,4,5],raspberri:[4,5],rate:0,rb:0,re:[0,3,4],reach:2,reachabl:[0,3,4],read:[0,1,4],readabl:[0,3,4],readi:[0,1],readili:5,real:5,reason:4,reassembl:4,recal:[0,3],recall_app_data:3,recap:4,receipt:[0,2,4],receiv:[0,3,4],received_announc:[0,3],recip:1,recipi:4,recommend:[0,4],reconstruct:4,record:4,recreat:4,refer:[0,1,2],regard:4,regist:[0,3],register_announce_handl:[0,3],rel:[4,5],releas:[1,4],relev:[0,3],reli:4,reliabl:[4,5],rem:0,remain:4,rememb:4,remot:[0,5],remotesensor:4,repeat:1,replac:[1,4],repli:0,replic:4,reply_data:0,reply_text:0,repositori:1,repres:4,represent:[0,4],request:[0,3,4],request_destin:0,request_packet:0,request_path:[0,3],requir:[0,4,5],research:5,resend:3,reserv:4,resili:5,resourc:[0,2],resource_callback:3,resource_sending_conclud:0,resource_strategi:3,respond:[0,3],rest:5,result:[0,4],reticulum:0,retransmiss:4,retransmit:4,retri:4,reveal:4,review:5,right:[],rn:[0,1,3],rnode:[4,5],robot:4,rotat:4,round:[0,3],rout:[3,4,5],rprogress:0,rsa:[],rtt:[0,4],rttstring:0,rule:4,run:[0,1,3,4,5],runtim:4,rw:4,s:[0,1,4,5],said:4,same:[1,3,4],satisfi:4,save:[3,4],save_error:0,saved_filenam:0,scenario:[1,4],screen:0,search:2,second:[0,3,4,5],secreci:[3,4,5],section:4,secur:[4,5],see:[0,3,4],seen:4,segment_index:3,select:0,self:[0,5],send:[0,3,4],sender:[0,4],sensibl:1,sensor:4,sent:[0,3,4],sentiment:4,separ:4,sequenc:[0,3,4,5],serial:[4,5],serv:[0,4],serve_path:0,server:[0,1],server_callback:0,server_destin:0,server_fil:0,server_ident:0,server_link:0,server_loop:0,server_packet_receiv:0,session:4,set:[0,3,4,5],set_default_app_data:3,set_delivery_callback:[0,3],set_link_closed_callback:0,set_link_established_callback:[0,3],set_packet_callback:[0,3],set_proof_requested_callback:3,set_proof_strategi:[0,3],set_resource_callback:3,set_resource_concluded_callback:[0,3],set_resource_started_callback:[0,3],set_resource_strategi:[0,3],set_timeout:[0,3],set_timeout_callback:3,setdaemon:0,setup:[0,2],sever:3,sha256:5,sha:[3,4],shall:4,share:[1,3,4],shelf:[4,5],shortest:4,should:[0,3,4,5],should_allow_unencrypt:3,should_quit:0,should_use_implicit_proof:3,shown:0,side:5,sign:[3,4],signatur:[3,4,5],similar:5,simpl:[0,4,5],simplest:4,simpli:[0,1,4],simplic:4,sinc:[0,3,4],singl:[0,3,4],singular:4,situat:4,size:[0,3,4],size_str:0,sleep:0,slice:0,slow:[0,4],small:[0,4],so:[0,1,4,5],softwar:[4,5],some:[0,1,4],someth:4,somethign:0,soon:3,sort:4,sourc:[0,1,4,5],space:[0,5],span:4,special:4,specif:[0,2,3,5],specifi:[0,3],spectrum:4,split:0,sponsor:5,stabl:[4,5],stack:[0,1,4,5],stage:4,standard:4,start:[0,2,3,4],startup:0,state:0,station:4,statist:0,statu:[0,2,3,4],stdout:0,step:1,still:[0,4],stop:5,store:[0,4],store_tru:0,str:0,strategi:3,stream:4,strength:5,strictli:4,string:[0,3],structur:4,subject:4,subsequ:4,successful:3,successfulli:0,sucessfulli:4,suffic:4,suffici:4,suffix:0,suit:[1,4],suitabl:[0,4],suppli:[3,4],support:[0,2,4],sy:0,symlink:1,symmetr:[3,4],system:[0,2,3,5],t:[0,1,4],tabl:4,take:[0,1,4,5],taken:[0,4],tangerin:0,target:0,tcp:[4,5],tdata:0,teardown:[0,3],teardown_reason:0,teffect:0,tell:0,temperatur:4,ten:4,term:4,termin:3,terminolog:4,test:4,text:[0,4],tfile:0,than:[0,4],thei:[0,3,4],them:[0,4],thereaft:4,therefor:[4,5],thi:[0,1,2,3,4],though:4,thourough:5,thread:0,three:4,through:[4,5],throughout:4,throughput:[4,5],thu:4,ti:[0,4],time:[0,1,3,4],timeout:[0,3],timeout_callback:0,timeoutarg:0,timestr:0,tnc:[3,5],to_fil:3,todai:4,todo:[],togeth:4,token:[3,4],too:[0,4],tool:5,top:4,topic:4,topolog:4,total:[4,5],total_s:0,touch:5,toward:[0,4],traffic:[0,3,4],tramsit:[],transceiv:[4,5],transfer:[0,3,4,5],transfer_s:0,transmiss:4,transmit:[0,4],transpar:4,transport:[0,2,5],transport_en:3,transport_id:3,transport_typ:3,travers:4,treat:4,tri:0,trip:[0,3],trivial:5,truli:4,truncat:[3,4],truncated_hash:3,truncated_hashlength:3,trust:4,trustless:[4,5],ttime:0,ttransfer:0,tunnel:[4,5],tupl:3,two:[0,4],type:[0,2,3],typeerror:3,udp:[4,5],umsgpack:0,uncencrypt:0,underli:5,understand:[1,2],unencrypt:[0,3,4],unequivoc:4,unforg:5,uninterest:0,uniqu:[4,5],unit:0,unknown:[0,3,4],unless:[1,3,4],unlicens:4,unpack:0,unpackb:0,unsupport:3,until:[0,3,4],unwant:4,up:[0,4,5],updat:[0,3],upon:[0,4],urandom:5,us:[0,2,3,4],usabl:4,usag:[],usb:[4,5],useabl:4,user:[0,1,3,4],user_input:0,userland:5,utf:0,util:[0,1,4],utilis:[4,5],valid:[0,3,4],valu:4,valueerror:[0,3],variabl:0,varieti:[4,5],variou:[0,4],ve:1,vendor:0,veri:[3,4,5],verif:[3,4],verifi:[0,4],versa:5,version:3,vhf:4,via:[1,4],vice:5,view:4,visibl:0,wa:[0,3,4,5],wai:[0,1,4],wait:[0,4],want:[0,1,4,5],warrant:5,wb:0,we:[0,4],well:[3,4,5],went:0,what:[0,1,2,3,4],whatev:4,when:[0,1,3,4],whenev:3,where:[2,3,4],whereupon:4,whether:[0,3,4],which:[0,1,3,4],who:4,wide:[4,5],wifi:[4,5],wildcard:0,window:4,wire:[4,5],wish:4,within:[0,3,4],won:0,work:[4,5],world:5,would:4,write:[0,3],written:4,wrong:0,x25519:[3,4,5],x:4,xenon:0,y:0,ye:4,year:4,yet:[0,4],yi:0,you:[0,1,2,3,4,5],your:[0,1,4,5],yourself:[4,5],z:0,zero:3,zi:0},titles:["Examples","Getting Started Fast","Reticulum Network Stack Manual","API Reference","Understanding Reticulum","What is Reticulum?"],titleterms:{"1":[],"2":[],"class":3,"function":4,"public":4,"try":1,The:4,announc:[0,4],api:3,base:1,basic:4,binari:4,broadcast:0,can:5,caveat:5,current:5,deliveri:[],destin:[3,4],detail:4,develop:1,devic:5,doe:5,echo:0,emptor:5,establish:4,exampl:0,fast:1,filetransf:0,format:4,further:4,get:[1,4],goal:4,ident:[3,4],indic:2,interfac:5,introduct:4,kei:4,link:[0,3,4],manual:2,mechan:4,minim:0,motiv:4,name:4,network:2,node:4,offer:5,packet:[3,4],particip:1,pathfind:[],prioritis:4,program:1,protocol:4,proven:[],reach:4,receipt:3,refer:[3,4],resourc:[3,4],reticulum:[1,2,3,4,5],setup:4,specif:4,stack:2,start:1,statu:5,step:[],support:5,system:4,tabl:2,transport:[3,4],type:[4,5],understand:4,us:[1,5],what:5,where:5}})
\ No newline at end of file
diff --git a/docs/manual/understanding.html b/docs/manual/understanding.html
index 7bc4a5f..e1fb947 100644
--- a/docs/manual/understanding.html
+++ b/docs/manual/understanding.html
@@ -205,12 +205,14 @@ when a node is directly reachable.
Destinations are created and named in an easy to understand dotted notation of aspects , and
+
Destinations are created and named in an easy to understand dotted notation of aspects, and
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 80 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. For example,
-a destination for a environmental monitoring application could be made up of the application name, a
-device type and measurement type, like this:
+The next levels of aspects can be defined in any way by the creator of the application.
+
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.
+
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:
app name : environmentlogger
aspects : remotesensor, temperature
@@ -246,9 +248,8 @@ receives.
-
Group
When private communication between two or more endpoints is needed. More efficient in
-data usage than single destinations. Supports multiple hops indirectly, but must first be
-established through a single destination.
+
Group
When private communication between two or more endpoints is needed. Supports multiple hops
+indirectly, but must first be established through a single destination.
@@ -264,9 +265,9 @@ nodes aware of your destinations public key, called the announce. It is
an unknown public key from the network, as all participating nodes serve as a distributed ledger
of public keys.
Note that public key information can be shared and verified in many other ways than using the
-built-in methodology, and that it is therefore not required to use the announce/request functionality.
-It is by far the easiest though, and should definitely be used if there is not a good reason for
-doing it differently.
+built-in announce functionality, and that it is therefore not required to use the announce/request
+functionality to obtain public keys. It is by far the easiest though, and should definitely be used
+if there is not a good reason for doing it differently.
@@ -282,7 +283,7 @@ contain the following information:
The announcers public key
Application specific data, in this case the users nickname and availability status
A random blob, making each new announce unique
-
A signature of the above information, verifying authenticity
+
An Ed25519 signature of the above information, verifying authenticity
With this information, any Reticulum node that receives it will be able to reconstruct an outgoing
destination to securely communicate with that destination. You might have noticed that there is one
@@ -290,8 +291,9 @@ piece of information lacking to reconstruct full knowledge of the announced dest
the aspect names of the destination. These are intentionally left out to save bandwidth, since they
will be implicit in almost all cases. If a destination name is not entirely implicit, information can be
included in the application specific data part that will allow the receiver to infer the naming.
-
It is important to note that announcements will be forwarded throughout the network according to a
-certain pattern. This will be detailed later.
+
It is important to note that announces will be forwarded throughout the network according to a
+certain pattern. This will be detailed in the section
+The Announce Mechanism in Detail.
Seeing how single destinations are always tied to a private/public key pair leads us to the next topic.
@@ -308,16 +310,16 @@ automatically. This may be desirable in some situations, but often you will prob
the identity first, and then link it to created destinations.
Building upon the simple messenger example, we could use an identity to represent the user of the
application. Destinations created will then be linked to this identity to allow communication to
-reach the user. In such a case it is of great importance to store the user’s identity securely and
-privately.
+reach the user. In all cases it is of great importance to store the private keys associated with any
+Reticulum Identity securely and privately.
The above functions and principles form the core of Reticulum, and would suffice to create
functional networked applications in local clusters, for example over radio links where all interested
nodes can directly hear each other. But to be truly useful, we need a way to direct traffic over multiple
-hops in the network. In the next sections, two concepts that allow this will be introduced, paths and
-links.
+hops in the network.
+
In the following sections, two concepts that allow this will be introduced, paths and links.
@@ -331,7 +333,70 @@ very limited. Existing routing protocols like BGP or OSPF carry too much overhea
useable over bandwidth-limited, high-latency links.
To overcome such challenges, Reticulum’s Transport system uses public-key cryptography to
implement the concept of paths that allow discovery of how to get information to a certain
-destination, and resources that help make reliable data transfer more efficient.
+destination. It is important to note that no single node in a Reticulum network knows the complete
+path to a destination. Every Transport node participating in a Reticulum network will only
+know what the most direct way to get a packet one hop closer to it’s destination is.
+
When an announce is transmitted by a node, it will be forwarded by any node receiving it, but
+according to some specific rules:
+
+
+
If this exact announce has already been received before, ignore it.
+
+
+
+
If not, record into a table which node the announce was received from, and how many times in
+total it has been retransmitted to get here.
+
+
+
+
If the announce has been retransmitted m+1 times, it will not be forwarded. By default, m is
+set to 18.
+
+
+
+
The announce will be assigned a delay d = ch seconds, where c is a decay constant, and h is the amount of times this packet has already been forwarded.
+
+
+
+
The packet will be given a priority p = 1/d.
+
+
+
+
If at least d seconds has passed since the announce was received, and no other packets with a
+priority higher than p are waiting in the queue (see Packet Prioritisation), and the channel is
+not utilized by other traffic, the announce will be forwarded.
+
+
+
+
If no other nodes are heard retransmitting the announce with a greater hop count than when
+it left this node, transmitting it will be retried r times. By default, r is set to 1. Retries
+follow same rules as above, with the exception that it must wait for at least d = ch+1 +
+t + rand(0, rw) seconds. This amount of time is equal to the amount of time it would take the next
+node to retransmit the packet, plus a random window. By default, t is set to 10 seconds, and the
+random window rw is set to 10 seconds.
+
+
+
+
If a newer announce from the same destination arrives, while an identical one is already in
+the queue, the newest announce is discarded. If the newest announce contains different
+application specific data, it will replace the old announce, but will use d and p of the old
+announce.
+
+
+
+
Once an announce has reached a node in the network, any other node in direct contact with that
+node will be able to reach the destination the announce originated from, simply by sending a packet
+addressed to that destination. Any node with knowledge of the announce will be able to direct the
+packet towards the destination by looking up the next node with the shortest amount of hops to the
+destination.
+
According to these rules and default constants, an announce will propagate throughout the network
+in a predictable way. In an example network utilising the default constants, and with an average link
+distance of Lavg = 15 kilometers, an announce will be able to propagate outwards to a radius of 180
+kilometers in 34 minutes, and a maximum announce radius of 270 kilometers in approximately 3
+days.
In networks with changing topology and trustless connectivity, nodes need a way to establish
@@ -341,27 +406,46 @@ expect. Reticulum offers two ways to do this.
For exchanges of small amounts of information, Reticulum offers the Packet API, which works exactly like you would expect - on a per packet level. The following process is employed when sending a packet:
-
A packet is always created with an associated destination and some payload data. When the packet is sent to a single destination type, Reticulum will automatically create an ephemeral encryption key, perform an ECDH key exchange with the destinations public key, and encrypt the information.
+
A packet is always created with an associated destination and some payload data. When the packet is sent
+to a single destination type, Reticulum will automatically create an ephemeral encryption key, perform
+an ECDH key exchange with the destinations public key, and encrypt the information.
-
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 announce, and can thus perform the ECDH key exchange locally.
+
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 announce, and can thus perform the ECDH
+key exchange locally, before sending the packet.
-
The public key part of the newly generated ephemeral key is included with the encrypted token, and sent along with the encrypted payload data in the packet.
+
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.
-
When the destination receives the packet, it can itself perform an ECDH key exchange and decrypt the packet.
+
When the destination receives the packet, it can itself perform an ECDH key exchange and decrypt the
+packet.
-
A new ephemeral key is used for every packet sent in this way, and forward secrecy is guaranteed on a per packet level.
+
A new ephemeral key is used for every packet sent in this way, and forward secrecy is guaranteed on a
+per packet level.
-
In case the packet is addressed to a group destination type, the packet will be encrypted with the pre-shared AES-128 key associated with the destination. In case the packet is addressed to a plain destination type, the payload data will not be encrypted. Neither of these two destination types offer forward secrecy. In general, it is recommended to always use the single destination type, unless it is strictly necessary to use one of the others.
+
Once the packet has been received and decrypted by the addressed destination, that destination can opt
+to prove its receipt of the packet. It does this by calculating the SHA-256 hash of the received packet,
+and signing this hash with it’s Ed25519 signing key. Transport nodes in the network can then direct this
+proof back to the packets origin, where the signature can be verified against the destinations known
+public signing key.
+
+
+
+
In case the packet is addressed to a group destination type, the packet will be encrypted with the
+pre-shared AES-128 key associated with the destination. In case the packet is addressed to a plain
+destination type, the payload data will not be encrypted. Neither of these two destination types offer
+forward secrecy. In general, it is recommended to always use the single destination type, unless it is
+strictly necessary to use one of the others.
@@ -387,16 +471,15 @@ remember the link , and it can subsequently be used by referring to a h
As a part of the link request , a Diffie-Hellman key exchange takes place, that sets up an
-efficient symmetrically encrypted tunnel between the two nodes, using elliptic curve
-cryptography. 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.
+efficiently encrypted tunnel between the two nodes, using elliptic curve cryptography. 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.
-
When a link has been set up, it automatically provides message receipt functionality, so the
-sending node can obtain verified confirmation that the information reached the intended
-recipient.
+
When a link has been set up, it automatically provides message receipt functionality, through
+the same proof mechanism discussed before, so the sending node can obtain verified confirmation
+that the information reached the intended recipient.
@@ -407,76 +490,18 @@ At the same time we establish an efficient encrypted channel. The setup of this
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 link id , 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 link id.
-
The total bandwidth cost of setting up a link is 409 bytes (more info in the Binary Packet Format section). The amount of bandwidth used on keeping a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
The pathfinding method builds on the announce functionality discussed earlier. When an announce
-is sent out by a node, it will be forwarded by any node receiving it, but according to some specific
-rules:
-
-
-
If this announce has already been received before, ignore it.
-
-
-
-
Record into a table which node the announce was received from, and how many times in
-total it has been retransmitted to get here.
-
-
-
-
If the announce has been retransmitted m+1 times, it will not be forwarded. By default, m is
-set to 18.
-
-
-
-
The announce will be assigned a delay d = ch seconds, where c is a decay constant, by
-default 2, and h is the amount of times this packet has already been forwarded.
-
-
-
-
The packet will be given a priority p = 1/d.
-
-
-
-
If at least d seconds has passed since the announce was received, and no other packets with a
-priority higher than p are waiting in the queue (see Packet Prioritisation), and the channel is
-not utilized by other traffic, the announce will be forwarded.
-
-
-
-
If no other nodes are heard retransmitting the announce with a greater hop count than when
-it left this node, transmitting it will be retried r times. By default, r is set to 2. Retries follow
-same rules as above, with the exception that it must wait for at least d = ch+1 + t seconds, ie.,
-the amount of time it would take the next node to retransmit the packet. By default, t is set to
-10.
-
-
-
-
If a newer announce from the same destination arrives, while an identical one is already in
-the queue, the newest announce is discarded. If the newest announce contains different
-application specific data, it will replace the old announce, but will use d and p of the old
-announce.
-
-
-
-
Once an announce has reached a node in the network, any other node in direct contact with that
-node will be able to reach the destination the announce originated from, simply by sending a packet
-addressed to that destination. Any node with knowledge of the announce will be able to direct the
-packet towards the destination by looking up the next node with the shortest amount of hops to the
-destination.
-
According to these rules and default constants, an announce will propagate throughout the network
-in a predictable way. In an example network utilising the default constants, and with an average link
-distance of Lavg = 15 kilometers, an announce will be able to propagate outwards to a radius of 180
-kilometers in 34 minutes, and a maximum announce radius of 270 kilometers in approximately 3
-days.
-
+
The combined bandwidth cost of setting up a link is 3 packets totalling 409 bytes (more info in the
+Binary Packet Format section). The amount of bandwidth used on keeping
+a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet
+radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
After seeing how the conditions for finding a path through the network are created, we will now
-explore how two nodes can establish reliable communications over multiple hops. The link in
-Reticulum terminology should not be viewed as a direct node-to-node link on the physical layer, but
-as an abstract channel, that can be open for any amount of time, and can span an arbitrary number
-of hops, where information will be exchanged between two nodes.
+
After exploring the basics of the announce mechanism, finding a path through the network, and an overview
+of the link establishment procedure, this section will go into greater detail about the Reticulum link
+establishment process.
+
The link in Reticulum terminology should not be viewed as a direct node-to-node link on the
+physical layer, but as an abstract channel, that can be open for any amount of time, and can span
+an arbitrary number of hops, where information will be exchanged between two nodes.
When a node in the network wants to establish verified connectivity with another node, it
@@ -491,8 +516,7 @@ considered as single public key for simplicity in this explanation.
The link request is addressed to the destination hash of the desired destination, and
-contains the following data: The newly generated X25519 public key LKi. The contents
-are encrypted with the RSA public key of the destination and tramsitted over the network.
+contains the following data: The newly generated X25519 public key LKi.
@@ -503,21 +527,22 @@ previously.
Any node that forwards the link request will store a link id in it’s link table , along with the
amount of hops the packet had taken when received. The link id is a hash of the entire link
-request packet. If the path is not proven within some set amount of time, the entry will be
-dropped from the link table again.
+request packet. If the link request packet is not proven by the addressed destination within some
+set amount of time, the entry will be dropped from the link table again.
-
When the destination receives the link request packet, it will decrypt it and decide whether to
-accept the request. If it is accepted, the destination will also generate a new X25519 private/public
-key pair, and perform a Diffie Hellman Key Exchange, deriving a new symmetric key that will be used
-to encrypt the channel, once it has been established.
+
When the destination receives the link request packet, it will decide whether to accept the request.
+If it is accepted, the destination will also generate a new X25519 private/public key pair, and
+perform a Diffie Hellman Key Exchange, deriving a new symmetric key that will be used to encrypt the
+channel, once it has been established.
A link proof packet is now constructed and transmitted over the network. This packet is
addressed to the link id of the link. It contains the following data: The newly generated X25519
-public key LKr and an RSA-1024 signature of the link id and LKr.
+public key LKr and an Ed25519 signature of the link id and LKr made by the signing key of
+the addressed destination.
@@ -541,10 +566,6 @@ reveal any identifying information about itself. The link initiator remains comp
When using links, Reticulum will automatically verify all data sent over the link, and can also
automate retransmissions if Resources are used.
diff --git a/docs/source/understanding.rst b/docs/source/understanding.rst
index 7c711e6..ecc106f 100644
--- a/docs/source/understanding.rst
+++ b/docs/source/understanding.rst
@@ -157,12 +157,16 @@ destinations. Reticulum uses three different basic destination types, and one sp
Destination Naming
^^^^^^^^^^^^^^^^^^
-Destinations are created and named in an easy to understand dotted notation of *aspects* , and
+Destinations are created and named in an easy to understand dotted notation of *aspects*, and
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 80 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. For example,
-a destination for a environmental monitoring application could be made up of the application name, a
-device type and measurement type, like this:
+The next levels of aspects can be defined in any way by the creator of the application.
+
+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.
+
+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:
.. code-block:: text
@@ -201,9 +205,8 @@ To recap, the different destination types should be used in the following situat
* **Single**
When private communication between two endpoints is needed. Supports multiple hops.
* **Group**
- When private communication between two or more endpoints is needed. More efficient in
- data usage than *single* destinations. Supports multiple hops indirectly, but must first be
- established through a *single* destination.
+ When private communication between two or more endpoints is needed. Supports multiple hops
+ indirectly, but must first be established through a *single* destination.
* **Plain**
When plain-text communication is desirable, for example when broadcasting information.
@@ -214,9 +217,9 @@ an unknown public key from the network, as all participating nodes serve as a di
of public keys.
Note that public key information can be shared and verified in many other ways than using the
-built-in methodology, and that it is therefore not required to use the announce/request functionality.
-It is by far the easiest though, and should definitely be used if there is not a good reason for
-doing it differently.
+built-in *announce* functionality, and that it is therefore not required to use the announce/request
+functionality to obtain public keys. It is by far the easiest though, and should definitely be used
+if there is not a good reason for doing it differently.
.. _understanding-keyannouncements:
@@ -235,7 +238,7 @@ contain the following information:
* The announcers public key
* Application specific data, in this case the users nickname and availability status
* A random blob, making each new announce unique
-* A signature of the above information, verifying authenticity
+* An Ed25519 signature of the above information, verifying authenticity
With this information, any Reticulum node that receives it will be able to reconstruct an outgoing
destination to securely communicate with that destination. You might have noticed that there is one
@@ -244,8 +247,9 @@ the aspect names of the destination. These are intentionally left out to save ba
will be implicit in almost all cases. If a destination name is not entirely implicit, information can be
included in the application specific data part that will allow the receiver to infer the naming.
-It is important to note that announcements will be forwarded throughout the network according to a
-certain pattern. This will be detailed later.
+It is important to note that announces will be forwarded throughout the network according to a
+certain pattern. This will be detailed in the section
+:ref:`The Announce Mechanism in Detail`.
Seeing how *single* destinations are always tied to a private/public key pair leads us to the next topic.
@@ -268,8 +272,8 @@ the identity first, and then link it to created destinations.
Building upon the simple messenger example, we could use an identity to represent the user of the
application. Destinations created will then be linked to this identity to allow communication to
-reach the user. In such a case it is of great importance to store the user’s identity securely and
-privately.
+reach the user. In all cases it is of great importance to store the private keys associated with any
+Reticulum Identity securely and privately.
.. _understanding-gettingfurther:
@@ -279,8 +283,9 @@ Getting Further
The above functions and principles form the core of Reticulum, and would suffice to create
functional networked applications in local clusters, for example over radio links where all interested
nodes can directly hear each other. But to be truly useful, we need a way to direct traffic over multiple
-hops in the network. In the next sections, two concepts that allow this will be introduced, *paths* and
-*links*.
+hops in the network.
+
+In the following sections, two concepts that allow this will be introduced, *paths* and *links*.
.. _understanding-transport:
@@ -298,85 +303,28 @@ useable over bandwidth-limited, high-latency links.
To overcome such challenges, Reticulum’s *Transport* system uses public-key cryptography to
implement the concept of *paths* that allow discovery of how to get information to a certain
-destination, and *resources* that help make reliable data transfer more efficient.
+destination. It is important to note that no single node in a Reticulum network knows the complete
+path to a destination. Every Transport node participating in a Reticulum network will only
+know what the most direct way to get a packet one hop closer to it's destination is.
-.. _understanding-paths:
+.. _understanding-announce:
-Reaching the Destination
-------------------------
+The Announce Mechanism in Detail
+--------------------------------
-In networks with changing topology and trustless connectivity, nodes need a way to establish
-*verified connectivity* 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.
-
-For exchanges of small amounts of information, Reticulum offers the *Packet* API, which works exactly like you would expect - on a per packet level. The following process is employed when sending a packet:
-
-* | A packet is always created with an associated destination and some payload data. When the packet is sent to a *single* destination type, Reticulum will automatically create an ephemeral encryption key, perform an ECDH key exchange with the destinations public key, and encrypt the information.
-
-* | 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 *announce*, and can thus perform the ECDH key exchange locally.
-
-* | The public key part of the newly generated ephemeral key is included with the encrypted token, and sent along with the encrypted payload data in the packet.
-
-* | When the destination receives the packet, it can itself perform an ECDH key exchange and decrypt the packet.
-
-* | A new ephemeral key is used for every packet sent in this way, and forward secrecy is guaranteed on a per packet level.
-
-* | In case the packet is addressed to a *group* destination type, the packet will be encrypted with the pre-shared AES-128 key associated with the destination. In case the packet is addressed to a *plain* destination type, the payload data will not be encrypted. Neither of these two destination types offer forward secrecy. In general, it is recommended to always use the *single* destination type, unless it is strictly necessary to use one of the others.
+When an *announce* is transmitted by a node, it will be forwarded by any node receiving it, but
+according to some specific rules:
-For exchanges of larger amounts of data, or when longer sessions of bidirectional communication is desired, Reticulum offers the *Link* API. To establish a *link*, the following process is employed:
+* | If this exact announce has already been received before, ignore it.
-* | 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 nodes that
- forward the packet will take note of this *link request*.
-
-* | Second, if the destination accepts the *link request* , it will send back a packet that proves the
- authenticity of it’s 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 *link* throughout the network.
-
-* | When the validity of the *link* has been accepted by forwarding nodes, these nodes will
- remember the *link* , and it can subsequently be used by referring to a hash representing it.
-
-* | As a part of the *link request* , a Diffie-Hellman key exchange takes place, that sets up an
- efficient symmetrically encrypted tunnel between the two nodes, using elliptic curve
- cryptography. 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.
-
-* | When a *link* has been set up, it automatically provides message receipt functionality, so the
- sending node can obtain verified confirmation that the information reached the intended
- recipient.
-
-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 *link id* , 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 *link id*.
-
-The total bandwidth cost of setting up a link is 409 bytes (more info in the :ref:`Binary Packet Format` section). The amount of bandwidth used on keeping a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
-
-Pathfinding in Detail
-^^^^^^^^^^^^^^^^^^^^^
-
-The pathfinding method builds on the *announce* functionality discussed earlier. When an announce
-is sent out by a node, it will be forwarded by any node receiving it, but according to some specific
-rules:
-
-
-* | If this announce has already been received before, ignore it.
-
-* | Record into a table which node the announce was received from, and how many times in
+* | If not, record into a table which node the announce was received from, and how many times in
total it has been retransmitted to get here.
* | If the announce has been retransmitted *m+1* times, it will not be forwarded. By default, *m* is
set to 18.
-* | The announce will be assigned a delay *d* = c\ :sup:`h` seconds, where *c* is a decay constant, by
- default 2, and *h* is the amount of times this packet has already been forwarded.
+* | The announce will be assigned a delay *d* = c\ :sup:`h` seconds, where *c* is a decay constant, and *h* is the amount of times this packet has already been forwarded.
* | The packet will be given a priority *p = 1/d*.
@@ -385,10 +333,11 @@ rules:
not utilized by other traffic, the announce will be forwarded.
* | If no other nodes are heard retransmitting the announce with a greater hop count than when
- it left this node, transmitting it will be retried *r* times. By default, *r* is set to 2. Retries follow
- same rules as above, with the exception that it must wait for at least *d* = c\ :sup:`h+1` + t seconds, ie.,
- the amount of time it would take the next node to retransmit the packet. By default, *t* is set to
- 10.
+ it left this node, transmitting it will be retried *r* times. By default, *r* is set to 1. Retries
+ follow same rules as above, with the exception that it must wait for at least *d* = c\ :sup:`h+1` +
+ t + rand(0, rw) seconds. This amount of time is equal to the amount of time it would take the next
+ node to retransmit the packet, plus a random window. By default, *t* is set to 10 seconds, and the
+ random window *rw* is set to 10 seconds.
* | If a newer announce from the same destination arrives, while an identical one is already in
the queue, the newest announce is discarded. If the newest announce contains different
@@ -407,14 +356,95 @@ distance of *Lavg =* 15 kilometers, an announce will be able to propagate outwar
kilometers in 34 minutes, and a *maximum announce radius* of 270 kilometers in approximately 3
days.
+.. _understanding-paths:
+
+Reaching the Destination
+------------------------
+
+In networks with changing topology and trustless connectivity, nodes need a way to establish
+*verified connectivity* 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.
+
+For exchanges of small amounts of information, Reticulum offers the *Packet* API, which works exactly like you would expect - on a per packet level. The following process is employed when sending a packet:
+
+* | A packet is always created with an associated destination and some payload data. When the packet is sent
+ to a *single* destination type, Reticulum will automatically create an ephemeral encryption key, perform
+ an ECDH key exchange with the destinations public key, and encrypt the information.
+
+* | 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 *announce*, and can thus perform the ECDH
+ key exchange locally, before sending the packet.
+
+* | 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.
+
+* | When the destination receives the packet, it can itself perform an ECDH key exchange and decrypt the
+ packet.
+
+* | A new ephemeral key is used for every packet sent in this way, and forward secrecy is guaranteed on a
+ per packet level.
+
+* | Once the packet has been received and decrypted by the addressed destination, that destination can opt
+ to *prove* its receipt of the packet. It does this by calculating the SHA-256 hash of the received packet,
+ and signing this hash with it's Ed25519 signing key. Transport nodes in the network can then direct this
+ *proof* back to the packets origin, where the signature can be verified against the destinations known
+ public signing key.
+
+* | In case the packet is addressed to a *group* destination type, the packet will be encrypted with the
+ pre-shared AES-128 key associated with the destination. In case the packet is addressed to a *plain*
+ destination type, the payload data will not be encrypted. Neither of these two destination types offer
+ forward secrecy. In general, it is recommended to always use the *single* destination type, unless it is
+ strictly necessary to use one of the others.
+
+
+For exchanges of larger amounts of data, or when longer sessions of bidirectional communication is desired, Reticulum offers the *Link* API. To establish a *link*, the following process is employed:
+
+* | 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 nodes that
+ forward the packet will take note of this *link request*.
+
+* | Second, if the destination accepts the *link request* , it will send back a packet that proves the
+ authenticity of it’s 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 *link* throughout the network.
+
+* | When the validity of the *link* has been accepted by forwarding nodes, these nodes will
+ remember the *link* , and it can subsequently be used by referring to a hash representing it.
+
+* | As a part of the *link request* , a Diffie-Hellman key exchange takes place, that sets up an
+ efficiently encrypted tunnel between the two nodes, using elliptic curve cryptography. 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.
+
+* | When a *link* has been set up, it automatically provides message receipt functionality, through
+ the same *proof* mechanism discussed before, so the sending node can obtain verified confirmation
+ that the information reached the intended recipient.
+
+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 *link id* , 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 *link id*.
+
+The combined bandwidth cost of setting up a link is 3 packets totalling 409 bytes (more info in the
+:ref:`Binary Packet Format` section). The amount of bandwidth used on keeping
+a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet
+radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
+
+
Link Establishment in Detail
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-After seeing how the conditions for finding a path through the network are created, we will now
-explore how two nodes can establish reliable communications over multiple hops. The *link* in
-Reticulum terminology should not be viewed as a direct node-to-node link on the physical layer, but
-as an abstract channel, that can be open for any amount of time, and can span an arbitrary number
-of hops, where information will be exchanged between two nodes.
+After exploring the basics of the announce mechanism, finding a path through the network, and an overview
+of the link establishment procedure, this section will go into greater detail about the Reticulum link
+establishment process.
+
+The *link* in Reticulum terminology should not be viewed as a direct node-to-node link on the
+physical layer, but as an abstract channel, that can be open for any amount of time, and can span
+an arbitrary number of hops, where information will be exchanged between two nodes.
* | When a node in the network wants to establish verified connectivity with another node, it
@@ -427,25 +457,25 @@ of hops, where information will be exchanged between two nodes.
considered as single public key for simplicity in this explanation.*
* | The *link request* is addressed to the destination hash of the desired destination, and
- contains the following data: The newly generated X25519 public key *LKi*. The contents
- are encrypted with the RSA public key of the destination and tramsitted over the network.
+ contains the following data: The newly generated X25519 public key *LKi*.
* | The broadcasted packet will be directed through the network according to the rules laid out
previously.
* | Any node that forwards the link request will store a *link id* in it’s *link table* , along with the
amount of hops the packet had taken when received. The link id is a hash of the entire link
- request packet. If the path is not *proven* within some set amount of time, the entry will be
- dropped from the *link table* again.
+ request packet. If the link request packet is not *proven* by the addressed destination within some
+ set amount of time, the entry will be dropped from the *link table* again.
-* | When the destination receives the link request packet, it will decrypt it and decide whether to
- accept the request. If it is accepted, the destination will also generate a new X25519 private/public
- key pair, and perform a Diffie Hellman Key Exchange, deriving a new symmetric key that will be used
- to encrypt the channel, once it has been established.
+* | When the destination receives the link request packet, it will decide whether to accept the request.
+ If it is accepted, the destination will also generate a new X25519 private/public key pair, and
+ perform a Diffie Hellman Key Exchange, deriving a new symmetric key that will be used to encrypt the
+ channel, once it has been established.
* | A *link proof* packet is now constructed and transmitted over the network. This packet is
addressed to the *link id* of the *link*. It contains the following data: The newly generated X25519
- public key *LKr* and an RSA-1024 signature of the *link id* and *LKr*.
+ public key *LKr* and an Ed25519 signature of the *link id* and *LKr* made by the signing key of
+ the addressed destination.
* | By verifying this *link proof* packet, all nodes that originally transported the *link request*
packet to the destination from the originator can now verify that the intended destination received
@@ -465,11 +495,6 @@ reveal any identifying information about itself. The link initiator remains comp
When using *links*, Reticulum will automatically verify all data sent over the link, and can also
automate retransmissions if *Resources* are used.
-Proven Delivery
-^^^^^^^^^^^^^^^
-
-TODO: Write
-
.. _understanding-resources:
Resources