32 #ifndef MCKL_RANDOM_INTERNAL_THREEFRY_COMMON_HPP 33 #define MCKL_RANDOM_INTERNAL_THREEFRY_COMMON_HPP 42 template <
typename T, std::
size_t K,
typename Constants>
46 static void eval(std::array<T, K> &s)
49 eval<0>(s, tmp, std::integral_constant<bool, 0 < K>());
50 std::memcpy(s.data(), tmp.data(),
sizeof(T) * K);
56 eval<0>(s, tmp, std::integral_constant<bool, 0 < K>());
57 std::memcpy(s, tmp.data(),
sizeof(T) * K);
61 template <std::
size_t>
63 const std::array<T, K> &, std::array<T, K> &, std::false_type)
67 template <std::
size_t I>
69 const std::array<T, K> &s, std::array<T, K> &tmp, std::true_type)
71 constexpr std::size_t P = Constants::permute::value[I];
73 std::get<I>(tmp) = std::get<P>(s);
74 eval<I + 1>(s, tmp, std::integral_constant<bool, I + 1 < K>());
77 template <std::
size_t>
78 static void eval(
const T *, std::array<T, K> &, std::false_type)
82 template <std::
size_t I>
83 static void eval(
const T *s, std::array<T, K> &tmp, std::true_type)
85 constexpr std::size_t P = Constants::permute::value[I];
87 std::get<I>(tmp) = s[P];
88 eval<I + 1>(s, tmp, std::integral_constant<bool, I + 1 < K>());
92 template <
typename T,
typename U>
96 static void eval(std::array<T, 2> &) {}
101 template <
typename T,
typename U>
105 static void eval(std::array<T, 4> &s)
107 T s1 = std::get<1>(s);
108 std::get<1>(s) = std::get<3>(s);
120 template <
typename T,
typename U>
124 static void eval(std::array<T, 8> &s)
126 T s0 = std::get<0>(s);
127 T s3 = std::get<3>(s);
129 std::get<0>(s) = std::get<2>(s);
130 std::get<3>(s) = std::get<7>(s);
132 std::get<2>(s) = std::get<4>(s);
133 std::get<4>(s) = std::get<6>(s);
155 template <
typename T,
typename U>
159 static void eval(std::array<T, 16> &s)
161 T s1 = std::get<0x1>(s);
162 T s3 = std::get<0x3>(s);
163 T s4 = std::get<0x4>(s);
164 T s8 = std::get<0x8>(s);
166 std::get<0x1>(s) = std::get<0x9>(s);
167 std::get<0x3>(s) = std::get<0xD>(s);
168 std::get<0x4>(s) = std::get<0x6>(s);
169 std::get<0x8>(s) = std::get<0xA>(s);
171 std::get<0x9>(s) = std::get<0x7>(s);
172 std::get<0xD>(s) = std::get<0x5>(s);
173 std::get<0xA>(s) = std::get<0xC>(s);
175 std::get<0x7>(s) = std::get<0xF>(s);
176 std::get<0x5>(s) = std::get<0xB>(s);
177 std::get<0xC>(s) = std::get<0xE>(s);
179 std::get<0xF>(s) = s1;
180 std::get<0xB>(s) = s3;
181 std::get<0x6>(s) = s4;
182 std::get<0xE>(s) = s8;
212 template <
typename T, std::
size_t K, std::
size_t N>
216 template <std::
size_t I>
217 static T
key(
const std::array<T, K + 4> &par)
219 constexpr std::size_t
S = N / 4;
221 const T p = (I + 1 == K ? S : 0) +
222 (I + 2 == K ? std::get<K + 1 + (S + 1) % 3>(par) : 0) +
223 (I + 3 == K ? std::get<K + 1 + (S + 0) % 3>(par) : 0);
225 return std::get<(S + I) % (K + 1)>(par) + p;
228 static void eval(std::array<T, K> &s,
const std::array<T, K + 4> &par)
230 eval<0>(s, par, std::integral_constant<bool, 0 < K>());
234 template <std::
size_t>
236 std::array<T, K> &,
const std::array<T, K + 4> &, std::false_type)
240 template <std::
size_t I>
242 std::array<T, K> &s,
const std::array<T, K + 4> &par, std::true_type)
244 std::get<I>(s) += key<I>(par);
245 eval<I + 1>(s, par, std::integral_constant<bool, I + 1 < K>());
249 template <
typename T, std::
size_t K, std::
size_t N,
typename Constants>
253 static void eval(std::array<T, K> &s)
255 sbox<0>(s, std::integral_constant<bool, 0 < K / 2>());
260 template <std::
size_t>
261 static void sbox(std::array<T, K> &, std::false_type)
265 template <std::
size_t I>
266 static void sbox(std::array<T, K> &s, std::true_type)
268 constexpr std::size_t I0 = I * 2;
269 constexpr std::size_t I1 = I * 2 + 1;
270 constexpr
int L = Constants::rotate::value[I][(N - 1) % 8];
271 constexpr
int R = std::numeric_limits<T>::digits - L;
273 T x = std::get<I1>(s);
274 std::get<I0>(s) += x;
275 x = (x << L) | (x >> R);
276 x ^= std::get<I0>(s);
278 sbox<I + 1>(s, std::integral_constant<bool, I + 1 < K / 2>());
286 #endif // MCKL_RANDOM_INTERNAL_THREEFRY_COMMON_HPP
static T key(const std::array< T, K+4 > &par)
static void eval(std::array< T, 8 > &s)
static void eval(std::array< T, K > &s)
static void eval(std::array< T, K > &s)
Default Threefry constants.
static void eval(std::array< T, 16 > &s)
static void eval(std::array< T, 2 > &)
static void eval(std::array< T, K > &s, const std::array< T, K+4 > &par)
static void eval(std::array< T, 4 > &s)