use crate::field::{Elem, FieldBuffer, FieldElem};
pub fn add_assign<F: FieldBuffer>(dst: &mut [u8], src: &[u8]) {
debug_assert_eq!(dst.len(), src.len());
for (d, s) in dst
.chunks_exact_mut(F::BYTES)
.zip(src.chunks_exact(F::BYTES))
{
let value = F::decode(d).add(F::decode(s));
F::encode(d, value);
}
}
pub fn sub_assign<F: FieldBuffer>(dst: &mut [u8], src: &[u8]) {
debug_assert_eq!(dst.len(), src.len());
for (d, s) in dst
.chunks_exact_mut(F::BYTES)
.zip(src.chunks_exact(F::BYTES))
{
let value = F::decode(d).sub(F::decode(s));
F::encode(d, value);
}
}
pub fn mul_add<F: FieldBuffer>(dst: &mut [u8], coeff: Elem<F>, src: &[u8]) {
debug_assert_eq!(dst.len(), src.len());
if coeff.is_zero() {
return;
}
if coeff.is_one() {
add_assign::<F>(dst, src);
return;
}
for (d, s) in dst
.chunks_exact_mut(F::BYTES)
.zip(src.chunks_exact(F::BYTES))
{
let value = F::decode(d).add(F::decode(s).mul(coeff));
F::encode(d, value);
}
}
pub fn mul_assign<F: FieldBuffer>(dst: &mut [u8], coeff: Elem<F>) {
if coeff.is_one() {
return;
}
if coeff.is_zero() {
dst.fill(0);
return;
}
for d in dst.chunks_exact_mut(F::BYTES) {
let value = F::decode(d).mul(coeff);
F::encode(d, value);
}
}
pub fn mul_add_scatter<F: FieldBuffer>(
rows: &mut [u8],
row_len: usize,
coeffs: &[Elem<F>],
src: &[u8],
) {
for (row, &coeff) in rows.chunks_exact_mut(row_len).zip(coeffs) {
mul_add::<F>(row, coeff, src);
}
}
pub fn mul_add_gather<F: FieldBuffer>(dst: &mut [u8], coeffs: &[Elem<F>], srcs: &[&[u8]]) {
for (&coeff, &src) in coeffs.iter().zip(srcs) {
mul_add::<F>(dst, coeff, src);
}
}
pub fn mul_add_matrix<F: FieldBuffer>(
rows: &mut [u8],
row_len: usize,
nrows: usize,
terms: &[(&[Elem<F>], &[u8])],
) {
for &(coeffs, src) in terms {
for (row, &coeff) in rows.chunks_exact_mut(row_len).take(nrows).zip(coeffs) {
mul_add::<F>(row, coeff, src);
}
}
}
pub fn mul_elementwise<F: FieldBuffer>(dst: &mut [u8], a: &[u8], b: &[u8]) {
debug_assert_eq!(dst.len(), a.len());
debug_assert_eq!(dst.len(), b.len());
for ((d, x), y) in dst
.chunks_exact_mut(F::BYTES)
.zip(a.chunks_exact(F::BYTES))
.zip(b.chunks_exact(F::BYTES))
{
F::encode(d, F::decode(x).mul(F::decode(y)));
}
}
pub fn add_assign_scalar<F: FieldBuffer>(dst: &mut [u8], value: Elem<F>) {
for d in dst.chunks_exact_mut(F::BYTES) {
F::encode(d, F::decode(d).add(value));
}
}
pub fn sub_assign_scalar<F: FieldBuffer>(dst: &mut [u8], value: Elem<F>) {
for d in dst.chunks_exact_mut(F::BYTES) {
F::encode(d, F::decode(d).sub(value));
}
}