Crate anubis_rage

Crate anubis_rage 

Source
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-rage

This installs three command-line tools:

  • anubis-rage - Encrypt/decrypt files with quantum-resistant encryption
  • anubis-rage-keygen - Generate ML-KEM-1024 encryption keys
  • anubis-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:

OperationFile SizeTimeThroughput
Key Generation-~2ms-
Encryption1 MB~8ms125 MB/s
Encryption1 GB~7.5s133 MB/s
Decryption1 MB~8ms125 MB/s
Decryption1 GB~7.3s137 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

FeatureAnubis Rageage/rageGPGNaCl
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:

ComponentAlgorithmSecurity
KEMML-KEM-1024NIST L5 (β‰₯256-bit)
SignatureML-DSA-87NIST L5 (β‰₯256-bit)
KDFHKDF-SHA512256-bit
MACHMAC-SHA512256-bit
AEADAES-256-GCM-SIV256-bit + nonce-misuse resistant

Β§πŸ”— Resources

Β§πŸ›‘οΈ Security Disclosure

If you discover a security vulnerability, please report it via:

Β§πŸ“„ License

Licensed under either of:

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
SecretBox wrapper 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.
IdentityFile
A list of identities that has been parsed from some input file.
NoCallbacks
An implementation of Callbacks that does not allow callbacks.

EnumsΒ§

DecryptError
The various errors that can be returned during the decryption process.
EncryptError
The various errors that can be returned during the encryption process.
IdentityFileConvertError
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 Localizer to be used for localizing this library.