use crate::field::{Elem, Field};
pub fn add_assign<F: Field>(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: Field>(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: Field>(dst: &mut [u8], coeff: F::Elem, 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: Field>(dst: &mut [u8], coeff: F::Elem) {
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: Field>(rows: &mut [u8], row_len: usize, coeffs: &[F::Elem], 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: Field>(dst: &mut [u8], coeffs: &[F::Elem], srcs: &[&[u8]]) {
for (&coeff, &src) in coeffs.iter().zip(srcs) {
mul_add::<F>(dst, coeff, src);
}
}
pub fn mul_add_matrix<F: Field>(
rows: &mut [u8],
row_len: usize,
nrows: usize,
terms: &[(&[F::Elem], &[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: Field>(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: Field>(dst: &mut [u8], value: F::Elem) {
for d in dst.chunks_exact_mut(F::BYTES) {
F::encode(d, F::decode(d).add(value));
}
}
pub fn sub_assign_scalar<F: Field>(dst: &mut [u8], value: F::Elem) {
for d in dst.chunks_exact_mut(F::BYTES) {
F::encode(d, F::decode(d).sub(value));
}
}