32 #ifndef MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_HPP 33 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_HPP 40 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_KBOX(N) \ 41 s0 += ThreefryKBox<T, K, N>::template key<0x0>(par); \ 42 s1 += ThreefryKBox<T, K, N>::template key<0x1>(par); \ 43 s2 += ThreefryKBox<T, K, N>::template key<0x2>(par); \ 44 s3 += ThreefryKBox<T, K, N>::template key<0x3>(par); \ 45 s4 += ThreefryKBox<T, K, N>::template key<0x4>(par); \ 46 s5 += ThreefryKBox<T, K, N>::template key<0x5>(par); \ 47 s6 += ThreefryKBox<T, K, N>::template key<0x6>(par); \ 48 s7 += ThreefryKBox<T, K, N>::template key<0x7>(par); \ 49 s8 += ThreefryKBox<T, K, N>::template key<0x8>(par); \ 50 s9 += ThreefryKBox<T, K, N>::template key<0x9>(par); \ 51 sA += ThreefryKBox<T, K, N>::template key<0xA>(par); \ 52 sB += ThreefryKBox<T, K, N>::template key<0xB>(par); \ 53 sC += ThreefryKBox<T, K, N>::template key<0xC>(par); \ 54 sD += ThreefryKBox<T, K, N>::template key<0xD>(par); \ 55 sE += ThreefryKBox<T, K, N>::template key<0xE>(par); \ 56 sF += ThreefryKBox<T, K, N>::template key<0xF>(par); 58 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N) \ 60 constexpr int L0 = Constants::rotate::value[0][(N - 1) % 8]; \ 61 constexpr int L1 = Constants::rotate::value[1][(N - 1) % 8]; \ 62 constexpr int L2 = Constants::rotate::value[2][(N - 1) % 8]; \ 63 constexpr int L3 = Constants::rotate::value[3][(N - 1) % 8]; \ 64 constexpr int L4 = Constants::rotate::value[4][(N - 1) % 8]; \ 65 constexpr int L5 = Constants::rotate::value[5][(N - 1) % 8]; \ 66 constexpr int L6 = Constants::rotate::value[6][(N - 1) % 8]; \ 67 constexpr int L7 = Constants::rotate::value[7][(N - 1) % 8]; \ 68 constexpr int R0 = 64 - L0; \ 69 constexpr int R1 = 64 - L1; \ 70 constexpr int R2 = 64 - L2; \ 71 constexpr int R3 = 64 - L3; \ 72 constexpr int R4 = 64 - L4; \ 73 constexpr int R5 = 64 - L5; \ 74 constexpr int R6 = 64 - L6; \ 75 constexpr int R7 = 64 - L7; \ 84 t1 = (s1 << L0) | (s1 >> R0); \ 85 t3 = (s3 << L1) | (s3 >> R1); \ 86 t5 = (s5 << L2) | (s5 >> R2); \ 87 t7 = (s7 << L3) | (s7 >> R3); \ 88 t9 = (s9 << L4) | (s9 >> R4); \ 89 tB = (sB << L5) | (sB >> R5); \ 90 tD = (sD << L6) | (sD >> R6); \ 91 tF = (sF << L7) | (sF >> R7); \ 110 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_4(N) \ 111 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 1); \ 112 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 2); \ 113 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 3); \ 114 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 4); \ 115 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_KBOX(N * 8 + 4); 117 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(N) \ 118 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 1); \ 119 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 2); \ 120 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 3); \ 121 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 4); \ 122 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_KBOX(N * 8 + 4); \ 123 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 5); \ 124 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 6); \ 125 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 7); \ 126 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_RBOX(N * 8 + 8); \ 127 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_KBOX(N * 8 + 8); 129 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_ROUND_20 \ 130 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_KBOX(0) \ 131 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(0) \ 132 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(1) \ 133 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_4(2) 135 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_ROUND_80 \ 136 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_KBOX(0) \ 137 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(0) \ 138 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(1) \ 139 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(2) \ 140 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(3) \ 141 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(4) \ 142 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(5) \ 143 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(6) \ 144 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(7) \ 145 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(8) \ 146 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_CYCLE_8(9) 148 #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_ROUND(L) \ 149 T s0 = std::get<0x0>(buf.s); \ 150 T s1 = std::get<0x1>(buf.s); \ 151 T s2 = std::get<0x2>(buf.s); \ 152 T s3 = std::get<0x3>(buf.s); \ 153 T s4 = std::get<0x4>(buf.s); \ 154 T s5 = std::get<0x5>(buf.s); \ 155 T s6 = std::get<0x6>(buf.s); \ 156 T s7 = std::get<0x7>(buf.s); \ 157 T s8 = std::get<0x8>(buf.s); \ 158 T s9 = std::get<0x9>(buf.s); \ 159 T sA = std::get<0xA>(buf.s); \ 160 T sB = std::get<0xB>(buf.s); \ 161 T sC = std::get<0xC>(buf.s); \ 162 T sD = std::get<0xD>(buf.s); \ 163 T sE = std::get<0xE>(buf.s); \ 164 T sF = std::get<0xF>(buf.s); \ 181 MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_ROUND_##L; \ 182 std::get<0x0>(buf.s) = s0; \ 183 std::get<0x1>(buf.s) = s1; \ 184 std::get<0x2>(buf.s) = s2; \ 185 std::get<0x3>(buf.s) = s3; \ 186 std::get<0x4>(buf.s) = s4; \ 187 std::get<0x5>(buf.s) = s5; \ 188 std::get<0x6>(buf.s) = s6; \ 189 std::get<0x7>(buf.s) = s7; \ 190 std::get<0x8>(buf.s) = s8; \ 191 std::get<0x9>(buf.s) = s9; \ 192 std::get<0xA>(buf.s) = sA; \ 193 std::get<0xB>(buf.s) = sB; \ 194 std::get<0xC>(buf.s) = sC; \ 195 std::get<0xD>(buf.s) = sD; \ 196 std::get<0xE>(buf.s) = sE; \ 197 std::get<0xF>(buf.s) = sF; 203 template <
typename T>
206 static_assert(std::numeric_limits<T>::digits == 64,
207 "**Threefry16x64GeneratorGenericImpl** used with T other than a " 208 "64-bit unsigned integers");
210 static constexpr std::size_t K = 16;
211 static constexpr std::size_t Rounds = 20;
216 const void *plain,
void *cipher,
const std::array<T, K + 4> &par)
220 std::array<char, sizeof(T) * K> r;
223 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
224 union_le<char>(buf.s);
227 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
230 template <
typename ResultType>
232 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K + 4> &par)
237 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
242 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 243 union_le<typename Counter<T, K>::value_type>(buf.s);
246 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 249 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
252 template <
typename ResultType>
254 const std::array<T, K + 4> &par)
256 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
258 for (std::size_t i = 0; i != n; ++i, r += R) {
264 template <
typename T>
267 static_assert(std::numeric_limits<T>::digits == 64,
268 "**Threefish1024GeneratorGenericImpl** used with T other than a " 269 "64-bit unsigned integers");
271 static constexpr std::size_t K = 16;
272 static constexpr std::size_t Rounds = 80;
277 const void *plain,
void *cipher,
const std::array<T, K + 4> &par)
281 std::array<char, sizeof(T) * K> r;
284 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
285 union_le<char>(buf.s);
288 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
291 template <
typename ResultType>
293 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K + 4> &par)
298 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
303 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 304 union_le<typename Counter<T, K>::value_type>(buf.s);
307 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 310 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
313 template <
typename ResultType>
315 const std::array<T, K + 4> &par)
317 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
319 for (std::size_t i = 0; i != n; ++i, r += R) {
329 #endif // MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_HPP #define MCKL_RANDOM_INTERNAL_THREEFRY_GENERIC_16X64_ROUND(L)
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(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)
Default Threefry constants.
static void eval(const void *plain, void *cipher, 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)
static void eval(Counter< T, K > &ctr, ResultType *r, 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)
#define MCKL_ALIGNMENT
The default alignment for scalar type.