eme2 0.1.2

EME2 (ECB-Mask-ECB) wide-block cipher mode of operation
Documentation
# eme2

[![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.

Mode functionality is accessed using traits from the re-exported [`cipher`][cipher-doc] crate.

## About EME2 and Test Vectors

The official EME2 specification is standardized under [IEEE P1619.2][EME2-IEEE]. 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} + x^7 + 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`:

```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).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:

 * [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/badge.svg
[docs-link]: https://docs.rs/eme2/
[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
[cipher-doc]: https://docs.rs/cipher/