## DEV Community # CryptoPals Crypto Challenges Using Rust: Detect AES in ECB mode

This is Challenge 8 of Cryptopals challenges implemented in Rust language.

## Context

We're given a file which lists a bunch of hex-encoded ciphertexts. One of these texts is encrypted with AES-128 in ECB mode. We have to detect which one is it. I recommend to see Challenge 7 if you haven't yet.

Remember that AES-128 divides message into 16 byte blocks before encrypting. In ECB mode each block is encrypted seperately. Therefore - the same 16 byte plaintext block will always produce the same 16 byte ciphertext. We'll exploit this property of ECB mode.

Given the ciphertext, the more number of identical 16-byte blocks, the higher the probability of it having encrypted in ECB mode. Because that means (most probably) the text message contained some identical phrases/blocks that were repeated. And these repeated phrases/blocks encrypted to exactly same ciphertext because of nature of ECB.

``````...and there was yellow submarine...yellow submarine sank in...
|------ECB-----|   |------ECB-----|
...a733hj32hbczxsbv...a733hj32hbczxsbv....
``````

## Code

In code we basically loop through each hex string. Convert it to bytes then divide these bytes into 16-byte blocks. Then count number of identical blocks among these. The hex-string that corresponds to max number of identical blocks is encrypted in ECB mode.

``````use hex;
use std::collections::HashSet;
use std::fs::File;

pub fn detect_aes_ecb_encryption(path: &str) -> (usize, usize) {
let file = File::open(path).expect("Error reading file!");
let mut i_line: usize = 0;
let mut max_identical_blocks: usize = 0;

let mut n_identical_blocks: usize;
for (i, line) in lines.enumerate() {
let hex = line.unwrap();
// Hex line to bytes vec
let bytes = hex::decode(hex).unwrap();

// Divide bytes into 16 byte blocks (&[u8] blocks)
let blocks: Vec<_> = bytes.chunks_exact(16).collect();

// Get unique blocks
let unique_blocks: HashSet<_> = blocks.iter().cloned().collect();

// No. of identical blocks detected
n_identical_blocks = blocks.len() - unique_blocks.len();

// Cipher containing most identical blocks is more likely to be
// ECB mode encrypted
if n_identical_blocks > max_identical_blocks {
max_identical_blocks = n_identical_blocks;
i_line = i;
}
}

(i_line, max_identical_blocks)
}
``````

And this is it. We've concluded Set 1.

See code on Github

Find me on: