use crate::poly::Poly;
use crate::params::KYBER_N;
fn load32_littleendian(x: &[u8]) -> u32
{
let mut r = x[0] as u32;
r |= (x[1] as u32) << 8;
r |= (x[2] as u32) << 16;
r |= (x[3] as u32) << 24;
r
}
fn load24_littleendian(x: &[u8]) -> u32
{
let mut r = x[0] as u32;
r |= (x[1] as u32) << 8;
r |= (x[2] as u32) << 16;
r
}
pub fn cbd2(r: &mut Poly, buf: &[u8])
{
let (mut d, mut t, mut a, mut b);
for i in 0..(KYBER_N/8) {
t = load32_littleendian(&buf[4*i..]);
d = t & 0x55555555;
d += (t>>1) & 0x55555555;
for j in 0..8 {
a = ((d >> (4*j)) & 0x3) as i16;
b = ((d >> (4*j+2)) & 0x3) as i16;
r.coeffs[8*i+j] = a - b;
}
}
}
pub fn cbd3(r: &mut Poly, buf: &[u8])
{
let (mut d, mut t, mut a, mut b);
for i in 0..(KYBER_N/4) {
t = load24_littleendian(&buf[3*i..]);
d = t & 0x00249249;
d += (t>>1) & 0x00249249;
d += (t>>2) & 0x00249249;
for j in 0..4 {
a = ((d >> (6*j)) & 0x7) as i16;
b = ((d >> (6*j+3)) & 0x7) as i16;
r.coeffs[4*i+j] = a - b;
}
}
}
pub fn poly_cbd_eta1(r: &mut Poly, buf: &[u8])
{
if cfg!(feature="kyber512") {
cbd3(r, buf)
}
else {
cbd2(r, buf)
}
}
pub fn poly_cbd_eta2(r: &mut Poly, buf: &[u8])
{
cbd2(r, buf)
}