mirror of
https://github.com/markqvist/LXMF.git
synced 2025-07-27 17:15:19 -04:00
Updated LXMF to Reticulum 0.2.1 elliptic curve cryptography
This commit is contained in:
parent
5f578f93b3
commit
75c7e80269
3 changed files with 25 additions and 26 deletions
47
LXMF/LXMF.py
47
LXMF/LXMF.py
|
@ -32,37 +32,37 @@ class LXMessage:
|
||||||
DESTINATION_LENGTH = RNS.Identity.TRUNCATED_HASHLENGTH//8
|
DESTINATION_LENGTH = RNS.Identity.TRUNCATED_HASHLENGTH//8
|
||||||
SIGNATURE_LENGTH = RNS.Identity.SIGLENGTH//8
|
SIGNATURE_LENGTH = RNS.Identity.SIGLENGTH//8
|
||||||
|
|
||||||
# LXMF overhead is 163 bytes per message:
|
# LXMF overhead is 99 bytes per message:
|
||||||
# 10 bytes for destination hash
|
# 10 bytes for destination hash
|
||||||
# 10 bytes for source hash
|
# 10 bytes for source hash
|
||||||
# 128 bytes for RSA signature
|
# 64 bytes for Ed25519 signature
|
||||||
# 8 bytes for timestamp
|
# 8 bytes for timestamp
|
||||||
# 7 bytes for msgpack structure
|
# 7 bytes for msgpack structure
|
||||||
LXMF_OVERHEAD = 2*DESTINATION_LENGTH + SIGNATURE_LENGTH + 8 + 7
|
LXMF_OVERHEAD = 2*DESTINATION_LENGTH + SIGNATURE_LENGTH + 8 + 7
|
||||||
|
|
||||||
# With an MTU of 500, the maximum RSA-encrypted
|
# With an MTU of 500, the maximum amount of data
|
||||||
# amount of data we can send in a single packet
|
# we can send in a single encrypted packet is
|
||||||
# is given by the below calculation; 258 bytes.
|
# 383 bytes.
|
||||||
RSA_PACKET_MDU = RNS.Packet.RSA_MDU
|
ENCRYPTED_PACKET_MDU = RNS.Packet.ENCRYPTED_MDU
|
||||||
|
|
||||||
# The max content length we can fit in LXMF message
|
# The max content length we can fit in LXMF message
|
||||||
# inside a single RNS packet is the RSA MDU, minus
|
# inside a single RNS packet is the encrypted MDU, minus
|
||||||
# the LXMF overhead. We can optimise a bit though, by
|
# the LXMF overhead. We can optimise a bit though, by
|
||||||
# inferring the destination hash from the destination
|
# inferring the destination hash from the destination
|
||||||
# field of the packet, therefore we also add the length
|
# field of the packet, therefore we also add the length
|
||||||
# of a destination hash to the calculation. With default
|
# of a destination hash to the calculation. With default
|
||||||
# RNS and LXMF parameters, the largest single-packet
|
# RNS and LXMF parameters, the largest single-packet
|
||||||
# LXMF message we can send is 105 bytes. If a message
|
# LXMF message we can send is 294 bytes. If a message
|
||||||
# is larger than that, a Reticulum link will be used.
|
# is larger than that, a Reticulum link will be used.
|
||||||
RSA_PACKET_MAX_CONTENT = RSA_PACKET_MDU - LXMF_OVERHEAD + DESTINATION_LENGTH
|
ENCRYPTED_PACKET_MAX_CONTENT = ENCRYPTED_PACKET_MDU - LXMF_OVERHEAD + DESTINATION_LENGTH
|
||||||
|
|
||||||
# Links can carry a significantly larger MDU, due to
|
# Links can carry a larger MDU, due to less overhead per
|
||||||
# more efficient elliptic curve cryptography. The link
|
# packet. The link MDU with default Reticulum parameters
|
||||||
# MDU with default Reticulum parameters is 415 bytes.
|
# is 415 bytes.
|
||||||
LINK_PACKET_MDU = RNS.Link.MDU
|
LINK_PACKET_MDU = RNS.Link.MDU
|
||||||
|
|
||||||
# Which means that we can deliver single-packet LXMF
|
# Which means that we can deliver single-packet LXMF
|
||||||
# messages with content of up to 252 bytes over a link.
|
# messages with content of up to 316 bytes over a link.
|
||||||
# If a message is larger than that, LXMF will sequence
|
# If a message is larger than that, LXMF will sequence
|
||||||
# and transfer it as a RNS resource over the link instead.
|
# and transfer it as a RNS resource over the link instead.
|
||||||
LINK_PACKET_MAX_CONTENT = LINK_PACKET_MDU - LXMF_OVERHEAD
|
LINK_PACKET_MAX_CONTENT = LINK_PACKET_MDU - LXMF_OVERHEAD
|
||||||
|
@ -73,9 +73,8 @@ class LXMessage:
|
||||||
PLAIN_PACKET_MAX_CONTENT = PLAIN_PACKET_MDU - LXMF_OVERHEAD + DESTINATION_LENGTH
|
PLAIN_PACKET_MAX_CONTENT = PLAIN_PACKET_MDU - LXMF_OVERHEAD + DESTINATION_LENGTH
|
||||||
|
|
||||||
# Descriptive strings regarding transport encryption
|
# Descriptive strings regarding transport encryption
|
||||||
ENCRYPTION_DESCRIPTION_RSA = "RSA-"+str(RNS.Identity.KEYSIZE)
|
|
||||||
ENCRYPTION_DESCRIPTION_AES = "AES-128"
|
ENCRYPTION_DESCRIPTION_AES = "AES-128"
|
||||||
ENCRYPTION_DESCRIPTION_EC = "Curve25519+Fernet"
|
ENCRYPTION_DESCRIPTION_EC = "Curve25519"
|
||||||
ENCRYPTION_DESCRIPTION_UNENCRYPTED = "Unencrypted"
|
ENCRYPTION_DESCRIPTION_UNENCRYPTED = "Unencrypted"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -255,7 +254,7 @@ class LXMessage:
|
||||||
self.determine_transport_encryption()
|
self.determine_transport_encryption()
|
||||||
|
|
||||||
if self.method == LXMessage.OPPORTUNISTIC:
|
if self.method == LXMessage.OPPORTUNISTIC:
|
||||||
self.__as_packet().send().delivery_callback(self.__mark_delivered)
|
self.__as_packet().send().set_delivery_callback(self.__mark_delivered)
|
||||||
self.state = LXMessage.SENT
|
self.state = LXMessage.SENT
|
||||||
elif self.method == LXMessage.DIRECT:
|
elif self.method == LXMessage.DIRECT:
|
||||||
self.state = LXMessage.SENDING
|
self.state = LXMessage.SENDING
|
||||||
|
@ -272,7 +271,7 @@ class LXMessage:
|
||||||
if self.method == LXMessage.OPPORTUNISTIC:
|
if self.method == LXMessage.OPPORTUNISTIC:
|
||||||
if self.destination.type == RNS.Destination.SINGLE:
|
if self.destination.type == RNS.Destination.SINGLE:
|
||||||
self.transport_encrypted = True
|
self.transport_encrypted = True
|
||||||
self.transport_encryption = LXMessage.ENCRYPTION_DESCRIPTION_RSA
|
self.transport_encryption = LXMessage.ENCRYPTION_DESCRIPTION_EC
|
||||||
elif destination_type == RNS.Destination.GROUP:
|
elif destination_type == RNS.Destination.GROUP:
|
||||||
self.transport_encrypted = True
|
self.transport_encrypted = True
|
||||||
self.transport_encryption = LXMessage.ENCRYPTION_DESCRIPTION_AES
|
self.transport_encryption = LXMessage.ENCRYPTION_DESCRIPTION_AES
|
||||||
|
@ -285,7 +284,7 @@ class LXMessage:
|
||||||
elif self.method == LXMessage.PROPAGATED:
|
elif self.method == LXMessage.PROPAGATED:
|
||||||
if self.destination.type == RNS.Destination.SINGLE:
|
if self.destination.type == RNS.Destination.SINGLE:
|
||||||
self.transport_encrypted = True
|
self.transport_encrypted = True
|
||||||
self.transport_encryption = LXMessage.ENCRYPTION_DESCRIPTION_RSA
|
self.transport_encryption = LXMessage.ENCRYPTION_DESCRIPTION_EC
|
||||||
elif destination_type == RNS.Destination.GROUP:
|
elif destination_type == RNS.Destination.GROUP:
|
||||||
self.transport_encrypted = True
|
self.transport_encrypted = True
|
||||||
self.transport_encryption = LXMessage.ENCRYPTION_DESCRIPTION_AES
|
self.transport_encryption = LXMessage.ENCRYPTION_DESCRIPTION_AES
|
||||||
|
@ -479,8 +478,8 @@ class LXMRouter:
|
||||||
|
|
||||||
def register_delivery_identity(self, identity, display_name = None):
|
def register_delivery_identity(self, identity, display_name = None):
|
||||||
delivery_destination = RNS.Destination(identity, RNS.Destination.IN, RNS.Destination.SINGLE, "lxmf", "delivery")
|
delivery_destination = RNS.Destination(identity, RNS.Destination.IN, RNS.Destination.SINGLE, "lxmf", "delivery")
|
||||||
delivery_destination.packet_callback(self.delivery_packet)
|
delivery_destination.set_packet_callback(self.delivery_packet)
|
||||||
delivery_destination.link_established_callback(self.delivery_link_established)
|
delivery_destination.set_link_established_callback(self.delivery_link_established)
|
||||||
delivery_destination.display_name = display_name
|
delivery_destination.display_name = display_name
|
||||||
|
|
||||||
if display_name != None:
|
if display_name != None:
|
||||||
|
@ -559,10 +558,10 @@ class LXMRouter:
|
||||||
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
def delivery_link_established(self, link):
|
def delivery_link_established(self, link):
|
||||||
link.packet_callback(self.delivery_packet)
|
link.set_packet_callback(self.delivery_packet)
|
||||||
link.set_resource_strategy(RNS.Link.ACCEPT_ALL)
|
link.set_resource_strategy(RNS.Link.ACCEPT_ALL)
|
||||||
link.resource_started_callback(self.resource_transfer_began)
|
link.set_resource_started_callback(self.resource_transfer_began)
|
||||||
link.resource_concluded_callback(self.resource_transfer_concluded)
|
link.set_resource_concluded_callback(self.resource_transfer_concluded)
|
||||||
|
|
||||||
def delivery_link_closed(self, link):
|
def delivery_link_closed(self, link):
|
||||||
pass
|
pass
|
||||||
|
@ -669,7 +668,7 @@ class LXMRouter:
|
||||||
if RNS.Transport.has_path(lxmessage.get_destination().hash):
|
if RNS.Transport.has_path(lxmessage.get_destination().hash):
|
||||||
RNS.log("Establishing link to "+RNS.prettyhexrep(lxmessage.get_destination().hash)+" for delivery attempt "+str(lxmessage.delivery_attempts)+" to "+RNS.prettyhexrep(lxmessage.get_destination().hash), RNS.LOG_DEBUG)
|
RNS.log("Establishing link to "+RNS.prettyhexrep(lxmessage.get_destination().hash)+" for delivery attempt "+str(lxmessage.delivery_attempts)+" to "+RNS.prettyhexrep(lxmessage.get_destination().hash), RNS.LOG_DEBUG)
|
||||||
delivery_link = RNS.Link(lxmessage.get_destination())
|
delivery_link = RNS.Link(lxmessage.get_destination())
|
||||||
delivery_link.link_established_callback(self.process_outbound)
|
delivery_link.set_link_established_callback(self.process_outbound)
|
||||||
self.direct_links[delivery_destination_hash] = delivery_link
|
self.direct_links[delivery_destination_hash] = delivery_link
|
||||||
else:
|
else:
|
||||||
RNS.log("No path known for delivery attempt "+str(lxmessage.delivery_attempts)+" to "+RNS.prettyhexrep(lxmessage.get_destination().hash)+". Requesting path...", RNS.LOG_DEBUG)
|
RNS.log("No path known for delivery attempt "+str(lxmessage.delivery_attempts)+" to "+RNS.prettyhexrep(lxmessage.get_destination().hash)+". Requesting path...", RNS.LOG_DEBUG)
|
||||||
|
|
|
@ -95,7 +95,7 @@ The complete message overhead for LXMF is only 163 bytes, which in return gives
|
||||||
|
|
||||||
## Caveat Emptor
|
## Caveat Emptor
|
||||||
|
|
||||||
As with Reticulum, LXMF is alpha software, and should be considered experimental. While it has been built with cryptography best-practices very foremost in mind, it _has not_ been externally security audited, and there could very well be privacy-breaking bugs. If you want to help out, or help sponsor an audit, please do get in touch.
|
LXMF is alpha software, and should be considered experimental. While it has been built with cryptography best-practices very foremost in mind, it _has not_ been externally security audited, and there could very well be privacy-breaking bugs. If you want to help out, or help sponsor an audit, please do get in touch.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="lxmf",
|
name="lxmf",
|
||||||
version="0.0.4",
|
version="0.0.5",
|
||||||
author="Mark Qvist",
|
author="Mark Qvist",
|
||||||
author_email="mark@unsigned.io",
|
author_email="mark@unsigned.io",
|
||||||
description="Lightweight Extensible Message Format for Reticulum",
|
description="Lightweight Extensible Message Format for Reticulum",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue