9#include <botan/internal/bit_ops.h>
10#include <botan/internal/isa_extn.h>
24consteval std::array<uint64_t, 256> zfec_gfni_mul_matrix() {
25 std::array<uint64_t, 256> tbl = {};
27 for(
size_t y = 0; y != 256; ++y) {
29 for(
size_t r = 0; r != 8; ++r) {
30 const size_t out_bit = 7 - r;
32 for(
size_t b = 0; b != 8; ++b) {
33 const uint8_t prod =
poly_mul<0x1D>(
static_cast<uint8_t
>(1U << b),
static_cast<uint8_t
>(y));
34 if(((prod >> out_bit) & 1) != 0) {
35 byte_r |=
static_cast<uint8_t
>(1U << b);
38 q |=
static_cast<uint64_t
>(byte_r) << (8 * r);
46alignas(256)
constexpr auto ZFEC_GFNI_MUL_MATRIX = zfec_gfni_mul_matrix();
53BOTAN_FN_ISA_AVX512_GFNI
void ZFEC::linear_combination_gfni(
54 uint8_t z[],
const uint8_t*
const x[],
const uint8_t y[],
size_t k,
size_t size) {
57 while(off + 128 <= size) {
58 __m512i acc0 = _mm512_setzero_si512();
59 __m512i acc1 = _mm512_setzero_si512();
61 for(
size_t j = 0; j != k; ++j) {
62 const __m512i mat = _mm512_set1_epi64(
static_cast<int64_t
>(ZFEC_GFNI_MUL_MATRIX[y[j]]));
63 const __m512i x0 = _mm512_loadu_si512(x[j] + off);
64 const __m512i x1 = _mm512_loadu_si512(x[j] + off + 64);
65 acc0 = _mm512_xor_si512(acc0, _mm512_gf2p8affine_epi64_epi8(x0, mat, 0));
66 acc1 = _mm512_xor_si512(acc1, _mm512_gf2p8affine_epi64_epi8(x1, mat, 0));
69 _mm512_storeu_si512(z + off, acc0);
70 _mm512_storeu_si512(z + off + 64, acc1);
75 while(off + 64 <= size) {
76 __m512i acc = _mm512_setzero_si512();
78 for(
size_t j = 0; j != k; ++j) {
79 const __m512i mat = _mm512_set1_epi64(
static_cast<int64_t
>(ZFEC_GFNI_MUL_MATRIX[y[j]]));
80 acc = _mm512_xor_si512(acc, _mm512_gf2p8affine_epi64_epi8(_mm512_loadu_si512(x[j] + off), mat, 0));
83 _mm512_storeu_si512(z + off, acc);
89 const __mmask64 mask = (uint64_t(1) << (size - off)) - 1;
91 __m512i acc = _mm512_setzero_si512();
93 for(
size_t j = 0; j != k; ++j) {
94 const __m512i mat = _mm512_set1_epi64(
static_cast<int64_t
>(ZFEC_GFNI_MUL_MATRIX[y[j]]));
95 const __m512i xv = _mm512_maskz_loadu_epi8(mask, x[j] + off);
96 acc = _mm512_xor_si512(acc, _mm512_gf2p8affine_epi64_epi8(xv, mat, 0));
99 _mm512_mask_storeu_epi8(z + off, mask, acc);
constexpr T poly_mul(T x, uint8_t y)