32 #ifndef MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_HPP 33 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_HPP 40 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_KBOX(N) \ 41 s0 += ThreefryKBox<T, K, N>::template key<0>(par); \ 42 s1 += ThreefryKBox<T, K, N>::template key<1>(par); \ 43 s2 += ThreefryKBox<T, K, N>::template key<2>(par); \ 44 s3 += ThreefryKBox<T, K, N>::template key<3>(par); \ 45 s4 += ThreefryKBox<T, K, N>::template key<4>(par); \ 46 s5 += ThreefryKBox<T, K, N>::template key<5>(par); \ 47 s6 += ThreefryKBox<T, K, N>::template key<6>(par); \ 48 s7 += ThreefryKBox<T, K, N>::template key<7>(par); 50 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N) \ 52 constexpr int L0 = Constants::rotate::value[0][(N - 1) % 8]; \ 53 constexpr int L1 = Constants::rotate::value[1][(N - 1) % 8]; \ 54 constexpr int L2 = Constants::rotate::value[2][(N - 1) % 8]; \ 55 constexpr int L3 = Constants::rotate::value[3][(N - 1) % 8]; \ 56 constexpr int R0 = 64 - L0; \ 57 constexpr int R1 = 64 - L1; \ 58 constexpr int R2 = 64 - L2; \ 59 constexpr int R3 = 64 - L3; \ 64 t1 = (s1 << L0) | (s1 >> R0); \ 65 t3 = (s3 << L1) | (s3 >> R1); \ 66 t5 = (s5 << L2) | (s5 >> R2); \ 67 t7 = (s7 << L3) | (s7 >> R3); \ 78 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_4(N) \ 79 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 1); \ 80 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 2); \ 81 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 3); \ 82 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 4); \ 83 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_KBOX(N * 8 + 4); 85 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(N) \ 86 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 1); \ 87 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 2); \ 88 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 3); \ 89 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 4); \ 90 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_KBOX(N * 8 + 4); \ 91 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 5); \ 92 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 6); \ 93 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 7); \ 94 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_RBOX(N * 8 + 8); \ 95 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_KBOX(N * 8 + 8); 97 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_ROUND_20 \ 98 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_KBOX(0) \ 99 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(0) \ 100 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(1) \ 101 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_4(2) 103 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_ROUND_72 \ 104 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_KBOX(0) \ 105 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(0) \ 106 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(1) \ 107 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(2) \ 108 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(3) \ 109 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(4) \ 110 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(5) \ 111 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(6) \ 112 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(7) \ 113 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_CYCLE_8(8) 115 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_ROUND(L) \ 116 T s0 = std::get<0>(buf.s); \ 117 T s1 = std::get<1>(buf.s); \ 118 T s2 = std::get<2>(buf.s); \ 119 T s3 = std::get<3>(buf.s); \ 120 T s4 = std::get<4>(buf.s); \ 121 T s5 = std::get<5>(buf.s); \ 122 T s6 = std::get<6>(buf.s); \ 123 T s7 = std::get<7>(buf.s); \ 132 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_ROUND_##L; \ 133 std::get<0>(buf.s) = s0; \ 134 std::get<1>(buf.s) = s1; \ 135 std::get<2>(buf.s) = s2; \ 136 std::get<3>(buf.s) = s3; \ 137 std::get<4>(buf.s) = s4; \ 138 std::get<5>(buf.s) = s5; \ 139 std::get<6>(buf.s) = s6; \ 140 std::get<7>(buf.s) = s7; 146 template <
typename T>
149 static_assert(std::numeric_limits<T>::digits == 64,
150 "**Threefry8x64GeneratorGenericImpl** used with T other than a " 151 "64-bit unsigned integers");
153 static constexpr std::size_t K = 8;
154 static constexpr std::size_t Rounds = 20;
159 const void *plain,
void *cipher,
const std::array<T, K + 4> &par)
163 std::array<char, sizeof(T) * K> r;
166 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
167 union_le<char>(buf.s);
170 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
173 template <
typename ResultType>
175 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K + 4> &par)
180 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
185 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 186 union_le<typename Counter<T, K>::value_type>(buf.s);
189 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 192 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
195 template <
typename ResultType>
197 const std::array<T, K + 4> &par)
199 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
201 for (std::size_t i = 0; i != n; ++i, r += R) {
207 template <
typename T>
210 static_assert(std::numeric_limits<T>::digits == 64,
211 "**Threefish512GeneratorGenericImpl** used with T other than a " 212 "64-bit unsigned integers");
214 static constexpr std::size_t K = 8;
215 static constexpr std::size_t Rounds = 72;
220 const void *plain,
void *cipher,
const std::array<T, K + 4> &par)
224 std::array<char, sizeof(T) * K> r;
227 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
228 union_le<char>(buf.s);
231 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
234 template <
typename ResultType>
236 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K + 4> &par)
241 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
246 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 247 union_le<typename Counter<T, K>::value_type>(buf.s);
250 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 253 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
256 template <
typename ResultType>
258 const std::array<T, K + 4> &par)
260 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
262 for (std::size_t i = 0; i != n; ++i, r += R) {
272 #endif // MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_HPP static void eval(Counter< T, K > &ctr, ResultType *r, const std::array< T, K+4 > &par)
#define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_8X64_ROUND(L)
static void eval(const void *plain, void *cipher, const std::array< T, K+4 > &par)
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(Counter< T, K > &ctr, std::size_t n, ResultType *r, const std::array< T, K+4 > &par)
static void eval(const void *plain, void *cipher, const std::array< T, K+4 > &par)
Default Threefry constants.
static void eval(Counter< T, K > &ctr, std::size_t n, ResultType *r, const std::array< T, K+4 > &par)
void increment(std::array< T, K > &ctr, std::integral_constant< T, NSkip >)
Increment a counter by given steps.
static void eval(Counter< T, K > &ctr, ResultType *r, const std::array< T, K+4 > &par)
#define MCKL_ALIGNMENT
The default alignment for scalar type.