eme2-extended 0.2.1

EME2-extended (ECB-Mask-ECB) wide-block cipher mode of operation for any block size ciphers
Documentation

eme2-extended

Docs Apache2/MIT licensed Rust Version

Generic implementation of the EME2 (ECB-Mask-ECB) wide-block cipher mode of operation, extended for generic block sizes.

Mode functionality is accessed using traits from the re-exported cipher crate.

Standards and Specifications

This crate implements IEEE Std 1619.2 EME2-AES, which is the original academic EME* specification instantiated with a block cipher and a concrete key schedule (one master key split into Key1/Key2/Key3) in place of EME*'s independent masks L and R, extended natively to support larger block ciphers via the EmePoly trait. The two specs describe the same algorithm, so there is a single implementation ([Eme2::hash_ad], encrypt_with_ad, decrypt_with_ad).

Reference Documents

Cipher Compatibility & EmePoly Compile-Time Safety

This crate supports block ciphers of 128-bit, 256-bit, 512-bit, and 1024-bit sizes.

While the original EME2 standard mathematically limits processing to a 128-bit polynomial ($x{128} + x7 + x^2 + x + 1$), this extended implementation dynamically supports generic block sizes. It achieves this via a custom EmePoly trait that enforces Galois Field polynomial arithmetic strictly at compile time.

Instead of crashing or panicking at runtime, the compiler guarantees that your block cipher size maps to a mathematically proven irreducible polynomial:

  • 128-bit blocks (e.g. AES, Serpent): $x{128} + x7 + x^2 + x + 1$
  • 256-bit blocks (e.g. Threefish256): $x{256} + x{10} + x5 + x2 + 1$
  • 512-bit blocks (e.g. Threefish512): $x{512} + x8 + x5 + x2 + 1$
  • 1024-bit blocks (e.g. Threefish1024): $x{1024} + x9 + x8 + x7 + x^5 + x + 1$

The implementation is explictly tested to guarantee compatibility across the ecosystem:

  • aes-128
  • aes-256
  • serpent
  • Threefish256 (256-bit)
  • Threefish512 (512-bit)
  • Threefish1024 (1024-bit)

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:

// 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).expect("encryption succeeded");
cipher.decrypt(&mut data).expect("decryption succeeded");

Usage Examples

1. Encryption with a tweak

use aes::Aes256;
use cipher::KeyIvInit;
use eme2_extended::Eme2;

type Aes256Eme2 = Eme2<Aes256>;

let key = [0x42; 64]; // Partitioned internally into Key1, Key2, and Key3
let tweak = [0x11; 16];
let mut data = vec![0u8; 64];

// Initialization using KeyIvInit trait (hashes the tweak via `Eme2::hash_ad`)
let cipher = Aes256Eme2::new(&key.into(), &tweak.into());

cipher.encrypt(&mut data).expect("encryption succeeded");
cipher.decrypt(&mut data).expect("decryption succeeded");

2. Encryption with associated data

use aes::Aes256;
use cipher::KeyInit;
use eme2_extended::Eme2;

type Aes256Eme2 = Eme2<Aes256>;

let key = [0x42; 64];
let mut data = vec![0u8; 64];

let cipher = <Aes256Eme2 as cipher::KeyInit>::new(&key.into());

let associated_data = b"associated data";
cipher.encrypt_with_ad(associated_data, &mut data).expect("encryption succeeded");
cipher.decrypt_with_ad(associated_data, &mut data).expect("decryption succeeded");

⚠️ 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.