eme2
Generic implementation of the EME2 (ECB-Mask-ECB) wide-block cipher mode of operation.
Mode functionality is accessed using traits from the re-exported cipher crate.
Standards and Specifications
This crate implements both the IEEE Std 1619.2 EME2-AES standard and the original academic EME* specification.
- IEEE Std 1619.2-2008 (EME2): Dropped the outer XOR with $Key_3$ in the associated data hashing loop for simplicity.
- Academic EME* (2004): Retains the outer XOR with $Key_3s$ in the associated data hashing loop.
Reference Documents
- EME2 (Standard): IEEE Std 1619.2-2008: IEEE Standard for Wide-Block Encryption for Shared Storage Media (located at
docs/eme2-ieee.pdf) - EME* (Academic Paper): "A Parallelizable Symmetric Alternative to OCB" (Halevi & Rogaway, 2004) (located at
docs/2004-125.pdf)
Cipher Compatibility
This crate ONLY supports block ciphers with a 16-byte (128-bit) block size.
EME2 mathematically requires a 128-bit polynomial ($x{128} + x7 + x^2 + x + 1$) for its internal tweak processing. Ciphers with larger block sizes (such as Threefish256, Threefish512, or Threefish1024) are structurally incompatible with EME2 and are safely rejected at compile time by the crate's generic trait bounds (BlockSizeUser<BlockSize = U16>).
The implementation is explictly tested against standard 128-bit block ciphers to guarantee compatibility across the ecosystem:
aes-128aes-256serpent
Migrating from Stream Ciphers (e.g., CTR Mode)
Because eme2 strictly implements RustCrypto's KeyIvInit traits, instantiating the cipher is a 1:1 drop-in replacement for stream ciphers like ctr:
// CTR Mode Initialization
let cipher = new;
// EME2 Mode Initialization
let cipher = new;
However, execution differs. Stream ciphers use the StreamCipher trait because their encryption and decryption processes are mathematically identical (XORing a keystream). EME2 is a Wide-Block Cipher, meaning its encryption and decryption passes are mathematically asymmetric. Therefore, it does not implement StreamCipher and instead exposes explicit .encrypt() and .decrypt() methods:
// Stream Ciphers (CTR)
cipher.apply_keystream; // Handles both encryption and decryption
// Wide-Block Ciphers (EME2)
cipher.encrypt.expect;
cipher.decrypt.expect;
Usage Examples
1. Standard EME2 (IEEE P1619.2)
By default, the KeyIvInit trait and default methods target the IEEE Std 1619.2 (EME2) standard.
use Aes256;
use ;
use Eme2;
type Aes256Eme2 = ;
let key = ; // Partitioned internally into Key1, Key2, and Key3
let tweak = ;
let mut data = vec!;
// Initialization using KeyIvInit trait (defaults to EME2 tweak hashing)
let cipher = new;
// Encryption & Decryption
cipher.encrypt.expect;
cipher.decrypt.expect;
// Associated Data (EME2 style)
let associated_data = b"associated data";
cipher.encrypt_with_ad_eme2.expect;
cipher.decrypt_with_ad_eme2.expect;
2. EME* Compatibility
For compatibility with systems using the EME* academic specification:
use Aes256;
use KeyInit;
use Eme2;
type Aes256Eme2 = ;
let key = ;
let tweak = ;
let mut data = vec!;
// Initialize using the raw KeyInit trait (tweak defaults to all-zeros)
let mut cipher = new;
// Compute the tweak using EME* AD hashing and configure it
let t_star = cipher.hash_ad_emestar;
cipher.set_tweak;
// Encryption & Decryption (with EME* pre-computed tweak)
cipher.encrypt.expect;
cipher.decrypt.expect;
// Inline Associated Data (EME* style)
let associated_data = b"associated data";
cipher.encrypt_with_ad_emestar.expect;
cipher.decrypt_with_ad_emestar.expect;
⚠️ 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.
License
Licensed under either of:
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.