32 #ifndef MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_HPP 33 #define MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_HPP 40 #define MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(N) \ 42 constexpr T w0 = Constants::weyl::value[0] * static_cast<T>(N - 1); \ 43 constexpr T w1 = Constants::weyl::value[1] * static_cast<T>(N - 1); \ 44 constexpr T m2 = Constants::multiplier::value[0]; \ 45 constexpr T m0 = Constants::multiplier::value[1]; \ 49 s1 = PhiloxHiLo<T>::eval(s2, m2, t2); \ 50 s3 = PhiloxHiLo<T>::eval(s0, m0, t0); \ 51 s0 = (k0 + w0) ^ (t1 ^ t2); \ 52 s2 = (k1 + w1) ^ (t3 ^ t0); \ 55 #define MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_ROUND_10 \ 56 T k0 = std::get<0>(key); \ 57 T k1 = std::get<1>(key); \ 58 T s0 = std::get<0>(buf.s); \ 59 T s1 = std::get<1>(buf.s); \ 60 T s2 = std::get<2>(buf.s); \ 61 T s3 = std::get<3>(buf.s); \ 66 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0x1) \ 67 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0x2) \ 68 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0x3) \ 69 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0x4) \ 70 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0x5) \ 71 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0x6) \ 72 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0x7) \ 73 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0x8) \ 74 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0x9) \ 75 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_RBOX(0xA) \ 76 std::get<0>(buf.s) = s0; \ 77 std::get<1>(buf.s) = s1; \ 78 std::get<2>(buf.s) = s2; \ 79 std::get<3>(buf.s) = s3; 85 template <
typename T,
typename Constants>
88 static constexpr std::size_t K = 4;
89 static constexpr std::size_t Rounds = 10;
93 const void *plain,
void *cipher,
const std::array<T, K / 2> &key)
97 std::array<char, sizeof(T) * K> r;
100 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
101 union_le<char>(buf.s);
104 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
107 template <
typename ResultType>
109 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K / 2> &key)
114 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
119 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 120 union_le<typename Counter<T, K>::value_type>(buf.s);
123 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 126 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
129 template <
typename ResultType>
131 const std::array<T, K / 2> &key)
133 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
135 for (std::size_t i = 0; i != n; ++i, r += R) {
141 template <
typename T,
typename Constants>
144 static_assert(std::numeric_limits<T>::digits == 64,
145 "**Philox4x64GeneratorGenericImpl** used with T other than a 64-bit " 146 "unsigned integers");
148 static constexpr std::size_t K = 4;
149 static constexpr std::size_t Rounds = 10;
153 const void *plain,
void *cipher,
const std::array<T, K / 2> &key)
157 std::array<char, sizeof(T) * K> r;
160 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
161 union_le<char>(buf.s);
164 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
167 template <
typename ResultType>
169 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K / 2> &key)
174 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
179 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 180 union_le<typename Counter<T, K>::value_type>(buf.s);
183 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 186 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
189 #if MCKL_USE_ASM_LIBRARY && MCKL_USE_BMI2 190 template <
typename ResultType>
192 const std::array<T, K / 2> &key)
194 constexpr T w0 = Constants::weyl::value[0];
195 constexpr T w1 = Constants::weyl::value[1];
196 constexpr T m0 = Constants::multiplier::value[0];
197 constexpr T m1 = Constants::multiplier::value[1];
199 const T mwk[6] = {m0, m1, w0, w1, std::get<0>(key), std::get<1>(key)};
202 #else // MCKL_USE_ASM_LIBRARY && MCKL_USE_BMI2 203 template <
typename ResultType>
205 const std::array<T, K / 2> &key)
207 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
209 for (std::size_t i = 0; i != n; ++i, r += R)
212 #endif // MCKL_USE_ASM_LIBRARY && MCKL_USE_BMI2 219 #endif // MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_HPP
static void eval(Counter< T, K > &ctr, std::size_t n, ResultType *r, const std::array< T, K/2 > &key)
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/2 > &key)
void mckl_philox4x64_bmi2_kernel(uint64_t *, size_t, void *, const void *)
void increment(std::array< T, K > &ctr, std::integral_constant< T, NSkip >)
Increment a counter by given steps.
static void eval(const void *plain, void *cipher, const std::array< T, K/2 > &key)
#define MCKL_ALIGNMENT
The default alignment for scalar type.
static void eval(Counter< T, K > &ctr, ResultType *r, const std::array< T, K/2 > &key)
static void eval(Counter< T, K > &ctr, std::size_t n, ResultType *r, const std::array< T, K/2 > &key)
#define MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_4X_ROUND_10
static void eval(Counter< T, K > &ctr, ResultType *r, const std::array< T, K/2 > &key)