eme2 0.1.3

EME2 (ECB-Mask-ECB) wide-block cipher mode of operation
Documentation
eme2-0.1.3 has been yanked.

eme2

Docs Apache2/MIT licensed Rust Version

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.

About EME2 and Test Vectors

The official EME2 specification is standardized under IEEE P1619.2. Unfortunately, the official IEEE document and its test vectors are hidden behind a paywall.

Because the official test vectors are not freely available, this implementation was verified using self-generated test vectors derived from reference Python implementations of Shai Halevi's original EME* paper. Despite this limitation, this crate provides a fully-compliant EME2 implementation that handles arbitrary length messages (via ciphertext stealing) and adheres strictly to the $GF(2^{128})$ Galois Field arithmetic specified by the standard.

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 extensively tested against standard 128-bit block ciphers to guarantee compatibility across the ecosystem:

  • aes-128
  • aes-256
  • serpent

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 = Ctr128BE::<Aes128>::new(&key.into(), &nonce.into());

// EME2 Mode Initialization
let cipher = Eme2::<Aes128>::new(&key.into(), &tweak.into());

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(&mut data); // Handles both encryption and decryption

// Wide-Block Ciphers (EME2)
cipher.encrypt(&mut data).unwrap();
cipher.decrypt(&mut data).unwrap();

⚠️ 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 (like BLAKE3) 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.