use aes::Aes128;
use aes::cipher::{Array, BlockCipherEncrypt, KeyInit};
use crate::crypto::ecb::BLOCK_SIZE;
const BATCH: usize = 256;
pub fn keystream_xor(key: &[u8; 16], nonce: &[u8; 16], abs_offset: u64, buf: &mut [u8]) {
let cipher = Aes128::new(key.into());
let mut counter = abs_offset >> 4;
let mut skip = (abs_offset & 0xF) as usize; let mut blocks = [Array::<u8, _>::default(); BATCH];
let mut pos = 0;
while pos < buf.len() {
let n = (skip + buf.len() - pos).div_ceil(BLOCK_SIZE).min(BATCH);
for b in &mut blocks[..n] {
b[..8].copy_from_slice(&nonce[..8]);
b[8..].copy_from_slice(&counter.to_be_bytes());
counter += 1;
}
cipher.encrypt_blocks(&mut blocks[..n]);
let keystream = blocks[..n].iter().flat_map(|b| b.iter()).skip(skip);
for (byte, k) in buf[pos..].iter_mut().zip(keystream) {
*byte ^= k;
pos += 1;
}
skip = 0;
}
}