Compare commits

..

7 Commits

Author SHA1 Message Date
Mark Qvist
6a392fdb0f Updated readme 2024-09-05 15:21:45 +02:00
Mark Qvist
b42e075be0 Updated manual and documentation 2024-09-05 15:17:58 +02:00
Mark Qvist
4bc8a0b69b Updated manual and documentation 2024-09-05 15:16:09 +02:00
Mark Qvist
9ef10a7b3e Expanded and documented ratchet API 2024-09-05 15:02:22 +02:00
Mark Qvist
320704f812 Updated documentation 2024-09-05 14:58:06 +02:00
Mark Qvist
c5e5986b89 Updated documentation 2024-09-05 12:58:35 +02:00
Mark Qvist
d21dda2830 Set context flags on path response 2024-09-04 19:39:59 +02:00
29 changed files with 400 additions and 152 deletions

View File

@ -306,9 +306,11 @@ general-purpose CPUs and on microcontrollers. The necessary primitives are:
- X22519 for ECDH key exchanges - X22519 for ECDH key exchanges
- HKDF for key derivation - HKDF for key derivation
- Modified Fernet for encrypted tokens - Modified Fernet for encrypted tokens
- AES-128 in CBC mode - Ephemeral keys derived from an ECDH key exchange on Curve25519
- HMAC for message authentication - AES-128 in CBC mode with PKCS7 padding
- No Fernet version and timestamp fields - HMAC using SHA256 for message authentication
- IVs are generated through os.urandom()
- No Fernet version and timestamp metadata fields
- SHA-256 - SHA-256
- SHA-512 - SHA-512

View File

@ -72,7 +72,16 @@ class Destination:
directions = [IN, OUT] directions = [IN, OUT]
PR_TAG_WINDOW = 30 PR_TAG_WINDOW = 30
RATCHET_COUNT = 512
RATCHET_COUNT = 512
"""
The default number of generated ratchet keys a destination will retain, if it has ratchets enabled.
"""
RATCHET_INTERVAL = 30*60
"""
The minimum interval between rotating ratchet keys, in seconds.
"""
@staticmethod @staticmethod
def expand_name(identity, app_name, *aspects): def expand_name(identity, app_name, *aspects):
@ -142,6 +151,10 @@ class Destination:
self.proof_strategy = Destination.PROVE_NONE self.proof_strategy = Destination.PROVE_NONE
self.ratchets = None self.ratchets = None
self.ratchets_path = None self.ratchets_path = None
self.ratchet_interval = Destination.RATCHET_INTERVAL
self.retained_ratchets = Destination.RATCHET_COUNT
self.latest_ratchet_time = None
self.__enforce_ratchets = False
self.mtu = 0 self.mtu = 0
self.path_responses = {} self.path_responses = {}
@ -175,36 +188,12 @@ class Destination:
""" """
return "<"+self.name+"/"+self.hexhash+">" return "<"+self.name+"/"+self.hexhash+">"
def enable_ratchets(self, ratchets_path): def _clean_ratchets(self):
if ratchets_path != None: if self.ratchets != None:
if os.path.isfile(ratchets_path): if len (self.ratchets) > self.retained_ratchets:
try: self.ratchets = self.ratchets[:Destination.RATCHET_COUNT]
ratchets_file = open(ratchets_path, "rb")
persisted_data = umsgpack.unpackb(ratchets_file.read())
if "signature" in persisted_data and "ratchets" in persisted_data:
if self.identity.validate(persisted_data["signature"], persisted_data["ratchets"]):
self.ratchets = umsgpack.unpackb(persisted_data["ratchets"])
self.ratchets_path = ratchets_path
else:
raise KeyError("Invalid ratchet file signature")
except Exception as e: def _persist_ratchets(self):
self.ratchets = None
self.ratchets_path = None
raise OSError("Could not read ratchet file contents for "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
else:
RNS.log("No existing ratchet data found, initialising new ratchet file for "+str(self), RNS.LOG_DEBUG)
self.ratchets = []
self.ratchets_path = ratchets_path
self.persist_ratchets()
RNS.log("Ratchets enabled on "+str(self), RNS.LOG_DEBUG) # TODO: Remove
return True
else:
raise ValueError("No ratchet file path specified for "+str(self))
def persist_ratchets(self):
try: try:
packed_ratchets = umsgpack.packb(self.ratchets) packed_ratchets = umsgpack.packb(self.ratchets)
persisted_data = {"signature": self.sign(packed_ratchets), "ratchets": packed_ratchets} persisted_data = {"signature": self.sign(packed_ratchets), "ratchets": packed_ratchets}
@ -218,15 +207,20 @@ class Destination:
def rotate_ratchets(self): def rotate_ratchets(self):
if self.ratchets != None: if self.ratchets != None:
RNS.log("Rotating ratchets for "+str(self), RNS.LOG_DEBUG) # TODO: Remove now = time.time()
new_ratchet = RNS.Identity._generate_ratchet() if now > self.latest_ratchet_time+self.ratchet_interval:
self.ratchets.insert(0, new_ratchet) RNS.log("Rotating ratchets for "+str(self), RNS.LOG_DEBUG)
if len (self.ratchets) > Destination.RATCHET_COUNT: new_ratchet = RNS.Identity._generate_ratchet()
self.ratchets = self.ratchets[:Destination.RATCHET_COUNT] self.ratchets.insert(0, new_ratchet)
self.persist_ratchets() self.latest_ratchet_time = now
self._clean_ratchets()
self._persist_ratchets()
return True
else: else:
raise SystemError("Cannot rotate ratchet on "+str(self)+", ratchets are not enabled") raise SystemError("Cannot rotate ratchet on "+str(self)+", ratchets are not enabled")
return False
def announce(self, app_data=None, path_response=False, attached_interface=None, tag=None, send=True): def announce(self, app_data=None, path_response=False, attached_interface=None, tag=None, send=True):
""" """
Creates an announce packet for this destination and broadcasts it on all Creates an announce packet for this destination and broadcasts it on all
@ -272,8 +266,8 @@ class Destination:
self.rotate_ratchets() self.rotate_ratchets()
ratchet = RNS.Identity._ratchet_public_bytes(self.ratchets[0]) ratchet = RNS.Identity._ratchet_public_bytes(self.ratchets[0])
# TODO: Remove debug output # TODO: Remove at some point
RNS.log(f"Including ratchet {RNS.prettyhexrep(RNS.Identity.truncated_hash(ratchet))} in announce", RNS.LOG_DEBUG) RNS.log(f"Including ratchet {RNS.prettyhexrep(RNS.Identity.truncated_hash(ratchet))} in announce", RNS.LOG_EXTREME)
if app_data == None and self.default_app_data != None: if app_data == None and self.default_app_data != None:
if isinstance(self.default_app_data, bytes): if isinstance(self.default_app_data, bytes):
@ -366,7 +360,6 @@ class Destination:
else: else:
self.proof_strategy = proof_strategy self.proof_strategy = proof_strategy
def register_request_handler(self, path, response_generator = None, allow = ALLOW_NONE, allowed_list = None): def register_request_handler(self, path, response_generator = None, allow = ALLOW_NONE, allowed_list = None):
""" """
Registers a request handler. Registers a request handler.
@ -388,7 +381,6 @@ class Destination:
request_handler = [path, response_generator, allow, allowed_list] request_handler = [path, response_generator, allow, allowed_list]
self.request_handlers[path_hash] = request_handler self.request_handlers[path_hash] = request_handler
def deregister_request_handler(self, path): def deregister_request_handler(self, path):
""" """
Deregisters a request handler. Deregisters a request handler.
@ -403,8 +395,6 @@ class Destination:
else: else:
return False return False
def receive(self, packet): def receive(self, packet):
if packet.packet_type == RNS.Packet.LINKREQUEST: if packet.packet_type == RNS.Packet.LINKREQUEST:
plaintext = packet.data plaintext = packet.data
@ -419,13 +409,99 @@ class Destination:
except Exception as e: except Exception as e:
RNS.log("Error while executing receive callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Error while executing receive callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
def incoming_link_request(self, data, packet): def incoming_link_request(self, data, packet):
if self.accept_link_requests: if self.accept_link_requests:
link = RNS.Link.validate_request(self, data, packet) link = RNS.Link.validate_request(self, data, packet)
if link != None: if link != None:
self.links.append(link) self.links.append(link)
def enable_ratchets(self, ratchets_path):
"""
Enables ratchets on the destination. When ratchets are enabled, Reticulum will automatically rotate
the keys used to encrypt packets to this destination, and include the latest ratchet key in announces.
Enabling ratchets on a destination will provide forward secrecy for packets sent to that destination,
even when sent outside a ``Link``. The normal Reticulum ``Link`` establishment procedure already performs
its own ephemeral key exchange for each link establishment, which means that ratchets are not necessary
to provide forward secrecy for links.
Enabling ratchets will have a small impact on announce size, adding 32 bytes to every sent announce.
:param ratchets_path: The path to a file to store ratchet data in.
:returns: True if the operation succeeded, otherwise False.
"""
if ratchets_path != None:
self.latest_ratchet_time = 0
if os.path.isfile(ratchets_path):
try:
ratchets_file = open(ratchets_path, "rb")
persisted_data = umsgpack.unpackb(ratchets_file.read())
if "signature" in persisted_data and "ratchets" in persisted_data:
if self.identity.validate(persisted_data["signature"], persisted_data["ratchets"]):
self.ratchets = umsgpack.unpackb(persisted_data["ratchets"])
self.ratchets_path = ratchets_path
else:
raise KeyError("Invalid ratchet file signature")
except Exception as e:
self.ratchets = None
self.ratchets_path = None
raise OSError("Could not read ratchet file contents for "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
else:
RNS.log("No existing ratchet data found, initialising new ratchet file for "+str(self), RNS.LOG_DEBUG)
self.ratchets = []
self.ratchets_path = ratchets_path
self._persist_ratchets()
# TODO: Remove at some point
RNS.log("Ratchets enabled on "+str(self), RNS.LOG_DEBUG)
return True
else:
raise ValueError("No ratchet file path specified for "+str(self))
def enforce_ratchets(self):
"""
When ratchet enforcement is enabled, this destination will never accept packets that use its
base Identity key for encryption, but only accept packets encrypted with one of the retained
ratchet keys.
"""
if self.ratchets != None:
self.__enforce_ratchets = True
RNS.log("Ratchets enforced on "+str(self), RNS.LOG_DEBUG)
return True
else:
return False
def set_retained_ratchets(self, retained_ratchets):
"""
Sets the number of previously generated ratchet keys this destination will retain,
and try to use when decrypting incoming packets. Defaults to ``Destination.RATCHET_COUNT``.
:param retained_ratchets: The number of generated ratchets to retain.
:returns: True if the operation succeeded, False if not.
"""
if isinstance(retained_ratchets, int) and retained_ratchets > 0:
self.retained_ratchets = retained_ratchets
self._clean_ratchets()
return True
else:
return False
def set_ratchet_interval(self, interval):
"""
Sets the minimum interval in seconds between ratchet key rotation.
Defaults to ``Destination.RATCHET_INTERVAL``.
:param interval: The minimum interval in seconds.
:returns: True if the operation succeeded, False if not.
"""
if isinstance(interval, int) and interval > 0:
self.ratchet_interval = interval
return True
else:
return False
def create_keys(self): def create_keys(self):
""" """
For a ``RNS.Destination.GROUP`` type destination, creates a new symmetric key. For a ``RNS.Destination.GROUP`` type destination, creates a new symmetric key.
@ -442,7 +518,6 @@ class Destination:
self.prv_bytes = Fernet.generate_key() self.prv_bytes = Fernet.generate_key()
self.prv = Fernet(self.prv_bytes) self.prv = Fernet(self.prv_bytes)
def get_private_key(self): def get_private_key(self):
""" """
For a ``RNS.Destination.GROUP`` type destination, returns the symmetric private key. For a ``RNS.Destination.GROUP`` type destination, returns the symmetric private key.
@ -456,7 +531,6 @@ class Destination:
else: else:
return self.prv_bytes return self.prv_bytes
def load_private_key(self, key): def load_private_key(self, key):
""" """
For a ``RNS.Destination.GROUP`` type destination, loads a symmetric private key. For a ``RNS.Destination.GROUP`` type destination, loads a symmetric private key.
@ -480,7 +554,6 @@ class Destination:
else: else:
raise TypeError("A single destination holds keys through an Identity instance") raise TypeError("A single destination holds keys through an Identity instance")
def encrypt(self, plaintext): def encrypt(self, plaintext):
""" """
Encrypts information for ``RNS.Destination.SINGLE`` or ``RNS.Destination.GROUP`` type destination. Encrypts information for ``RNS.Destination.SINGLE`` or ``RNS.Destination.GROUP`` type destination.
@ -504,8 +577,6 @@ class Destination:
else: else:
raise ValueError("No private key held by GROUP destination. Did you create or load one?") raise ValueError("No private key held by GROUP destination. Did you create or load one?")
def decrypt(self, ciphertext): def decrypt(self, ciphertext):
""" """
Decrypts information for ``RNS.Destination.SINGLE`` or ``RNS.Destination.GROUP`` type destination. Decrypts information for ``RNS.Destination.SINGLE`` or ``RNS.Destination.GROUP`` type destination.
@ -517,7 +588,7 @@ class Destination:
return ciphertext return ciphertext
if self.type == Destination.SINGLE and self.identity != None: if self.type == Destination.SINGLE and self.identity != None:
return self.identity.decrypt(ciphertext, ratchets=self.ratchets) return self.identity.decrypt(ciphertext, ratchets=self.ratchets, enforce_ratchets=self.__enforce_ratchets)
if self.type == Destination.GROUP: if self.type == Destination.GROUP:
if hasattr(self, "prv") and self.prv != None: if hasattr(self, "prv") and self.prv != None:
@ -529,7 +600,6 @@ class Destination:
else: else:
raise ValueError("No private key held by GROUP destination. Did you create or load one?") raise ValueError("No private key held by GROUP destination. Did you create or load one?")
def sign(self, message): def sign(self, message):
""" """
Signs information for ``RNS.Destination.SINGLE`` type destination. Signs information for ``RNS.Destination.SINGLE`` type destination.

View File

@ -26,6 +26,7 @@ import RNS
import time import time
import atexit import atexit
import hashlib import hashlib
import threading
from .vendor import umsgpack as umsgpack from .vendor import umsgpack as umsgpack
@ -49,11 +50,20 @@ class Identity:
KEYSIZE = 256*2 KEYSIZE = 256*2
""" """
X25519 key size in bits. A complete key is the concatenation of a 256 bit encryption key, and a 256 bit signing key. X.25519 key size in bits. A complete key is the concatenation of a 256 bit encryption key, and a 256 bit signing key.
""" """
RATCHETSIZE = 256 RATCHETSIZE = 256
"""
X.25519 ratchet key size in bits.
"""
RATCHET_EXPIRY = 60*60*24*30 RATCHET_EXPIRY = 60*60*24*30
"""
The expiry time for received ratchets in seconds, defaults to 30 days. Reticulum will always use the most recently
announced ratchet, and remember it for up to ``RATCHET_EXPIRY`` since receiving it, after which it will be discarded.
If a newer ratchet is announced in the meantime, it will be replace the already known ratchet.
"""
# Non-configurable constants # Non-configurable constants
FERNET_OVERHEAD = RNS.Cryptography.Fernet.FERNET_OVERHEAD FERNET_OVERHEAD = RNS.Cryptography.Fernet.FERNET_OVERHEAD
@ -72,6 +82,8 @@ class Identity:
known_destinations = {} known_destinations = {}
known_ratchets = {} known_ratchets = {}
ratchet_persist_lock = threading.Lock()
@staticmethod @staticmethod
def remember(packet_hash, destination_hash, public_key, app_data = None): def remember(packet_hash, destination_hash, public_key, app_data = None):
if len(public_key) != Identity.KEYSIZE//8: if len(public_key) != Identity.KEYSIZE//8:
@ -237,33 +249,64 @@ class Identity:
@staticmethod @staticmethod
def _remember_ratchet(destination_hash, ratchet): def _remember_ratchet(destination_hash, ratchet):
RNS.log(f"Remembering ratchet {RNS.prettyhexrep(Identity.truncated_hash(ratchet))} for {RNS.prettyhexrep(destination_hash)}", RNS.LOG_DEBUG) # TODO: Remove # TODO: Remove at some point
RNS.log(f"Remembering ratchet {RNS.prettyhexrep(Identity.truncated_hash(ratchet))} for {RNS.prettyhexrep(destination_hash)}", RNS.LOG_EXTREME)
try: try:
Identity.known_ratchets[destination_hash] = ratchet Identity.known_ratchets[destination_hash] = ratchet
hexhash = RNS.hexrep(destination_hash, delimit=False)
ratchet_data = {"ratchet": ratchet, "received": time.time()}
ratchetdir = RNS.Reticulum.storagepath+"/ratchets" if not RNS.Transport.owner.is_connected_to_shared_instance:
def persist_job():
with Identity.ratchet_persist_lock:
hexhash = RNS.hexrep(destination_hash, delimit=False)
ratchet_data = {"ratchet": ratchet, "received": time.time()}
if not os.path.isdir(ratchetdir): ratchetdir = RNS.Reticulum.storagepath+"/ratchets"
os.makedirs(ratchetdir)
outpath = f"{ratchetdir}/{hexhash}.out" if not os.path.isdir(ratchetdir):
finalpath = f"{ratchetdir}/{hexhash}" os.makedirs(ratchetdir)
ratchet_file = open(outpath, "wb")
ratchet_file.write(umsgpack.packb(ratchet_data)) outpath = f"{ratchetdir}/{hexhash}.out"
ratchet_file.close() finalpath = f"{ratchetdir}/{hexhash}"
os.rename(outpath, finalpath) ratchet_file = open(outpath, "wb")
ratchet_file.write(umsgpack.packb(ratchet_data))
ratchet_file.close()
os.rename(outpath, finalpath)
threading.Thread(target=persist_job, daemon=True).start()
except Exception as e: except Exception as e:
RNS.log(f"Could not persist ratchet for {RNS.prettyhexrep(destination_hash)} to storage.", RNS.LOG_ERROR) RNS.log(f"Could not persist ratchet for {RNS.prettyhexrep(destination_hash)} to storage.", RNS.LOG_ERROR)
RNS.log(f"The contained exception was: {e}") RNS.log(f"The contained exception was: {e}")
RNS.trace_exception(e) RNS.trace_exception(e)
@staticmethod
def _clean_ratchets():
RNS.log("Cleaning ratchets...", RNS.LOG_DEBUG)
try:
now = time.time()
ratchetdir = RNS.Reticulum.storagepath+"/ratchets"
for filename in os.listdir(ratchetdir):
try:
expired = False
with open(f"{ratchetdir}/{filename}", "rb") as rf:
ratchet_data = umsgpack.unpackb(rf.read())
if now > ratchet_data["received"]+Identity.RATCHET_EXPIRY:
expired = True
if expired:
os.unlink(f"{ratchetdir}/{filename}")
except Exception as e:
RNS.log(f"An error occurred while cleaning ratchets, in the processing of {ratchetdir}/{filename}.", RNS.LOG_ERROR)
RNS.log(f"The contained exception was: {e}", RNS.LOG_ERROR)
except Exception as e:
RNS.log(f"An error occurred while cleaning ratchets. The contained exception was: {e}", RNS.LOG_ERROR)
@staticmethod @staticmethod
def get_ratchet(destination_hash): def get_ratchet(destination_hash):
if not destination_hash in Identity.known_ratchets: if not destination_hash in Identity.known_ratchets:
RNS.log(f"Trying to load ratchet for {RNS.prettyhexrep(destination_hash)} from storage") # TODO: Remove
ratchetdir = RNS.Reticulum.storagepath+"/ratchets" ratchetdir = RNS.Reticulum.storagepath+"/ratchets"
hexhash = RNS.hexrep(destination_hash, delimit=False) hexhash = RNS.hexrep(destination_hash, delimit=False)
ratchet_path = f"{ratchetdir}/hexhash" ratchet_path = f"{ratchetdir}/hexhash"
@ -284,6 +327,7 @@ class Identity:
if destination_hash in Identity.known_ratchets: if destination_hash in Identity.known_ratchets:
return Identity.known_ratchets[destination_hash] return Identity.known_ratchets[destination_hash]
else: else:
RNS.log(f"Could not load ratchet for {RNS.prettyhexrep(destination_hash)}", RNS.LOG_DEBUG)
return None return None
@staticmethod @staticmethod
@ -572,7 +616,8 @@ class Identity:
ephemeral_pub_bytes = ephemeral_key.public_key().public_bytes() ephemeral_pub_bytes = ephemeral_key.public_key().public_bytes()
if ratchet != None: if ratchet != None:
RNS.log(f"Encrypting with ratchet {RNS.prettyhexrep(RNS.Identity.truncated_hash(ratchet))}", RNS.LOG_DEBUG) # TODO: Remove # TODO: Remove at some point
RNS.log(f"Encrypting with ratchet {RNS.prettyhexrep(RNS.Identity.truncated_hash(ratchet))}", RNS.LOG_EXTREME)
target_public_key = X25519PublicKey.from_public_bytes(ratchet) target_public_key = X25519PublicKey.from_public_bytes(ratchet)
else: else:
target_public_key = self.pub target_public_key = self.pub
@ -595,7 +640,7 @@ class Identity:
raise KeyError("Encryption failed because identity does not hold a public key") raise KeyError("Encryption failed because identity does not hold a public key")
def decrypt(self, ciphertext_token, ratchets=None): def decrypt(self, ciphertext_token, ratchets=None, enforce_ratchets=False):
""" """
Decrypts information for the identity. Decrypts information for the identity.
@ -626,14 +671,17 @@ class Identity:
fernet = Fernet(derived_key) fernet = Fernet(derived_key)
plaintext = fernet.decrypt(ciphertext) plaintext = fernet.decrypt(ciphertext)
# TODO: Remove # TODO: Remove at some point
RNS.log(f"Decrypted with ratchet {RNS.prettyhexrep(RNS.Identity.truncated_hash(ratchet_prv.public_key().public_bytes()))}", RNS.LOG_DEBUG) RNS.log(f"Decrypted with ratchet {RNS.prettyhexrep(RNS.Identity.truncated_hash(ratchet_prv.public_key().public_bytes()))}", RNS.LOG_EXTREME)
break break
except Exception as e: except Exception as e:
pass pass
# RNS.log("Decryption using this ratchet failed", RNS.LOG_DEBUG) # TODO: Remove
if enforce_ratchets and plaintext == None:
RNS.log("Decryption with ratchet enforcement by "+RNS.prettyhexrep(self.hash)+" failed. Dropping packet.", RNS.LOG_DEBUG)
return None
if plaintext == None: if plaintext == None:
shared_key = self.prv.exchange(peer_pub) shared_key = self.prv.exchange(peer_pub)

View File

@ -295,6 +295,7 @@ class Reticulum:
def __start_jobs(self): def __start_jobs(self):
if self.jobs_thread == None: if self.jobs_thread == None:
RNS.Identity._clean_ratchets()
self.jobs_thread = threading.Thread(target=self.__jobs) self.jobs_thread = threading.Thread(target=self.__jobs)
self.jobs_thread.daemon = True self.jobs_thread.daemon = True
self.jobs_thread.start() self.jobs_thread.start()

View File

@ -1604,7 +1604,8 @@ class Transport:
header_type = RNS.Packet.HEADER_2, header_type = RNS.Packet.HEADER_2,
transport_type = Transport.TRANSPORT, transport_type = Transport.TRANSPORT,
transport_id = Transport.identity.hash, transport_id = Transport.identity.hash,
attached_interface = local_interface attached_interface = local_interface,
context_flag = packet.context_flag,
) )
new_announce.hops = packet.hops new_announce.hops = packet.hops
@ -1621,7 +1622,8 @@ class Transport:
header_type = RNS.Packet.HEADER_2, header_type = RNS.Packet.HEADER_2,
transport_type = Transport.TRANSPORT, transport_type = Transport.TRANSPORT,
transport_id = Transport.identity.hash, transport_id = Transport.identity.hash,
attached_interface = local_interface attached_interface = local_interface,
context_flag = packet.context_flag,
) )
new_announce.hops = packet.hops new_announce.hops = packet.hops
@ -1652,7 +1654,8 @@ class Transport:
header_type = RNS.Packet.HEADER_2, header_type = RNS.Packet.HEADER_2,
transport_type = Transport.TRANSPORT, transport_type = Transport.TRANSPORT,
transport_id = Transport.identity.hash, transport_id = Transport.identity.hash,
attached_interface = attached_interface attached_interface = attached_interface,
context_flag = packet.context_flag,
) )
new_announce.hops = packet.hops new_announce.hops = packet.hops

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
# Sphinx build info version 1 # Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 4a5b669a6756de77e9b7c6b7dc5d5702 config: 895ecce87b0f2ca7fbb104a33248dc3e
tags: 645f666f9bcd5a90fca523b33c5a78b7 tags: 645f666f9bcd5a90fca523b33c5a78b7

View File

@ -134,10 +134,11 @@ be sufficient, even far into the future.
By default Reticulum encrypts all data using elliptic curve cryptography and AES. Any packet sent to a By default Reticulum encrypts all data using elliptic curve cryptography and AES. Any packet sent to a
destination is encrypted with a per-packet derived key. Reticulum can also set up an encrypted destination is encrypted with a per-packet derived key. Reticulum can also set up an encrypted
channel to a destination, called a *Link*. Both data sent over Links and single packets offer channel to a destination, called a *Link*. Both data sent over Links and single packets offer
*Initiator Anonymity*, and links additionally offer *Forward Secrecy* by using an Elliptic Curve *Initiator Anonymity*. Links additionally offer *Forward Secrecy* by default, employing an Elliptic Curve
Diffie Hellman key exchange on Curve25519 to derive per-link ephemeral keys. The multi-hop transport, Diffie Hellman key exchange on Curve25519 to derive per-link ephemeral keys. Asymmetric, link-less
coordination, verification and reliability layers are fully autonomous and also based on elliptic packet communication can also provide forward secrecy, with automatic key ratcheting, by enabling
curve cryptography. ratchets on a per-destination basis. The multi-hop transport, coordination, verification and reliability
layers are fully autonomous and also based on elliptic curve cryptography.
Reticulum also offers symmetric key encryption for group-oriented communications, as well as Reticulum also offers symmetric key encryption for group-oriented communications, as well as
unencrypted packets for local broadcast purposes. unencrypted packets for local broadcast purposes.
@ -431,7 +432,7 @@ For exchanges of small amounts of information, Reticulum offers the *Packet* API
* | A packet is always created with an associated destination and some payload data. When the packet is sent * | 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 to a *single* destination type, Reticulum will automatically create an ephemeral encryption key, perform
an ECDH key exchange with the destination's public key, and encrypt the information. an ECDH key exchange with the destination's public key (or ratchet key, if available), and encrypt the information.
* | It is important to note that this key exchange does not require any network traffic. The sender already * | 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 knows the public key of the destination from an earlier received *announce*, and can thus perform the ECDH
@ -867,12 +868,14 @@ both on general-purpose CPUs and on microcontrollers. The necessary primitives a
* HKDF for key derivation * HKDF for key derivation
* Fernet for encrypted tokens * Modified Fernet for encrypted tokens
* AES-128 in CBC mode * AES-128 in CBC mode
* HMAC for message authentication * HMAC for message authentication
* No Version and Timestamp metadata included
* SHA-256 * SHA-256
* SHA-512 * SHA-512

View File

@ -53,9 +53,9 @@ What does Reticulum Offer?
* Forward Secrecy by using ephemeral Elliptic Curve Diffie-Hellman keys on Curve25519 * Forward Secrecy by using ephemeral Elliptic Curve Diffie-Hellman keys on Curve25519
* Reticulum uses the `Fernet <https://github.com/fernet/spec/blob/master/Spec.md>`_ specification for on-the-wire / over-the-air encryption * Reticulum uses a modified version of the `Fernet <https://github.com/fernet/spec/blob/master/Spec.md>`_ specification for on-the-wire / over-the-air encryption
* All keys are ephemeral and derived from an ECDH key exchange on Curve25519 * Keys are ephemeral and derived from an ECDH key exchange on Curve25519
* AES-128 in CBC mode with PKCS7 padding * AES-128 in CBC mode with PKCS7 padding
@ -63,6 +63,8 @@ What does Reticulum Offer?
* IVs are generated through os.urandom() * IVs are generated through os.urandom()
* No Version and Timestamp metadata included
* Unforgeable packet delivery confirmations * Unforgeable packet delivery confirmations
* A variety of supported interface types * A variety of supported interface types
@ -99,7 +101,8 @@ of the types of interfaces Reticulum was designed for.
An open-source LoRa-based interface called `RNode <https://unsigned.io/rnode>`_ An open-source LoRa-based interface called `RNode <https://unsigned.io/rnode>`_
has been designed as an example transceiver that is very suitable for has been designed as an example transceiver that is very suitable for
Reticulum. It is possible to build it yourself, to transform a common LoRa Reticulum. It is possible to build it yourself, to transform a common LoRa
development board into one, or it can be purchased as a complete transceiver. development board into one, or it can be purchased as a complete transceiver
from various vendors.
Reticulum can also be encapsulated over existing IP networks, so there's Reticulum can also be encapsulated over existing IP networks, so there's
nothing stopping you from using it over wired Ethernet or your local WiFi nothing stopping you from using it over wired Ethernet or your local WiFi

View File

@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = { var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.7.6 beta', VERSION: '0.7.7 beta',
LANGUAGE: 'en', LANGUAGE: 'en',
COLLAPSE_INDEX: false, COLLAPSE_INDEX: false,
BUILDER: 'html', BUILDER: 'html',

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Support Reticulum" href="support.html" /><link rel="prev" title="Building Networks" href="networks.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Support Reticulum" href="support.html" /><link rel="prev" title="Building Networks" href="networks.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Code Examples - Reticulum Network Stack 0.7.6 beta documentation</title> <title>Code Examples - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>An Explanation of Reticulum for Human Beings - Reticulum Network Stack 0.7.6 beta documentation</title> <title>An Explanation of Reticulum for Human Beings - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

View File

@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/> <meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="#" /><link rel="search" title="Search" href="search.html" /> <meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="#" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/><title>Index - Reticulum Network Stack 0.7.6 beta documentation</title> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/><title>Index - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -139,7 +139,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -165,7 +165,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@ -330,6 +330,8 @@
<h2>E</h2> <h2>E</h2>
<table style="width: 100%" class="indextable genindextable"><tr> <table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul> <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Destination.enable_ratchets">enable_ratchets() (RNS.Destination method)</a>
</li>
<li><a href="reference.html#RNS.Destination.encrypt">encrypt() (RNS.Destination method)</a> <li><a href="reference.html#RNS.Destination.encrypt">encrypt() (RNS.Destination method)</a>
<ul> <ul>
@ -339,6 +341,8 @@
</ul></td> </ul></td>
<td style="width: 33%; vertical-align: top;"><ul> <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Packet.ENCRYPTED_MDU">ENCRYPTED_MDU (RNS.Packet attribute)</a> <li><a href="reference.html#RNS.Packet.ENCRYPTED_MDU">ENCRYPTED_MDU (RNS.Packet attribute)</a>
</li>
<li><a href="reference.html#RNS.Destination.enforce_ratchets">enforce_ratchets() (RNS.Destination method)</a>
</li> </li>
<li><a href="reference.html#RNS.Link.ESTABLISHMENT_TIMEOUT_PER_HOP">ESTABLISHMENT_TIMEOUT_PER_HOP (RNS.Link attribute)</a> <li><a href="reference.html#RNS.Link.ESTABLISHMENT_TIMEOUT_PER_HOP">ESTABLISHMENT_TIMEOUT_PER_HOP (RNS.Link attribute)</a>
</li> </li>
@ -568,6 +572,14 @@
<h2>R</h2> <h2>R</h2>
<table style="width: 100%" class="indextable genindextable"><tr> <table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul> <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Destination.RATCHET_COUNT">RATCHET_COUNT (RNS.Destination attribute)</a>
</li>
<li><a href="reference.html#RNS.Identity.RATCHET_EXPIRY">RATCHET_EXPIRY (RNS.Identity attribute)</a>
</li>
<li><a href="reference.html#RNS.Destination.RATCHET_INTERVAL">RATCHET_INTERVAL (RNS.Destination attribute)</a>
</li>
<li><a href="reference.html#RNS.Identity.RATCHETSIZE">RATCHETSIZE (RNS.Identity attribute)</a>
</li>
<li><a href="reference.html#RNS.RawChannelReader">RawChannelReader (class in RNS)</a> <li><a href="reference.html#RNS.RawChannelReader">RawChannelReader (class in RNS)</a>
</li> </li>
<li><a href="reference.html#RNS.RawChannelWriter">RawChannelWriter (class in RNS)</a> <li><a href="reference.html#RNS.RawChannelWriter">RawChannelWriter (class in RNS)</a>
@ -580,12 +592,12 @@
</li> </li>
<li><a href="reference.html#RNS.Channel.Channel.register_message_type">register_message_type() (RNS.Channel.Channel method)</a> <li><a href="reference.html#RNS.Channel.Channel.register_message_type">register_message_type() (RNS.Channel.Channel method)</a>
</li> </li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Destination.register_request_handler">register_request_handler() (RNS.Destination method)</a> <li><a href="reference.html#RNS.Destination.register_request_handler">register_request_handler() (RNS.Destination method)</a>
</li> </li>
<li><a href="reference.html#RNS.Reticulum.remote_management_enabled">remote_management_enabled() (RNS.Reticulum static method)</a> <li><a href="reference.html#RNS.Reticulum.remote_management_enabled">remote_management_enabled() (RNS.Reticulum static method)</a>
</li> </li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Channel.Channel.remove_message_handler">remove_message_handler() (RNS.Channel.Channel method)</a> <li><a href="reference.html#RNS.Channel.Channel.remove_message_handler">remove_message_handler() (RNS.Channel.Channel method)</a>
</li> </li>
<li><a href="reference.html#RNS.RawChannelReader.remove_ready_callback">remove_ready_callback() (RNS.RawChannelReader method)</a> <li><a href="reference.html#RNS.RawChannelReader.remove_ready_callback">remove_ready_callback() (RNS.RawChannelReader method)</a>
@ -633,6 +645,8 @@
<li><a href="reference.html#RNS.Destination.set_proof_requested_callback">set_proof_requested_callback() (RNS.Destination method)</a> <li><a href="reference.html#RNS.Destination.set_proof_requested_callback">set_proof_requested_callback() (RNS.Destination method)</a>
</li> </li>
<li><a href="reference.html#RNS.Destination.set_proof_strategy">set_proof_strategy() (RNS.Destination method)</a> <li><a href="reference.html#RNS.Destination.set_proof_strategy">set_proof_strategy() (RNS.Destination method)</a>
</li>
<li><a href="reference.html#RNS.Destination.set_ratchet_interval">set_ratchet_interval() (RNS.Destination method)</a>
</li> </li>
<li><a href="reference.html#RNS.Link.set_remote_identified_callback">set_remote_identified_callback() (RNS.Link method)</a> <li><a href="reference.html#RNS.Link.set_remote_identified_callback">set_remote_identified_callback() (RNS.Link method)</a>
</li> </li>
@ -645,6 +659,8 @@
<li><a href="reference.html#RNS.Link.set_resource_started_callback">set_resource_started_callback() (RNS.Link method)</a> <li><a href="reference.html#RNS.Link.set_resource_started_callback">set_resource_started_callback() (RNS.Link method)</a>
</li> </li>
<li><a href="reference.html#RNS.Link.set_resource_strategy">set_resource_strategy() (RNS.Link method)</a> <li><a href="reference.html#RNS.Link.set_resource_strategy">set_resource_strategy() (RNS.Link method)</a>
</li>
<li><a href="reference.html#RNS.Destination.set_retained_ratchets">set_retained_ratchets() (RNS.Destination method)</a>
</li> </li>
<li><a href="reference.html#RNS.PacketReceipt.set_timeout">set_timeout() (RNS.PacketReceipt method)</a> <li><a href="reference.html#RNS.PacketReceipt.set_timeout">set_timeout() (RNS.PacketReceipt method)</a>
</li> </li>

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Using Reticulum on Your System" href="using.html" /><link rel="prev" title="What is Reticulum?" href="whatis.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Using Reticulum on Your System" href="using.html" /><link rel="prev" title="What is Reticulum?" href="whatis.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Getting Started Fast - Reticulum Network Stack 0.7.6 beta documentation</title> <title>Getting Started Fast - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Configuring Interfaces" href="interfaces.html" /><link rel="prev" title="Understanding Reticulum" href="understanding.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Configuring Interfaces" href="interfaces.html" /><link rel="prev" title="Understanding Reticulum" href="understanding.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Communications Hardware - Reticulum Network Stack 0.7.6 beta documentation</title> <title>Communications Hardware - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="What is Reticulum?" href="whatis.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="What is Reticulum?" href="whatis.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Reticulum Network Stack 0.7.6 beta documentation</title> <title>Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="#"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="#"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Building Networks" href="networks.html" /><link rel="prev" title="Communications Hardware" href="hardware.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Building Networks" href="networks.html" /><link rel="prev" title="Communications Hardware" href="hardware.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Configuring Interfaces - Reticulum Network Stack 0.7.6 beta documentation</title> <title>Configuring Interfaces - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Code Examples" href="examples.html" /><link rel="prev" title="Configuring Interfaces" href="interfaces.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Code Examples" href="examples.html" /><link rel="prev" title="Configuring Interfaces" href="interfaces.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Building Networks - Reticulum Network Stack 0.7.6 beta documentation</title> <title>Building Networks - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

Binary file not shown.

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="prev" title="Support Reticulum" href="support.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="prev" title="Support Reticulum" href="support.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>API Reference - Reticulum Network Stack 0.7.6 beta documentation</title> <title>API Reference - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@ -356,7 +356,21 @@ for all encrypted communication over Reticulum networks.</p>
<dl class="py attribute"> <dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Identity.KEYSIZE"> <dt class="sig sig-object py" id="RNS.Identity.KEYSIZE">
<span class="sig-name descname"><span class="pre">KEYSIZE</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">512</span></em><a class="headerlink" href="#RNS.Identity.KEYSIZE" title="Permalink to this definition">#</a></dt> <span class="sig-name descname"><span class="pre">KEYSIZE</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">512</span></em><a class="headerlink" href="#RNS.Identity.KEYSIZE" title="Permalink to this definition">#</a></dt>
<dd><p>X25519 key size in bits. A complete key is the concatenation of a 256 bit encryption key, and a 256 bit signing key.</p> <dd><p>X.25519 key size in bits. A complete key is the concatenation of a 256 bit encryption key, and a 256 bit signing key.</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Identity.RATCHETSIZE">
<span class="sig-name descname"><span class="pre">RATCHETSIZE</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">256</span></em><a class="headerlink" href="#RNS.Identity.RATCHETSIZE" title="Permalink to this definition">#</a></dt>
<dd><p>X.25519 ratchet key size in bits.</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Identity.RATCHET_EXPIRY">
<span class="sig-name descname"><span class="pre">RATCHET_EXPIRY</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">2592000</span></em><a class="headerlink" href="#RNS.Identity.RATCHET_EXPIRY" title="Permalink to this definition">#</a></dt>
<dd><p>The expiry time for received ratchets in seconds, defaults to 30 days. Reticulum will always use the most recently
announced ratchet, and remember it for up to <code class="docutils literal notranslate"><span class="pre">RATCHET_EXPIRY</span></code> since receiving it, after which it will be discarded.
If a newer ratchet is announced in the meantime, it will be replace the already known ratchet.</p>
</dd></dl> </dd></dl>
<dl class="py attribute"> <dl class="py attribute">
@ -549,7 +563,7 @@ communication for the identity. Be very careful with this method.</p>
<dl class="py method"> <dl class="py method">
<dt class="sig sig-object py" id="RNS.Identity.decrypt"> <dt class="sig sig-object py" id="RNS.Identity.decrypt">
<span class="sig-name descname"><span class="pre">decrypt</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">ciphertext_token</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">ratchets</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Identity.decrypt" title="Permalink to this definition">#</a></dt> <span class="sig-name descname"><span class="pre">decrypt</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">ciphertext_token</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">ratchets</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">enforce_ratchets</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Identity.decrypt" title="Permalink to this definition">#</a></dt>
<dd><p>Decrypts information for the identity.</p> <dd><p>Decrypts information for the identity.</p>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt> <dt class="field-odd">Parameters<span class="colon">:</span></dt>
@ -624,6 +638,18 @@ encrypted communication with it.</p>
</ul> </ul>
</dd> </dd>
</dl> </dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Destination.RATCHET_COUNT">
<span class="sig-name descname"><span class="pre">RATCHET_COUNT</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">512</span></em><a class="headerlink" href="#RNS.Destination.RATCHET_COUNT" title="Permalink to this definition">#</a></dt>
<dd><p>The default number of generated ratchet keys a destination will retain, if it has ratchets enabled.</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Destination.RATCHET_INTERVAL">
<span class="sig-name descname"><span class="pre">RATCHET_INTERVAL</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">1800</span></em><a class="headerlink" href="#RNS.Destination.RATCHET_INTERVAL" title="Permalink to this definition">#</a></dt>
<dd><p>The minimum interval between rotating ratchet keys, in seconds.</p>
</dd></dl>
<dl class="py method"> <dl class="py method">
<dt class="sig sig-object py" id="RNS.Destination.expand_name"> <dt class="sig sig-object py" id="RNS.Destination.expand_name">
<em class="property"><span class="pre">static</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">expand_name</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">identity</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">app_name</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">aspects</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.expand_name" title="Permalink to this definition">#</a></dt> <em class="property"><span class="pre">static</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">expand_name</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">identity</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">app_name</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">aspects</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.expand_name" title="Permalink to this definition">#</a></dt>
@ -774,6 +800,64 @@ proofs should be returned for received packets.</p>
</dl> </dl>
</dd></dl> </dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Destination.enable_ratchets">
<span class="sig-name descname"><span class="pre">enable_ratchets</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">ratchets_path</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.enable_ratchets" title="Permalink to this definition">#</a></dt>
<dd><p>Enables ratchets on the destination. When ratchets are enabled, Reticulum will automatically rotate
the keys used to encrypt packets to this destination, and include the latest ratchet key in announces.</p>
<p>Enabling ratchets on a destination will provide forward secrecy for packets sent to that destination,
even when sent outside a <code class="docutils literal notranslate"><span class="pre">Link</span></code>. The normal Reticulum <code class="docutils literal notranslate"><span class="pre">Link</span></code> establishment procedure already performs
its own ephemeral key exchange for each link establishment, which means that ratchets are not necessary
to provide forward secrecy for links.</p>
<p>Enabling ratchets will have a small impact on announce size, adding 32 bytes to every sent announce.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>ratchets_path</strong> The path to a file to store ratchet data in.</p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>True if the operation succeeded, otherwise False.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Destination.enforce_ratchets">
<span class="sig-name descname"><span class="pre">enforce_ratchets</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.enforce_ratchets" title="Permalink to this definition">#</a></dt>
<dd><p>When ratchet enforcement is enabled, this destination will never accept packets that use its
base Identity key for encryption, but only accept packets encrypted with one of the retained
ratchet keys.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Destination.set_retained_ratchets">
<span class="sig-name descname"><span class="pre">set_retained_ratchets</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">retained_ratchets</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.set_retained_ratchets" title="Permalink to this definition">#</a></dt>
<dd><p>Sets the number of previously generated ratchet keys this destination will retain,
and try to use when decrypting incoming packets. Defaults to <code class="docutils literal notranslate"><span class="pre">Destination.RATCHET_COUNT</span></code>.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>retained_ratchets</strong> The number of generated ratchets to retain.</p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>True if the operation succeeded, False if not.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Destination.set_ratchet_interval">
<span class="sig-name descname"><span class="pre">set_ratchet_interval</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">interval</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.set_ratchet_interval" title="Permalink to this definition">#</a></dt>
<dd><p>Sets the minimum interval in seconds between ratchet key rotation.
Defaults to <code class="docutils literal notranslate"><span class="pre">Destination.RATCHET_INTERVAL</span></code>.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>interval</strong> The minimum interval in seconds.</p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>True if the operation succeeded, False if not.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method"> <dl class="py method">
<dt class="sig sig-object py" id="RNS.Destination.create_keys"> <dt class="sig sig-object py" id="RNS.Destination.create_keys">
<span class="sig-name descname"><span class="pre">create_keys</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.create_keys" title="Permalink to this definition">#</a></dt> <span class="sig-name descname"><span class="pre">create_keys</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.create_keys" title="Permalink to this definition">#</a></dt>
@ -1964,6 +2048,8 @@ will announce it.</p>
<li><a class="reference internal" href="#RNS.Identity"><code class="docutils literal notranslate"><span class="pre">Identity</span></code></a><ul> <li><a class="reference internal" href="#RNS.Identity"><code class="docutils literal notranslate"><span class="pre">Identity</span></code></a><ul>
<li><a class="reference internal" href="#RNS.Identity.CURVE"><code class="docutils literal notranslate"><span class="pre">CURVE</span></code></a></li> <li><a class="reference internal" href="#RNS.Identity.CURVE"><code class="docutils literal notranslate"><span class="pre">CURVE</span></code></a></li>
<li><a class="reference internal" href="#RNS.Identity.KEYSIZE"><code class="docutils literal notranslate"><span class="pre">KEYSIZE</span></code></a></li> <li><a class="reference internal" href="#RNS.Identity.KEYSIZE"><code class="docutils literal notranslate"><span class="pre">KEYSIZE</span></code></a></li>
<li><a class="reference internal" href="#RNS.Identity.RATCHETSIZE"><code class="docutils literal notranslate"><span class="pre">RATCHETSIZE</span></code></a></li>
<li><a class="reference internal" href="#RNS.Identity.RATCHET_EXPIRY"><code class="docutils literal notranslate"><span class="pre">RATCHET_EXPIRY</span></code></a></li>
<li><a class="reference internal" href="#RNS.Identity.TRUNCATED_HASHLENGTH"><code class="docutils literal notranslate"><span class="pre">TRUNCATED_HASHLENGTH</span></code></a></li> <li><a class="reference internal" href="#RNS.Identity.TRUNCATED_HASHLENGTH"><code class="docutils literal notranslate"><span class="pre">TRUNCATED_HASHLENGTH</span></code></a></li>
<li><a class="reference internal" href="#RNS.Identity.recall"><code class="docutils literal notranslate"><span class="pre">recall()</span></code></a></li> <li><a class="reference internal" href="#RNS.Identity.recall"><code class="docutils literal notranslate"><span class="pre">recall()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Identity.recall_app_data"><code class="docutils literal notranslate"><span class="pre">recall_app_data()</span></code></a></li> <li><a class="reference internal" href="#RNS.Identity.recall_app_data"><code class="docutils literal notranslate"><span class="pre">recall_app_data()</span></code></a></li>
@ -1984,6 +2070,8 @@ will announce it.</p>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#RNS.Destination"><code class="docutils literal notranslate"><span class="pre">Destination</span></code></a><ul> <li><a class="reference internal" href="#RNS.Destination"><code class="docutils literal notranslate"><span class="pre">Destination</span></code></a><ul>
<li><a class="reference internal" href="#RNS.Destination.RATCHET_COUNT"><code class="docutils literal notranslate"><span class="pre">RATCHET_COUNT</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.RATCHET_INTERVAL"><code class="docutils literal notranslate"><span class="pre">RATCHET_INTERVAL</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.expand_name"><code class="docutils literal notranslate"><span class="pre">expand_name()</span></code></a></li> <li><a class="reference internal" href="#RNS.Destination.expand_name"><code class="docutils literal notranslate"><span class="pre">expand_name()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.app_and_aspects_from_name"><code class="docutils literal notranslate"><span class="pre">app_and_aspects_from_name()</span></code></a></li> <li><a class="reference internal" href="#RNS.Destination.app_and_aspects_from_name"><code class="docutils literal notranslate"><span class="pre">app_and_aspects_from_name()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.hash_from_name_and_identity"><code class="docutils literal notranslate"><span class="pre">hash_from_name_and_identity()</span></code></a></li> <li><a class="reference internal" href="#RNS.Destination.hash_from_name_and_identity"><code class="docutils literal notranslate"><span class="pre">hash_from_name_and_identity()</span></code></a></li>
@ -1996,6 +2084,10 @@ will announce it.</p>
<li><a class="reference internal" href="#RNS.Destination.set_proof_strategy"><code class="docutils literal notranslate"><span class="pre">set_proof_strategy()</span></code></a></li> <li><a class="reference internal" href="#RNS.Destination.set_proof_strategy"><code class="docutils literal notranslate"><span class="pre">set_proof_strategy()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.register_request_handler"><code class="docutils literal notranslate"><span class="pre">register_request_handler()</span></code></a></li> <li><a class="reference internal" href="#RNS.Destination.register_request_handler"><code class="docutils literal notranslate"><span class="pre">register_request_handler()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.deregister_request_handler"><code class="docutils literal notranslate"><span class="pre">deregister_request_handler()</span></code></a></li> <li><a class="reference internal" href="#RNS.Destination.deregister_request_handler"><code class="docutils literal notranslate"><span class="pre">deregister_request_handler()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.enable_ratchets"><code class="docutils literal notranslate"><span class="pre">enable_ratchets()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.enforce_ratchets"><code class="docutils literal notranslate"><span class="pre">enforce_ratchets()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.set_retained_ratchets"><code class="docutils literal notranslate"><span class="pre">set_retained_ratchets()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.set_ratchet_interval"><code class="docutils literal notranslate"><span class="pre">set_ratchet_interval()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.create_keys"><code class="docutils literal notranslate"><span class="pre">create_keys()</span></code></a></li> <li><a class="reference internal" href="#RNS.Destination.create_keys"><code class="docutils literal notranslate"><span class="pre">create_keys()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.get_private_key"><code class="docutils literal notranslate"><span class="pre">get_private_key()</span></code></a></li> <li><a class="reference internal" href="#RNS.Destination.get_private_key"><code class="docutils literal notranslate"><span class="pre">get_private_key()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Destination.load_private_key"><code class="docutils literal notranslate"><span class="pre">load_private_key()</span></code></a></li> <li><a class="reference internal" href="#RNS.Destination.load_private_key"><code class="docutils literal notranslate"><span class="pre">load_private_key()</span></code></a></li>

View File

@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/> <meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="#" /> <meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="#" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/><title>Search - Reticulum Network Stack 0.7.6 beta documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/><title>Search - Reticulum Network Stack 0.7.7 beta documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
@ -138,7 +138,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -164,7 +164,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="#" role="search"> </a><form class="sidebar-search-container" method="get" action="#" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="API Reference" href="reference.html" /><link rel="prev" title="Code Examples" href="examples.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="API Reference" href="reference.html" /><link rel="prev" title="Code Examples" href="examples.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Support Reticulum - Reticulum Network Stack 0.7.6 beta documentation</title> <title>Support Reticulum - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Communications Hardware" href="hardware.html" /><link rel="prev" title="Using Reticulum on Your System" href="using.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Communications Hardware" href="hardware.html" /><link rel="prev" title="Using Reticulum on Your System" href="using.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Understanding Reticulum - Reticulum Network Stack 0.7.6 beta documentation</title> <title>Understanding Reticulum - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@ -360,10 +360,11 @@ be sufficient, even far into the future.</p>
<p>By default Reticulum encrypts all data using elliptic curve cryptography and AES. Any packet sent to a <p>By default Reticulum encrypts all data using elliptic curve cryptography and AES. Any packet sent to a
destination is encrypted with a per-packet derived key. Reticulum can also set up an encrypted destination is encrypted with a per-packet derived key. Reticulum can also set up an encrypted
channel to a destination, called a <em>Link</em>. Both data sent over Links and single packets offer channel to a destination, called a <em>Link</em>. Both data sent over Links and single packets offer
<em>Initiator Anonymity</em>, and links additionally offer <em>Forward Secrecy</em> by using an Elliptic Curve <em>Initiator Anonymity</em>. Links additionally offer <em>Forward Secrecy</em> by default, employing an Elliptic Curve
Diffie Hellman key exchange on Curve25519 to derive per-link ephemeral keys. The multi-hop transport, Diffie Hellman key exchange on Curve25519 to derive per-link ephemeral keys. Asymmetric, link-less
coordination, verification and reliability layers are fully autonomous and also based on elliptic packet communication can also provide forward secrecy, with automatic key ratcheting, by enabling
curve cryptography.</p> ratchets on a per-destination basis. The multi-hop transport, coordination, verification and reliability
layers are fully autonomous and also based on elliptic curve cryptography.</p>
<p>Reticulum also offers symmetric key encryption for group-oriented communications, as well as <p>Reticulum also offers symmetric key encryption for group-oriented communications, as well as
unencrypted packets for local broadcast purposes.</p> unencrypted packets for local broadcast purposes.</p>
<p>Reticulum can connect to a variety of interfaces such as radio modems, data radios and serial ports, <p>Reticulum can connect to a variety of interfaces such as radio modems, data radios and serial ports,
@ -639,7 +640,7 @@ expect. Reticulum offers two ways to do this.</p>
<li><div class="line-block"> <li><div class="line-block">
<div class="line">A packet is always created with an associated destination and some payload data. When the packet is sent <div class="line">A packet is always created with an associated destination and some payload data. When the packet is sent
to a <em>single</em> destination type, Reticulum will automatically create an ephemeral encryption key, perform to a <em>single</em> destination type, Reticulum will automatically create an ephemeral encryption key, perform
an ECDH key exchange with the destinations public key, and encrypt the information.</div> an ECDH key exchange with the destinations public key (or ratchet key, if available), and encrypt the information.</div>
</div> </div>
</li> </li>
<li><div class="line-block"> <li><div class="line-block">
@ -1068,10 +1069,11 @@ both on general-purpose CPUs and on microcontrollers. The necessary primitives a
<li><p>Ed25519 for signatures</p></li> <li><p>Ed25519 for signatures</p></li>
<li><p>X25519 for ECDH key exchanges</p></li> <li><p>X25519 for ECDH key exchanges</p></li>
<li><p>HKDF for key derivation</p></li> <li><p>HKDF for key derivation</p></li>
<li><p>Fernet for encrypted tokens</p> <li><p>Modified Fernet for encrypted tokens</p>
<ul> <ul>
<li><p>AES-128 in CBC mode</p></li> <li><p>AES-128 in CBC mode</p></li>
<li><p>HMAC for message authentication</p></li> <li><p>HMAC for message authentication</p></li>
<li><p>No Version and Timestamp metadata included</p></li>
</ul> </ul>
</li> </li>
<li><p>SHA-256</p></li> <li><p>SHA-256</p></li>

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Understanding Reticulum" href="understanding.html" /><link rel="prev" title="Getting Started Fast" href="gettingstartedfast.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Understanding Reticulum" href="understanding.html" /><link rel="prev" title="Getting Started Fast" href="gettingstartedfast.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Using Reticulum on Your System - Reticulum Network Stack 0.7.6 beta documentation</title> <title>Using Reticulum on Your System - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Getting Started Fast" href="gettingstartedfast.html" /><link rel="prev" title="Reticulum Network Stack Manual" href="index.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Getting Started Fast" href="gettingstartedfast.html" /><link rel="prev" title="Reticulum Network Stack Manual" href="index.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>What is Reticulum? - Reticulum Network Stack 0.7.6 beta documentation</title> <title>What is Reticulum? - Reticulum Network Stack 0.7.7 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.6 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.7 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.6 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.7 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@ -262,12 +262,13 @@ considered complete and stable at the moment, but could change if absolutely war
<li><p>Complete initiator anonymity, communicate without revealing your identity</p></li> <li><p>Complete initiator anonymity, communicate without revealing your identity</p></li>
<li><p>Asymmetric encryption based on X25519, and Ed25519 signatures as a basis for all communication</p></li> <li><p>Asymmetric encryption based on X25519, and Ed25519 signatures as a basis for all communication</p></li>
<li><p>Forward Secrecy by using ephemeral Elliptic Curve Diffie-Hellman keys on Curve25519</p></li> <li><p>Forward Secrecy by using ephemeral Elliptic Curve Diffie-Hellman keys on Curve25519</p></li>
<li><p>Reticulum uses the <a class="reference external" href="https://github.com/fernet/spec/blob/master/Spec.md">Fernet</a> specification for on-the-wire / over-the-air encryption</p> <li><p>Reticulum uses a modified version of the <a class="reference external" href="https://github.com/fernet/spec/blob/master/Spec.md">Fernet</a> specification for on-the-wire / over-the-air encryption</p>
<ul> <ul>
<li><p>All keys are ephemeral and derived from an ECDH key exchange on Curve25519</p></li> <li><p>Keys are ephemeral and derived from an ECDH key exchange on Curve25519</p></li>
<li><p>AES-128 in CBC mode with PKCS7 padding</p></li> <li><p>AES-128 in CBC mode with PKCS7 padding</p></li>
<li><p>HMAC using SHA256 for authentication</p></li> <li><p>HMAC using SHA256 for authentication</p></li>
<li><p>IVs are generated through os.urandom()</p></li> <li><p>IVs are generated through os.urandom()</p></li>
<li><p>No Version and Timestamp metadata included</p></li>
</ul> </ul>
</li> </li>
<li><p>Unforgeable packet delivery confirmations</p></li> <li><p>Unforgeable packet delivery confirmations</p></li>
@ -300,7 +301,8 @@ of the types of interfaces Reticulum was designed for.</p>
<p>An open-source LoRa-based interface called <a class="reference external" href="https://unsigned.io/rnode">RNode</a> <p>An open-source LoRa-based interface called <a class="reference external" href="https://unsigned.io/rnode">RNode</a>
has been designed as an example transceiver that is very suitable for has been designed as an example transceiver that is very suitable for
Reticulum. It is possible to build it yourself, to transform a common LoRa Reticulum. It is possible to build it yourself, to transform a common LoRa
development board into one, or it can be purchased as a complete transceiver.</p> development board into one, or it can be purchased as a complete transceiver
from various vendors.</p>
<p>Reticulum can also be encapsulated over existing IP networks, so theres <p>Reticulum can also be encapsulated over existing IP networks, so theres
nothing stopping you from using it over wired Ethernet or your local WiFi nothing stopping you from using it over wired Ethernet or your local WiFi
network, where itll work just as well. In fact, one of the strengths of network, where itll work just as well. In fact, one of the strengths of

View File

@ -134,10 +134,11 @@ be sufficient, even far into the future.
By default Reticulum encrypts all data using elliptic curve cryptography and AES. Any packet sent to a By default Reticulum encrypts all data using elliptic curve cryptography and AES. Any packet sent to a
destination is encrypted with a per-packet derived key. Reticulum can also set up an encrypted destination is encrypted with a per-packet derived key. Reticulum can also set up an encrypted
channel to a destination, called a *Link*. Both data sent over Links and single packets offer channel to a destination, called a *Link*. Both data sent over Links and single packets offer
*Initiator Anonymity*, and links additionally offer *Forward Secrecy* by using an Elliptic Curve *Initiator Anonymity*. Links additionally offer *Forward Secrecy* by default, employing an Elliptic Curve
Diffie Hellman key exchange on Curve25519 to derive per-link ephemeral keys. The multi-hop transport, Diffie Hellman key exchange on Curve25519 to derive per-link ephemeral keys. Asymmetric, link-less
coordination, verification and reliability layers are fully autonomous and also based on elliptic packet communication can also provide forward secrecy, with automatic key ratcheting, by enabling
curve cryptography. ratchets on a per-destination basis. The multi-hop transport, coordination, verification and reliability
layers are fully autonomous and also based on elliptic curve cryptography.
Reticulum also offers symmetric key encryption for group-oriented communications, as well as Reticulum also offers symmetric key encryption for group-oriented communications, as well as
unencrypted packets for local broadcast purposes. unencrypted packets for local broadcast purposes.
@ -431,7 +432,7 @@ For exchanges of small amounts of information, Reticulum offers the *Packet* API
* | A packet is always created with an associated destination and some payload data. When the packet is sent * | 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 to a *single* destination type, Reticulum will automatically create an ephemeral encryption key, perform
an ECDH key exchange with the destination's public key, and encrypt the information. an ECDH key exchange with the destination's public key (or ratchet key, if available), and encrypt the information.
* | It is important to note that this key exchange does not require any network traffic. The sender already * | 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 knows the public key of the destination from an earlier received *announce*, and can thus perform the ECDH
@ -867,12 +868,14 @@ both on general-purpose CPUs and on microcontrollers. The necessary primitives a
* HKDF for key derivation * HKDF for key derivation
* Fernet for encrypted tokens * Modified Fernet for encrypted tokens
* AES-128 in CBC mode * AES-128 in CBC mode
* HMAC for message authentication * HMAC for message authentication
* No Version and Timestamp metadata included
* SHA-256 * SHA-256
* SHA-512 * SHA-512

View File

@ -53,9 +53,9 @@ What does Reticulum Offer?
* Forward Secrecy by using ephemeral Elliptic Curve Diffie-Hellman keys on Curve25519 * Forward Secrecy by using ephemeral Elliptic Curve Diffie-Hellman keys on Curve25519
* Reticulum uses the `Fernet <https://github.com/fernet/spec/blob/master/Spec.md>`_ specification for on-the-wire / over-the-air encryption * Reticulum uses a modified version of the `Fernet <https://github.com/fernet/spec/blob/master/Spec.md>`_ specification for on-the-wire / over-the-air encryption
* All keys are ephemeral and derived from an ECDH key exchange on Curve25519 * Keys are ephemeral and derived from an ECDH key exchange on Curve25519
* AES-128 in CBC mode with PKCS7 padding * AES-128 in CBC mode with PKCS7 padding
@ -63,6 +63,8 @@ What does Reticulum Offer?
* IVs are generated through os.urandom() * IVs are generated through os.urandom()
* No Version and Timestamp metadata included
* Unforgeable packet delivery confirmations * Unforgeable packet delivery confirmations
* A variety of supported interface types * A variety of supported interface types
@ -99,7 +101,8 @@ of the types of interfaces Reticulum was designed for.
An open-source LoRa-based interface called `RNode <https://unsigned.io/rnode>`_ An open-source LoRa-based interface called `RNode <https://unsigned.io/rnode>`_
has been designed as an example transceiver that is very suitable for has been designed as an example transceiver that is very suitable for
Reticulum. It is possible to build it yourself, to transform a common LoRa Reticulum. It is possible to build it yourself, to transform a common LoRa
development board into one, or it can be purchased as a complete transceiver. development board into one, or it can be purchased as a complete transceiver
from various vendors.
Reticulum can also be encapsulated over existing IP networks, so there's Reticulum can also be encapsulated over existing IP networks, so there's
nothing stopping you from using it over wired Ethernet or your local WiFi nothing stopping you from using it over wired Ethernet or your local WiFi