mgostih

Stream Encryption

Mar 22nd, 2019
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.67 KB | None | 0 0
  1. use byteorder::{ReadBytesExt, WriteBytesExt, LE};
  2. use crc::{crc64,Hasher64};
  3. use rand::{Rng, SeedableRng};
  4. use rand_chacha::ChaChaRng;
  5. use std::io::{self, Read, Write};
  6. use std::hash::Hasher;
  7.  
  8. #[derive(Debug)]
  9. pub struct EncodedString<F>
  10. where
  11.     F: FnMut(u64, &mut [u8]) -> (),
  12. {
  13.     seed: u64,
  14.     length: u64,
  15.     check : u64,
  16.     data: Vec<u8>,
  17.     encode_function: F,
  18. }
  19.  
  20. impl<F> EncodedString<F>
  21. where
  22.     F: FnMut(u64, &mut [u8]) -> (),
  23. {
  24.     pub fn new(source: String, mut encode_function: F) -> Self {
  25.         let seed = rand::random();
  26.         let mut data = source.into_bytes();
  27.         encode_function(seed, &mut data);
  28.         let check = Self::generate_crc(seed, &data);
  29.         EncodedString {
  30.             seed,
  31.             length: (data.len() as u64) ^ seed ^ 0x32DF9B0617010FED,
  32.             check,
  33.             data,
  34.             encode_function,
  35.         }
  36.     }
  37.  
  38.     pub fn decode(mut self) -> Result<String, std::string::FromUtf8Error> {
  39.         (self.encode_function)(self.seed, &mut self.data); // Decoding is the same as encoding
  40.         String::from_utf8(self.data)
  41.     }
  42.  
  43.     pub fn write<T>(&self, writer: &mut T) -> io::Result<()>
  44.     where
  45.         T: Write,
  46.     {
  47.         writer.write_u64::<LE>(self.seed)?;
  48.         writer.write_u64::<LE>(self.length)?;
  49.         writer.write_u64::<LE>(Self::generate_crc(self.seed, &self.data))?;
  50.  
  51.         writer.write_all(&self.data)
  52.     }
  53.  
  54.     pub fn read<T>(reader: &mut T, encode_function: F) -> io::Result<Self>
  55.     where
  56.         T: Read,
  57.     {
  58.         let seed = reader.read_u64::<LE>()?;
  59.         let length = reader.read_u64::<LE>()? ^ seed ^ 0x32DF9B0617010FED;
  60.         let check = reader.read_u64::<LE>()?;
  61.         let mut data = vec![0; length as usize];
  62.         reader.read_exact(&mut data)?;
  63.         if check == Self::generate_crc(seed, &data){
  64.             Ok(EncodedString {
  65.             seed,
  66.             length,
  67.             check,
  68.             data,
  69.             encode_function,
  70.         })
  71.         }
  72.         else{
  73.             Err(io::Error::new(io::ErrorKind::Other,"Data is corrupt"))
  74.         }
  75.     }
  76.  
  77.     #[inline]
  78.     fn generate_crc(seed : u64, data : &[u8]) -> u64{
  79.         let mut check = crc64::Digest::new(crc64::ECMA);
  80.         check.write_u64(seed);
  81.         check.write_u64(data.len() as u64);
  82.         Hasher::write(&mut check, data);
  83.         check.sum64()
  84.     }
  85. }
  86.  
  87. fn generic_encode<F>(data: &mut [u8], mut generator: F)
  88. where
  89.     F: FnMut() -> u8,
  90. {
  91.     for n in data {
  92.         *n ^= generator();
  93.     }
  94. }
  95.  
  96. pub fn random_encode(seed: u64, data: &mut [u8]) {
  97.     let mut rng = ChaChaRng::seed_from_u64(seed);
  98.     generic_encode(data, || rng.gen());
  99. }
Add Comment
Please, Sign In to add comment