aes-elk 0.1.1

ELK (Encrypted LFSR Keystream) mode of operation for block ciphers
Documentation
# aes-elk

[![Apache2/MIT licensed](https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg)](#license)
![Rust Version](https://img.shields.io/badge/rustc-1.87+-blue.svg)

Generic implementation of the ELK (Encrypted LFSR Keystream) mode of operation for block ciphers defined in §4.4 [SP 800-197](https://csrc.nist.gov/files/pubs/sp/800/197/iprd/docs/3_samvadini.pdf).

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

## About ELK

ELK is a keystream-based stream cipher mode of operation that generates a keystream by encrypting the state of a Galois-Field Linear Feedback Shift Register (LFSR) with a block cipher.

## Cipher & Block Size Compatibility

Unlike other modes that are restricted to a single block size, this implementation of ELK supports multiple block sizes:
*   **16-byte (128-bit) block ciphers** (e.g., `Aes128`, `Aes256`, `Serpent`) using the self-computed $GF(2^{128})$ polynomial:
    $$X^{128} + X^{113} + X^{97} + X^{89} + X^{71} + X^{59} + X^{37} + X^{23} + 1$$
*   **32-byte (256-bit) block ciphers** (e.g., `Threefish256`) using the NIST Samvadini-compliant polynomial:
    $$X^{256} + X^{229} + X^{193} + X^{167} + X^{139} + X^{109} + X^{71} + X^{37} + 1$$
*   **64-byte (512-bit) block ciphers** (e.g., `Threefish512`) using the NIST Samvadini-compliant polynomial:
    $$X^{512} + X^{461} + X^{397} + X^{331} + X^{281} + X^{211} + X^{139} + X^{71} + 1$$

Ciphers with unsupported block sizes (such as `Threefish1024` with 128-byte block size) are safely rejected at compile time by the crate's generic trait bounds (`C::BlockSize: ElkPolynomial`).

## Usage

Because ELK implements RustCrypto's `KeyIvInit` traits, instantiating the cipher is straightforward:

```rust
use aes::cipher::KeyIvInit;
use aes_elk::Elk;

type Aes128Elk = Elk<aes::Aes128>;

let key = [0x42; 16];
let iv = [0x24; 16];
let plaintext = *b"hello world! this is my plaintext! it can be any length.";

// Encrypt in-place
let mut buf = plaintext.to_vec();
let mut encryptor = Aes128Elk::new(&key.into(), &iv.into());
let mut decryptor = encryptor.clone(); // Clone state or re-initialize for decryption

encryptor.apply_keystream(&mut buf).unwrap();
assert_ne!(buf[..], plaintext[..]);

// Decrypt in-place
decryptor.apply_keystream(&mut buf).unwrap();
assert_eq!(buf[..], plaintext[..]);
```

## Formal Verification

The core ELK keystream application logic for 128-bit block ciphers is formally verified using the [Kani Rust Verifier](https://github.com/model-checking/kani). 

This verification mathematically proves the absence of undefined behavior and ensures panic-free execution across all possible initialization vectors and payloads up to the block boundary. Specifically, the Kani harness guarantees that the 128-bit ELK mode wrapper is completely free from:
* Memory-safety violations (e.g., out-of-bounds reads/writes)
* Arithmetic errors (e.g., integer overflows/underflows)
* Unhandled runtime panics

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

[cipher-doc]: https://docs.rs/cipher/