Advertisement
Guest User

Untitled

a guest
Jul 9th, 2019
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.62 KB | None | 0 0
  1. use crate::crypto::{PSOCipher, CipherError};
  2. use std::num::Wrapping as W;
  3.  
  4. const BB_SBOX_COUNT: usize = 4;
  5. const BB_SBOX_SIZE: usize = 256;
  6. const BB_PARRAY_SIZE: usize = 18;
  7. const BB_SEED_SIZE: usize = 48; // theoretically this could be 56?
  8.  
  9. pub struct PSOBBCipher {
  10.     p_array: [u32; BB_PARRAY_SIZE],
  11.     sbox: [[u32; BB_SBOX_SIZE]; BB_SBOX_COUNT],
  12. }
  13.  
  14. impl PSOBBCipher {
  15.     fn f(&self, x: u32) -> u32 {
  16.         let mut k = W(self.sbox[0][((x >> 24) & 0xFF) as usize]);
  17.         k += W(self.sbox[1][((x >> 16) & 0xFF) as usize]);
  18.         k ^= W(self.sbox[2][((x >> 8) & 0xFF) as usize]);
  19.         k += W(self.sbox[3][((x) & 0xFF) as usize]);
  20.         k.0
  21.     }
  22.  
  23.     fn init_block(&self, mut l: u32, mut r: u32) -> (u32, u32) {
  24.         for i in (0..16).step_by(2) {
  25.             l ^= self.p_array[i];
  26.             r ^= self.f(l);
  27.             r ^= self.p_array[i+1];
  28.             l ^= self.f(r);
  29.         }
  30.         l ^= self.p_array[16];
  31.         r ^= self.p_array[17];
  32.  
  33.         (r, l)
  34.     }
  35.  
  36.     pub fn new(p: [u32; BB_PARRAY_SIZE], s: [[u32; BB_SBOX_SIZE]; BB_SBOX_COUNT], mut seed: [u8; BB_SEED_SIZE]) -> PSOBBCipher {
  37.         for chunk in seed.chunks_mut(3) {
  38.             chunk[0] ^= 0x19;
  39.             chunk[1] ^= 0x16;
  40.             chunk[2] ^= 0x18;
  41.         }
  42.  
  43.         let mut cipher = PSOBBCipher {
  44.             p_array: p,
  45.             sbox: s
  46.         };
  47.  
  48.         for k in cipher.p_array.iter_mut() {
  49.             let mut pt = *k as u16;
  50.             pt = ((pt & 0x00FF) << 8) + ((pt & 0xFF00) >> 8);
  51.             *k = ((((*k >> 16) ^ pt as u32) << 16)) + pt as u32;
  52.         }
  53.  
  54.         for i in 0..18 {
  55.             let k = u32::from_le_bytes([seed[(i * 4 + 3) % BB_SEED_SIZE],
  56.                                         seed[(i * 4 + 2) % BB_SEED_SIZE],
  57.                                         seed[(i * 4 + 1) % BB_SEED_SIZE],
  58.                                         seed[(i * 4) % BB_SEED_SIZE]]);
  59.             cipher.p_array[i] ^= k;
  60.         }
  61.  
  62.         let mut l = 0;
  63.         let mut r = 0;
  64.         for k in (0..BB_PARRAY_SIZE).step_by(2) {
  65.             // pls rust let me destructure without messing up scope
  66.             let tmp = cipher.init_block(l, r);
  67.             l = tmp.0;
  68.             r = tmp.1;
  69.             cipher.p_array[k] = l;
  70.             cipher.p_array[k + 1] = r;
  71.         }
  72.  
  73.         for block in 0..BB_SBOX_COUNT {
  74.             for item in (0..BB_SBOX_SIZE).step_by(2) {
  75.                 let tmp = cipher.init_block(l, r);
  76.                 l = tmp.0;
  77.                 r = tmp.1;
  78.                 cipher.sbox[block][item] = l;
  79.                 cipher.sbox[block][item + 1] = r;
  80.             }
  81.         }
  82.  
  83.         cipher
  84.     }
  85. }
  86.  
  87. impl PSOCipher for PSOBBCipher {
  88.     fn encrypt(&mut self, data: &Vec<u8>) -> Result<Vec<u8>, CipherError> {
  89.         if data.len() % 8 != 0 {
  90.             return Err(CipherError::InvalidSize);
  91.         }
  92.  
  93.         let real_data = data.chunks(4).map(|k| {
  94.             u32::from_le_bytes([k[0], k[1], k[2], k[3]])
  95.         }).collect::<Vec<_>>();
  96.  
  97.         let mut result = Vec::new();
  98.         for d in real_data.chunks(2) {
  99.             let mut l = d[0];
  100.             let mut r = d[1];
  101.             for i in (0..4).step_by(2) {
  102.                 l ^= self.p_array[i];
  103.                 r ^= self.f(l);
  104.                 r ^= self.p_array[i + 1];
  105.                 l ^= self.f(r);
  106.             }
  107.             l ^= self.p_array[4];
  108.             r ^= self.p_array[5];
  109.  
  110.             let tmp = l;
  111.             l = r;
  112.             r = tmp;
  113.  
  114.             result.extend_from_slice(&l.to_le_bytes());
  115.             result.extend_from_slice(&r.to_le_bytes());
  116.         }
  117.  
  118.  
  119.         Ok(result)
  120.     }
  121.  
  122.     fn decrypt(&mut self, data: &Vec<u8>) -> Result<Vec<u8>, CipherError> {
  123.         if data.len() % 8 != 0 {
  124.             return Err(CipherError::InvalidSize);
  125.         }
  126.  
  127.         let real_data = data.chunks(4).map(|k| {
  128.             u32::from_le_bytes([k[0], k[1], k[2], k[3]])
  129.         }).collect::<Vec<_>>();
  130.  
  131.         let mut result = Vec::new();
  132.         for d in real_data.chunks(2) {
  133.             let mut l = d[0];
  134.             let mut r = d[1];
  135.             for i in (1..=4).rev().step_by(2) {
  136.                 l ^= self.p_array[i + 1];
  137.                 r ^= self.f(l);
  138.                 r ^= self.p_array[i];
  139.                 l ^= self.f(r);
  140.             }
  141.             l ^= self.p_array[1];
  142.             r ^= self.p_array[0];
  143.  
  144.             let tmp = l;
  145.             l = r;
  146.             r = tmp;
  147.  
  148.             result.extend_from_slice(&l.to_le_bytes());
  149.             result.extend_from_slice(&r.to_le_bytes());
  150.         }
  151.  
  152.         Ok(result)
  153.     }
  154. }
  155.  
  156.  
  157. #[cfg(test)]
  158. mod tests {
  159.     #[test]
  160.     fn test_crypto() {
  161.         use rand::{Rng, RngCore};
  162.         use super::{PSOCipher, PSOBBCipher};
  163.  
  164.         let mut rng = rand::thread_rng();
  165.  
  166.         let mut p = [0u32; 18];
  167.         let mut s = [[0u32; super::BB_SBOX_SIZE]; super::BB_SBOX_COUNT];
  168.         let mut seed = [0u8; super::BB_SEED_SIZE];
  169.  
  170.         rng.fill(&mut p[..]);
  171.         rng.fill(&mut s[0][..]);
  172.         rng.fill(&mut s[1][..]);
  173.         rng.fill(&mut s[2][..]);
  174.         rng.fill(&mut s[3][..]);
  175.         rng.fill(&mut seed[..]);
  176.  
  177.         let mut cipher_in = PSOBBCipher::new(p, s, seed);
  178.         let mut cipher_out = PSOBBCipher::new(p, s, seed);
  179.  
  180.         for _ in 0..50 {
  181.             let len = (rng.gen::<u16>() / 8) * 8;
  182.  
  183.             let mut random_junk = vec![0u8; len as usize];
  184.             rng.fill_bytes(&mut random_junk);
  185.  
  186.             let enc_data = cipher_in.encrypt(&random_junk).unwrap();
  187.             let orig_data = cipher_out.decrypt(&enc_data).unwrap();
  188.  
  189.             assert!(random_junk == orig_data);
  190.         }
  191.     }
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement