32 #ifndef VSMC_RNG_AES_NI_HPP    33 #define VSMC_RNG_AES_NI_HPP    37 #include <wmmintrin.h>    44 template <
typename ResultType, 
typename KeySeqType, std::size_t Rounds,
    48     static_assert(std::is_unsigned<ResultType>::value,
    49         "**AESNIGenerator** USED WITH ResultType OTHER THAN UNSIGNED INTEGER "    53         Blocks != 0, 
"**AESNIGenerator** USED WITH Blocks EQUAL TO ZERO");
    57     using ctr_type = std::array<ResultType, M128I<ResultType>::size()>;
    58     using key_type = 
typename KeySeqType::key_type;
    60     static constexpr std::size_t 
size()
    68         std::array<ResultType, 
size()> &buffer)
 const    71             std::array<M128I<>, Blocks> state;
    72             std::array<ctr_type, Blocks> ctr_block;
    73             std::array<ResultType, size()> result;
    76         std::array<M128I<>, Rounds + 1> rk;
    79         enc_first(buf.state, rk);
    81             buf.state, rk, std::integral_constant<bool, 1 < Rounds>());
    82         enc_last(buf.state, rk);
    87         std::array<ResultType, 
size()> *buffer)
 const    93             std::array<M128I<>, Blocks> state;
    94             std::array<ctr_type, Blocks> ctr_block;
    95             std::array<ResultType, size()> result;
    98         std::array<M128I<>, Rounds + 1> rk;
   100         for (std::size_t i = 0; i != n; ++i) {
   102             enc_first(buf.state, rk);
   104                 buf.state, rk, std::integral_constant<bool, 1 < Rounds>());
   105             enc_last(buf.state, rk);
   106             buffer[i] = buf.result;
   113     template <std::
size_t K>
   114     void enc_first(std::array<
M128I<>, K> &state,
   115         const std::array<
M128I<>, Rounds + 1> &rk)
 const   117         enc_first<0>(state, rk, std::true_type());
   120     template <std::
size_t, std::
size_t K>
   121     void enc_first(std::array<
M128I<>, K> &,
   122         const std::array<
M128I<>, Rounds + 1> &, std::false_type)
 const   126     template <std::
size_t B, std::
size_t K>
   127     void enc_first(std::array<
M128I<>, K> &state,
   128         const std::array<
M128I<>, Rounds + 1> &rk, std::true_type)
 const   130         std::get<B>(state) ^= std::get<0>(rk);
   131         enc_first<B + 1>(state, rk, std::integral_constant<bool, B + 1 < K>());
   134     template <std::
size_t, std::
size_t K>
   135     void enc_round(std::array<
M128I<>, K> &,
   136         const std::array<
M128I<>, Rounds + 1> &, std::false_type)
 const   140     template <std::
size_t N, std::
size_t K>
   141     void enc_round(std::array<
M128I<>, K> &state,
   142         const std::array<
M128I<>, Rounds + 1> &rk, std::true_type)
 const   144         enc_round_block<0, N>(state, rk, std::true_type());
   146             state, rk, std::integral_constant<bool, N + 1 < Rounds>());
   149     template <std::
size_t, std::
size_t, std::
size_t K>
   150     void enc_round_block(std::array<
M128I<>, K> &,
   151         const std::array<
M128I<>, Rounds + 1> &, std::false_type)
 const   155     template <std::
size_t B, std::
size_t N, std::
size_t K>
   156     void enc_round_block(std::array<
M128I<>, K> &state,
   157         const std::array<
M128I<>, Rounds + 1> &rk, std::true_type)
 const   160         std::get<B>(state) = _mm_aesenc_si128(
   161             std::get<B>(state).value(), std::get<N>(rk).value());
   162         enc_round_block<B + 1, N>(
   163             state, rk, std::integral_constant<bool, B + 1 < K>());
   166     template <std::
size_t K>
   167     void enc_last(std::array<
M128I<>, K> &state,
   168         const std::array<
M128I<>, Rounds + 1> &rk)
 const   170         enc_last<0>(state, rk, std::true_type());
   173     template <std::
size_t, std::
size_t K>
   174     void enc_last(std::array<
M128I<>, K> &,
   175         const std::array<
M128I<>, Rounds + 1> &, std::false_type)
 const   179     template <std::
size_t B, std::
size_t K>
   180     void enc_last(std::array<
M128I<>, K> &state,
   181         const std::array<
M128I<>, Rounds + 1> &rk, std::true_type)
 const   183         std::get<B>(state) = _mm_aesenclast_si128(
   184             std::get<B>(state).value(), std::get<Rounds>(rk).value());
   185         enc_last<B + 1>(state, rk, std::integral_constant<bool, B + 1 < K>());
   191 template <
typename ResultType, 
typename KeySeqType, std::size_t Rounds,
   198 #endif // VSMC_RNG_AES_NI_HPP 
void increment(std::array< T, K > &ctr)
Increment a counter by one. 
 
Counter based RNG engine. 
 
void operator()(ctr_type &ctr, const key_type &key, std::size_t n, std::array< ResultType, size()> *buffer) const 
 
static constexpr std::size_t size()
 
std::array< ResultType, M128I< ResultType >::size()> ctr_type
 
void reset(const key_type &key)
 
typename KeySeqType::key_type key_type
 
static constexpr std::size_t size()
 
void operator()(ctr_type &ctr, const key_type &key, std::array< ResultType, size()> &buffer) const 
 
RNG generator using AES-NI instructions.