Expand description
Β§Anubis Rage - Post-Quantum Secure File Encryption
π Quantum-Resistant File Encryption
Powered by ML-KEM-1024 (NIST FIPS 203) and ML-DSA-87 (NIST FIPS 204)
Anubis Rage is a modern, secure file encryption tool and library implementing NIST-standardized post-quantum cryptography to protect your data against both current and future threats, including attacks from quantum computers.
Β§π― Key Features
- π Post-Quantum Security: ML-KEM-1024 encryption resistant to quantum attacks
- βοΈ Digital Signatures: Mandatory ML-DSA-87 signatures for authenticated encryption (v1.1.0+)
- π NIST Level-5 Security: Highest standardized post-quantum security level (256-bit equivalent)
- β‘ High Performance: Efficient implementation via liboqs
- π Simple API: Clean, ergonomic interface for both CLI and library usage
- π Secure by Default: No passphrases, no config files, explicit keys only
Β§π¦ Installation
Β§As a Library
Add to your Cargo.toml:
[dependencies]
anubis-rage = "1.1"Β§As CLI Tools
cargo install anubis-rageThis installs three command-line tools:
anubis-rage- Encrypt/decrypt files with quantum-resistant encryptionanubis-rage-keygen- Generate ML-KEM-1024 encryption keysanubis-rage-sign- Generate ML-DSA-87 signing keys
Β§π Quick Start (Library)
Β§Basic Encryption/Decryption
use anubis_rage::pqc::mlkem;
use std::io::{Read, Write};
// Generate ML-KEM-1024 keypair
let identity = mlkem::Identity::generate();
let recipient = identity.to_public();
// Encrypt data
let plaintext = b"Secret quantum-resistant message!";
let encryptor = anubis_rage::Encryptor::with_recipients(vec![&recipient as _])?;
let mut ciphertext = vec![];
let mut writer = encryptor.wrap_output(&mut ciphertext)?;
writer.write_all(plaintext)?;
writer.finish()?;
// Decrypt data
let decryptor = anubis_rage::Decryptor::new(&ciphertext[..])?;
let mut decrypted = vec![];
decryptor.decrypt(vec![&identity as _])?.read_to_end(&mut decrypted)?;
assert_eq!(decrypted, plaintext);
println!("β Encryption and decryption successful!");Β§Multiple Recipients
use anubis_rage::pqc::mlkem;
use std::io::Write;
// Generate keys for multiple recipients
let alice_identity = mlkem::Identity::generate();
let bob_identity = mlkem::Identity::generate();
let alice_recipient = alice_identity.to_public();
let bob_recipient = bob_identity.to_public();
// Encrypt to multiple recipients (any one can decrypt)
let encryptor = anubis_rage::Encryptor::with_recipients(vec![
&alice_recipient as _,
&bob_recipient as _,
])?;
let mut ciphertext = vec![];
let mut writer = encryptor.wrap_output(&mut ciphertext)?;
writer.write_all(b"Team secret")?;
writer.finish()?;
// Both Alice and Bob can decrypt
let decryptor = anubis_rage::Decryptor::new(&ciphertext[..])?;
let mut decrypted = vec![];
decryptor.decrypt(vec![&alice_identity as _])?.read_to_end(&mut decrypted)?;
assert_eq!(decrypted, b"Team secret");Β§π» Quick Start (CLI)
Β§Generate Keys
# Generate encryption keys
anubis-rage-keygen -o my-key.txt
# Public key: anubis1mlkem11ptpjg078r7rjw3x86e0mj346h8223derqruv8qx...
# Generate signing keys (required for v1.1.0+)
anubis-rage-sign keygen --output signing-key.txt
# verification key: anubis1mldsa871tu22gw7ysld7gsw3c8dn7aydpagllmunu...Β§Encrypt with Mandatory Signature (v1.1.0+)
anubis-rage -r anubis1mlkem1... \
--signing-key signing-key.txt \
-o secrets.txt.age secrets.txt
# File encrypted and signed with ML-DSA-87Β§Decrypt with Mandatory Verification (v1.1.0+)
anubis-rage -d \
--verify-key anubis1mldsa87... \
-i my-key.txt \
-o secrets.txt secrets.txt.age
# Signature verified successfullyΒ§π Security Guarantees
Β§Encryption (ML-KEM-1024)
- Algorithm: Module-Lattice-Based Key-Encapsulation Mechanism
- Standard: NIST FIPS 203 (approved August 2024)
- Security Level: NIST Category 5 (β₯256-bit equivalent)
- Security Property: IND-CCA2 (Indistinguishability under Adaptive Chosen-Ciphertext Attack)
- Quantum Resistance: Secure against Shorβs and Groverβs algorithms
- Key Sizes:
- Public Key: 1,568 bytes
- Secret Key: 3,168 bytes
- Ciphertext: 1,568 bytes
Β§Digital Signatures (ML-DSA-87, Mandatory in v1.1.0+)
- Algorithm: Module-Lattice-Based Digital Signature Algorithm
- Standard: NIST FIPS 204 (approved August 2024)
- Security Level: NIST Category 5 (β₯256-bit equivalent)
- Security Property: SUF-CMA (Strong Unforgeability under Chosen-Message Attack)
- Quantum Resistance: Secure against quantum forgery attacks
- Key/Signature Sizes:
- Public Key: 2,592 bytes
- Secret Key: 4,896 bytes
- Signature: 4,595 bytes
Β§Additional Security Features
- AEAD Encryption: AES-256-GCM-SIV (RFC 8452, nonce-misuse resistant)
- Key Derivation: HKDF-SHA512 (NIST SP 800-56C)
- Header Authentication: HMAC-SHA512 (64-byte MAC)
- Forward Secrecy: Ephemeral key wrapping
- No Metadata Leakage: Recipient public keys not stored in ciphertext
Β§π Version Compatibility
Β§v1.1.0+ (Current) - Mandatory Signatures
All files are automatically signed with ML-DSA-87:
- Encryption requires
--signing-key - Decryption requires
--verify-key - Provides authenticated encryption
- Detects tampering automatically
Β§v1.0.0 - Encryption Only
- No signature support
- Files lack authentication
- β οΈ Not compatible with v1.1.0+
Migration: Re-encrypt files with v1.1.0+ to add mandatory signatures.
Β§β‘ Performance
Benchmarks on 2023 MacBook Pro M2:
| Operation | File Size | Time | Throughput |
|---|---|---|---|
| Key Generation | - | ~2ms | - |
| Encryption | 1 MB | ~8ms | 125 MB/s |
| Encryption | 1 GB | ~7.5s | 133 MB/s |
| Decryption | 1 MB | ~8ms | 125 MB/s |
| Decryption | 1 GB | ~7.3s | 137 MB/s |
ML-DSA-87 signature overhead (v1.1.0+):
- Signing: +3-5ms
- Verification: +3-5ms
- File size: +4.6KB
Β§π Advanced Usage
Β§Streaming Large Files
use anubis_rage::pqc::mlkem;
use std::fs::File;
use std::io::{BufReader, BufWriter, copy};
let identity = mlkem::Identity::generate();
let recipient = identity.to_public();
// Encrypt large file with streaming
let input = BufReader::new(File::open("large-file.bin")?);
let output = BufWriter::new(File::create("large-file.bin.age")?);
let encryptor = anubis_rage::Encryptor::with_recipients(vec![&recipient as _])?;
let mut writer = encryptor.wrap_output(output)?;
// Stream data efficiently
let mut reader = input;
copy(&mut reader, &mut writer)?;
writer.finish()?;Β§ASCII Armor Format
use anubis_rage::pqc::mlkem;
use anubis_rage::armor::{ArmoredWriter, Format};
use std::io::Write;
let identity = mlkem::Identity::generate();
let recipient = identity.to_public();
let encryptor = anubis_rage::Encryptor::with_recipients(vec![&recipient as _])?;
let mut output = vec![];
let armored = ArmoredWriter::wrap_output(&mut output, Format::AsciiArmor)?;
let mut writer = encryptor.wrap_output(armored)?;
writer.write_all(b"Text-safe encrypted data")?;
writer.finish()?.finish()?;
// Output is ASCII-armored
let armored_text = String::from_utf8(output)?;
assert!(armored_text.starts_with("-----BEGIN AGE ENCRYPTED FILE-----"));Β§π Comparison with Other Tools
| Feature | Anubis Rage | age/rage | GPG | NaCl |
|---|---|---|---|---|
| Post-Quantum | β ML-KEM-1024 | β X25519 | β RSA/ECC | β X25519 |
| PQ Signatures | β ML-DSA-87 | β | β | β |
| NIST Standardized | β FIPS 203/204 | β | β (legacy) | β |
| Quantum Resistant | β | β | β | β |
| Simple API | β | β | β | β |
| No Config Files | β | β | β | β |
Β§π Technical Documentation
Β§File Format
Anubis Rage encrypted files use the following structure:
anubis-encryption.org/v1
-> MLKEM-1024
[base64-encoded-encapsulated-key]
[base64-encoded-wrapped-file-key]
-> [grease-stanza]
[grease-body]
--- [86-character-SHA512-MAC]
[encrypted-payload]With ML-DSA-87 signatures (v1.1.0+), the entire encrypted file is signed.
Β§Cryptographic Primitives
All primitives achieve strong security guarantees:
| Component | Algorithm | Security |
|---|---|---|
| KEM | ML-KEM-1024 | NIST L5 (β₯256-bit) |
| Signature | ML-DSA-87 | NIST L5 (β₯256-bit) |
| KDF | HKDF-SHA512 | 256-bit |
| MAC | HMAC-SHA512 | 256-bit |
| AEAD | AES-256-GCM-SIV | 256-bit + nonce-misuse resistant |
Β§π Resources
- GitHub: AnubisQuantumCipher/anubis-rage
- Crates.io: anubis-rage
- NIST PQC: Post-Quantum Cryptography Project
- FIPS 203: ML-KEM Standard
- FIPS 204: ML-DSA Standard
Β§π‘οΈ Security Disclosure
If you discover a security vulnerability, please report it via:
- GitHub Security Advisories: Report a vulnerability
- GitHub Issues: Create an issue
Β§π License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
ModulesΒ§
- armor
- I/O helper structs for the age ASCII armor format.
- cli_
common - Common helpers for CLI binaries.
- fips
- FIPS 140-3 compliance module
- pqc
- Post-quantum cryptography (PQC) using ML-KEM (formerly Kyber).
- secrecy
SecretBoxwrapper type for more carefully handling secret values (e.g. passwords, cryptographic keys, access tokens or other credentials)- stream
- I/O helper structs for age file encryption and decryption.
StructsΒ§
- Decryptor
- Decryptor for an age file.
- Encryptor
- Encryptor for creating an age file.
- Identity
File - A list of identities that has been parsed from some input file.
- NoCallbacks
- An implementation of
Callbacksthat does not allow callbacks.
EnumsΒ§
- Decrypt
Error - The various errors that can be returned during the decryption process.
- Encrypt
Error - The various errors that can be returned during the encryption process.
- Identity
File Convert Error - Errors returned when converting an identity file to a recipients file.
TraitsΒ§
- Callbacks
- Callbacks that might be triggered during encryption or decryption.
- Identity
- A private key or other value that can unwrap an opaque file key from a recipient stanza.
- Recipient
- A public key or other value that can wrap an opaque file key to a recipient stanza.
FunctionsΒ§
- decrypt
- Decrypts the given ciphertext with the given identity.
- encrypt
- Encrypts the given plaintext to the given recipient.
- encrypt_
and_ armor - Encrypts the given plaintext to the given recipient, and wraps the ciphertext in ASCII armor.
- localizer
- Returns the
Localizerto be used for localizing this library.