A post-quantum, metadata-resistant secure messenger — now actually networked.
AEGIS reuses only vetted primitives (X25519 + ML-KEM-768, Ed25519 + ML-DSA-65,
ChaCha20-Poly1305, HKDF); its originality is in the composition: a hybrid
post-quantum ratchet, a privacy-preserving quantified web of trust, and a
universal-relay cover-traffic transport, as one stack. See AEGIS_whitepaper.md
for the full design and every security-vs-usability trade-off named explicitly.
This is pre-review research code. It needs independent cryptographic audit before it protects anyone at real risk.
This repo includes a ready-to-publish project site in docs/ (a landing page,
the interface screenshot, and the PDFs). It is a static site about AEGIS — it
does not and cannot run the app, because AEGIS is peer-to-peer with no central
server. To put it online with GitHub Pages (Settings → Pages → Deploy from branch
→ main / /docs), and to publish the code, see PUBLISHING.md.
| Document | What it covers |
|---|---|
AEGIS_whitepaper.md / .pdf |
The protocol design, security argument, and limitations |
AEGIS_due_diligence.md / .pdf |
Security claims stated precisely, threat model, and the full known-gaps register — read §6 first |
AEGIS_hardening_checklist.md / .pdf |
Prioritized engineering work required before an external audit |
AEGIS_commercialization.md / .pdf |
Market, regulatory path, business models, and cost/timeline model |
SECURITY.md |
Vulnerability reporting policy |
pip install -r requirements.txt
python demo.py # the core layers, in-process, narrated
python net_demo.py # the WHOLE stack over real TCP sockets: 4 mix nodes on
# localhost, a live encrypted+deniable conversation, and
# what a global passive adversary would (fail to) measure
python -m pytest -q # 31 tests: crypto, handshake, ratchet, trust, deniable
# handshake, persistence, wire, transport, messenger, provider auth,
# DoS bounds, signed directory, safety numbers, API auth, key vault
net_demo.py is the easiest way to watch the networked messenger actually work —
no terminals to juggle, no input required.
aegis_app.py turns the stack into a real chat application: it runs the AEGIS
engine locally and serves a messenger UI you open in your browser. It is
stdlib-only — no extra installs. Run one per person, all sharing a directory
folder:
python aegis_app.py --name Alice --http 8001 --port 9001 --dir board
python aegis_app.py --name Bob --http 8002 --port 9002 --dir board
python aegis_app.py --name Relay --http 8003 --port 9003 --dir board # optional relay
Each prints a link like http://127.0.0.1:8001/?t=… — open that exact link;
the ?t= token is an access credential. The local API is token-gated and refuses
cross-origin and rebound-host requests, so another web page in your browser cannot
drive it. You'll get a contact list, a conversation view, and a Verify button
that shows the safety number to compare out-of-band. Messages travel end-to-end
encrypted through the live onion mixnet; the browser is only the screen.
Add --state alice.key to keep a stable identity across restarts — the file is
encrypted with a passphrase (pass --passphrase, set AEGIS_PASSPHRASE, or
you'll be prompted). (This is a local desktop app using your browser as the
window — not a hosted service or a mobile app.)
Run each participant in its own terminal window, all pointing at the same directory folder (share the folder across machines and it works across hosts):
python aegis_chat.py --name Alice --port 9001 --dir board
python aegis_chat.py --name Bob --port 9002 --dir board
python aegis_chat.py --name Relay --port 9003 --dir board
(The third is an optional pure relay that enlarges everyone's anonymity set.)
Then in Alice's terminal, type (don't paste a block — see note):
/who list discovered peers
/msg Bob hello send Bob a message (most reliable)
/dm Bob set Bob as the current partner, then just type
/verify Bob show the safety number to compare with Bob out-of-band
/quit exit
(If your terminal shows /skill-creator where this guide says /to, that's a
display rewrite in your terminal, not the program — use /msg or /dm, which
aren't affected.)
Notes for Windows / non-interactive shells. The client needs a real interactive console for typing. If it detects that stdin is not a live console (for example, when several commands are pasted as one block, or stdin is redirected), it will not read commands — instead it stays up as a relay/receiver so it can still forward traffic and print messages sent to it. For those cases, send without typing using the one-shot flag, which sends once and then keeps running to receive replies:
python aegis_chat.py --name Alice --port 9001 --dir board --send "Bob:hello there"
Add --state alice.key to keep a stable AegisID across restarts.
If a port is already in use ([Errno 10048] / "address in use"), the client
now automatically binds a free port instead and registers it in the directory, so
peers still find you — no action needed. This usually means an earlier client is
still running (a non-interactive launch stays up as a relay until you stop it). To
clear leftovers on Windows, close those windows or run taskkill /F /IM python.exe
(stops all Python processes); on macOS/Linux use pkill -f aegis_chat.
| Layer | Module | Status |
|---|---|---|
| Primitives + hybrid composition | crypto.py |
✓ |
| Self-certifying identity + prekeys | identity.py |
✓ |
| Signed PQ handshake | handshake.py |
✓ |
| Deniable handshake (classical-DH auth) | deniable.py |
✓ |
| Hybrid Double Ratchet (DH + KEM) | ratchet.py |
✓ |
| Web of trust (k-disjoint paths + accumulator) | trust.py |
✓ |
| Group messaging (sender keys) | groups.py |
✓ |
| Session persistence | persistence.py |
✓ |
| Fixed-size onion packets + framing | wire.py |
✓ |
| Async TCP mix transport + cover traffic | transport.py |
✓ |
| Poisson mix delays (per-hop timing defence) | transport.py |
✓ |
| Provider mailboxes (recipient not final hop) | transport.py + messenger.py |
✓ |
| End-to-end messenger over the mixnet | messenger.py |
✓ |
| Safety numbers (out-of-band MITM check) | verify.py |
✓ |
| File-backed peer discovery | directory.py |
✓ |
| Terminal chat client | aegis_chat.py |
✓ |
| Desktop chat app (browser UI + local engine) | aegis_app.py + aegis_webui.html |
✓ |
Documented simplifications vs a production build: on-wire size uniformity via re-padding rather than full (post-quantum) Sphinx; mailbox tokens derived from the public AegisID rather than a provider-shared secret with authenticated polls; and a 2048-bit RSA accumulator rather than class groups. Provider mailboxes, Poisson mix delays, the deniable handshake, and safety numbers are now implemented. All remaining simplifications are called out in the whitepaper's §8 and §15.