32 #ifndef MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_HPP 33 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_HPP 40 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_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_4X32_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 = 32 - L0; \ 51 constexpr int R1 = 32 - L1; \ 54 t1 = (s1 << L0) | (s1 >> R0); \ 55 t3 = (s3 << L1) | (s3 >> R1); \ 60 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_CYCLE_4(N) \ 61 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 1); \ 62 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 2); \ 63 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 3); \ 64 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 4); \ 65 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_KBOX(N * 8 + 4); 67 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_CYCLE_8(N) \ 68 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 1); \ 69 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 2); \ 70 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 3); \ 71 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 4); \ 72 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_KBOX(N * 8 + 4); \ 73 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 5); \ 74 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 6); \ 75 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 7); \ 76 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_RBOX(N * 8 + 8); \ 77 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_KBOX(N * 8 + 8); 79 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_ROUND_20 \ 80 T s0 = std::get<0>(buf.s); \ 81 T s1 = std::get<1>(buf.s); \ 82 T s2 = std::get<2>(buf.s); \ 83 T s3 = std::get<3>(buf.s); \ 86 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_KBOX(0) \ 87 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_CYCLE_8(0) \ 88 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_CYCLE_8(1) \ 89 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_CYCLE_4(2) \ 90 std::get<0>(buf.s) = s0; \ 91 std::get<1>(buf.s) = s1; \ 92 std::get<2>(buf.s) = s2; \ 93 std::get<3>(buf.s) = s3; 102 static_assert(std::numeric_limits<T>::digits == 32,
103 "**Threefry4x32GeneratorGenericImpl** used with T other than a " 104 "32-bit unsigned integers");
106 static constexpr std::size_t K = 4;
107 static constexpr std::size_t Rounds = 20;
112 const void *plain,
void *cipher,
const std::array<T, K + 4> &par)
116 std::array<char, sizeof(T) * K> r;
119 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
120 union_le<char>(buf.s);
123 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
126 template <
typename ResultType>
128 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K + 4> &par)
133 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
138 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 139 union_le<typename Counter<T, K>::value_type>(buf.s);
142 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 145 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
148 template <
typename ResultType>
150 const std::array<T, K + 4> &par)
152 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
154 for (std::size_t i = 0; i != n; ++i, r += R) {
164 #endif // MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_HPP static void eval(Counter< T, K > &ctr, std::size_t n, 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)
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.
#define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_4X32_ROUND_20
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.