age Rust library (Anubis Rage Edition)
Post-quantum secure file encryption library with hybrid X25519+ML-KEM-1024 support
age is a simple, modern, and secure file encryption library. This is the Anubis Rage edition, which extends the original age library with defense-in-depth post-quantum cryptography through hybrid mode combining X25519 and ML-KEM-1024.
Features
- 🛡️ Hybrid Mode (RECOMMENDED): X25519 + ML-KEM-1024 defense-in-depth
- 🔐 Quantum-Resistant: ML-KEM-1024 (NIST FIPS 203) for post-quantum security
- 🎯 Classical Algorithms: X25519, scrypt, and SSH key support remain available
- 🚀 Simple API: Small explicit keys, no config options, UNIX-style composability
- ⚡ High Performance: Efficient implementations via liboqs and Rust crypto ecosystem
- 🔒 NIST Level-5: Highest standardized post-quantum security level (256-bit equivalent)
What's New in Anubis Rage v2.0
This crate provides a set of Rust APIs that can be used to build tools based on the age format, with defense-in-depth post-quantum cryptography:
Hybrid Mode (NEW in v2.0)
- Defense-in-Depth: Combines X25519 ECDH with ML-KEM-1024 KEM
- Dual-Algorithm Security: Attacker must break BOTH algorithms
- Industry Standard: Same approach as Signal Protocol, TLS 1.3
- NIST Compliant: Follows NIST SP 800-56C Rev. 2 for hybrid KDF
Pure Post-Quantum Mode
- ML-KEM-1024 Recipients: Encrypt to quantum-resistant public keys
- ML-KEM-1024 Identities: Decrypt with quantum-resistant private keys
- NIST Standardized: Implements FIPS 203 approved post-quantum KEM
Classical Mode
- Backward Compatible: Still supports X25519, scrypt, and SSH keys
- Battle-Tested: Proven security against classical attacks
The primary consumer of these APIs is the anubis-rage CLI tool, which provides straightforward quantum-resistant encryption and decryption of files or streams.
Format Specification
The age format specification is at age-encryption.org/v1.
Anubis Rage extends this with two post-quantum recipient stanza formats:
Hybrid Mode (RECOMMENDED)
-> hybrid [base64-x25519-epk] [base64-mlkem-ciphertext]
[base64-encoded-wrapped-file-key]
Pure ML-KEM-1024
-> mlkem1024 [base64-encoded-ciphertext]
[base64-encoded-wrapped-file-key]
The age format was designed by @Benjojo and @FiloSottile.
The reference interoperable Go implementation is available at filippo.io/age.
Installation
Add this line to your Cargo.toml:
= "2.0"
For post-quantum features, ensure you have liboqs installed:
macOS:
Ubuntu/Debian:
&& &&
&&
Usage
Hybrid Mode (RECOMMENDED - Defense-in-Depth)
use ;
use ;
use ;
// Generate a new hybrid identity (X25519 + ML-KEM-1024)
let identity = generate;
let recipient = identity.to_public;
// Encrypt
let encryptor = with_recipients
.expect;
let mut encrypted = vec!;
let mut writer = encryptor.wrap_output?;
writer.write_all?;
writer.finish?;
// Decrypt
let decryptor = match new? ;
let mut decrypted = vec!;
let mut reader = decryptor.decrypt?;
reader.read_to_end?;
assert_eq!;
Pure ML-KEM-1024 (Post-Quantum Only)
use ;
// Generate a new ML-KEM-1024 identity (quantum-resistant only)
let identity = generate;
let recipient = identity.to_public;
// Use same Encryptor/Decryptor API as above
Using X25519 (Classical)
use x25519;
let identity = generate;
let recipient = identity.to_public;
// Use same Encryptor/Decryptor API as above
Using Passphrase Encryption
use scrypt;
let identity = new;
// Encrypt
let encryptor = with_user_passphrase;
// Decrypt using scrypt::Identity
API Documentation
See the documentation for complete API details and examples.
Feature Flags
pqc-mlkem- Enables ML-KEM-1024 and hybrid mode support (enabled by default)armor- Enables theage::armormodule for ASCII-armored age filesasync- Enables asynchronous APIs for encryption and decryptioncli-common- Common helper functions for building age CLI toolsssh- Enables theage::sshmodule for reusing SSH key filesweb-sys- WebAssembly support for passphrase work factor calculationunstable- In-development functionality (no stability guarantees)
Security Considerations
Hybrid Mode (RECOMMENDED)
Hybrid mode provides defense-in-depth by requiring an attacker to break BOTH:
- X25519 ECDH: ~128-bit classical security (discrete log problem)
- ML-KEM-1024: ~256-bit quantum security (Module-LWE problem)
Key Properties:
- No Single Point of Failure: If either algorithm is broken, the other still protects data
- Future-Proof: Protected against both classical and quantum attacks
- Industry Standard: Same approach used in Signal Protocol, TLS 1.3, SSH
- NIST Compliant: Follows NIST SP 800-56C Rev. 2 hybrid key derivation
Pure Post-Quantum Security
ML-KEM-1024 provides:
- IND-CCA2 security: Indistinguishability under adaptive chosen-ciphertext attack
- NIST Level-5: Equivalent to AES-256 classical security
- Quantum resistance: Secure against Shor's and Grover's algorithms
- Standardized: NIST FIPS 203 compliant
Classical Security
X25519, scrypt, and SSH support remain available for:
- Backward compatibility with existing age files
- Integration with existing SSH infrastructure
- Scenarios where post-quantum security is not required
Recommendations
| Use Case | Recommended Mode | Rationale |
|---|---|---|
| Long-term data protection | Hybrid | Defense-in-depth, no single point of failure |
| High-security scenarios | Hybrid | Industry best practice |
| General file encryption | Hybrid | Future-proof with minimal overhead |
| Legacy compatibility | X25519 | Interoperability with original age |
| Passphrase-based | scrypt | Simple, password-based encryption |
Comparison with Original rage
| Feature | Anubis Rage v2.0 | Original rage |
|---|---|---|
| Hybrid Mode | ✅ X25519 + ML-KEM-1024 | ❌ No |
| Post-Quantum Security | ✅ ML-KEM-1024 | ❌ No |
| Defense-in-Depth | ✅ Dual-algorithm | ❌ Single algorithm |
| NIST Standardized PQC | ✅ FIPS 203 | ❌ |
| X25519 Support | ✅ Yes | ✅ Yes |
| SSH Key Support | ✅ Yes | ✅ Yes |
| Passphrase Encryption | ✅ Yes | ✅ Yes |
| File Compatibility | ✅ Full (with age v1) | ✅ Standard age |
| Quantum Resistant | ✅ With hybrid/ML-KEM | ❌ No |
Examples
Multiple Recipients (Defense-in-Depth)
use hybrid;
let hybrid_identity = generate;
// Encrypt to hybrid recipient (recommended)
let recipients: = vec!;
let encryptor = with_recipients
.expect;
Streaming Encryption
use Encryptor;
use hybrid;
use Write;
let recipient = generate.to_public;
let encryptor = with_recipients?;
let output = create?;
let mut writer = encryptor.wrap_output?;
// Stream data in chunks
for chunk in data_chunks
writer.finish?;
ASCII Armoring
use ArmoredWriter;
use hybrid;
let recipient = generate.to_public;
let encryptor = with_recipients?;
let output = Vecnew;
let armored = wrap_output?;
let mut writer = encryptor.wrap_output?;
writer.write_all?;
let armored_output = writer.finish?.into_inner?;
// armored_output contains ASCII-armored ciphertext
Migration from v1.x
Files encrypted with v1.x (pure ML-KEM-1024) can still be decrypted by v2.0:
// Old v1.x files using pure ML-KEM-1024
let old_mlkem_identity = from_string;
// Works fine in v2.0
let decryptor = new?;
let reader = decryptor.decrypt?;
For new encryptions, we recommend migrating to hybrid mode:
// New v2.0 hybrid mode (recommended)
let new_hybrid_identity = generate;
let recipient = new_hybrid_identity.to_public;
// Encrypt with defense-in-depth
let encryptor = with_recipients?;
Library Development
Building
# Build the library
# Run tests
# Build with all features
Testing
# Run all tests
# Test hybrid mode specifically
# Test with sanitizers (requires nightly)
RUSTFLAGS="-Z sanitizer=address"
Contributing
See CONTRIBUTING.md for guidelines on:
- Code style and conventions
- Adding new features
- Localization support
- Testing requirements
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Acknowledgments
- NIST - For post-quantum cryptography standardization (FIPS 203)
- Open Quantum Safe - For the liboqs ML-KEM-1024 implementation
- Signal Foundation - For pioneering hybrid post-quantum cryptography
- Filippo Valsorda & Ben Cox - For designing the age format
- Original rage contributors - For the excellent foundation
- Rust crypto community - For high-quality cryptography crates
Further Reading
- NIST Post-Quantum Cryptography
- FIPS 203: ML-KEM Standard
- NIST SP 800-56C Rev. 2: Hybrid Key Derivation
- Signal Protocol: PQXDH
- age specification v1
- Open Quantum Safe Project
- Anubis Rage GitHub
Anubis Rage v2.0 - Defense-in-depth protection for the quantum era.