Expand description
Generic implementation of EME2 mode extended for arbitrary block ciphers.
Mode functionality is accessed using traits from re-exported cipher crate.
EME2-extended (ECB-Mask-ECB) is a wide-block cipher mode of operation that acts as a
Strong Pseudorandom Permutation (SPRP).
Unlike standard EME2 which is limited to 128-bit block ciphers, this crate
utilizes an EmePoly trait to provide compile-time verified Galois Field
polynomials for 128-bit, 256-bit, 512-bit, and 1024-bit block sizes, securely
supporting ciphers like Threefish.
§⚠️ Security Warning: Hazmat!
This crate does not ensure ciphertexts are authentic! Thus ciphertext integrity is not verified, which can lead to serious vulnerabilities! It is highly recommended to use EME2 in combination with a strong MAC to provide robust authenticated encryption.
§Migrating from Stream Ciphers (e.g., CTR Mode)
Because eme2-extended strictly implements RustCrypto’s KeyIvInit traits, instantiating the cipher
is a 1:1 drop-in replacement for stream ciphers like ctr. However, execution differs:
- Stream Ciphers (CTR): Encryption and decryption are mathematically identical, so they use the
StreamCiphertrait and expose.apply_keystream(&mut data). - Wide-Block Ciphers (EME2): Encryption and decryption are asymmetric. Thus, EME2 does not implement
StreamCipherand instead exposes explicit.encrypt(&mut data)and.decrypt(&mut data)methods.
§Examples
§Encryption with a tweak
use aes::cipher::KeyIvInit;
use eme2_extended::Eme2;
type Aes128Eme2 = Eme2<aes::Aes128>;
let key = [0x42; 48];
let tweak = [0x24; 16];
let plaintext = b"hello world! this is my plaintext! it needs to be longer.";
let mut buf = plaintext.to_vec();
// Initialize using standard KeyIvInit (hashes the tweak via `Eme2::hash_ad`)
let cipher = Aes128Eme2::new(&key.into(), &tweak.into());
// Encrypt in-place
cipher.encrypt(&mut buf).expect("encryption succeeded");
assert_ne!(buf[..], plaintext[..]);
// Decrypt in-place
cipher.decrypt(&mut buf).expect("decryption succeeded");
assert_eq!(buf[..], plaintext[..]);§Encryption with associated data
use eme2_extended::Eme2;
use eme2_extended::cipher::KeyInit;
type Aes128Eme2 = Eme2<aes::Aes128>;
let key = [0x42; 48];
let associated_data = b"associated data";
let plaintext = b"hello world! this is my plaintext! it needs to be longer.";
let mut buf = plaintext.to_vec();
// Initialize cipher using the base KeyInit trait
let cipher = <Aes128Eme2 as KeyInit>::new(&key.into());
// Encrypt in-place, hashing the associated data into the tweak internally
cipher.encrypt_with_ad(associated_data, &mut buf).expect("encryption succeeded");
assert_ne!(buf[..], plaintext[..]);
// Decrypt in-place
cipher.decrypt_with_ad(associated_data, &mut buf).expect("decryption succeeded");
assert_eq!(buf[..], plaintext[..]);Re-exports§
pub use cipher;
Structs§
- Eme2
- EME2 cipher mode.
Enums§
- Error
- Error types for EME2 operations.
Traits§
- EmePoly
- A trait for block sizes that support EME2 Galois Field polynomial arithmetic.