32 #ifndef MCKL_RANDOM_INTERNAL_AES_GENERIC_HPP 33 #define MCKL_RANDOM_INTERNAL_AES_GENERIC_HPP 47 using rk_type = std::array<std::uint32_t, 4>;
49 template <std::
size_t Rp1>
51 const std::array<std::array<std::uint32_t, 4>, Rp1> &rk)
54 std::memcpy(key.data(), rk.data(),
sizeof(
key_type));
59 template <std::
size_t Rp1>
61 const key_type &
key, std::array<std::array<std::uint32_t, 4>, Rp1> &rk)
64 std::get<0>(rk) = tmp0_;
65 generate<1>(rk, std::integral_constant<bool, 1 < Rp1>());
69 std::array<std::uint32_t, 4> tmp0_;
71 template <std::
size_t, std::
size_t Rp1>
73 std::array<std::array<std::uint32_t, 4>, Rp1> &, std::false_type)
77 template <std::
size_t N, std::
size_t Rp1>
79 std::array<std::array<std::uint32_t, 4>, Rp1> &rk, std::true_type)
86 std::get<0>(tmp0_) ^= rcon;
87 std::get<0>(tmp0_) ^= table[(t >> 0x08) & 0xFF] & 0x000000FF;
88 std::get<0>(tmp0_) ^= table[(t >> 0x10) & 0xFF] & 0x0000FF00;
89 std::get<0>(tmp0_) ^= table[(t >> 0x18) & 0xFF] & 0x00FF0000;
90 std::get<0>(tmp0_) ^= table[(t >> 0x00) & 0xFF] & 0xFF000000;
91 std::get<1>(tmp0_) ^= std::get<0>(tmp0_);
92 std::get<2>(tmp0_) ^= std::get<1>(tmp0_);
93 std::get<3>(tmp0_) ^= std::get<2>(tmp0_);
95 std::get<N>(rk) = tmp0_;
96 generate<N + 1>(rk, std::integral_constant<bool, N + 1 < Rp1>());
106 template <std::
size_t Rp1>
108 const std::array<std::array<std::uint32_t, 4>, Rp1> &rk)
111 std::memcpy(key.data(), rk.data(),
sizeof(
key_type));
116 template <std::
size_t Rp1>
118 const key_type &
key, std::array<std::array<std::uint32_t, 4>, Rp1> &rk)
120 constexpr std::size_t Rs1 = Rp1 * 4 / 6 + ((Rp1 * 4) % 6 == 0 ? 0 : 1);
122 std::array<std::array<std::uint32_t, 6>, Rs1> rs;
124 std::get<0>(rs) = tmp0_;
125 generate<1>(rs, std::integral_constant<bool, 1 < Rs1>());
126 std::memcpy(rk.data(), rs.data(),
sizeof(
std::uint32_t) * Rp1 * 4);
130 std::array<std::uint32_t, 6> tmp0_;
132 template <std::
size_t, std::
size_t Rs1>
134 std::array<std::array<std::uint32_t, 6>, Rs1> &, std::false_type)
138 template <std::
size_t N, std::
size_t Rs1>
140 std::array<std::array<std::uint32_t, 6>, Rs1> &rk, std::true_type)
147 std::get<0>(tmp0_) ^= rcon;
148 std::get<0>(tmp0_) ^= table[(t >> 0x08) & 0xFF] & 0x000000FF;
149 std::get<0>(tmp0_) ^= table[(t >> 0x10) & 0xFF] & 0x0000FF00;
150 std::get<0>(tmp0_) ^= table[(t >> 0x18) & 0xFF] & 0x00FF0000;
151 std::get<0>(tmp0_) ^= table[(t >> 0x00) & 0xFF] & 0xFF000000;
152 std::get<1>(tmp0_) ^= std::get<0>(tmp0_);
153 std::get<2>(tmp0_) ^= std::get<1>(tmp0_);
154 std::get<3>(tmp0_) ^= std::get<2>(tmp0_);
155 std::get<4>(tmp0_) ^= std::get<3>(tmp0_);
156 std::get<5>(tmp0_) ^= std::get<4>(tmp0_);
158 std::get<N>(rk) = tmp0_;
159 generate<N + 1>(rk, std::integral_constant<bool, N + 1 < Rs1>());
169 template <std::
size_t Rp1>
171 const std::array<std::array<std::uint32_t, 4>, Rp1> &rk)
174 std::memcpy(key.data(), rk.data(),
sizeof(
key_type));
179 template <std::
size_t Rp1>
181 const key_type &
key, std::array<std::array<std::uint32_t, 4>, Rp1> &rk)
183 std::get<0>(tmp0_) = std::get<0>(key);
184 std::get<1>(tmp0_) = std::get<1>(key);
185 std::get<2>(tmp0_) = std::get<2>(key);
186 std::get<3>(tmp0_) = std::get<3>(key);
187 std::get<0>(tmp1_) = std::get<4>(key);
188 std::get<1>(tmp1_) = std::get<5>(key);
189 std::get<2>(tmp1_) = std::get<6>(key);
190 std::get<3>(tmp1_) = std::get<7>(key);
191 std::get<0>(rk) = tmp0_;
192 std::get<1>(rk) = tmp1_;
193 generate<2>(rk, std::integral_constant<bool, 2 < Rp1>());
197 std::array<std::uint32_t, 4> tmp0_;
198 std::array<std::uint32_t, 4> tmp1_;
200 template <std::
size_t, std::
size_t Rp1>
202 std::array<std::array<std::uint32_t, 4>, Rp1> &, std::false_type)
206 template <std::
size_t N, std::
size_t Rp1>
208 std::array<std::array<std::uint32_t, 4>, Rp1> &rk, std::true_type)
210 generate_key<N>(rk, std::integral_constant<bool, N % 2 == 0>());
211 generate<N + 1>(rk, std::integral_constant<bool, N + 1 < Rp1>());
214 template <std::
size_t N, std::
size_t Rp1>
216 std::array<std::array<std::uint32_t, 4>, Rp1> &rk, std::true_type)
223 std::get<0>(tmp0_) ^= rcon;
224 std::get<0>(tmp0_) ^= table[(t >> 0x08) & 0xFF] & 0x000000FF;
225 std::get<0>(tmp0_) ^= table[(t >> 0x10) & 0xFF] & 0x0000FF00;
226 std::get<0>(tmp0_) ^= table[(t >> 0x18) & 0xFF] & 0x00FF0000;
227 std::get<0>(tmp0_) ^= table[(t >> 0x00) & 0xFF] & 0xFF000000;
228 std::get<1>(tmp0_) ^= std::get<0>(tmp0_);
229 std::get<2>(tmp0_) ^= std::get<1>(tmp0_);
230 std::get<3>(tmp0_) ^= std::get<2>(tmp0_);
232 std::get<N>(rk) = tmp0_;
235 template <std::
size_t N, std::
size_t Rp1>
237 std::array<std::array<std::uint32_t, 4>, Rp1> &rk, std::false_type)
242 std::get<0>(tmp1_) ^= table[(t >> 0x00) & 0xFF] & 0x000000FF;
243 std::get<0>(tmp1_) ^= table[(t >> 0x08) & 0xFF] & 0x0000FF00;
244 std::get<0>(tmp1_) ^= table[(t >> 0x10) & 0xFF] & 0x00FF0000;
245 std::get<0>(tmp1_) ^= table[(t >> 0x18) & 0xFF] & 0xFF000000;
246 std::get<1>(tmp1_) ^= std::get<0>(tmp1_);
247 std::get<2>(tmp1_) ^= std::get<1>(tmp1_);
248 std::get<3>(tmp1_) ^= std::get<2>(tmp1_);
250 std::get<N>(rk) = tmp1_;
254 template <
typename Constants>
261 template <std::
size_t Rp1>
263 const std::array<std::array<std::uint32_t, 4>, Rp1> &rk)
266 std::memcpy(key.data(), rk.data(),
sizeof(
key_type));
271 template <std::
size_t Rp1>
273 const key_type &
key, std::array<std::array<std::uint32_t, 4>, Rp1> &rk)
275 std::get<0>(key_) = static_cast<std::uint64_t>(std::get<0>(key)) +
276 (static_cast<std::uint64_t>(std::get<1>(key)) << 32);
277 std::get<1>(key_) = static_cast<std::uint64_t>(std::get<2>(key)) +
278 (static_cast<std::uint64_t>(std::get<3>(key)) << 32);
279 generate<0>(rk, std::integral_constant<bool, 0 < Rp1>());
283 std::array<std::uint64_t, 2> key_;
285 template <std::
size_t, std::
size_t Rp1>
287 std::array<std::array<std::uint32_t, 4>, Rp1> &, std::false_type)
const 291 template <std::
size_t N, std::
size_t Rp1>
292 void generate(std::array<std::array<std::uint32_t, 4>, Rp1> &rk,
293 std::true_type)
const 300 std::get<0>(std::get<N>(rk)) =
static_cast<std::uint32_t>(k0);
301 std::get<1>(std::get<N>(rk)) =
static_cast<std::uint32_t>(k0 >> 32);
302 std::get<2>(std::get<N>(rk)) =
static_cast<std::uint32_t>(k1);
303 std::get<3>(std::get<N>(rk)) =
static_cast<std::uint32_t>(k1 >> 32);
304 generate<N + 1>(rk, std::integral_constant<bool, N + 1 < Rp1>());
308 template <
typename KeySeqType>
312 static void eval(
const void *plain,
void *cipher,
const KeySeqType &ks)
315 std::array<std::uint32_t, 4> s;
316 std::array<char, sizeof(std::uint32_t) * 4> r;
319 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> rk(
323 union_le<char>(buf.s);
325 round<1>(buf.s, rk, std::integral_constant<bool, 1 < rounds_>());
327 union_le<std::uint32_t>(buf.r);
328 std::memcpy(cipher, buf.s.data(),
sizeof(
std::uint32_t) * 4);
331 template <
typename ResultType>
336 std::array<std::uint32_t, 4> s;
338 std::array<ResultType,
343 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> rk(
348 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 349 union_le<typename Counter<std::uint32_t, 4>::value_type>(buf.s);
352 round<1>(buf.s, rk, std::integral_constant<bool, 1 < rounds_>());
354 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 355 union_le<std::uint32_t>(buf.r);
360 template <
typename ResultType>
362 ResultType *r,
const KeySeqType &ks)
364 constexpr std::size_t R =
368 std::array<std::uint32_t, 4> s;
370 std::array<ResultType,
375 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> rk(
378 for (std::size_t i = 0; i != n; ++i, r += R) {
381 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 382 union_le<typename Counter<std::uint32_t, 4>::value_type>(buf.s);
385 round<1>(buf.s, rk, std::integral_constant<bool, 1 < rounds_>());
387 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 388 union_le<std::uint32_t>(buf.r);
395 static constexpr std::size_t rounds_ = KeySeqType::rounds();
397 template <std::
size_t>
398 static void round(std::array<std::uint32_t, 4> &,
399 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> &,
404 template <std::
size_t N>
405 static void round(std::array<std::uint32_t, 4> &s,
406 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> &rk,
410 round<N + 1>(s, rk, std::integral_constant<bool, N + 1 < rounds_>());
413 static void encfirst(std::array<std::uint32_t, 4> &s,
414 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> &rk)
416 std::get<0>(s) ^= std::get<0>(std::get<0>(rk));
417 std::get<1>(s) ^= std::get<1>(std::get<0>(rk));
418 std::get<2>(s) ^= std::get<2>(std::get<0>(rk));
419 std::get<3>(s) ^= std::get<3>(std::get<0>(rk));
422 template <std::
size_t N>
423 static void enc(std::array<std::uint32_t, 4> &s,
424 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> &rk)
426 enc<N>(s, rk, std::integral_constant<bool, (N > 0 && N < rounds_)>());
429 template <std::
size_t>
430 static void enc(std::array<std::uint32_t, 4> &,
431 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> &,
436 template <std::
size_t N>
437 static void enc(std::array<std::uint32_t, 4> &s,
438 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> &rk,
445 std::array<std::uint32_t, 4> t(std::get<N>(rk));
447 std::get<0>(t) ^= table0[(std::get<0>(s) >> 0x00) & 0xFF];
448 std::get<1>(t) ^= table0[(std::get<1>(s) >> 0x00) & 0xFF];
449 std::get<2>(t) ^= table0[(std::get<2>(s) >> 0x00) & 0xFF];
450 std::get<3>(t) ^= table0[(std::get<3>(s) >> 0x00) & 0xFF];
451 std::get<0>(t) ^= table1[(std::get<1>(s) >> 0x08) & 0xFF];
452 std::get<1>(t) ^= table1[(std::get<2>(s) >> 0x08) & 0xFF];
453 std::get<2>(t) ^= table1[(std::get<3>(s) >> 0x08) & 0xFF];
454 std::get<3>(t) ^= table1[(std::get<0>(s) >> 0x08) & 0xFF];
455 std::get<0>(t) ^= table2[(std::get<2>(s) >> 0x10) & 0xFF];
456 std::get<1>(t) ^= table2[(std::get<3>(s) >> 0x10) & 0xFF];
457 std::get<2>(t) ^= table2[(std::get<0>(s) >> 0x10) & 0xFF];
458 std::get<3>(t) ^= table2[(std::get<1>(s) >> 0x10) & 0xFF];
459 std::get<0>(t) ^= table3[(std::get<3>(s) >> 0x18) & 0xFF];
460 std::get<1>(t) ^= table3[(std::get<0>(s) >> 0x18) & 0xFF];
461 std::get<2>(t) ^= table3[(std::get<1>(s) >> 0x18) & 0xFF];
462 std::get<3>(t) ^= table3[(std::get<2>(s) >> 0x18) & 0xFF];
467 static void enclast(std::array<std::uint32_t, 4> &s,
468 const std::array<std::array<std::uint32_t, 4>, rounds_ + 1> &rk)
471 std::array<std::uint32_t, 4> t(std::get<rounds_>(rk));
473 std::get<0>(t) ^= table4[(std::get<0>(s) >> 0x00) & 0xFF] & 0x000000FF;
474 std::get<1>(t) ^= table4[(std::get<1>(s) >> 0x00) & 0xFF] & 0x000000FF;
475 std::get<2>(t) ^= table4[(std::get<2>(s) >> 0x00) & 0xFF] & 0x000000FF;
476 std::get<3>(t) ^= table4[(std::get<3>(s) >> 0x00) & 0xFF] & 0x000000FF;
477 std::get<0>(t) ^= table4[(std::get<1>(s) >> 0x08) & 0xFF] & 0x0000FF00;
478 std::get<1>(t) ^= table4[(std::get<2>(s) >> 0x08) & 0xFF] & 0x0000FF00;
479 std::get<2>(t) ^= table4[(std::get<3>(s) >> 0x08) & 0xFF] & 0x0000FF00;
480 std::get<3>(t) ^= table4[(std::get<0>(s) >> 0x08) & 0xFF] & 0x0000FF00;
481 std::get<0>(t) ^= table4[(std::get<2>(s) >> 0x10) & 0xFF] & 0x00FF0000;
482 std::get<1>(t) ^= table4[(std::get<3>(s) >> 0x10) & 0xFF] & 0x00FF0000;
483 std::get<2>(t) ^= table4[(std::get<0>(s) >> 0x10) & 0xFF] & 0x00FF0000;
484 std::get<3>(t) ^= table4[(std::get<1>(s) >> 0x10) & 0xFF] & 0x00FF0000;
485 std::get<0>(t) ^= table4[(std::get<3>(s) >> 0x18) & 0xFF] & 0xFF000000;
486 std::get<1>(t) ^= table4[(std::get<0>(s) >> 0x18) & 0xFF] & 0xFF000000;
487 std::get<2>(t) ^= table4[(std::get<1>(s) >> 0x18) & 0xFF] & 0xFF000000;
488 std::get<3>(t) ^= table4[(std::get<2>(s) >> 0x18) & 0xFF] & 0xFF000000;
498 #endif // MCKL_RANDOM_INTERNAL_AES_GENERIC_HPP std::array< std::uint32_t, 4 > rk_type
std::array< std::uint32_t, 4 > key_type
void operator()(const key_type &key, std::array< std::array< std::uint32_t, 4 >, Rp1 > &rk)
static void eval(Counter< std::uint32_t, 4 > &ctr, ResultType *r, const KeySeqType &ks)
void round(std::size_t n, const float *a, float *y)
const std::uint32_t * aes_table()
typename internal::CounterImpl< T, K >::type Counter
A counter type with the same width as std::array<T, K> but with possibly fewer elements.
void operator()(const key_type &key, std::array< std::array< std::uint32_t, 4 >, Rp1 > &rk)
static void eval(Counter< std::uint32_t, 4 > &ctr, std::size_t n, ResultType *r, const KeySeqType &ks)
std::array< std::uint32_t, 4 > rk_type
static key_type key(const std::array< std::array< std::uint32_t, 4 >, Rp1 > &rk)
std::array< std::uint32_t, 8 > key_type
static key_type key(const std::array< std::array< std::uint32_t, 4 >, Rp1 > &rk)
std::array< std::uint32_t, 4 > rk_type
static key_type key(const std::array< std::array< std::uint32_t, 4 >, Rp1 > &rk)
static void eval(const void *plain, void *cipher, const KeySeqType &ks)
std::array< std::uint32_t, 6 > key_type
void increment(std::array< T, K > &ctr, std::integral_constant< T, NSkip >)
Increment a counter by given steps.
void operator()(const key_type &key, std::array< std::array< std::uint32_t, 4 >, Rp1 > &rk)
static constexpr std::uint32_t value[256]
#define MCKL_ALIGNMENT
The default alignment for scalar type.
std::array< std::uint32_t, 4 > key_type
void operator()(const key_type &key, std::array< std::array< std::uint32_t, 4 >, Rp1 > &rk)
static key_type key(const std::array< std::array< std::uint32_t, 4 >, Rp1 > &rk)
std::array< std::uint32_t, 4 > rk_type