use crate::echelon::{ct_compare_8, ef};
use crate::gf16::{mat_mul, mul_fx8, sub_f};
#[allow(clippy::too_many_arguments)]
pub(crate) fn sample_solution(
a: &mut [u8],
y: &[u8],
r: &[u8],
x: &mut [u8],
k: usize,
o: usize,
m: usize,
a_cols: usize,
) -> bool {
let ko = k * o;
x[..ko].copy_from_slice(&r[..ko]);
let mut ar = vec![0u8; m];
for i in 0..m {
a[ko + i * a_cols] = 0;
}
mat_mul(a, r, &mut ar, a_cols, m, 1);
for i in 0..m {
a[ko + i * a_cols] = sub_f(y[i], ar[i]);
}
ef(a, m, a_cols);
let mut full_rank: u8 = 0;
for i in 0..(a_cols - 1) {
full_rank |= a[(m - 1) * a_cols + i];
}
for row in (0..m).rev() {
let mut finished: u8 = 0;
let col_upper_bound = (row + 32 / (m - row)).min(ko);
for col in row..=col_upper_bound {
let correct_column = ct_compare_8(a[row * a_cols + col], 0) & !finished;
let u = correct_column & a[row * a_cols + a_cols - 1];
x[col] ^= u;
let mut i = 0;
while i < row {
let end = (i + 8).min(row);
let mut tmp: u64 = 0;
for ii in i..end {
tmp ^= u64::from(a[ii * a_cols + col]) << ((ii - i) * 8);
}
tmp = mul_fx8(u, tmp);
for ii in i..end {
a[ii * a_cols + a_cols - 1] ^= ((tmp >> ((ii - i) * 8)) & 0xf) as u8;
}
i += 8;
}
finished |= correct_column;
}
}
full_rank != 0
}