Expand description
§Anubis Rage - Post-Quantum Secure File Encryption
Quantum-resistant file encryption using ML-KEM-1024 (NIST FIPS 203)
Anubis Rage is a modern, simple, and secure file encryption tool and library that implements post-quantum cryptography to protect your files against both current and future threats, including attacks from quantum computers.
§Table of Contents
- Quick Start
- What is Anubis Rage?
- Security Guarantees
- Installation
- Library Usage
- Command-Line Usage
- File Format
- Cryptographic Stack
- Performance
- Examples
§Quick Start
§Library Usage
use std::io::{Read, Write};
// Generate Hybrid keypair (X25519 + ML-KEM-1024) - RECOMMENDED
let identity = age::pqc::hybrid::Identity::generate();
let recipient = identity.to_public();
// Encrypt (uses both X25519 and ML-KEM-1024)
let plaintext = b"Secret message with defense-in-depth security!";
let encryptor = age::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 (both X25519 and ML-KEM-1024 must succeed)
let decryptor = age::Decryptor::new(&ciphertext[..])?;
let mut decrypted = vec![];
let mut reader = decryptor.decrypt(vec![&identity as _])?;
reader.read_to_end(&mut decrypted)?;
assert_eq!(decrypted, plaintext);
§CLI Tool
# Install
cargo install anubis-rage
# Generate a key
anubis-rage-keygen -o key.txt
# Encrypt a file
anubis-rage -r $(grep -o 'anubis1[^"]*' key.txt) -o secret.txt.anubis secret.txt
# Decrypt a file
anubis-rage -d -i key.txt -o decrypted.txt secret.txt.anubis
§What is Anubis Rage?
Anubis Rage is a post-quantum secure file encryption tool based on ML-KEM-1024 (Module-Lattice-Based Key-Encapsulation Mechanism), standardized as NIST FIPS 203.
§Key Features
- ✅ Post-Quantum Security: NIST Category 5 (maximum security level)
- ✅ Simple & Modern: Small explicit keys, no config files, UNIX-style composability
- ✅ Streaming Encryption: Handles files of any size with constant memory usage
- ✅ Authenticated Encryption: AES-256-GCM-SIV or ChaCha20-Poly1305 AEAD
- ✅ Forward Secrecy: Ephemeral key encapsulation per recipient
- ✅ Standards Compliant: NIST FIPS 203, FIPS 198-1, SP 800-56C
§Why Post-Quantum Cryptography?
Quantum computers (when built at sufficient scale) will break current public-key cryptography:
- Shor’s Algorithm: Breaks RSA, ECDSA, ECDH in polynomial time
- Grover’s Algorithm: Halves symmetric key security (256-bit → 128-bit effective)
Anubis Rage uses lattice-based cryptography (ML-KEM-1024) which resists both classical and quantum attacks, ensuring your encrypted files remain secure for decades to come.
§Security Guarantees
§Cryptographic Security
Property | Status |
---|---|
Confidentiality | ✅ IND-CCA2 secure (ML-KEM-1024) |
Integrity | ✅ Authenticated encryption (AEAD) |
Forward Secrecy | ✅ Ephemeral key wrapping |
Post-Quantum | ✅ NIST Category 5 (256-bit quantum security) |
Classical Security | ✅ 256-bit equivalent (AES-256) |
§NIST Category 5 Security Level
Anubis Rage achieves NIST Category 5 - the highest security classification:
- Classical Attack Cost: 2^256 operations (equivalent to AES-256)
- Quantum Attack Cost: > 2^170 quantum gates (exceeds NIST requirement)
- Public Key Size: 2592 bytes
- Secret Key Size: 4736 bytes
- Ciphertext Overhead: 1568 bytes + 64-byte SHA-512 MAC
§Installation
§As a Library
Add to your Cargo.toml
:
[dependencies]
anubis-rage = "1.0"
§As a CLI Tool
cargo install anubis-rage
This installs three binaries:
anubis-rage
: Encryption/decryption toolanubis-rage-keygen
: Key generation utilityanubis-rage-sign
: Digital signature tool (ML-DSA-87)
§Library Usage
§Basic Encryption/Decryption
use anubis_rage::{pqc::mlkem, Encryptor, Decryptor};
use std::io::{Read, Write};
// Generate keypair
let identity = mlkem::Identity::generate();
let recipient = identity.to_public();
// Encrypt data
let plaintext = b"Top secret quantum-safe data";
let encryptor = 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 = Decryptor::new(&ciphertext[..])?;
let mut decrypted = vec![];
let mut reader = decryptor.decrypt(vec![&identity as _])?;
reader.read_to_end(&mut decrypted)?;
assert_eq!(decrypted, plaintext);
§Multi-Recipient Encryption
use anubis_rage::{pqc::mlkem, Encryptor};
// Generate keys for multiple recipients
let alice = mlkem::Identity::generate();
let bob = mlkem::Identity::generate();
let carol = mlkem::Identity::generate();
let recipients = vec![
&alice.to_public() as &dyn anubis_rage::Recipient,
&bob.to_public() as &dyn anubis_rage::Recipient,
&carol.to_public() as &dyn anubis_rage::Recipient,
];
// Encrypt to all recipients (any can decrypt)
let encryptor = Encryptor::with_recipients(recipients)?;
// ... encrypt data ...
§Async I/O Support
use anubis_rage::{pqc::mlkem, Encryptor};
use futures::io::AsyncWriteExt;
let identity = mlkem::Identity::generate();
let recipient = identity.to_public();
let encryptor = Encryptor::with_recipients(vec![&recipient as _])?;
let mut encrypted = vec![];
let mut writer = encryptor.wrap_async_output(&mut encrypted).await?;
writer.write_all(b"Async quantum-safe encryption!").await?;
writer.close().await?;
§Command-Line Usage
§Key Generation
# Generate new ML-KEM-1024 keypair
anubis-rage-keygen -o identity.txt
chmod 600 identity.txt
# Extract public key
grep "public key:" identity.txt
§Encryption
# Encrypt to a recipient
anubis-rage -r RECIPIENT_PUBLIC_KEY -o file.anubis file.txt
# Encrypt to multiple recipients
anubis-rage -r alice.pub -r bob.pub -o file.anubis file.txt
# Encrypt with ASCII armor
anubis-rage -r RECIPIENT --armor -o file.anubis file.txt
# Pipe encryption
cat file.txt | anubis-rage -r RECIPIENT > file.anubis
§Decryption
# Decrypt with identity file
anubis-rage -d -i identity.txt -o output.txt file.anubis
# Pipe decryption
cat file.anubis | anubis-rage -d -i identity.txt > output.txt
§File Format
Anubis Rage uses the anubis-encryption.org/v1
file format:
anubis-encryption.org/v1
-> MLKEM-1024
[2144-char base64: ML-KEM-1024 encapsulated key (1568 bytes)]
[76-char base64: wrapped file key with ChaCha20-Poly1305 (44 bytes)]
--- [86-char base64: SHA-512 HMAC header MAC (64 bytes)]
[encrypted payload with AES-256-GCM-SIV or ChaCha20-Poly1305]
§Size Overhead
- Fixed header: ~2.4 KB
- Per recipient: ~2.1 KB
- Total: ~2.4 KB + (num_recipients × 2.1 KB)
For files >100 KB, overhead is <2%. For files >1 MB, overhead is <0.2%.
§Cryptographic Stack
Anubis Rage uses NIST Category 5 (maximum strength) cryptography throughout:
Component | Algorithm | Security Level | Standard |
---|---|---|---|
Key Encapsulation | ML-KEM-1024 | Cat. 5 (256-bit) | NIST FIPS 203 |
Key Derivation | HKDF-SHA512 | 256-bit | SP 800-56C Rev. 2 |
Message Auth | HMAC-SHA512 | 256-bit | FIPS 198-1 |
AEAD (Default) | AES-256-GCM-SIV | 256-bit | RFC 8452 |
AEAD (Alt) | ChaCha20-Poly1305 | 256-bit | RFC 8439 |
Random Generation | OS CSPRNG | System | /dev/urandom |
§Key Derivation Process
1. ML-KEM-1024.Encapsulate(recipient_pk) → (ciphertext, shared_secret)
2. wrap_key = HKDF-SHA512-Expand(
HKDF-SHA512-Extract(
salt: recipient_pk || ciphertext,
IKM: shared_secret
),
info: "anubis-encryption.org/v1/MLKEM-1024",
L: 32 bytes
)
3. encrypted_file_key = ChaCha20-Poly1305.Encrypt(wrap_key, file_key)
4. payload = AES-256-GCM-SIV.Encrypt(file_key, plaintext)
§Performance
Benchmarks on Apple M1 with 2.0 GB video file:
Operation | Throughput | Time |
---|---|---|
Encryption | ~187 MB/s | 10.97s |
Decryption | ~159 MB/s | 12.89s |
Key Generation | N/A | ~2ms |
§Cryptographic Operation Timing
- ML-KEM-1024 KeyGen: ~2ms
- ML-KEM-1024 Encapsulate: ~0.5ms
- ML-KEM-1024 Decapsulate: ~0.6ms
- HKDF-SHA512 Derive: <0.1ms
- File Encryption: I/O-bound (~170 MB/s)
§Memory Usage
- Encryption: ~64 KB constant (streaming)
- Decryption: ~64 KB constant (streaming)
- Key Storage: ~5 KB per identity
Files of any size can be encrypted with constant memory usage.
§Examples
§File Encryption
use anubis_rage::{pqc::mlkem, Encryptor};
use std::fs::File;
use std::io::{copy, Write};
fn encrypt_file(
input_path: &str,
output_path: &str,
recipient: &mlkem::Recipient
) -> Result<(), Box<dyn std::error::Error>> {
let encryptor = Encryptor::with_recipients(vec![recipient as _])?;
let mut input = File::open(input_path)?;
let output = File::create(output_path)?;
let mut writer = encryptor.wrap_output(output)?;
copy(&mut input, &mut writer)?;
writer.finish()?;
Ok(())
}
§Streaming Large Files
use anubis_rage::{pqc::mlkem, Encryptor, Decryptor};
use std::io::{Read, Write, copy};
let identity = mlkem::Identity::generate();
let recipient = identity.to_public();
// Encrypt a large file with constant memory
let encryptor = Encryptor::with_recipients(vec![&recipient as _])?;
let input = std::fs::File::open("large-file.bin")?;
let output = std::fs::File::create("large-file.bin.anubis")?;
let mut writer = encryptor.wrap_output(output)?;
std::io::copy(&mut input.take(u64::MAX), &mut writer)?;
writer.finish()?;
// Decrypt with constant memory
let encrypted = std::fs::File::open("large-file.bin.anubis")?;
let decryptor = Decryptor::new(encrypted)?;
let mut reader = decryptor.decrypt(vec![&identity as _])?;
let mut output = std::fs::File::create("large-file-decrypted.bin")?;
std::io::copy(&mut reader, &mut output)?;
§Identity File Management
use anubis_rage::{IdentityFile, pqc::mlkem};
use std::fs::File;
use std::io::Write;
// Generate and save identity
let identity = mlkem::Identity::generate();
let recipient = identity.to_public();
let identity_file = format!(
"# Anubis Rage ML-KEM-1024 identity\n\
{}",
recipient.to_string(),
identity.to_string()
);
let mut file = File::create("identity.txt")?;
file.write_all(identity_file.as_bytes())?;
§Module Organization
pqc
: Post-quantum cryptography (ML-KEM-1024, ML-DSA-87)Encryptor
: Encryption APIDecryptor
: Decryption APIarmor
: ASCII armoring supportstream
: Low-level streaming encryption primitivesfips
: FIPS 140-3 compliance and self-tests
§Platform Support
Anubis Rage runs on all platforms supported by Rust and liboqs:
- ✅ Linux (x86_64, aarch64)
- ✅ macOS (Intel, Apple Silicon)
- ✅ Windows (x86_64)
- ✅ BSD (FreeBSD, OpenBSD, NetBSD)
- ✅ Android / iOS (via FFI)
§Standards Compliance
- NIST FIPS 203: ML-KEM (Module-Lattice-Based KEM)
- NIST FIPS 204: ML-DSA (Module-Lattice-Based Digital Signature Algorithm)
- NIST FIPS 198-1: HMAC (Keyed-Hash Message Authentication Code)
- NIST SP 800-56C Rev. 2: Key Derivation (HKDF)
- RFC 8452: AES-GCM-SIV (Authenticated Encryption)
- RFC 8439: ChaCha20-Poly1305 (Authenticated Encryption)
- RFC 4648: Base64 Encoding
§License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.
§Contributing
Contributions are welcome! Please see CONTRIBUTING.md.
For security issues, see SECURITY.md or email security@anubis-rage.org.
Re-exports§
pub use anubis_core::secrecy;
Modules§
- armor
armor
- I/O helper structs for the age ASCII armor format.
- cli_
common cli-common
- Common helpers for CLI binaries.
- fips
- FIPS 140-3 compliance module
- pqc
pqc-mlkem
- Post-quantum cryptography (PQC) using ML-KEM (formerly Kyber).
- 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
Callbacks
that 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 armor
- Encrypts the given plaintext to the given recipient, and wraps the ciphertext in ASCII armor.
- localizer
- Returns the
Localizer
to be used for localizing this library.