32 #ifndef MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_HPP 33 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_HPP 40 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_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); 46 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N) \ 48 constexpr int L0 = Constants::rotate::value[0][(N - 1) % 8]; \ 49 constexpr int L1 = Constants::rotate::value[1][(N - 1) % 8]; \ 50 constexpr int R0 = 64 - L0; \ 51 constexpr int R1 = 64 - L1; \ 54 t1 = (s1 << L0) | (s1 >> R0); \ 55 t3 = (s3 << L1) | (s3 >> R1); \ 60 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_4(N) \ 61 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 1); \ 62 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 2); \ 63 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 3); \ 64 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 4); \ 65 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_KBOX(N * 8 + 4); 67 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(N) \ 68 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 1); \ 69 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 2); \ 70 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 3); \ 71 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 4); \ 72 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_KBOX(N * 8 + 4); \ 73 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 5); \ 74 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 6); \ 75 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 7); \ 76 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_RBOX(N * 8 + 8); \ 77 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_KBOX(N * 8 + 8); 79 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_ROUND_20 \ 80 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_KBOX(0) \ 81 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(0) \ 82 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(1) \ 83 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_4(2) 85 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_ROUND_72 \ 86 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_KBOX(0) \ 87 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(0) \ 88 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(1) \ 89 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(2) \ 90 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(3) \ 91 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(4) \ 92 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(5) \ 93 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(6) \ 94 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(7) \ 95 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_CYCLE_8(8) 97 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_ROUND(L) \ 98 T s0 = std::get<0>(buf.s); \ 99 T s1 = std::get<1>(buf.s); \ 100 T s2 = std::get<2>(buf.s); \ 101 T s3 = std::get<3>(buf.s); \ 104 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_ROUND_##L; \ 105 std::get<0>(buf.s) = s0; \ 106 std::get<1>(buf.s) = s1; \ 107 std::get<2>(buf.s) = s2; \ 108 std::get<3>(buf.s) = s3; 114 template <
typename T>
117 static_assert(std::numeric_limits<T>::digits == 64,
118 "**Threefry4x64GeneratorGenericImpl** used with T other than a " 119 "64-bit unsigned integers");
121 static constexpr std::size_t K = 4;
122 static constexpr std::size_t Rounds = 20;
127 const void *plain,
void *cipher,
const std::array<T, K + 4> &par)
131 std::array<char, sizeof(T) * K> r;
134 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
135 union_le<char>(buf.s);
138 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
141 template <
typename ResultType>
143 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K + 4> &par)
148 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
153 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 154 union_le<typename Counter<T, K>::value_type>(buf.s);
157 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 160 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
163 template <
typename ResultType>
165 const std::array<T, K + 4> &par)
167 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
169 for (std::size_t i = 0; i != n; ++i, r += R) {
175 template <
typename T>
178 static_assert(std::numeric_limits<T>::digits == 64,
179 "**Threefish256GeneratorGenericImpl** used with T other than a " 180 "64-bit unsigned integers");
182 static constexpr std::size_t K = 4;
183 static constexpr std::size_t Rounds = 72;
188 const void *plain,
void *cipher,
const std::array<T, K + 4> &par)
192 std::array<char, sizeof(T) * K> r;
195 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
196 union_le<char>(buf.s);
199 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
202 template <
typename ResultType>
204 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K + 4> &par)
209 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
214 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 215 union_le<typename Counter<T, K>::value_type>(buf.s);
218 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 221 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
224 template <
typename ResultType>
226 const std::array<T, K + 4> &par)
228 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
230 for (std::size_t i = 0; i != n; ++i, r += R) {
240 #endif // MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_HPP static void eval(Counter< T, K > &ctr, ResultType *r, const std::array< T, K+4 > &par)
static void eval(Counter< T, K > &ctr, ResultType *r, 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)
#define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X64_ROUND(L)
Default Threefry constants.
void increment(std::array< T, K > &ctr, std::integral_constant< T, NSkip >)
Increment a counter by given steps.
#define MCKL_ALIGNMENT
The default alignment for scalar type.
static void eval(const void *plain, void *cipher, const std::array< T, K+4 > &par)
static void eval(Counter< T, K > &ctr, std::size_t n, ResultType *r, const std::array< T, K+4 > &par)