Skip to content

[crypto] ML-KEM-768 session encryption for Jetson↔ATAK transport #68

Description

@jdev-02

Lane: crypto · Owner: P2 (Satriyo) · Phase: stretch · Priority: P2

Why

Closes the harvest-now-decrypt-later gap on the Jetson↔ATAK transport. PRD §7.2 already lists ML-KEM-768 as a stretch row in the component table; PRD §8.2 step 5 documents the construct ("Encrypt to peer: ML-KEM-768 (Kyber) key exchange + AES-256-GCM payload for unicast peer comms"). This issue is the implementation.

In Phase 3, the link is physically private (USB tether, see Kyle's #11). Application-layer authenticity is already guaranteed by ML-DSA-signed CoT (PRD §8.2). This stretch adds confidentiality on top: a passive eavesdropper with future quantum compute can't recover routes, waypoints, or operator location from a captured pcap.

Pairs with the Android-side sidecar issue (sister stretch issue) — that's the harder half because ATAK does not natively speak liboqs.

Acceptance criteria

  • crypto/kem_session.py exposes Session.establish(role) returning an authenticated AEAD context. Both ends derive the same AES-256-GCM key.
  • At agent startup, Jetson and the ATAK-side peer perform a one-shot ML-KEM-768 handshake (liboqs-python).
  • Hybrid handshake: combine ML-KEM-768 shared secret with X25519 ECDH via HKDF-SHA256 (defense-in-depth — if either primitive falls, the session still holds).
  • All CoT bytes pass through Session.seal(plaintext) -> ciphertext before bridge.py writes to TCP. Bridge ingest does the inverse via Session.open(ciphertext).
  • Replay protection: per-direction monotonic counter in the AEAD AAD; any out-of-order ciphertext rejected.
  • Re-key on agent restart. No persistent session state across reboots.
  • Unit tests: round-trip seal/open, tampered ciphertext rejected, replay rejected, mismatched key rejected.
  • Bench: handshake < 50ms on Jetson, per-CoT seal/open < 1ms.
  • Doc: docs/contracts/pqc_session.md describing the wire format (handshake message structure, sealed envelope structure, counter semantics).

File pointers

  • crypto/kem_session.py (new)
  • crypto/aead.py (new — thin wrapper around AES-256-GCM)
  • atak/bridge.py (wraps emit/ingest in Session)
  • tests/test_kem_session.py (new)
  • docs/contracts/pqc_session.md (new)

Dependencies

  • Hard prerequisite: Phase-3 USB-tether POC working end-to-end (signed CoT plaintext over the tether → ATAK draws the line). Don't build encryption on top of a transport that isn't proven.
  • Hard prerequisite: Android-side sidecar (sister issue) — without it, this is server-side only and the pitch is "encrypted to nowhere."
  • Soft prerequisite: ML-DSA signer already shipping (✅ done).

Defer condition

Only start if Sun 0700 go/no-go on Phase 3 + mesh stretch is GO AND the Android sidecar (sister issue) is also feasible. Otherwise demo the architecture diagram, ship as post-hackathon roadmap.

Refs PRD §7.2 (stretch row), §8.2 step 5, §8.5 (deferred-but-documented).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions