Dethron
Verifiable message delivery over Reticulum and LXMF.
Guaranteed delivery is impossible over intermittent contact: if the recipient never appears, nothing reaches them. What is possible is knowing, with cryptographic proof and without trusting the relay, which state a message is in.
| State | Proof | Who signs it |
|---|---|---|
| Entered | A custody attestation naming the message, the recipient, and the bytes actually stored | the relay |
| Pending | A relay holding custody with no receipt: awaiting contact or attested and not delivered | derived, not claimed |
| Left | A receipt over the exact reconstructed bytes, which reaches the sender through any relay carrying it | the recipient |
A relay that attests and then discards the message is named by the absence of the recipient's receipt. That is the point: nothing here asks you to trust an intermediary.
Install
pip install dethron
Python 3.10 or newer. Reticulum and LXMF come with it. Exercised on Windows 11 with Python 3.10 and on Ubuntu 24.04 with Python 3.12, end-to-end test included.
Try it
Three terminals, or one and some patience. Everything below is real: real Reticulum instances, real LXMF propagation, real signatures.
# 1. Mint three identities and note their contacts
dethron identity ./relay
dethron identity ./alice
dethron identity ./bob
# 2. Run a relay, which holds objects for recipients who are not here yet
dethron relay ./relay --port 45810
With the relay running, and using the contact and propagation values it printed:
# 3. Alice hands an object to the relay and comes back with proof it was taken
dethron send ./alice report.pdf \
--to <bob's contact> \
--relay 127.0.0.1:45810/<relay propagation> \
--relay-contact <relay's contact>
# 4. Bob, who was not around for any of that, collects and reconstructs it
dethron fetch ./bob \
--source <alice's contact> \
--relay 127.0.0.1:45810/<relay propagation> \
--receipt-to <alice's contact>
# 5. Alice comes back later and picks up the receipt Bob signed
dethron receipts ./alice --relay 127.0.0.1:45810/<relay propagation>
# 6. Either of them recomputes every proof from the files on disk
dethron verify ./alice
verify ends with both halves of the claim:
{
"verdict": "pass",
"checks": [
{ "check": "custody 10019ad5 is signed by the relay that was asked",
"passed": true, "proves": "entry", "stored_size": 18688 },
{ "check": "receipt 02377a24 is signed by the recipient sent to",
"passed": true, "proves": "exit",
"digest": "02377a2438d3a5ab8f90f2bbc0cf67f16d8f1ce89da2d867dec1fc4ea2389070" }
]
}
Alice and Bob were never online at the same time.
As a library
from dethron import Node
with Node('./alice', peers=['relay.example:45810']) as node:
handoff = node.send(payload, to=bob_contact, via=relay_propagation)
proof = node.custody_of(handoff['transient_id'], relay=relay_contact)
Calls are synchronous: send returns once the relay has taken the object, custody_of
returns the relay's signed attestation, fetch returns once the parts reconstruct. Each
node writes an events.jsonl beside itself — not a log for humans, but the record an
audit reads afterwards.
What is proved, and what is not
The claims come with artifacts, in evidence/, and with documents
stating the controls that had to fail: see docs/.
Proved, within a declared scope:
- Custody, pendency and receipt return (V1, receipt).
- Reproduction on an independent machine following the document alone (V2).
- An object crossing between two distinct machines over a link carrying no IP, with the recipient proved to hold no IP interface (V3c).
Not proved, and not claimed:
- Scale. One message, one relay, one recipient. No numbers for many peers or a queue.
- Key exchange and discovery. Contacts are exchanged out of band, by you.
- A hostile relay in the wild. The refusals are tested; the adversary is simulated.
- Long offline periods. The sessions in the evidence are disjoint by seconds, not days.
- Anything beyond two platforms. Windows and Linux are exercised; Android, macOS and the BSDs are not. The milestone evidence below was produced on Windows, and says so.
- Everything the milestone documents list under "Limits", which is where to look first.
Contributing
Bug reports and reproductions are the most useful thing you can send. See CONTRIBUTING.md. The house rule is that a claim arrives with the control that would have caught it being wrong.
Where the evidence came from
The bench that produced it — generations of nodes, cut media, two-machine schedules, the auditors — lives in dethron-research, along with the deliberation and the runs that failed. This repository is the part that is meant to be used; that one is the part that is meant to be checked.
Licence
Apache 2.0. Reticulum and LXMF are dependencies under their own licences; this work imports them, it does not derive from them.
Metadata
Release files for dethron 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dethron-0.1.0.tar.gz | 42.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dethron-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 80.1 kB
Release files / dethron-0.1.0.tar.gz
| Download URL | dethron-0.1.0.tar.gz |
|---|---|
| Size | 42.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eb39574e582a86d76bb69da852bb397c7246386384d77edf5a9e2bb24f6cb940
|
|
BLAKE2b-256 checksum How to use checksums |
489abf87ccc364fe38e814714df1f42c618e305326d1ed8b40b0e7efce733923
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.11
|
Release files / dethron-0.1.0-py3-none-any.whl
| Download URL | dethron-0.1.0-py3-none-any.whl |
|---|---|
| Size | 38.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
35afcf08edc76007191edc730e9b0d8c2c9719da720a7d4dacb646f3ef7b0fd5
|
|
BLAKE2b-256 checksum How to use checksums |
71357bd938973786fc64848b2eae76e6312af3514b1808827324e7570b5a7933
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.11
|