Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save gcharnock/29cbe573ef555b23e75ab4cb7fa40e9b to your computer and use it in GitHub Desktop.
Save gcharnock/29cbe573ef555b23e75ab4cb7fa40e9b to your computer and use it in GitHub Desktop.
My take on getting my head around http://theamazingking.com/crypto-diff.php while also learning some Reust
const SBOX: [u8; 16] = [3, 14, 1, 10, 4, 9, 5, 6, 8, 11, 15, 2, 13, 12, 0, 7];
const INV_SBOX: [u8; 16] = [14, 2, 11, 0, 4, 6, 7, 15, 8, 5, 3, 9, 13, 12, 1, 10];
fn toy_cipher(p: u8, k0: u8, k1: u8) -> u8 {
return k1 ^ SBOX[(p ^ k0) as usize];
}
fn find_diffs() -> Vec<Vec<Differential>> {
println!("Creating XOR differential table:");
let mut diff_table: Vec<Vec<Differential>> = Vec::new();
for d_x in 0..16 {
let mut row = Vec::new();
for d_y in 0..16 {
row.push(Differential {
diff_in: d_x,
diff_out: d_y,
frequency: 0,
pre_sbox_states: Vec::new()
});
}
diff_table.push(row);
}
for c in 0..16 {
for d in 0..16 {
let d_x = c ^ d;
let d_y = SBOX[c as usize] ^ SBOX[d as usize];
diff_table[d_x as usize][d_y as usize].frequency+=1;
diff_table[d_x as usize][d_y as usize].pre_sbox_states.push(c);
}
}
return diff_table;
}
struct Differential {
diff_in: u8,
diff_out: u8,
frequency: u8,
pre_sbox_states: Vec<u8>
}
fn find_good_pair(diff_in: u8, diff_out: u8, k1: u8, k2: u8) -> u8 {
for p in 0..16 {
let c1 = toy_cipher(p, k1, k2);
let c2 = toy_cipher(p ^ diff_in, k1, k2);
if c1 ^ c2 == diff_out {
return p;
}
}
panic!("Could not find good pair");
}
fn main() {
let k1 = 7;
let k2 = 8;
let plaintext = 0;
let ciphertext = toy_cipher(plaintext, k1, k2);
println!("ciphertext = {}", ciphertext);
let diff_table = find_diffs();
for c in 1..16 {
for d in 1..16 {
print!(" {} ", diff_table[c as usize][d as usize].frequency);
}
println!("");
}
println!("Displaying most probable differentials:");
let mut diff_list: Vec<&Differential> = Vec::new();
for d_x in 1..16 {
for d_y in 1..16 {
diff_list.push(&diff_table[d_x][d_y]);
}
}
diff_list.sort_by_key(|a| 16 - a.frequency);
for c in 0..256 {
if diff_list[c].frequency < 4 {
break;
}
println!(" {}/16: {} --> {} ", diff_list[c].frequency, diff_list[c].diff_in, diff_list[c].diff_out);
}
println!("Trying to find a good pair");
let characteristic = diff_list[0];
let good_pair = find_good_pair(characteristic.diff_in, characteristic.diff_out, k1, k2);
println!("Found good pair ({}, {})", good_pair, good_pair ^ characteristic.diff_in);
println!("The internal state of the cipher past the XOR op must be one of:");
println!("{:?}", characteristic.pre_sbox_states);
let possible_k0 = characteristic.pre_sbox_states.iter().map(|s| s ^ good_pair).collect::<Vec<u8>>();
println!("Therefore, the possible k0 we need to brute force are {:?}", possible_k0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment