7#include <botan/internal/ghash.h>
9#include <botan/internal/isa_extn.h>
10#include <botan/internal/polyval_fn.h>
11#include <botan/internal/simd_4x32.h>
12#include <botan/internal/target_info.h>
15#if defined(BOTAN_HAS_POLYVAL)
16 #include <botan/internal/polyval.h>
25 const auto B = _mm512_loadu_si512(in);
29 const auto swap = _mm512_set_epi64(0x0001020304050607,
37 return _mm512_shuffle_epi8(B, swap);
44 return _mm512_xor_si512(H, _mm512_bsrli_epi128(H, 8));
48 auto y = _mm256_xor_si256(_mm512_castsi512_si256(z), _mm512_extracti64x4_epi64(z, 0x1));
49 auto x = _mm_xor_si128(_mm256_castsi256_si128(y), _mm256_extracti32x4_epi32(y, 0x1));
54ghash_x4_accum(__m512i H, __m512i H_fold, __m512i M, __m512i& lo, __m512i& hi, __m512i& mid) {
55 lo = _mm512_xor_si512(lo, _mm512_clmulepi64_epi128(H, M, 0x00));
56 hi = _mm512_xor_si512(hi, _mm512_clmulepi64_epi128(H, M, 0x11));
57 mid = _mm512_xor_si512(mid, _mm512_clmulepi64_epi128(H_fold, fold(M), 0x00));
61 mid = _mm512_ternarylogic_epi64(lo, mid, hi, 0x96);
62 hi = _mm512_xor_si512(hi, _mm512_bsrli_epi128(mid, 8));
63 lo = _mm512_xor_si512(lo, _mm512_bslli_epi128(mid, 8));
68 return _mm512_xor_epi64(M, _mm512_inserti64x2(_mm512_setzero_si512(), a.raw(), 0));
71void BOTAN_FN_ISA_AVX512_CLMUL precompute_avx512(
const SIMD_4x32& H1, uint64_t H_pow[16 * 2]) {
94 H3.store_le(H_pow + 2);
95 H2.store_le(H_pow + 4);
96 H1.store_le(H_pow + 6);
98 H8.store_le(H_pow + 8);
99 H7.store_le(H_pow + 10);
100 H6.store_le(H_pow + 12);
101 H5.store_le(H_pow + 14);
103 H12.store_le(H_pow + 16);
104 H11.store_le(H_pow + 18);
105 H10.store_le(H_pow + 20);
106 H9.store_le(H_pow + 22);
108 H16.store_le(H_pow + 24);
109 H15.store_le(H_pow + 26);
110 H14.store_le(H_pow + 28);
111 H13.store_le(H_pow + 30);
115void BOTAN_FN_ISA_AVX512_CLMUL
116multiply_avx512(uint8_t x[16],
const uint64_t H_pow[16 * 2],
const uint8_t input[],
size_t blocks) {
120 const auto H1 = _mm512_loadu_si512(H_pow);
121 const auto H2 = _mm512_loadu_si512(H_pow + 8);
122 const auto H3 = _mm512_loadu_si512(H_pow + 16);
123 const auto H4 = _mm512_loadu_si512(H_pow + 24);
126 const auto H1_fold = fold(H1);
127 const auto H2_fold = fold(H2);
128 const auto H3_fold = fold(H3);
129 const auto H4_fold = fold(H4);
131 while(blocks >= 16) {
132 __m512i M1 = load_blocks<BSWAP>(input);
133 const auto M2 = load_blocks<BSWAP>(input + 64);
134 const auto M3 = load_blocks<BSWAP>(input + 128);
135 const auto M4 = load_blocks<BSWAP>(input + 192);
137 M1 = insert_a(M1, a);
139 auto lo = _mm512_setzero_si512();
140 auto hi = _mm512_setzero_si512();
141 auto mid = _mm512_setzero_si512();
143 ghash_x4_accum(H4, H4_fold, M1, lo, hi, mid);
144 ghash_x4_accum(H3, H3_fold, M2, lo, hi, mid);
145 ghash_x4_accum(H2, H2_fold, M3, lo, hi, mid);
146 ghash_x4_accum(H1, H1_fold, M4, lo, hi, mid);
148 a = ghash_reduce(lo, hi, mid);
156 const auto H1 = _mm512_loadu_si512(H_pow);
157 const auto H2 = _mm512_loadu_si512(H_pow + 8);
159 const auto H1_fold = fold(H1);
160 const auto H2_fold = fold(H2);
163 __m512i M1 = load_blocks<BSWAP>(input);
164 const __m512i M2 = load_blocks<BSWAP>(input + 64);
166 M1 = insert_a(M1, a);
168 auto lo = _mm512_setzero_si512();
169 auto hi = _mm512_setzero_si512();
170 auto mid = _mm512_setzero_si512();
172 ghash_x4_accum(H2, H2_fold, M1, lo, hi, mid);
173 ghash_x4_accum(H1, H1_fold, M2, lo, hi, mid);
175 a = ghash_reduce(lo, hi, mid);
183 const auto H1 = _mm512_loadu_si512(H_pow);
184 const auto H1_fold = fold(H1);
187 __m512i M = load_blocks<BSWAP>(input);
190 auto lo = _mm512_clmulepi64_epi128(H1, M, 0x00);
191 auto hi = _mm512_clmulepi64_epi128(H1, M, 0x11);
192 auto mid = _mm512_clmulepi64_epi128(H1_fold, fold(M), 0x00);
194 a = ghash_reduce(lo, hi, mid);
205 for(
size_t i = 0; i != blocks; ++i) {
217void BOTAN_FN_ISA_AVX512_CLMUL GHASH::ghash_precompute_avx512_clmul(
const uint8_t H_bytes[16], uint64_t H_pow[16 * 2]) {
221void BOTAN_FN_ISA_AVX512_CLMUL GHASH::ghash_multiply_avx512_clmul(uint8_t x[16],
222 const uint64_t H_pow[16 * 2],
223 const uint8_t input[],
225 multiply_avx512<true>(x, H_pow, input, blocks);
228#if defined(BOTAN_HAS_POLYVAL)
230void BOTAN_FN_ISA_AVX512_CLMUL Polyval::polyval_precompute_avx512_clmul(
const uint8_t H[16], uint64_t H_pow[16 * 2]) {
234void BOTAN_FN_ISA_AVX512_CLMUL Polyval::polyval_multiply_avx512_clmul(uint8_t x[16],
235 const uint64_t H_pow[16 * 2],
236 const uint8_t input[],
238 multiply_avx512<false>(x, H_pow, input, blocks);
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 load_le(const void *in) noexcept
#define BOTAN_FORCE_INLINE
BOTAN_FORCE_INLINE SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 mulx_polyval(const SIMD_4x32 &h)
BOTAN_FORCE_INLINE BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32 load_block(const uint8_t in[])
BOTAN_FORCE_INLINE SIMD_4x32 BOTAN_FN_ISA_CLMUL polyval_multiply(const SIMD_4x32 &H, const SIMD_4x32 &x)
BOTAN_FORCE_INLINE SIMD_4x32 BOTAN_FN_ISA_CLMUL polyval_reduce(const SIMD_4x32 &hi, const SIMD_4x32 &lo)
BOTAN_FORCE_INLINE BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32 reverse_vector(const SIMD_4x32 &in)
BOTAN_FORCE_INLINE BOTAN_FN_ISA_SIMD_4X32 void store_block(const SIMD_4x32 &b, uint8_t out[])