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.