pub(crate) fn decode(input: &[u8], output: &mut [u8], len: usize) {
let mut out_idx = 0;
let mut i = 0;
while i < len / 2 {
output[out_idx] = input[i] & 0xf;
output[out_idx + 1] = input[i] >> 4;
out_idx += 2;
i += 1;
}
if len % 2 == 1 {
output[out_idx] = input[i] & 0x0f;
}
}
pub(crate) fn encode(input: &[u8], output: &mut [u8], len: usize) {
let mut in_idx = 0;
let mut i = 0;
while i < len / 2 {
output[i] = input[in_idx] | (input[in_idx + 1] << 4);
in_idx += 2;
i += 1;
}
if len % 2 == 1 {
output[i] = input[in_idx];
}
}
pub(crate) fn unpack_m_vecs(input: &[u8], output: &mut [u64], vecs: usize, m: usize) {
let m_vec_limbs = m.div_ceil(16);
let packed_size = m / 2;
for i in 0..vecs {
let src = &input[i * packed_size..(i + 1) * packed_size];
let dst = &mut output[i * m_vec_limbs..(i + 1) * m_vec_limbs];
dst.fill(0);
for (j, chunk) in src.chunks(8).enumerate() {
let mut buf = [0u8; 8];
buf[..chunk.len()].copy_from_slice(chunk);
dst[j] = u64::from_le_bytes(buf);
}
}
}
#[allow(clippy::cast_possible_truncation)]
pub(crate) fn pack_m_vecs(input: &[u64], output: &mut [u8], vecs: usize, m: usize) {
let m_vec_limbs = m.div_ceil(16);
let packed_size = m / 2;
for i in 0..vecs {
let src = &input[i * m_vec_limbs..(i + 1) * m_vec_limbs];
for j in 0..packed_size {
let limb_idx = j / 8;
let byte_idx = j % 8;
output[i * packed_size + j] = (src[limb_idx] >> (byte_idx * 8)) as u8;
}
}
}