32 #ifndef MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_HPP 33 #define MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_HPP 40 #define MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(N) \ 42 constexpr T w0 = Constants::weyl::value[0] * static_cast<T>(N - 1); \ 43 constexpr T m0 = Constants::multiplier::value[0]; \ 46 s1 = PhiloxHiLo<T>::eval(s0, m0, t0); \ 47 s0 = (k0 + w0) ^ (t1 ^ t0); \ 50 #define MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_ROUND_10 \ 51 T k0 = std::get<0>(key); \ 52 T s0 = std::get<0>(buf.s); \ 53 T s1 = std::get<1>(buf.s); \ 56 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0x1) \ 57 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0x2) \ 58 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0x3) \ 59 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0x4) \ 60 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0x5) \ 61 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0x6) \ 62 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0x7) \ 63 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0x8) \ 64 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0x9) \ 65 MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_RBOX(0xA) \ 66 std::get<0>(buf.s) = s0; \ 67 std::get<1>(buf.s) = s1; 73 template <
typename T,
typename Constants>
76 static constexpr std::size_t K = 2;
77 static constexpr std::size_t Rounds = 10;
81 const void *plain,
void *cipher,
const std::array<T, K / 2> &key)
85 std::array<char, sizeof(T) * K> r;
88 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
89 union_le<char>(buf.s);
92 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
95 template <
typename ResultType>
97 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K / 2> &key)
102 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
107 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 108 union_le<typename Counter<T, K>::value_type>(buf.s);
111 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 114 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
117 template <
typename ResultType>
119 const std::array<T, K / 2> &key)
121 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
123 for (std::size_t i = 0; i != n; ++i, r += R) {
129 template <
typename T,
typename Constants>
132 static_assert(std::numeric_limits<T>::digits == 64,
133 "**Philox2x64GeneratorGenericImpl** used with T other than a 64-bit " 134 "unsigned integers");
136 static constexpr std::size_t K = 2;
137 static constexpr std::size_t Rounds = 10;
141 const void *plain,
void *cipher,
const std::array<T, K / 2> &key)
145 std::array<char, sizeof(T) * K> r;
148 std::memcpy(buf.s.data(), plain,
sizeof(T) * K);
149 union_le<char>(buf.s);
152 std::memcpy(cipher, buf.s.data(),
sizeof(T) * K);
155 template <
typename ResultType>
157 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K / 2> &key)
162 std::array<ResultType,
sizeof(T) * K /
sizeof(ResultType)> r;
167 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 168 union_le<typename Counter<T, K>::value_type>(buf.s);
171 #if MCKL_REQUIRE_ENDIANNESS_NEUTURAL 174 std::memcpy(r, buf.r.data(),
sizeof(T) * K);
177 #if MCKL_USE_ASM_LIBRARY && MCKL_USE_BMI2 178 template <
typename ResultType>
180 const std::array<T, K / 2> &key)
182 constexpr T w0 = Constants::weyl::value[0];
183 constexpr T m0 = Constants::multiplier::value[0];
185 const T mwk[3] = {m0, w0, std::get<0>(key)};
188 #else // MCKL_USE_ASM_LIBRARY && MCKL_USE_BMI2 189 template <
typename ResultType>
191 const std::array<T, K / 2> &key)
193 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
195 for (std::size_t i = 0; i != n; ++i, r += R)
198 #endif // MCKL_USE_ASM_LIBRARY && MCKL_USE_BMI2 205 #endif // MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_HPP
typename internal::CounterImpl< T, K >::type Counter
A counter type with the same width as std::array<T, K> but with possibly fewer elements.
void mckl_philox2x64_bmi2_kernel(uint64_t *, size_t, void *, const void *)
static void eval(const void *plain, void *cipher, 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)
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(Counter< T, K > &ctr, std::size_t n, ResultType *r, const std::array< T, K/2 > &key)
static void eval(Counter< T, K > &ctr, ResultType *r, const std::array< T, K/2 > &key)
static void eval(const void *plain, void *cipher, const std::array< T, K/2 > &key)
#define MCKL_RANDOM_INTERNAL_PHILOX_GENERIC_2X_ROUND_10
static void eval(Counter< T, K > &ctr, ResultType *r, const std::array< T, K/2 > &key)