32 #ifndef MCKL_RANDOM_INTERNAL_AES_AESNI_HPP 33 #define MCKL_RANDOM_INTERNAL_AES_AESNI_HPP 50 template <
typename KeySeqType>
54 static void eval(
const void *plain,
void *cipher,
const KeySeqType &ks)
56 const std::array<__m128i, rounds_ + 1> rk(ks.get());
58 __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(plain));
59 s = _mm_xor_si128(s, std::get<0>(rk));
61 s = _mm_aesenclast_si128(s, std::get<rounds_>(rk));
62 _mm_storeu_si128(reinterpret_cast<__m128i *>(cipher), s);
65 template <
typename ResultType>
69 const std::array<__m128i, rounds_ + 1> rk(ks.get());
73 _mm_loadu_si128(reinterpret_cast<const __m128i *>(ctr.data()));
74 s = _mm_xor_si128(s, std::get<0>(rk));
76 s = _mm_aesenclast_si128(s, std::get<rounds_>(rk));
77 _mm_storeu_si128(reinterpret_cast<__m128i *>(r), s);
80 template <
typename ResultType>
82 ResultType *r,
const KeySeqType &ks)
84 constexpr std::size_t
S = 8;
85 constexpr std::size_t N = S;
86 constexpr std::size_t R =
sizeof(__m128i) /
sizeof(ResultType);
88 const std::array<__m128i, rounds_ + 1> rk(ks.get());
90 std::array<__m128i, S> s;
95 std::memcpy(r, s.data(),
sizeof(__m128i) * N);
101 for (std::size_t i = 0; i != n; ++i) {
104 _mm_loadu_si128(reinterpret_cast<const __m128i *>(ctr.data()));
105 s = _mm_xor_si128(s, std::get<0>(rk));
107 s = _mm_aesenclast_si128(s, std::get<rounds_>(rk));
108 _mm_store_si128(reinterpret_cast<__m128i *>(t.data() + i * R), s);
110 std::memcpy(r, t.data(),
sizeof(__m128i) * n);
114 static constexpr std::size_t rounds_ = KeySeqType::rounds();
116 template <std::
size_t>
118 __m128i &,
const std::array<__m128i, rounds_ + 1> &, std::false_type)
122 template <std::
size_t N>
124 __m128i &s,
const std::array<__m128i, rounds_ + 1> &rk, std::true_type)
129 template <std::
size_t, std::
size_t S>
130 static void round(std::array<__m128i, S> &,
131 const std::array<__m128i, rounds_ + 1> &, std::false_type)
135 template <std::
size_t N, std::
size_t S>
136 static void round(std::array<__m128i, S> &s,
137 const std::array<__m128i, rounds_ + 1> &rk, std::true_type)
142 template <std::
size_t N>
144 __m128i &s,
const std::array<__m128i, rounds_ + 1> &rk)
146 rbox<N>(s, rk, std::integral_constant<bool, (N > 0 && N < rounds_)>());
149 template <std::
size_t>
151 __m128i &,
const std::array<__m128i, rounds_ + 1> &, std::false_type)
155 template <std::
size_t N>
157 __m128i &s,
const std::array<__m128i, rounds_ + 1> &rk, std::true_type)
159 s = _mm_aesenc_si128(s, std::get<N>(rk));
162 template <std::
size_t N, std::
size_t S>
164 std::array<__m128i, S> &s,
const std::array<__m128i, rounds_ + 1> &rk)
166 rbox<N>(s, rk, std::integral_constant<bool, (N > 0 && N < rounds_)>());
169 template <std::
size_t, std::
size_t S>
170 static void rbox(std::array<__m128i, S> &,
171 const std::array<__m128i, rounds_ + 1> &, std::false_type)
175 template <std::
size_t N, std::
size_t S>
176 static void rbox(std::array<__m128i, S> &s,
177 const std::array<__m128i, rounds_ + 1> &rk, std::true_type)
179 aesenc_si128(s, std::get<N>(rk));
201 template <
typename Constants>
214 #endif // MCKL_RANDOM_INTERNAL_AES_AESNI_HPP
#define MCKL_PUSH_GCC_WARNING(warning)
void increment_si128(std::array< T, K > &ctr, std::array< __m128i, S > &s, std::false_type)
void round(std::size_t n, const float *a, float *y)
typename internal::CounterImpl< T, K >::type Counter
A counter type with the same width as std::array<T, K> but with possibly fewer elements.
static void eval(const void *plain, void *cipher, const KeySeqType &ks)
#define MCKL_RANDOM_INTERNAL_AES_UNROLL_ROUND(N, s, rk)
void increment(std::array< T, K > &ctr, std::integral_constant< T, NSkip >)
Increment a counter by given steps.
static void eval(Counter< std::uint32_t, 4 > &ctr, ResultType *r, const KeySeqType &ks)
#define MCKL_ALIGNMENT
The default alignment for scalar type.
#define MCKL_RANDOM_INTERNAL_AES_UNROLL(N, s, rk)
#define MCKL_POP_GCC_WARNING
static void eval(Counter< std::uint32_t, 4 > &ctr, std::size_t n, ResultType *r, const KeySeqType &ks)