linear_cryptanalysis

simple linear cryptanalysis attack on an spn
git clone git://git.superpozycja.net/linear_cryptanalysis
Log | Files | Refs | README

lib.rs (2343B)


      1 /* this can be side channeled i think */
      2 static S_BOX: [u8; 16] = 
      3     [0xe, 0x4, 0xd, 0x1, 0x2, 0xf, 0xb, 0x8,
      4      0x3, 0xa, 0x6, 0xc, 0x5, 0x9, 0x0, 0x7];
      5 
      6 #[inline(always)]
      7 fn copy_bit(a: &mut u8, an: u8, b: u8, bn: u8) {
      8     *a = *a & !(1 << an) | (((b >> bn) & 1) << an);
      9 }
     10 
     11 fn sub_byte(x: u8) -> u8 {
     12     let mut res: u8 = 0;
     13     res += S_BOX[(x & 0x0f) as usize];
     14     let x = x >> 4;
     15     res += S_BOX[(x & 0x0f) as usize] << 4;
     16 
     17     res
     18 }
     19 
     20 fn sub(x: &mut [u8; 2]) {
     21     x[0] = sub_byte(x[0]);
     22     x[1] = sub_byte(x[1]);
     23 }
     24 
     25 fn xor(x: &mut [u8; 2], y: &[u8; 2]) {
     26     x[0] ^= y[0];
     27     x[1] ^= y[1];
     28 }
     29 
     30 fn per(x: &mut [u8; 2]) {
     31     let x2 = x.clone();
     32 
     33     copy_bit(&mut x[0], 7, x2[0], 7);
     34     copy_bit(&mut x[0], 6, x2[0], 3);
     35     copy_bit(&mut x[0], 5, x2[1], 7);
     36     copy_bit(&mut x[0], 4, x2[1], 3);
     37 
     38     copy_bit(&mut x[0], 3, x2[0], 6);
     39     copy_bit(&mut x[0], 2, x2[0], 2);
     40     copy_bit(&mut x[0], 1, x2[1], 6);
     41     copy_bit(&mut x[0], 0, x2[1], 2);
     42     
     43     copy_bit(&mut x[1], 7, x2[0], 5);
     44     copy_bit(&mut x[1], 6, x2[0], 1);
     45     copy_bit(&mut x[1], 5, x2[1], 5);
     46     copy_bit(&mut x[1], 4, x2[1], 1);
     47 
     48     copy_bit(&mut x[1], 3, x2[0], 4);
     49     copy_bit(&mut x[1], 2, x2[0], 0);
     50     copy_bit(&mut x[1], 1, x2[1], 4);
     51     copy_bit(&mut x[1], 0, x2[1], 0);
     52 }
     53 
     54 fn round(x: &mut [u8; 2], r_k: &[u8; 2]) {
     55     xor(x, r_k);
     56     sub(x);
     57     per(x);
     58 }
     59 
     60 fn sched(key: &[u8; 4]) -> [u8; 10] {
     61     let mut s: [u8; 10] = [0; 10];
     62 
     63     for i in (0..10).step_by(2) {
     64         if i % 4 == 0 {
     65             s[i] = key[i/4];
     66             s[i+1] = key[i/4+1];
     67         } else {
     68             s[i] = key[i/4] & 0xf;
     69             s[i] <<= 4;
     70             s[i] += (key[i/4+1] & 0xf0) >> 4;
     71 
     72             s[i+1] = key[i/4+1] & 0xf;
     73             s[i+1] <<= 4;
     74             s[i+1] += (key[i/4+2] & 0xf0) >> 4;
     75 
     76         }
     77     }
     78     s
     79 }
     80 
     81 pub fn print_block(t: &[u8; 2]) {
     82     println!("{:#04x}{:02x}", t[0], t[1]);
     83 }
     84 
     85 pub fn print_block_b(t: &[u8; 2]) {
     86     println!("{:#010b}{:08b}", t[0], t[1]);
     87 }
     88 
     89 pub fn encrypt(pt: &[u8; 2], key: &[u8; 4]) -> [u8; 2] {
     90     let mut ct = pt.clone();
     91     let round_key = sched(key);
     92     for i in (0..6).step_by(2) {
     93         round(&mut ct, round_key[i..i+2].try_into().unwrap());
     94     }
     95     xor(&mut ct, round_key[6..8].try_into().unwrap());
     96     sub(&mut ct);
     97     xor(&mut ct, round_key[8..10].try_into().unwrap());
     98 
     99     ct
    100 }