zandGitHub d85096667d Run CI on linux-amd64
GitHub-hosted labels on a private repo are refused by the spending
limit, so these jobs never started. linux-amd64 is our own fleet.

Claude-Session: https://claude.ai/code/session_01HuMDfgFssPUptYUzgZ6Cp8
2026-09-24 10:10:05 -07:00
2026-09-24 10:10:05 -07:00
2026-06-02 11:20:05 -07:00
2026-06-28 20:56:57 -07:00

pqsafe

pqsafe

Reference implementation of PQSAFE-IL5-HYBRID-v1 — a crypto-agile, hybrid post-quantum envelope-encryption profile for DoD-grade file storage and transfer. Paper: luxfi/papers/pqsafe-il5.

PQSAFE encrypts files before they enter any storage or transfer system (DoD SAFE, S3-compatible object storage, SharePoint, MinIO, content-addressed stores, the Lux storage chain). The back-end sees only ciphertext + opaque manifests; sender, recipients, filenames, and classification labels never leave the client.

Cryptographic primitives

Layer Primitive Standard
Bulk AEAD (FIPS profile) AES-256-GCM FIPS 197 + SP 800-38D
Bulk AEAD (software profile) ChaCha20-Poly1305 RFC 8439
Hash SHA-384 / SHA-3-384 FIPS 180-4 / 202
KDF HKDF-SHA-384, domain-separated per layer RFC 5869
Key wrap (hybrid KEM) X-Wing = X25519 + ML-KEM-768 IETF draft-connolly-cfrg-xwing-kem
Key wrap (high-value) X448 + ML-KEM-1024 this profile
Sender signature (hybrid) Ed25519 + ML-DSA-65 (detached pair) RFC 8032 + FIPS 204
Long-term root signature SLH-DSA-SHA2-192f FIPS 205
Manifest format CBOR/COSE (deterministic encoding) RFC 8949 + RFC 8152

Layout

pqsafe/
├── cmd/pqsafe/        CLI: seal, open, verify, revoke, rewrap, push
├── pkg/envelope/      .pqsafe directory / archive packing
├── pkg/manifest/      CBOR/COSE canonical manifest + signature
├── pkg/capsule/       X-Wing recipient capsule (KEM wrap of DEK)
├── pkg/aead/          AES-256-GCM + ChaCha20-Poly1305 chunk AEAD
├── vectors/           deterministic KAT vectors
└── .github/workflows/ CI gates

Domain separation

Every HKDF and every signature carries an explicit context string:

const (
    CtxDEKWrap    = "PQSAFE-DEK-WRAP-v1"
    CtxChunkAEAD  = "PQSAFE-CHUNK-AEAD-v1"
    CtxManifest   = "PQSAFE-MANIFEST-SIG-v1"
    CtxRewrap     = "PQSAFE-REWRAP-v1"
    CtxRecovery   = "PQSAFE-RECOVERY-SHARE-v1"
)

No two layers ever derive a key from the same transcript. No primitive is reused across protocol boundaries.

CLI

# Seal a file
pqsafe seal \
  --in report.pdf \
  --out report.pdf.pqsafe \
  --recipient alice.mil --recipient bob.gov \
  --label CUI --ttl 7d \
  --hybrid mlkem768+x25519 --sign mldsa65+ed25519 \
  --audit lux-q

# Open
pqsafe open --in report.pdf.pqsafe --out report.pdf

# Verify (no decrypt)
pqsafe verify --in report.pdf.pqsafe

# Revoke a manifest
pqsafe revoke --manifest-hash sha384:... --reason "recipient compromised"

# Rewrap (rotate KEK without re-encrypting chunks)
pqsafe rewrap --in report.pdf.pqsafe --add-recipient charlie.gov

# Push via hanzo/replicate
pqsafe push report.pdf.pqsafe replicate://safe.apps.mil/cui/

Composition with the Lux stack

Component Role
luxfi/crypto primitive provider: ML-KEM, ML-DSA, SLH-DSA, AEAD, HKDF, hashes
luxfi/zwing secure channel over TCP/IP (X-Wing + Ed25519+ML-DSA-65 + ChaCha20-Poly1305)
luxfi/pqrns secure channel over Reticulum mesh / LoRa / packet radio
luxfi/age file-at-rest envelope when E2E transfer is impossible (replication / backup / legacy ingest)
luxfi/corona Ring-LWE threshold ML-DSA for recovery quorum
luxfi/pulsar Module-LWE threshold ML-DSA (FIPS 204 byte-equal)
luxfi/kms HSM-backed long-term key custody
Lux Q-Chain audit anchor (opaque hash commitments only)

Status

Reference implementation. Not FIPS-validated. Not approved for DoD production use without an Authority to Operate (ATO) and FIPS 140-3 module validation of the underlying primitives.

Paper

luxfi/papers/pqsafe-il5/pqsafe-il5.tex is the authoritative specification. The implementation tracks the paper; any divergence is a bug in the implementation.

License

Apache-2.0 (see LICENSE).

S
Description
PQSAFE-IL5-HYBRID-v1: crypto-agile hybrid post-quantum envelope encryption for DoD-grade file storage and transfer
Readme
121 KiB
Languages
Go 100%