eme2-extended 0.2.0

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

[![Docs][docs-image]][docs-link]
![Apache2/MIT licensed][license-image]
![Rust Version][rustc-image]

Generic implementation of the [EME2][EME2-IEEE] (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`][cipher-doc] crate.

## Standards and Specifications

This crate implements both the **IEEE Std 1619.2 EME2-AES** standard and the original academic **EME\*** specification, extended natively to support larger block ciphers.

*   **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_3$ 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][EME2-IEEE] (located at `docs/eme2-ieee.pdf`)
*   **EME\* (Academic Paper):** ["A Parallelizable Symmetric Alternative to OCB" (Halevi & Rogaway, 2004)][EME-Paper] (located at `docs/2004-125.pdf`)

## 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} + x^7 + 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} + x^7 + x^2 + x + 1$
*   **256-bit blocks (e.g. Threefish256):** $x^{256} + x^{10} + x^5 + x^2 + 1$
*   **512-bit blocks (e.g. Threefish512):** $x^{512} + x^8 + x^5 + x^2 + 1$
*   **1024-bit blocks (e.g. Threefish1024):** $x^{1024} + x^9 + x^8 + x^7 + 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`:

```rust
// 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:

```rust
// 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. Standard EME2 (IEEE P1619.2)

By default, the `KeyIvInit` trait and default methods target the **IEEE Std 1619.2 (EME2)** standard.

```rust
use aes::Aes256;
use cipher::{KeyIvInit, KeyInit};
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 (defaults to EME2 tweak hashing)
let cipher = Aes256Eme2::new(&key.into(), &tweak.into());

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

// Associated Data (EME2 style)
let associated_data = b"associated data";
cipher.encrypt_with_ad_eme2(associated_data, &mut data).expect("encryption succeeded");
cipher.decrypt_with_ad_eme2(associated_data, &mut data).expect("decryption succeeded");
```

### 2. EME* Compatibility

For compatibility with systems using the EME* academic specification:

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

type Aes256Eme2 = Eme2<Aes256>;

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

// Initialize using the raw KeyInit trait (tweak defaults to all-zeros)
let mut cipher = <Aes256Eme2 as cipher::KeyInit>::new(&key.into());

// Compute the tweak using EME* AD hashing and configure it
let t_star = cipher.hash_ad_emestar(&tweak);
cipher.set_tweak(t_star);

// Encryption & Decryption (with EME* pre-computed tweak)
cipher.encrypt(&mut data).expect("encryption succeeded");
cipher.decrypt(&mut data).expect("decryption succeeded");

// Inline Associated Data (EME* style)
let associated_data = b"associated data";
cipher.encrypt_with_ad_emestar(associated_data, &mut data).expect("encryption succeeded");
cipher.decrypt_with_ad_emestar(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:

 * [Apache License, Version 2.0]http://www.apache.org/licenses/LICENSE-2.0
 * [MIT license]http://opensource.org/licenses/MIT

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.

[//]: # (badges)

[docs-image]: https://docs.rs/eme2-extended/badge.svg
[docs-link]: https://docs.rs/eme2-extended/
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.87+-blue.svg

[//]: # (general links)

[EME2-IEEE]: https://ieeexplore.ieee.org/servlet/opac?punumber=11277321
[EME-Paper]: https://eprint.iacr.org/2004/125.pdf
[cipher-doc]: https://docs.rs/cipher/