use crate::fs::extend_extension;
use crate::fs::Mode;
use crate::fs::{open_file, read, remove_file, write};
use crate::Config;
use crate::Error;
use rand::Rng;
pub fn encrypt(buf_in: &[u8], buf_out1: &mut [u8], buf_out2: &mut [u8]) -> Result<(), Error> {
if (buf_out1.len() < buf_in.len()) || (buf_out2.len() < buf_in.len()) {
return Err(Error::InvalidBufferSizes);
}
let mut rng = rand::thread_rng();
for i in 0..buf_in.len() {
buf_out1[i] = rng.gen_range(0..=255);
buf_out2[i] = buf_in[i] ^ buf_out1[i];
}
Ok(())
}
pub fn decrypt(buf_in1: &[u8], buf_in2: &[u8], buf_out: &mut [u8]) -> Result<(), Error> {
if (buf_in1.len() != buf_in2.len()) || (buf_out.len() < buf_in1.len()) {
return Err(Error::InvalidBufferSizes);
}
for i in 0..buf_in1.len() {
buf_out[i] = buf_in1[i] ^ buf_in2[i];
}
Ok(())
}
pub fn encrypt_file(c: &Config) -> Result<(), Error> {
let mut f_in = open_file(&c.file, Mode::Open)?;
let f_out1_name = extend_extension(&c.file, &c.suffix1);
let f_out2_name = extend_extension(&c.file, &c.suffix2);
let mut f_out1 = open_file(&f_out1_name, Mode::Create)?;
let mut f_out2 = open_file(&f_out2_name, Mode::Create)?;
let mut buf_in = vec![0u8; c.buffer as usize];
let mut buf_out1 = vec![0u8; c.buffer as usize];
let mut buf_out2 = vec![0u8; c.buffer as usize];
loop {
let bytes = read(&mut f_in, &mut buf_in)?;
if bytes == 0 {
break;
}
encrypt(
&buf_in[..bytes],
&mut buf_out1[..bytes],
&mut buf_out2[..bytes],
)?;
write(&mut f_out1, &buf_out1[..bytes])?;
write(&mut f_out2, &buf_out2[..bytes])?;
}
if c.rm {
remove_file(&c.file)?;
}
Ok(())
}
pub fn decrypt_file(c: &Config) -> Result<(), Error> {
let f_in1_name = extend_extension(&c.file, &c.suffix1);
let f_in2_name = extend_extension(&c.file, &c.suffix2);
let mut f_in1 = open_file(&f_in1_name, Mode::Open)?;
let mut f_in2 = open_file(&f_in2_name, Mode::Open)?;
let mut f_out = open_file(&c.file, Mode::Create)?;
let mut buf_in1 = vec![0u8; c.buffer as usize];
let mut buf_in2 = vec![0u8; c.buffer as usize];
let mut buf_out = vec![0u8; c.buffer as usize];
loop {
let bytes_1 = read(&mut f_in1, &mut buf_in1)?;
let bytes_2 = read(&mut f_in2, &mut buf_in2)?;
if bytes_1 != bytes_2 {
return Err(Error::InvalidInput(
"The two input files differ in size!".to_string(),
));
}
if bytes_1 == 0 {
break;
}
decrypt(
&buf_in1[..bytes_1],
&buf_in2[..bytes_1],
&mut buf_out[..bytes_1],
)?;
write(&mut f_out, &buf_out[..bytes_1])?;
}
if c.rm {
remove_file(&f_in1_name)?;
remove_file(&f_in2_name)?;
}
Ok(())
}