propagare

module
v0.1.0-preview.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: AGPL-3.0

README

Propagare

Propagare ist ein ausführbares Grundprojekt für einen anonymitätsorientierten, dezentralen Messenger. Das zugrunde liegende Wire-Protokoll heißt ENIG (spezifiziert in docs/PROTOCOL.md); alle Adressen sind selbstzertifizierende ENIG…-IDs, und die Metadaten-/Cover-Schicht ist ENIG-Mix v2. Das Projekt trennt den plattformneutralen Client-Core strikt von Frontends und Node-Servern. Android-, iOS-, Desktop-, CLI- und Web-Oberflächen können später dieselbe Core-API verwenden.

Das Repository ist ein Security-Prototyp und kein produktionsfertiger Messenger. Die bereits implementierten Bausteine sind real und getestet; die noch fehlenden Sicherheitsgrenzen sind in SECURITY.md und docs/ARCHITECTURE.md explizit aufgeführt. Die verbindliche Release-Entscheidung und alle externen Gates stehen in docs/RELEASE-READINESS.md.

Bereits implementiert

  • Client-Core als öffentliches Go-Paket ohne Benutzeroberfläche
  • Node-Server mit persistenter, automatisch ablaufender Speicherung
  • persistente Lösch-Tombstones, signierte Bindung von Store und Node-Identität sowie ein exklusiver Schlüssel-Lease über die gesamte Prozesslaufzeit
  • festes Speicherfenster: jedes Item läuft exakt 60 Tage nach Erstellung ab; ein anderes Ablaufdatum wird abgelehnt, früheres Entfernen geht nur über die geheime Lösch-Capability
  • Rechenporto (Proof of Work), das bei hoher Speicherauslastung steigt
  • hybride ML-KEM-768/X25519-HPKE-Verschlüsselung für versiegelte Nachrichten
  • hybride Ed25519- und ML-DSA-65-Signaturen für Node-Belege und Administration
  • ein Schlüssel oder eine Signatur gilt nur, wenn beide Verfahren gültig sind
  • gepolsterte Textnachrichten und konstant große verschlüsselte Dateiblöcke
  • konfigurierbare Dateigrößenbegrenzung
  • Lösch-Capabilities statt Benutzeridentitäten auf Nodes
  • Löschen von Dateien erst nach vollständigem Download und Authentifizierung
  • Replikationsquorum, signierte Speicherbelege und automatische Ersatz-Nodes
  • zufällige Speicherprüfungen und lokaler Ausschluss unzuverlässiger Nodes
  • authentisiert verschlüsselter lokaler Client-Store mit standardmäßig und maximal 10 GiB, oldest-first Cache-Pruning und Schutz nicht abgelaufener Sicherheitszustände sowie exklusivem Prozess-Lock
  • signierter und replaygeschützter verschlüsselter Sync zu allen durch das aktuelle Konto-Profil autorisierten eigenen Geräten
  • selbstzertifizierende, typisierte ENIGC1…-Konten, ENIGD1…-Geräte und ENIGG1…-Gruppen; Directory-Antworten werden lokal neu gebunden und signiert
  • Registrierung hinter einer verpflichtenden OS-Keychain-/Hardware-Vault-Grenze
  • hybrid gerätesignierte Nachrichten und gerätesignierte Client-Zustellbelege
  • strikt geschlossener Nachrichtenpfad, der ohne auditierten PQ-Ratchet, persistenten Replay-Speicher und Mix-/Cover-Transport nicht startet
  • ENIG-Mix v2: moderater, größenbegrenzter Command-Layer und konstant getakteter Real-/Poll-/Cover-Scheduler mit festen Paketen und hartem Fail-Closed-Verhalten
  • verifizierte zufällige Full-Node-Routenzuweisung mit drei Mix-Hops, einem Courier und drei Replikaten ohne Identitäts- oder grobe IP-Präfix-Wiederholung
  • IP-basiertes Node-Verzeichnis mit ausgelieferter Seed-Pin-Liste, hybrid signierten Kurzzeit-Leases, Rückruf-Challenge, Seed-Quorum, Ablaufbereinigung und signierten vollständigen Snapshots für Nodes und Clients
  • CA-PKI-freie Client↔Node- und Node↔Node-Kanäle: automatisch aus der Node- Identität erzeugter Zertifikatscontainer, exaktes Schlüssel-Pinning und erzwungener TLS-1.3-Schlüsselaustausch mit X25519MLKEM768
  • Gruppenrollen, Ban, Admin-Delegation und Eigentümerübertragung
  • Provider-Schnittstelle für RFC-9420-MLS/TreeKEM
  • direkte 1:1-Audio-/Videoanrufe über authentisiertes WebRTC DTLS-SRTP
  • pro Call ephemerer DTLS-Fingerprint, hybrid signiertes SDP, Replay- und Ressourcenlimits sowie klassische Forward Secrecy auf Sitzungsebene

Bewusst noch nicht als „gelöst“ bezeichnet

  • Der Referenztransport ist direktes, identitätsgepinntes HTTPS ohne öffentliche PKI (Plain HTTP nur explizit für lokale Entwicklung). Er verbirgt IP-Adressen und Zeitkorrelationen nicht. Produktiv braucht er ein geprüftes Onion-/Mixnet- Transportmodul, Cover Traffic, Batching und TLS/QUIC innerhalb der Hops.
  • Der ENIG-Mix-Scheduler und seine PQ-/Audit-Provider-Grenzen sind implementiert; ein konkreter auditierter PQ-hybrider Sphinx-/Mixnet-Provider, Courier und reale Relay-Infrastruktur sind noch nicht enthalten.
  • Alle Nodes sollen dasselbe Full-Node-Binary mit Mix-, Courier-, Speicher- und Directory-Fähigkeiten ausführen. Die Aufgabenzuweisung ist implementiert; die gemeinsame Relay-/Courier-Laufzeit und ihre Konformitätsprüfung fehlen noch.
  • Die versiegelte HPKE-Nachricht ist ein sicherer PQ-hybrider Baustein, aber noch kein vollständiges PQXDH-/Double-Ratchet-Protokoll mit Forward Secrecy und Post-Compromise Security. message.StrictPipeline definiert und erzwingt die Provider-Grenze; ein konkreter auditierter Provider ist noch nicht enthalten.
  • Die Secret-Vault-Schnittstelle ist implementiert, nicht jedoch die plattformspezifischen Keychain-/Secure-Enclave-Adapter.
  • ENIG-IDs verhindern unbemerkten Schlüssel-Austausch. Ein Verzeichnis kann Profile weiterhin vorenthalten und bei einer frischen Installation einen alten, noch gültig signierten Stand wiedergeben; dafür fehlen Key Transparency und ein gesicherter lokaler Revisions-Pin.
  • Direkte 1:1-Calls sind E2EE und klassisch forward-secret. Der DTLS-ECDHE- Schlüsselaustausch ist noch nicht post-quantenresistent und besitzt während eines laufenden Calls keine Post-Compromise-Recovery. SFU-/Gruppencalls benötigen eine auditierte SFrame+MLS-Integration und sind nicht aktiviert.
  • Gruppen-Administration ist implementiert; die eigentliche Gruppenverschlüsselung muss über einen auditierten MLS-Provider erfolgen. Die hybriden PQ-MLS- Ciphersuites sind im Juli 2026 noch IETF-Entwürfe.
  • Das signierte Node-Verzeichnis verhindert ungeprüfte Einzelanmeldungen, ist aber noch keine permissionless Sybil-Lösung: Seed-Quorum, Betreiberdiversität, Probezeit und Ressourcennachweis bleiben eine Produktionsanforderung.
  • Ein lokaler Client kann böse Nodes ausschließen. Netzwerkweit beweisbarer Ausschluss benötigt Merkle-Speichernachweise und mehrere unabhängige Auditoren.

Projektstruktur

account/       Konten, Geräte-Zertifikate und verschlüsselter Geräte-Sync
identity/      selbstzertifizierende ENIG-Konto-, Geräte- und Gruppen-IDs
message/       signierte Nachrichten/Client-Belege und strikte Provider-Grenzen
mixtransport/  ENIG-Mix-v2-Commands und moderater Real/Poll/Cover-Scheduler
nodedir/       signierte IP-Leases, Seed-Quorum und Snapshot-Reconciliation
client/        UI-unabhängiger Client-Core, Replikation, Audit und Failover
cmd/propagare-node/  ausführbarer Referenz-Node
group/         Admin-/Ban-Zustandsmaschine und MLS-Provider-Grenze
call/          direkte, hybrid authentisierte WebRTC-DTLS-SRTP-Calls
media/         gepolsterte, verschlüsselte Datei- und Bildblöcke
node/          Node-HTTP-API und persistenter Speicher
pqcrypto/      Hybrid-HPKE, Hybrid-Signaturen und Padding
transportauth/ CA-PKI-freies Node-Key-Pinning und hybrides TLS-1.3-Profil
protocol/      versionsgebundene Transportobjekte und Proof of Work
docs/          Architektur, Protokoll und Codex-Weiterbauanleitung

Voraussetzungen

  • Go 1.26.5 oder neuer; go.mod pinnt den minimal gehärteten Toolchain
  • Linux, macOS oder Windows für die persistente Preview; weitere per Build-Tag unterstützte Unix-Ziele benötigen einen eigenen Plattform-CI-Lauf, alle anderen Dateisystemplattformen scheitern an der Lock-/Rechte-/Durability- Grenze geschlossen

Go 1.26 wird wegen dessen standardisierter ML-KEM- und hybrider HPKE-Unterstützung benötigt. Patchlevel 1.26.5 ist das Minimum, weil ältere 1.26-Patchstände erreichbare Standardbibliotheks-Advisories enthalten.

Testen

go mod download
go mod verify
test -z "$(gofmt -l $(git ls-files '*.go'))"
go mod tidy -diff
go vet ./...
go test -count=1 ./...
go test -race -count=1 ./...
go run golang.org/x/vuln/cmd/govulncheck@v1.1.4 -show verbose ./...

Die Integrationstests starten lokale kurzlebige Nodes und prüfen Verschlüsselung, Replikation, Ausfallersatz, Speicher-Audit und Löschen.

Entwicklungs-Node starten

go run ./cmd/propagare-node \
  -listen 127.0.0.1:8787 \
  -data ./local/node-1-data \
  -key ./local/node-1-key.json \
  -difficulty 16

Für ein Quorum sollten mindestens fünf unabhängige Nodes laufen. Der Referenzserver sollte nicht direkt ins öffentliche Internet gestellt werden.

Der Standardschlüssel liegt getrennt vom Datenspeicher unter ./propagare-secrets/node-key.json. Ein gebundener Store startet bei fehlendem Schlüssel immer geschlossen und erzeugt keine neue Identität. Soll ein bereits vorhandener Schlüssel absichtlich an ein neues leeres Datenverzeichnis gebunden werden, ist beim ersten Start zusätzlich -initialize-empty-store erforderlich. Alte nichtleere Stores ohne signierte Identitätsbindung werden nicht automatisch migriert; sie müssen mit einem kontrollierten, offline geprüften Migrationsplan überführt werden.

Der optionale Verzeichnisbetrieb verlangt eine mit Client-Releases gemeinsam ausgelieferte propagare-seeds.json. Sie pinnt vollständige hybride Seed-Identitäten und literale IP-Endpunkte. Eine öffentliche Node wird zum Beispiel mit -advertise-ip, -advertise-port, -node-seeds und -node-quorum gestartet. Der Server erzeugt seinen Zertifikatscontainer automatisch aus dem persistenten Node-Schlüssel; -tls-cert, -tls-key, eine CA und IP-SANs sind nicht erforderlich. Reale Seed-IP-Adressen und -Schlüssel sind absichtlich nicht erfunden oder im Prototyp vorgegeben. Der Zertifikatscontainer wird vor Ablauf automatisch erneuert, ohne den gepinnten Node-Schlüssel zu ändern.

Direkttransport verwenden

nodeA, _ := client.ConnectPinnedHTTPNode(ctx, "https://127.0.0.1:8787", pinnedIdentityA, nil)
nodeB, _ := client.ConnectPinnedHTTPNode(ctx, "https://127.0.0.1:8788", pinnedIdentityB, nil)
nodeC, _ := client.ConnectPinnedHTTPNode(ctx, "https://127.0.0.1:8789", pinnedIdentityC, nil)

// storeKey muss produktiv aus OS-Keychain/Secure Enclave kommen.
store, _ := client.NewEncryptedDiskStore(client.DiskClientStoreConfig{
    Directory: "./local/client-state",
    Key:       storeKey,
    // 0 verwendet das sichere Standard- und Maximallimit von 10 GiB.
    MaxBytes: 0,
}, time.Now())

core, _ := client.New(client.Config{
    Nodes:       []*client.HTTPNode{nodeA, nodeB, nodeC},
    Replicas:    3,
    WriteQuorum: 2,
    Store:       store,
})

recipient, _ := pqcrypto.GenerateHybridKEMKeyPair()
routeTag, _ := client.RandomCapability()
// Jedes Item wird exakt für das feste 60-Tage-Protokollfenster gespeichert.
delivery, err := core.SendDirect(
    ctx,
    recipient.PublicKey,
    routeTag,
    []byte("Hallo"),
)

Die pinnedIdentity*-Werte müssen aus der ausgelieferten Seed-Liste oder einem vollständig verifizierten Directory-Record stammen; sie dürfen nicht vom gerade kontaktierten Netzpfad übernommen werden. Der ausführbare Node lauscht immer mit diesem CA-PKI-freien verschlüsselten Transport. Plain HTTP bleibt ausschließlich für eingebettete private Entwicklungstests über DiscoverHTTPNodeForDevelopment verfügbar.

Core.SendDirect ist nur der direkte Entwicklungs-/Bootstrap-Pfad und erfüllt weder Forward Secrecy noch Metadatenanonymität. Eine produktive App registriert zuerst mit account.Register(ctx, secretVault), teilt die resultierende ENIGC1…-ID und verwendet ausschließlich message.NewStrictPipeline mit auditiertem Ratchet-, Replay- und Mixnet-Adapter.

Frontends sollen weder eigene Kryptografie implementieren noch direkt mit Nodes sprechen. Sie rufen ausschließlich den Client-Core auf und erhalten daraus Ereignisse, Nachrichtenmodelle und Zustandsänderungen.

Die geplante stabile Oberfläche für Apps und alternative Frontends steht in docs/FRONTEND-API.md. Das eigene Metadatenprotokoll ist in docs/ENIG-MIX-V2.md spezifiziert. Das Node-Verzeichnis ist in docs/NODE-DIRECTORY-V1.md beschrieben.

Direkten 1:1-Call aushandeln

caller, _ := call.NewEndpoint(call.Config{Signer: callerDeviceSigner})
callee, _ := call.NewEndpoint(call.Config{Signer: calleeDeviceSigner})

outgoing, offer, _ := caller.Start(ctx, callee.Identity(), call.Media{Audio: true})
// offer als Inhalt einer bestehenden E2E-verschlüsselten Nachricht senden.

incoming, answer, _ := callee.Accept(ctx, caller.Identity(), offer)
// answer auf demselben E2E-Kanal zurücksenden.
_ = outgoing.ApplyAnswer(answer)

// Plattformadapter hängen danach Pion-Audio-/Videotracks an die Sessions.
defer outgoing.Close()
defer incoming.Close()

Das vollständige SDP darf nicht durch ein Frontend oder einen Signaling-Server verändert werden. Direkte Kandidaten legen dem Gesprächspartner IP-Adressen offen; ICETransportPolicyRelay erzwingt TURN, schützt aber nicht vor Timing- und Volumenmetadaten beim Relay.

Kryptografische Grundlagen

Vor einem realen Einsatz sind unabhängige Protokoll-, Kryptografie-, Metadaten- und Implementierungs-Audits zwingend.

Lizenz

Dieses Projekt steht unter der GNU Affero General Public License v3.0 (AGPL-3.0). Wer Propagare verändert und als Netzwerkdienst betreibt, muss den Quelltext der veränderten Version den Nutzern dieses Dienstes zugänglich machen.

Directories

Path Synopsis
Package call provides authenticated direct 1:1 WebRTC calls.
Package call provides authenticated direct 1:1 WebRTC calls.
Package client is the UI-independent Propagare client core.
Package client is the UI-independent Propagare client core.
cmd
propagare-node command
Package identity defines the self-certifying, shareable ENIG identifiers.
Package identity defines the self-certifying, shareable ENIG identifiers.
internal
releaseinfo
Package releaseinfo contains build metadata injected into release binaries.
Package releaseinfo contains build metadata injected into release binaries.
Package message defines authenticated application messages and client delivery receipts.
Package message defines authenticated application messages and client delivery receipts.
Package mixtransport implements the ENIG-Mix v2 moderate constant-rate transport orchestration.
Package mixtransport implements the ENIG-Mix v2 moderate constant-rate transport orchestration.
Package nodedir implements Propagare's bounded, signed IP node directory.
Package nodedir implements Propagare's bounded, signed IP node directory.
Package transportauth provides CA-PKI-free node transport authentication.
Package transportauth provides CA-PKI-free node transport authentication.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL