Post-quantum secure recipients for age encryption using hybrid X25519 + ML-KEM-768 cryptography.
- 🔒 Post-quantum security with hybrid X25519 + ML-KEM-768
- 🔄 Drop-in age compatibility - works with existing age workflows
- 📦 Go library for easy integration
- 🔌 Age plugin support
# Install
go install github.com/zlobste/qage/cmd/qage@latest
# Generate a key
qage keygen -o ~/.age/qage-key
# Get the public recipient
qage pub -i ~/.age/qage-key
# → qage1abc...xyz
# Encrypt with age
age -R qage1abc...xyz -o secret.age secret.txt
# Decrypt
age -d -i ~/.age/qage-key secret.ageCLI command reference is auto-generated. See the markdown files in docs/ (e.g. docs/qage.md) for the latest command help.
Generate / refresh locally:
qage docs # Creates/updates markdown files in ./docs/
ls docs/*.mdimport "github.com/zlobste/qage/pkg/qage"
// Generate identity
identity, err := qage.NewIdentity()
// Get recipient for encryption
recipient := identity.Recipient()
// Use with age
recipients := []age.Recipient{recipient}
identities := []age.Identity{identity}qage combines two cryptographic components in a hybrid KEM:
| Component | Purpose | Status |
|---|---|---|
| X25519 | Classical ECDH security | Widely deployed |
| ML-KEM-768 | Post-quantum KEM (Kyber level 3) | NIST PQC selection |
The shared secret is derived from both encapsulations; an attacker must successfully break both to recover the file key. This follows the standard hybrid rationale: security degrades only if both primitives fail.
The optional age-plugin-qage binary allows the standard age tool to encrypt/decrypt using qage recipients transparently.
Build it:
go build -o age-plugin-qage ./cmd/age-plugin-qage
mv age-plugin-qage $(go env GOPATH)/bin/ # ensure it's on PATHThen age will automatically invoke it when encountering qage recipients.
go test ./... # Run all tests
go test -race ./... # Race detector
qage selftest # Built-in validationSee CONTRIBUTING.md for development guidelines.
MIT License - see LICENSE for details.