use chacha::ChaCha;
use byteorder::{ByteOrder,LittleEndian};
use chacha::KeyStream;
use crate::{ArxKwError};
pub struct ChaChaLQB {
pub input: [u32; 16],
pub output: [u8; 64],
pub offset: u8,
pub rounds: u8,
pub large_block_counter: bool,
}
fn _chacha8_encrypt_mut(key: &[u8;32], lqb: &[u8;16], mut msg: &mut [u8]) -> Result<(),ArxKwError> {
let (counter, nonce) = array_refs![lqb, 8,8]; let mut stream = new_chacha8_with_counter(key, *counter, *nonce);
stream.xor_read(&mut msg).map_err(|e| ArxKwError::ChaChaError(format!("Reached end of chacha stream: {:?} ",e)))
}
pub fn chacha8_encrypt(key: &[u8;32], lqb: &[u8;16], msg: &[u8]) -> Result<Vec<u8>,ArxKwError> {
let mut tmp = msg.to_vec();
let (counter, nonce) = array_refs![lqb, 8,8]; let mut stream = new_chacha8_with_counter(key, *counter, *nonce);
stream.xor_read(&mut tmp).map_err(|e| ArxKwError::ChaChaError(format!("Reached end of ChaCha stream: {:?} ",e)))?;
Ok(tmp)
}
pub fn new_chacha8_with_counter(key: &[u8; 32], counter: [u8;8], nonce: [u8; 8]) -> ChaCha {
let tmp = ChaChaLQB {
input: [
0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574,
LittleEndian::read_u32(&key[ 0.. 4]),
LittleEndian::read_u32(&key[ 4.. 8]),
LittleEndian::read_u32(&key[ 8..12]),
LittleEndian::read_u32(&key[12..16]),
LittleEndian::read_u32(&key[16..20]),
LittleEndian::read_u32(&key[20..24]),
LittleEndian::read_u32(&key[24..28]),
LittleEndian::read_u32(&key[28..32]),
LittleEndian::read_u32(&counter[ 0.. 4]), LittleEndian::read_u32(&counter[ 4.. 8]), LittleEndian::read_u32(&nonce[ 0.. 4]), LittleEndian::read_u32(&nonce[ 4.. 8]), ],
output: [0; 64],
offset: 255,
large_block_counter: true,
rounds: 8, };
let cc: ChaCha = unsafe {
std::mem::transmute(tmp)
};
cc
}