create
This commit is contained in:
95
Pods/abseil/absl/random/internal/distribution_caller.h
generated
Normal file
95
Pods/abseil/absl/random/internal/distribution_caller.h
generated
Normal file
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
|
||||
#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/fast_type_id.h"
|
||||
#include "absl/utility/utility.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// DistributionCaller provides an opportunity to overload the general
|
||||
// mechanism for calling a distribution, allowing for mock-RNG classes
|
||||
// to intercept such calls.
|
||||
template <typename URBG>
|
||||
struct DistributionCaller {
|
||||
static_assert(!std::is_pointer<URBG>::value,
|
||||
"You must pass a reference, not a pointer.");
|
||||
// SFINAE to detect whether the URBG type includes a member matching
|
||||
// bool InvokeMock(base_internal::FastTypeIdType, void*, void*).
|
||||
//
|
||||
// These live inside BitGenRef so that they have friend access
|
||||
// to MockingBitGen. (see similar methods in DistributionCaller).
|
||||
template <template <class...> class Trait, class AlwaysVoid, class... Args>
|
||||
struct detector : std::false_type {};
|
||||
template <template <class...> class Trait, class... Args>
|
||||
struct detector<Trait, absl::void_t<Trait<Args...>>, Args...>
|
||||
: std::true_type {};
|
||||
|
||||
template <class T>
|
||||
using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock(
|
||||
std::declval<::absl::base_internal::FastTypeIdType>(),
|
||||
std::declval<void*>(), std::declval<void*>()));
|
||||
|
||||
using HasInvokeMock = typename detector<invoke_mock_t, void, URBG>::type;
|
||||
|
||||
// Default implementation of distribution caller.
|
||||
template <typename DistrT, typename... Args>
|
||||
static typename DistrT::result_type Impl(std::false_type, URBG* urbg,
|
||||
Args&&... args) {
|
||||
DistrT dist(std::forward<Args>(args)...);
|
||||
return dist(*urbg);
|
||||
}
|
||||
|
||||
// Mock implementation of distribution caller.
|
||||
// The underlying KeyT must match the KeyT constructed by MockOverloadSet.
|
||||
template <typename DistrT, typename... Args>
|
||||
static typename DistrT::result_type Impl(std::true_type, URBG* urbg,
|
||||
Args&&... args) {
|
||||
using ResultT = typename DistrT::result_type;
|
||||
using ArgTupleT = std::tuple<absl::decay_t<Args>...>;
|
||||
using KeyT = ResultT(DistrT, ArgTupleT);
|
||||
|
||||
ArgTupleT arg_tuple(std::forward<Args>(args)...);
|
||||
ResultT result;
|
||||
if (!urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple,
|
||||
&result)) {
|
||||
auto dist = absl::make_from_tuple<DistrT>(arg_tuple);
|
||||
result = dist(*urbg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Default implementation of distribution caller.
|
||||
template <typename DistrT, typename... Args>
|
||||
static typename DistrT::result_type Call(URBG* urbg, Args&&... args) {
|
||||
return Impl<DistrT, Args...>(HasInvokeMock{}, urbg,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
|
||||
271
Pods/abseil/absl/random/internal/fast_uniform_bits.h
generated
Normal file
271
Pods/abseil/absl/random/internal/fast_uniform_bits.h
generated
Normal file
@@ -0,0 +1,271 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_
|
||||
#define ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/random/internal/traits.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
// Returns true if the input value is zero or a power of two. Useful for
|
||||
// determining if the range of output values in a URBG
|
||||
template <typename UIntType>
|
||||
constexpr bool IsPowerOfTwoOrZero(UIntType n) {
|
||||
return (n == 0) || ((n & (n - 1)) == 0);
|
||||
}
|
||||
|
||||
// Computes the length of the range of values producible by the URBG, or returns
|
||||
// zero if that would encompass the entire range of representable values in
|
||||
// URBG::result_type.
|
||||
template <typename URBG>
|
||||
constexpr typename URBG::result_type RangeSize() {
|
||||
using result_type = typename URBG::result_type;
|
||||
static_assert((URBG::max)() != (URBG::min)(), "URBG range cannot be 0.");
|
||||
return ((URBG::max)() == (std::numeric_limits<result_type>::max)() &&
|
||||
(URBG::min)() == std::numeric_limits<result_type>::lowest())
|
||||
? result_type{0}
|
||||
: ((URBG::max)() - (URBG::min)() + result_type{1});
|
||||
}
|
||||
|
||||
// Computes the floor of the log. (i.e., std::floor(std::log2(N));
|
||||
template <typename UIntType>
|
||||
constexpr UIntType IntegerLog2(UIntType n) {
|
||||
return (n <= 1) ? 0 : 1 + IntegerLog2(n >> 1);
|
||||
}
|
||||
|
||||
// Returns the number of bits of randomness returned through
|
||||
// `PowerOfTwoVariate(urbg)`.
|
||||
template <typename URBG>
|
||||
constexpr size_t NumBits() {
|
||||
return static_cast<size_t>(
|
||||
RangeSize<URBG>() == 0
|
||||
? std::numeric_limits<typename URBG::result_type>::digits
|
||||
: IntegerLog2(RangeSize<URBG>()));
|
||||
}
|
||||
|
||||
// Given a shift value `n`, constructs a mask with exactly the low `n` bits set.
|
||||
// If `n == 0`, all bits are set.
|
||||
template <typename UIntType>
|
||||
constexpr UIntType MaskFromShift(size_t n) {
|
||||
return ((n % std::numeric_limits<UIntType>::digits) == 0)
|
||||
? ~UIntType{0}
|
||||
: (UIntType{1} << n) - UIntType{1};
|
||||
}
|
||||
|
||||
// Tags used to dispatch FastUniformBits::generate to the simple or more complex
|
||||
// entropy extraction algorithm.
|
||||
struct SimplifiedLoopTag {};
|
||||
struct RejectionLoopTag {};
|
||||
|
||||
// FastUniformBits implements a fast path to acquire uniform independent bits
|
||||
// from a type which conforms to the [rand.req.urbg] concept.
|
||||
// Parameterized by:
|
||||
// `UIntType`: the result (output) type
|
||||
//
|
||||
// The std::independent_bits_engine [rand.adapt.ibits] adaptor can be
|
||||
// instantiated from an existing generator through a copy or a move. It does
|
||||
// not, however, facilitate the production of pseudorandom bits from an un-owned
|
||||
// generator that will outlive the std::independent_bits_engine instance.
|
||||
template <typename UIntType = uint64_t>
|
||||
class FastUniformBits {
|
||||
public:
|
||||
using result_type = UIntType;
|
||||
|
||||
static constexpr result_type(min)() { return 0; }
|
||||
static constexpr result_type(max)() {
|
||||
return (std::numeric_limits<result_type>::max)();
|
||||
}
|
||||
|
||||
template <typename URBG>
|
||||
result_type operator()(URBG& g); // NOLINT(runtime/references)
|
||||
|
||||
private:
|
||||
static_assert(IsUnsigned<UIntType>::value,
|
||||
"Class-template FastUniformBits<> must be parameterized using "
|
||||
"an unsigned type.");
|
||||
|
||||
// Generate() generates a random value, dispatched on whether
|
||||
// the underlying URBG must use rejection sampling to generate a value,
|
||||
// or whether a simplified loop will suffice.
|
||||
template <typename URBG>
|
||||
result_type Generate(URBG& g, // NOLINT(runtime/references)
|
||||
SimplifiedLoopTag);
|
||||
|
||||
template <typename URBG>
|
||||
result_type Generate(URBG& g, // NOLINT(runtime/references)
|
||||
RejectionLoopTag);
|
||||
};
|
||||
|
||||
template <typename UIntType>
|
||||
template <typename URBG>
|
||||
typename FastUniformBits<UIntType>::result_type
|
||||
FastUniformBits<UIntType>::operator()(URBG& g) { // NOLINT(runtime/references)
|
||||
// kRangeMask is the mask used when sampling variates from the URBG when the
|
||||
// width of the URBG range is not a power of 2.
|
||||
// Y = (2 ^ kRange) - 1
|
||||
static_assert((URBG::max)() > (URBG::min)(),
|
||||
"URBG::max and URBG::min may not be equal.");
|
||||
|
||||
using tag = absl::conditional_t<IsPowerOfTwoOrZero(RangeSize<URBG>()),
|
||||
SimplifiedLoopTag, RejectionLoopTag>;
|
||||
return Generate(g, tag{});
|
||||
}
|
||||
|
||||
template <typename UIntType>
|
||||
template <typename URBG>
|
||||
typename FastUniformBits<UIntType>::result_type
|
||||
FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
|
||||
SimplifiedLoopTag) {
|
||||
// The simplified version of FastUniformBits works only on URBGs that have
|
||||
// a range that is a power of 2. In this case we simply loop and shift without
|
||||
// attempting to balance the bits across calls.
|
||||
static_assert(IsPowerOfTwoOrZero(RangeSize<URBG>()),
|
||||
"incorrect Generate tag for URBG instance");
|
||||
|
||||
static constexpr size_t kResultBits =
|
||||
std::numeric_limits<result_type>::digits;
|
||||
static constexpr size_t kUrbgBits = NumBits<URBG>();
|
||||
static constexpr size_t kIters =
|
||||
(kResultBits / kUrbgBits) + (kResultBits % kUrbgBits != 0);
|
||||
static constexpr size_t kShift = (kIters == 1) ? 0 : kUrbgBits;
|
||||
static constexpr auto kMin = (URBG::min)();
|
||||
|
||||
result_type r = static_cast<result_type>(g() - kMin);
|
||||
for (size_t n = 1; n < kIters; ++n) {
|
||||
r = static_cast<result_type>(r << kShift) +
|
||||
static_cast<result_type>(g() - kMin);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename UIntType>
|
||||
template <typename URBG>
|
||||
typename FastUniformBits<UIntType>::result_type
|
||||
FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
|
||||
RejectionLoopTag) {
|
||||
static_assert(!IsPowerOfTwoOrZero(RangeSize<URBG>()),
|
||||
"incorrect Generate tag for URBG instance");
|
||||
using urbg_result_type = typename URBG::result_type;
|
||||
|
||||
// See [rand.adapt.ibits] for more details on the constants calculated below.
|
||||
//
|
||||
// It is preferable to use roughly the same number of bits from each generator
|
||||
// call, however this is only possible when the number of bits provided by the
|
||||
// URBG is a divisor of the number of bits in `result_type`. In all other
|
||||
// cases, the number of bits used cannot always be the same, but it can be
|
||||
// guaranteed to be off by at most 1. Thus we run two loops, one with a
|
||||
// smaller bit-width size (`kSmallWidth`) and one with a larger width size
|
||||
// (satisfying `kLargeWidth == kSmallWidth + 1`). The loops are run
|
||||
// `kSmallIters` and `kLargeIters` times respectively such
|
||||
// that
|
||||
//
|
||||
// `kResultBits == kSmallIters * kSmallBits
|
||||
// + kLargeIters * kLargeBits`
|
||||
//
|
||||
// where `kResultBits` is the total number of bits in `result_type`.
|
||||
//
|
||||
static constexpr size_t kResultBits =
|
||||
std::numeric_limits<result_type>::digits; // w
|
||||
static constexpr urbg_result_type kUrbgRange = RangeSize<URBG>(); // R
|
||||
static constexpr size_t kUrbgBits = NumBits<URBG>(); // m
|
||||
|
||||
// compute the initial estimate of the bits used.
|
||||
// [rand.adapt.ibits] 2 (c)
|
||||
static constexpr size_t kA = // ceil(w/m)
|
||||
(kResultBits / kUrbgBits) + ((kResultBits % kUrbgBits) != 0); // n'
|
||||
|
||||
static constexpr size_t kABits = kResultBits / kA; // w0'
|
||||
static constexpr urbg_result_type kARejection =
|
||||
((kUrbgRange >> kABits) << kABits); // y0'
|
||||
|
||||
// refine the selection to reduce the rejection frequency.
|
||||
static constexpr size_t kTotalIters =
|
||||
((kUrbgRange - kARejection) <= (kARejection / kA)) ? kA : (kA + 1); // n
|
||||
|
||||
// [rand.adapt.ibits] 2 (b)
|
||||
static constexpr size_t kSmallIters =
|
||||
kTotalIters - (kResultBits % kTotalIters); // n0
|
||||
static constexpr size_t kSmallBits = kResultBits / kTotalIters; // w0
|
||||
static constexpr urbg_result_type kSmallRejection =
|
||||
((kUrbgRange >> kSmallBits) << kSmallBits); // y0
|
||||
|
||||
static constexpr size_t kLargeBits = kSmallBits + 1; // w0+1
|
||||
static constexpr urbg_result_type kLargeRejection =
|
||||
((kUrbgRange >> kLargeBits) << kLargeBits); // y1
|
||||
|
||||
//
|
||||
// Because `kLargeBits == kSmallBits + 1`, it follows that
|
||||
//
|
||||
// `kResultBits == kSmallIters * kSmallBits + kLargeIters`
|
||||
//
|
||||
// and therefore
|
||||
//
|
||||
// `kLargeIters == kTotalWidth % kSmallWidth`
|
||||
//
|
||||
// Intuitively, each iteration with the large width accounts for one unit
|
||||
// of the remainder when `kTotalWidth` is divided by `kSmallWidth`. As
|
||||
// mentioned above, if the URBG width is a divisor of `kTotalWidth`, then
|
||||
// there would be no need for any large iterations (i.e., one loop would
|
||||
// suffice), and indeed, in this case, `kLargeIters` would be zero.
|
||||
static_assert(kResultBits == kSmallIters * kSmallBits +
|
||||
(kTotalIters - kSmallIters) * kLargeBits,
|
||||
"Error in looping constant calculations.");
|
||||
|
||||
// The small shift is essentially small bits, but due to the potential
|
||||
// of generating a smaller result_type from a larger urbg type, the actual
|
||||
// shift might be 0.
|
||||
static constexpr size_t kSmallShift = kSmallBits % kResultBits;
|
||||
static constexpr auto kSmallMask =
|
||||
MaskFromShift<urbg_result_type>(kSmallShift);
|
||||
static constexpr size_t kLargeShift = kLargeBits % kResultBits;
|
||||
static constexpr auto kLargeMask =
|
||||
MaskFromShift<urbg_result_type>(kLargeShift);
|
||||
|
||||
static constexpr auto kMin = (URBG::min)();
|
||||
|
||||
result_type s = 0;
|
||||
for (size_t n = 0; n < kSmallIters; ++n) {
|
||||
urbg_result_type v;
|
||||
do {
|
||||
v = g() - kMin;
|
||||
} while (v >= kSmallRejection);
|
||||
|
||||
s = (s << kSmallShift) + static_cast<result_type>(v & kSmallMask);
|
||||
}
|
||||
|
||||
for (size_t n = kSmallIters; n < kTotalIters; ++n) {
|
||||
urbg_result_type v;
|
||||
do {
|
||||
v = g() - kMin;
|
||||
} while (v >= kLargeRejection);
|
||||
|
||||
s = (s << kLargeShift) + static_cast<result_type>(v & kLargeMask);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_
|
||||
57
Pods/abseil/absl/random/internal/fastmath.h
generated
Normal file
57
Pods/abseil/absl/random/internal/fastmath.h
generated
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_FASTMATH_H_
|
||||
#define ABSL_RANDOM_INTERNAL_FASTMATH_H_
|
||||
|
||||
// This file contains fast math functions (bitwise ops as well as some others)
|
||||
// which are implementation details of various absl random number distributions.
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/numeric/bits.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// Compute log2(n) using integer operations.
|
||||
// While std::log2 is more accurate than std::log(n) / std::log(2), for
|
||||
// very large numbers--those close to std::numeric_limits<uint64_t>::max() - 2,
|
||||
// for instance--std::log2 rounds up rather than down, which introduces
|
||||
// definite skew in the results.
|
||||
inline int IntLog2Floor(uint64_t n) {
|
||||
return (n <= 1) ? 0 : (63 - countl_zero(n));
|
||||
}
|
||||
inline int IntLog2Ceil(uint64_t n) {
|
||||
return (n <= 1) ? 0 : (64 - countl_zero(n - 1));
|
||||
}
|
||||
|
||||
inline double StirlingLogFactorial(double n) {
|
||||
assert(n >= 1);
|
||||
// Using Stirling's approximation.
|
||||
constexpr double kLog2PI = 1.83787706640934548356;
|
||||
const double logn = std::log(n);
|
||||
const double ninv = 1.0 / static_cast<double>(n);
|
||||
return n * logn - n + 0.5 * (kLog2PI + logn) + (1.0 / 12.0) * ninv -
|
||||
(1.0 / 360.0) * ninv * ninv * ninv;
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_FASTMATH_H_
|
||||
144
Pods/abseil/absl/random/internal/generate_real.h
generated
Normal file
144
Pods/abseil/absl/random/internal/generate_real.h
generated
Normal file
@@ -0,0 +1,144 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
|
||||
#define ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
|
||||
|
||||
// This file contains some implementation details which are used by one or more
|
||||
// of the absl random number distributions.
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/numeric/bits.h"
|
||||
#include "absl/random/internal/fastmath.h"
|
||||
#include "absl/random/internal/traits.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// Tristate tag types controlling the output of GenerateRealFromBits.
|
||||
struct GeneratePositiveTag {};
|
||||
struct GenerateNegativeTag {};
|
||||
struct GenerateSignedTag {};
|
||||
|
||||
// GenerateRealFromBits generates a single real value from a single 64-bit
|
||||
// `bits` with template fields controlling the output.
|
||||
//
|
||||
// The `SignedTag` parameter controls whether positive, negative,
|
||||
// or either signed/unsigned may be returned.
|
||||
// When SignedTag == GeneratePositiveTag, range is U(0, 1)
|
||||
// When SignedTag == GenerateNegativeTag, range is U(-1, 0)
|
||||
// When SignedTag == GenerateSignedTag, range is U(-1, 1)
|
||||
//
|
||||
// When the `IncludeZero` parameter is true, the function may return 0 for some
|
||||
// inputs, otherwise it never returns 0.
|
||||
//
|
||||
// When a value in U(0,1) is required, use:
|
||||
// GenerateRealFromBits<double, PositiveValueT, true>;
|
||||
//
|
||||
// When a value in U(-1,1) is required, use:
|
||||
// GenerateRealFromBits<double, SignedValueT, false>;
|
||||
//
|
||||
// This generates more distinct values than the mathematical equivalent
|
||||
// `U(0, 1) * 2.0 - 1.0`.
|
||||
//
|
||||
// Scaling the result by powers of 2 (and avoiding a multiply) is also possible:
|
||||
// GenerateRealFromBits<double>(..., -1); => U(0, 0.5)
|
||||
// GenerateRealFromBits<double>(..., 1); => U(0, 2)
|
||||
//
|
||||
template <typename RealType, // Real type, either float or double.
|
||||
typename SignedTag = GeneratePositiveTag, // Whether a positive,
|
||||
// negative, or signed
|
||||
// value is generated.
|
||||
bool IncludeZero = true>
|
||||
inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) {
|
||||
using real_type = RealType;
|
||||
using uint_type = absl::conditional_t<std::is_same<real_type, float>::value,
|
||||
uint32_t, uint64_t>;
|
||||
|
||||
static_assert(
|
||||
(std::is_same<double, real_type>::value ||
|
||||
std::is_same<float, real_type>::value),
|
||||
"GenerateRealFromBits must be parameterized by either float or double.");
|
||||
|
||||
static_assert(sizeof(uint_type) == sizeof(real_type),
|
||||
"Mismatched unsigned and real types.");
|
||||
|
||||
static_assert((std::numeric_limits<real_type>::is_iec559 &&
|
||||
std::numeric_limits<real_type>::radix == 2),
|
||||
"RealType representation is not IEEE 754 binary.");
|
||||
|
||||
static_assert((std::is_same<SignedTag, GeneratePositiveTag>::value ||
|
||||
std::is_same<SignedTag, GenerateNegativeTag>::value ||
|
||||
std::is_same<SignedTag, GenerateSignedTag>::value),
|
||||
"");
|
||||
|
||||
static constexpr int kExp = std::numeric_limits<real_type>::digits - 1;
|
||||
static constexpr uint_type kMask = (static_cast<uint_type>(1) << kExp) - 1u;
|
||||
static constexpr int kUintBits = sizeof(uint_type) * 8;
|
||||
|
||||
int exp = exp_bias + int{std::numeric_limits<real_type>::max_exponent - 2};
|
||||
|
||||
// Determine the sign bit.
|
||||
// Depending on the SignedTag, this may use the left-most bit
|
||||
// or it may be a constant value.
|
||||
uint_type sign = std::is_same<SignedTag, GenerateNegativeTag>::value
|
||||
? (static_cast<uint_type>(1) << (kUintBits - 1))
|
||||
: 0;
|
||||
if (std::is_same<SignedTag, GenerateSignedTag>::value) {
|
||||
if (std::is_same<uint_type, uint64_t>::value) {
|
||||
sign = bits & uint64_t{0x8000000000000000};
|
||||
}
|
||||
if (std::is_same<uint_type, uint32_t>::value) {
|
||||
const uint64_t tmp = bits & uint64_t{0x8000000000000000};
|
||||
sign = static_cast<uint32_t>(tmp >> 32);
|
||||
}
|
||||
// adjust the bits and the exponent to account for removing
|
||||
// the leading bit.
|
||||
bits = bits & uint64_t{0x7FFFFFFFFFFFFFFF};
|
||||
exp++;
|
||||
}
|
||||
if (IncludeZero) {
|
||||
if (bits == 0u) return 0;
|
||||
}
|
||||
|
||||
// Number of leading zeros is mapped to the exponent: 2^-clz
|
||||
// bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0
|
||||
int clz = countl_zero(bits);
|
||||
bits <<= (IncludeZero ? clz : (clz & 63)); // remove 0-bits.
|
||||
exp -= clz; // set the exponent.
|
||||
bits >>= (63 - kExp);
|
||||
|
||||
// Construct the 32-bit or 64-bit IEEE 754 floating-point value from
|
||||
// the individual fields: sign, exp, mantissa(bits).
|
||||
uint_type val = sign | (static_cast<uint_type>(exp) << kExp) |
|
||||
(static_cast<uint_type>(bits) & kMask);
|
||||
|
||||
// bit_cast to the output-type
|
||||
real_type result;
|
||||
memcpy(static_cast<void*>(&result), static_cast<const void*>(&val),
|
||||
sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
|
||||
245
Pods/abseil/absl/random/internal/iostream_state_saver.h
generated
Normal file
245
Pods/abseil/absl/random/internal/iostream_state_saver.h
generated
Normal file
@@ -0,0 +1,245 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
|
||||
#define ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/numeric/int128.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// The null_state_saver does nothing.
|
||||
template <typename T>
|
||||
class null_state_saver {
|
||||
public:
|
||||
using stream_type = T;
|
||||
using flags_type = std::ios_base::fmtflags;
|
||||
|
||||
null_state_saver(T&, flags_type) {}
|
||||
~null_state_saver() {}
|
||||
};
|
||||
|
||||
// ostream_state_saver is a RAII object to save and restore the common
|
||||
// basic_ostream flags used when implementing `operator <<()` on any of
|
||||
// the absl random distributions.
|
||||
template <typename OStream>
|
||||
class ostream_state_saver {
|
||||
public:
|
||||
using ostream_type = OStream;
|
||||
using flags_type = std::ios_base::fmtflags;
|
||||
using fill_type = typename ostream_type::char_type;
|
||||
using precision_type = std::streamsize;
|
||||
|
||||
ostream_state_saver(ostream_type& os, // NOLINT(runtime/references)
|
||||
flags_type flags, fill_type fill)
|
||||
: os_(os),
|
||||
flags_(os.flags(flags)),
|
||||
fill_(os.fill(fill)),
|
||||
precision_(os.precision()) {
|
||||
// Save state in initialized variables.
|
||||
}
|
||||
|
||||
~ostream_state_saver() {
|
||||
// Restore saved state.
|
||||
os_.precision(precision_);
|
||||
os_.fill(fill_);
|
||||
os_.flags(flags_);
|
||||
}
|
||||
|
||||
private:
|
||||
ostream_type& os_;
|
||||
const flags_type flags_;
|
||||
const fill_type fill_;
|
||||
const precision_type precision_;
|
||||
};
|
||||
|
||||
#if defined(__NDK_MAJOR__) && __NDK_MAJOR__ < 16
|
||||
#define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 1
|
||||
#else
|
||||
#define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 0
|
||||
#endif
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
ostream_state_saver<std::basic_ostream<CharT, Traits>> make_ostream_state_saver(
|
||||
std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
|
||||
std::ios_base::fmtflags flags = std::ios_base::dec | std::ios_base::left |
|
||||
#if ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT
|
||||
std::ios_base::fixed |
|
||||
#endif
|
||||
std::ios_base::scientific) {
|
||||
using result_type = ostream_state_saver<std::basic_ostream<CharT, Traits>>;
|
||||
return result_type(os, flags, os.widen(' '));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
|
||||
null_state_saver<T>>
|
||||
make_ostream_state_saver(T& is, // NOLINT(runtime/references)
|
||||
std::ios_base::fmtflags flags = std::ios_base::dec) {
|
||||
std::cerr << "null_state_saver";
|
||||
using result_type = null_state_saver<T>;
|
||||
return result_type(is, flags);
|
||||
}
|
||||
|
||||
// stream_precision_helper<type>::kPrecision returns the base 10 precision
|
||||
// required to stream and reconstruct a real type exact binary value through
|
||||
// a binary->decimal->binary transition.
|
||||
template <typename T>
|
||||
struct stream_precision_helper {
|
||||
// max_digits10 may be 0 on MSVC; if so, use digits10 + 3.
|
||||
static constexpr int kPrecision =
|
||||
(std::numeric_limits<T>::max_digits10 > std::numeric_limits<T>::digits10)
|
||||
? std::numeric_limits<T>::max_digits10
|
||||
: (std::numeric_limits<T>::digits10 + 3);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct stream_precision_helper<float> {
|
||||
static constexpr int kPrecision = 9;
|
||||
};
|
||||
template <>
|
||||
struct stream_precision_helper<double> {
|
||||
static constexpr int kPrecision = 17;
|
||||
};
|
||||
template <>
|
||||
struct stream_precision_helper<long double> {
|
||||
static constexpr int kPrecision = 36; // assuming fp128
|
||||
};
|
||||
|
||||
// istream_state_saver is a RAII object to save and restore the common
|
||||
// std::basic_istream<> flags used when implementing `operator >>()` on any of
|
||||
// the absl random distributions.
|
||||
template <typename IStream>
|
||||
class istream_state_saver {
|
||||
public:
|
||||
using istream_type = IStream;
|
||||
using flags_type = std::ios_base::fmtflags;
|
||||
|
||||
istream_state_saver(istream_type& is, // NOLINT(runtime/references)
|
||||
flags_type flags)
|
||||
: is_(is), flags_(is.flags(flags)) {}
|
||||
|
||||
~istream_state_saver() { is_.flags(flags_); }
|
||||
|
||||
private:
|
||||
istream_type& is_;
|
||||
flags_type flags_;
|
||||
};
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
istream_state_saver<std::basic_istream<CharT, Traits>> make_istream_state_saver(
|
||||
std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
|
||||
std::ios_base::fmtflags flags = std::ios_base::dec |
|
||||
std::ios_base::scientific |
|
||||
std::ios_base::skipws) {
|
||||
using result_type = istream_state_saver<std::basic_istream<CharT, Traits>>;
|
||||
return result_type(is, flags);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
|
||||
null_state_saver<T>>
|
||||
make_istream_state_saver(T& is, // NOLINT(runtime/references)
|
||||
std::ios_base::fmtflags flags = std::ios_base::dec) {
|
||||
using result_type = null_state_saver<T>;
|
||||
return result_type(is, flags);
|
||||
}
|
||||
|
||||
// stream_format_type<T> is a helper struct to convert types which
|
||||
// basic_iostream cannot output as decimal numbers into types which
|
||||
// basic_iostream can output as decimal numbers. Specifically:
|
||||
// * signed/unsigned char-width types are converted to int.
|
||||
// * TODO(lar): __int128 => uint128, except there is no operator << yet.
|
||||
//
|
||||
template <typename T>
|
||||
struct stream_format_type
|
||||
: public std::conditional<(sizeof(T) == sizeof(char)), int, T> {};
|
||||
|
||||
// stream_u128_helper allows us to write out either absl::uint128 or
|
||||
// __uint128_t types in the same way, which enables their use as internal
|
||||
// state of PRNG engines.
|
||||
template <typename T>
|
||||
struct stream_u128_helper;
|
||||
|
||||
template <>
|
||||
struct stream_u128_helper<absl::uint128> {
|
||||
template <typename IStream>
|
||||
inline absl::uint128 read(IStream& in) {
|
||||
uint64_t h = 0;
|
||||
uint64_t l = 0;
|
||||
in >> h >> l;
|
||||
return absl::MakeUint128(h, l);
|
||||
}
|
||||
|
||||
template <typename OStream>
|
||||
inline void write(absl::uint128 val, OStream& out) {
|
||||
uint64_t h = absl::Uint128High64(val);
|
||||
uint64_t l = absl::Uint128Low64(val);
|
||||
out << h << out.fill() << l;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef ABSL_HAVE_INTRINSIC_INT128
|
||||
template <>
|
||||
struct stream_u128_helper<__uint128_t> {
|
||||
template <typename IStream>
|
||||
inline __uint128_t read(IStream& in) {
|
||||
uint64_t h = 0;
|
||||
uint64_t l = 0;
|
||||
in >> h >> l;
|
||||
return (static_cast<__uint128_t>(h) << 64) | l;
|
||||
}
|
||||
|
||||
template <typename OStream>
|
||||
inline void write(__uint128_t val, OStream& out) {
|
||||
uint64_t h = static_cast<uint64_t>(val >> 64u);
|
||||
uint64_t l = static_cast<uint64_t>(val);
|
||||
out << h << out.fill() << l;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename FloatType, typename IStream>
|
||||
inline FloatType read_floating_point(IStream& is) {
|
||||
static_assert(std::is_floating_point<FloatType>::value, "");
|
||||
FloatType dest;
|
||||
is >> dest;
|
||||
// Parsing a double value may report a subnormal value as an error
|
||||
// despite being able to represent it.
|
||||
// See https://stackoverflow.com/q/52410931/3286653
|
||||
// It may also report an underflow when parsing DOUBLE_MIN as an
|
||||
// ERANGE error, as the parsed value may be smaller than DOUBLE_MIN
|
||||
// and rounded up.
|
||||
// See: https://stackoverflow.com/q/42005462
|
||||
if (is.fail() &&
|
||||
(std::fabs(dest) == (std::numeric_limits<FloatType>::min)() ||
|
||||
std::fpclassify(dest) == FP_SUBNORMAL)) {
|
||||
is.clear(is.rdstate() & (~std::ios_base::failbit));
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
|
||||
161
Pods/abseil/absl/random/internal/nonsecure_base.h
generated
Normal file
161
Pods/abseil/absl/random/internal/nonsecure_base.h
generated
Normal file
@@ -0,0 +1,161 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
|
||||
#define ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/macros.h"
|
||||
#include "absl/container/inlined_vector.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/random/internal/pool_urbg.h"
|
||||
#include "absl/random/internal/salted_seed_seq.h"
|
||||
#include "absl/random/internal/seed_material.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// RandenPoolSeedSeq is a custom seed sequence type where generate() fills the
|
||||
// provided buffer via the RandenPool entropy source.
|
||||
class RandenPoolSeedSeq {
|
||||
private:
|
||||
struct ContiguousTag {};
|
||||
struct BufferTag {};
|
||||
|
||||
// Generate random unsigned values directly into the buffer.
|
||||
template <typename Contiguous>
|
||||
void generate_impl(ContiguousTag, Contiguous begin, Contiguous end) {
|
||||
const size_t n = static_cast<size_t>(std::distance(begin, end));
|
||||
auto* a = &(*begin);
|
||||
RandenPool<uint8_t>::Fill(
|
||||
absl::MakeSpan(reinterpret_cast<uint8_t*>(a), sizeof(*a) * n));
|
||||
}
|
||||
|
||||
// Construct a buffer of size n and fill it with values, then copy
|
||||
// those values into the seed iterators.
|
||||
template <typename RandomAccessIterator>
|
||||
void generate_impl(BufferTag, RandomAccessIterator begin,
|
||||
RandomAccessIterator end) {
|
||||
const size_t n = std::distance(begin, end);
|
||||
absl::InlinedVector<uint32_t, 8> data(n, 0);
|
||||
RandenPool<uint32_t>::Fill(absl::MakeSpan(data.begin(), data.end()));
|
||||
std::copy(std::begin(data), std::end(data), begin);
|
||||
}
|
||||
|
||||
public:
|
||||
using result_type = uint32_t;
|
||||
|
||||
size_t size() { return 0; }
|
||||
|
||||
template <typename OutIterator>
|
||||
void param(OutIterator) const {}
|
||||
|
||||
template <typename RandomAccessIterator>
|
||||
void generate(RandomAccessIterator begin, RandomAccessIterator end) {
|
||||
// RandomAccessIterator must be assignable from uint32_t
|
||||
if (begin != end) {
|
||||
using U = typename std::iterator_traits<RandomAccessIterator>::value_type;
|
||||
// ContiguousTag indicates the common case of a known contiguous buffer,
|
||||
// which allows directly filling the buffer. In C++20,
|
||||
// std::contiguous_iterator_tag provides a mechanism for testing this
|
||||
// capability, however until Abseil's support requirements allow us to
|
||||
// assume C++20, limit checks to a few common cases.
|
||||
using TagType = absl::conditional_t<
|
||||
(std::is_pointer<RandomAccessIterator>::value ||
|
||||
std::is_same<RandomAccessIterator,
|
||||
typename std::vector<U>::iterator>::value),
|
||||
ContiguousTag, BufferTag>;
|
||||
|
||||
generate_impl(TagType{}, begin, end);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Each instance of NonsecureURBGBase<URBG> will be seeded by variates produced
|
||||
// by a thread-unique URBG-instance.
|
||||
template <typename URBG, typename Seeder = RandenPoolSeedSeq>
|
||||
class NonsecureURBGBase {
|
||||
public:
|
||||
using result_type = typename URBG::result_type;
|
||||
|
||||
// Default constructor
|
||||
NonsecureURBGBase() : urbg_(ConstructURBG()) {}
|
||||
|
||||
// Copy disallowed, move allowed.
|
||||
NonsecureURBGBase(const NonsecureURBGBase&) = delete;
|
||||
NonsecureURBGBase& operator=(const NonsecureURBGBase&) = delete;
|
||||
NonsecureURBGBase(NonsecureURBGBase&&) = default;
|
||||
NonsecureURBGBase& operator=(NonsecureURBGBase&&) = default;
|
||||
|
||||
// Constructor using a seed
|
||||
template <class SSeq, typename = typename absl::enable_if_t<
|
||||
!std::is_same<SSeq, NonsecureURBGBase>::value>>
|
||||
explicit NonsecureURBGBase(SSeq&& seq)
|
||||
: urbg_(ConstructURBG(std::forward<SSeq>(seq))) {}
|
||||
|
||||
// Note: on MSVC, min() or max() can be interpreted as MIN() or MAX(), so we
|
||||
// enclose min() or max() in parens as (min)() and (max)().
|
||||
// Additionally, clang-format requires no space before this construction.
|
||||
|
||||
// NonsecureURBGBase::min()
|
||||
static constexpr result_type(min)() { return (URBG::min)(); }
|
||||
|
||||
// NonsecureURBGBase::max()
|
||||
static constexpr result_type(max)() { return (URBG::max)(); }
|
||||
|
||||
// NonsecureURBGBase::operator()()
|
||||
result_type operator()() { return urbg_(); }
|
||||
|
||||
// NonsecureURBGBase::discard()
|
||||
void discard(unsigned long long values) { // NOLINT(runtime/int)
|
||||
urbg_.discard(values);
|
||||
}
|
||||
|
||||
bool operator==(const NonsecureURBGBase& other) const {
|
||||
return urbg_ == other.urbg_;
|
||||
}
|
||||
|
||||
bool operator!=(const NonsecureURBGBase& other) const {
|
||||
return !(urbg_ == other.urbg_);
|
||||
}
|
||||
|
||||
private:
|
||||
static URBG ConstructURBG() {
|
||||
Seeder seeder;
|
||||
return URBG(seeder);
|
||||
}
|
||||
|
||||
template <typename SSeq>
|
||||
static URBG ConstructURBG(SSeq&& seq) { // NOLINT(runtime/references)
|
||||
auto salted_seq =
|
||||
random_internal::MakeSaltedSeedSeq(std::forward<SSeq>(seq));
|
||||
return URBG(salted_seq);
|
||||
}
|
||||
|
||||
URBG urbg_;
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
|
||||
287
Pods/abseil/absl/random/internal/pcg_engine.h
generated
Normal file
287
Pods/abseil/absl/random/internal/pcg_engine.h
generated
Normal file
@@ -0,0 +1,287 @@
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
|
||||
#define ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/numeric/bits.h"
|
||||
#include "absl/numeric/int128.h"
|
||||
#include "absl/random/internal/fastmath.h"
|
||||
#include "absl/random/internal/iostream_state_saver.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// pcg_engine is a simplified implementation of Melissa O'Neil's PCG engine in
|
||||
// C++. PCG combines a linear congruential generator (LCG) with output state
|
||||
// mixing functions to generate each random variate. pcg_engine supports only a
|
||||
// single sequence (oneseq), and does not support streams.
|
||||
//
|
||||
// pcg_engine is parameterized by two types:
|
||||
// Params, which provides the multiplier and increment values;
|
||||
// Mix, which mixes the state into the result.
|
||||
//
|
||||
template <typename Params, typename Mix>
|
||||
class pcg_engine {
|
||||
static_assert(std::is_same<typename Params::state_type,
|
||||
typename Mix::state_type>::value,
|
||||
"Class-template absl::pcg_engine must be parameterized by "
|
||||
"Params and Mix with identical state_type");
|
||||
|
||||
static_assert(std::is_unsigned<typename Mix::result_type>::value,
|
||||
"Class-template absl::pcg_engine must be parameterized by "
|
||||
"an unsigned Mix::result_type");
|
||||
|
||||
using params_type = Params;
|
||||
using mix_type = Mix;
|
||||
using state_type = typename Mix::state_type;
|
||||
|
||||
public:
|
||||
// C++11 URBG interface:
|
||||
using result_type = typename Mix::result_type;
|
||||
|
||||
static constexpr result_type(min)() {
|
||||
return (std::numeric_limits<result_type>::min)();
|
||||
}
|
||||
|
||||
static constexpr result_type(max)() {
|
||||
return (std::numeric_limits<result_type>::max)();
|
||||
}
|
||||
|
||||
explicit pcg_engine(uint64_t seed_value = 0) { seed(seed_value); }
|
||||
|
||||
template <class SeedSequence,
|
||||
typename = typename absl::enable_if_t<
|
||||
!std::is_same<SeedSequence, pcg_engine>::value>>
|
||||
explicit pcg_engine(SeedSequence&& seq) {
|
||||
seed(seq);
|
||||
}
|
||||
|
||||
pcg_engine(const pcg_engine&) = default;
|
||||
pcg_engine& operator=(const pcg_engine&) = default;
|
||||
pcg_engine(pcg_engine&&) = default;
|
||||
pcg_engine& operator=(pcg_engine&&) = default;
|
||||
|
||||
result_type operator()() {
|
||||
// Advance the LCG state, always using the new value to generate the output.
|
||||
state_ = lcg(state_);
|
||||
return Mix{}(state_);
|
||||
}
|
||||
|
||||
void seed(uint64_t seed_value = 0) {
|
||||
state_type tmp = seed_value;
|
||||
state_ = lcg(tmp + Params::increment());
|
||||
}
|
||||
|
||||
template <class SeedSequence>
|
||||
typename absl::enable_if_t<
|
||||
!std::is_convertible<SeedSequence, uint64_t>::value, void>
|
||||
seed(SeedSequence&& seq) {
|
||||
reseed(seq);
|
||||
}
|
||||
|
||||
void discard(uint64_t count) { state_ = advance(state_, count); }
|
||||
|
||||
bool operator==(const pcg_engine& other) const {
|
||||
return state_ == other.state_;
|
||||
}
|
||||
|
||||
bool operator!=(const pcg_engine& other) const { return !(*this == other); }
|
||||
|
||||
template <class CharT, class Traits>
|
||||
friend typename absl::enable_if_t<(sizeof(state_type) == 16),
|
||||
std::basic_ostream<CharT, Traits>&>
|
||||
operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
|
||||
const pcg_engine& engine) {
|
||||
auto saver = random_internal::make_ostream_state_saver(os);
|
||||
random_internal::stream_u128_helper<state_type> helper;
|
||||
helper.write(pcg_engine::params_type::multiplier(), os);
|
||||
os << os.fill();
|
||||
helper.write(pcg_engine::params_type::increment(), os);
|
||||
os << os.fill();
|
||||
helper.write(engine.state_, os);
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
friend typename absl::enable_if_t<(sizeof(state_type) <= 8),
|
||||
std::basic_ostream<CharT, Traits>&>
|
||||
operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
|
||||
const pcg_engine& engine) {
|
||||
auto saver = random_internal::make_ostream_state_saver(os);
|
||||
os << pcg_engine::params_type::multiplier() << os.fill();
|
||||
os << pcg_engine::params_type::increment() << os.fill();
|
||||
os << engine.state_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
friend typename absl::enable_if_t<(sizeof(state_type) == 16),
|
||||
std::basic_istream<CharT, Traits>&>
|
||||
operator>>(
|
||||
std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
|
||||
pcg_engine& engine) { // NOLINT(runtime/references)
|
||||
random_internal::stream_u128_helper<state_type> helper;
|
||||
auto mult = helper.read(is);
|
||||
auto inc = helper.read(is);
|
||||
auto tmp = helper.read(is);
|
||||
if (mult != pcg_engine::params_type::multiplier() ||
|
||||
inc != pcg_engine::params_type::increment()) {
|
||||
// signal failure by setting the failbit.
|
||||
is.setstate(is.rdstate() | std::ios_base::failbit);
|
||||
}
|
||||
if (!is.fail()) {
|
||||
engine.state_ = tmp;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
friend typename absl::enable_if_t<(sizeof(state_type) <= 8),
|
||||
std::basic_istream<CharT, Traits>&>
|
||||
operator>>(
|
||||
std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
|
||||
pcg_engine& engine) { // NOLINT(runtime/references)
|
||||
state_type mult{}, inc{}, tmp{};
|
||||
is >> mult >> inc >> tmp;
|
||||
if (mult != pcg_engine::params_type::multiplier() ||
|
||||
inc != pcg_engine::params_type::increment()) {
|
||||
// signal failure by setting the failbit.
|
||||
is.setstate(is.rdstate() | std::ios_base::failbit);
|
||||
}
|
||||
if (!is.fail()) {
|
||||
engine.state_ = tmp;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
private:
|
||||
state_type state_;
|
||||
|
||||
// Returns the linear-congruential generator next state.
|
||||
static inline constexpr state_type lcg(state_type s) {
|
||||
return s * Params::multiplier() + Params::increment();
|
||||
}
|
||||
|
||||
// Returns the linear-congruential arbitrary seek state.
|
||||
inline state_type advance(state_type s, uint64_t n) const {
|
||||
state_type mult = Params::multiplier();
|
||||
state_type inc = Params::increment();
|
||||
state_type m = 1;
|
||||
state_type i = 0;
|
||||
while (n > 0) {
|
||||
if (n & 1) {
|
||||
m *= mult;
|
||||
i = i * mult + inc;
|
||||
}
|
||||
inc = (mult + 1) * inc;
|
||||
mult *= mult;
|
||||
n >>= 1;
|
||||
}
|
||||
return m * s + i;
|
||||
}
|
||||
|
||||
template <class SeedSequence>
|
||||
void reseed(SeedSequence& seq) {
|
||||
using sequence_result_type = typename SeedSequence::result_type;
|
||||
constexpr size_t kBufferSize =
|
||||
sizeof(state_type) / sizeof(sequence_result_type);
|
||||
sequence_result_type buffer[kBufferSize];
|
||||
seq.generate(std::begin(buffer), std::end(buffer));
|
||||
// Convert the seed output to a single state value.
|
||||
state_type tmp = buffer[0];
|
||||
for (size_t i = 1; i < kBufferSize; i++) {
|
||||
tmp <<= (sizeof(sequence_result_type) * 8);
|
||||
tmp |= buffer[i];
|
||||
}
|
||||
state_ = lcg(tmp + params_type::increment());
|
||||
}
|
||||
};
|
||||
|
||||
// Parameterized implementation of the PCG 128-bit oneseq state.
|
||||
// This provides state_type, multiplier, and increment for pcg_engine.
|
||||
template <uint64_t kMultA, uint64_t kMultB, uint64_t kIncA, uint64_t kIncB>
|
||||
class pcg128_params {
|
||||
public:
|
||||
using state_type = absl::uint128;
|
||||
static inline constexpr state_type multiplier() {
|
||||
return absl::MakeUint128(kMultA, kMultB);
|
||||
}
|
||||
static inline constexpr state_type increment() {
|
||||
return absl::MakeUint128(kIncA, kIncB);
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation of the PCG xsl_rr_128_64 128-bit mixing function, which
|
||||
// accepts an input of state_type and mixes it into an output of result_type.
|
||||
struct pcg_xsl_rr_128_64 {
|
||||
using state_type = absl::uint128;
|
||||
using result_type = uint64_t;
|
||||
|
||||
inline uint64_t operator()(state_type state) {
|
||||
// This is equivalent to the xsl_rr_128_64 mixing function.
|
||||
uint64_t rotate = static_cast<uint64_t>(state >> 122u);
|
||||
state ^= state >> 64;
|
||||
uint64_t s = static_cast<uint64_t>(state);
|
||||
return rotr(s, static_cast<int>(rotate));
|
||||
}
|
||||
};
|
||||
|
||||
// Parameterized implementation of the PCG 64-bit oneseq state.
|
||||
// This provides state_type, multiplier, and increment for pcg_engine.
|
||||
template <uint64_t kMult, uint64_t kInc>
|
||||
class pcg64_params {
|
||||
public:
|
||||
using state_type = uint64_t;
|
||||
static inline constexpr state_type multiplier() { return kMult; }
|
||||
static inline constexpr state_type increment() { return kInc; }
|
||||
};
|
||||
|
||||
// Implementation of the PCG xsh_rr_64_32 64-bit mixing function, which accepts
|
||||
// an input of state_type and mixes it into an output of result_type.
|
||||
struct pcg_xsh_rr_64_32 {
|
||||
using state_type = uint64_t;
|
||||
using result_type = uint32_t;
|
||||
inline uint32_t operator()(uint64_t state) {
|
||||
return rotr(static_cast<uint32_t>(((state >> 18) ^ state) >> 27),
|
||||
state >> 59);
|
||||
}
|
||||
};
|
||||
|
||||
// Stable pcg_engine implementations:
|
||||
// This is a 64-bit generator using 128-bits of state.
|
||||
// The output sequence is equivalent to Melissa O'Neil's pcg64_oneseq.
|
||||
using pcg64_2018_engine = pcg_engine<
|
||||
random_internal::pcg128_params<0x2360ed051fc65da4ull, 0x4385df649fccf645ull,
|
||||
0x5851f42d4c957f2d, 0x14057b7ef767814f>,
|
||||
random_internal::pcg_xsl_rr_128_64>;
|
||||
|
||||
// This is a 32-bit generator using 64-bits of state.
|
||||
// This is equivalent to Melissa O'Neil's pcg32_oneseq.
|
||||
using pcg32_2018_engine = pcg_engine<
|
||||
random_internal::pcg64_params<0x5851f42d4c957f2dull, 0x14057b7ef767814full>,
|
||||
random_internal::pcg_xsh_rr_64_32>;
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
|
||||
171
Pods/abseil/absl/random/internal/platform.h
generated
Normal file
171
Pods/abseil/absl/random/internal/platform.h
generated
Normal file
@@ -0,0 +1,171 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_PLATFORM_H_
|
||||
#define ABSL_RANDOM_INTERNAL_PLATFORM_H_
|
||||
|
||||
// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
|
||||
// symbols from arbitrary system and other headers, since it may be built
|
||||
// with different flags from other targets, using different levels of
|
||||
// optimization, potentially introducing ODR violations.
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Platform Feature Checks
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Currently supported operating systems and associated preprocessor
|
||||
// symbols:
|
||||
//
|
||||
// Linux and Linux-derived __linux__
|
||||
// Android __ANDROID__ (implies __linux__)
|
||||
// Linux (non-Android) __linux__ && !__ANDROID__
|
||||
// Darwin (macOS and iOS) __APPLE__
|
||||
// Akaros (http://akaros.org) __ros__
|
||||
// Windows _WIN32
|
||||
// NaCL __native_client__
|
||||
// AsmJS __asmjs__
|
||||
// WebAssembly __wasm__
|
||||
// Fuchsia __Fuchsia__
|
||||
//
|
||||
// Note that since Android defines both __ANDROID__ and __linux__, one
|
||||
// may probe for either Linux or Android by simply testing for __linux__.
|
||||
//
|
||||
// NOTE: For __APPLE__ platforms, we use #include <TargetConditionals.h>
|
||||
// to distinguish os variants.
|
||||
//
|
||||
// http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Architecture Checks
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// These preprocessor directives are trying to determine CPU architecture,
|
||||
// including necessary headers to support hardware AES.
|
||||
//
|
||||
// ABSL_ARCH_{X86/PPC/ARM} macros determine the platform.
|
||||
#if defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || \
|
||||
defined(_M_X64)
|
||||
#define ABSL_ARCH_X86_64
|
||||
#elif defined(__i386) || defined(_M_IX86)
|
||||
#define ABSL_ARCH_X86_32
|
||||
#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)
|
||||
#define ABSL_ARCH_AARCH64
|
||||
#elif defined(__arm__) || defined(__ARMEL__) || defined(_M_ARM)
|
||||
#define ABSL_ARCH_ARM
|
||||
#elif defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
|
||||
defined(__ppc__) || defined(__PPC__)
|
||||
#define ABSL_ARCH_PPC
|
||||
#else
|
||||
// Unsupported architecture.
|
||||
// * https://sourceforge.net/p/predef/wiki/Architectures/
|
||||
// * https://msdn.microsoft.com/en-us/library/b0084kay.aspx
|
||||
// * for gcc, clang: "echo | gcc -E -dM -"
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Attribute Checks
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// ABSL_RANDOM_INTERNAL_RESTRICT annotates whether pointers may be considered
|
||||
// to be unaliased.
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#define ABSL_RANDOM_INTERNAL_RESTRICT __restrict__
|
||||
#elif defined(_MSC_VER)
|
||||
#define ABSL_RANDOM_INTERNAL_RESTRICT __restrict
|
||||
#else
|
||||
#define ABSL_RANDOM_INTERNAL_RESTRICT
|
||||
#endif
|
||||
|
||||
// ABSL_HAVE_ACCELERATED_AES indicates whether the currently active compiler
|
||||
// flags (e.g. -maes) allow using hardware accelerated AES instructions, which
|
||||
// implies us assuming that the target platform supports them.
|
||||
#define ABSL_HAVE_ACCELERATED_AES 0
|
||||
|
||||
#if defined(ABSL_ARCH_X86_64)
|
||||
|
||||
#if defined(__AES__) || defined(__AVX__)
|
||||
#undef ABSL_HAVE_ACCELERATED_AES
|
||||
#define ABSL_HAVE_ACCELERATED_AES 1
|
||||
#endif
|
||||
|
||||
#elif defined(ABSL_ARCH_PPC)
|
||||
|
||||
// Rely on VSX and CRYPTO extensions for vcipher on PowerPC.
|
||||
#if (defined(__VEC__) || defined(__ALTIVEC__)) && defined(__VSX__) && \
|
||||
defined(__CRYPTO__)
|
||||
#undef ABSL_HAVE_ACCELERATED_AES
|
||||
#define ABSL_HAVE_ACCELERATED_AES 1
|
||||
#endif
|
||||
|
||||
#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)
|
||||
|
||||
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf
|
||||
// Rely on NEON+CRYPTO extensions for ARM.
|
||||
#if defined(__ARM_NEON) && defined(__ARM_FEATURE_CRYPTO)
|
||||
#undef ABSL_HAVE_ACCELERATED_AES
|
||||
#define ABSL_HAVE_ACCELERATED_AES 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// NaCl does not allow AES.
|
||||
#if defined(__native_client__)
|
||||
#undef ABSL_HAVE_ACCELERATED_AES
|
||||
#define ABSL_HAVE_ACCELERATED_AES 0
|
||||
#endif
|
||||
|
||||
// ABSL_RANDOM_INTERNAL_AES_DISPATCH indicates whether the currently active
|
||||
// platform has, or should use run-time dispatch for selecting the
|
||||
// accelerated Randen implementation.
|
||||
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
|
||||
|
||||
#if defined(ABSL_ARCH_X86_64)
|
||||
// Dispatch is available on x86_64
|
||||
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
|
||||
#elif defined(__linux__) && defined(ABSL_ARCH_PPC)
|
||||
// Or when running linux PPC
|
||||
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
|
||||
#elif defined(__linux__) && defined(ABSL_ARCH_AARCH64)
|
||||
// Or when running linux AArch64
|
||||
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
|
||||
#elif defined(__linux__) && defined(ABSL_ARCH_ARM) && (__ARM_ARCH >= 8)
|
||||
// Or when running linux ARM v8 or higher.
|
||||
// (This captures a lot of Android configurations.)
|
||||
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
|
||||
#endif
|
||||
|
||||
// NaCl does not allow dispatch.
|
||||
#if defined(__native_client__)
|
||||
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
|
||||
#endif
|
||||
|
||||
// iOS does not support dispatch, even on x86, since applications
|
||||
// should be bundled as fat binaries, with a different build tailored for
|
||||
// each specific supported platform/architecture.
|
||||
#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \
|
||||
(defined(TARGET_OS_IPHONE_SIMULATOR) && TARGET_OS_IPHONE_SIMULATOR)
|
||||
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
|
||||
#endif
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_PLATFORM_H_
|
||||
253
Pods/abseil/absl/random/internal/pool_urbg.cc
generated
Normal file
253
Pods/abseil/absl/random/internal/pool_urbg.cc
generated
Normal file
@@ -0,0 +1,253 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/random/internal/pool_urbg.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/call_once.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/endian.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/base/internal/spinlock.h"
|
||||
#include "absl/base/internal/sysinfo.h"
|
||||
#include "absl/base/internal/unaligned_access.h"
|
||||
#include "absl/base/optimization.h"
|
||||
#include "absl/random/internal/randen.h"
|
||||
#include "absl/random/internal/seed_material.h"
|
||||
#include "absl/random/seed_gen_exception.h"
|
||||
|
||||
using absl::base_internal::SpinLock;
|
||||
using absl::base_internal::SpinLockHolder;
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
namespace {
|
||||
|
||||
// RandenPoolEntry is a thread-safe pseudorandom bit generator, implementing a
|
||||
// single generator within a RandenPool<T>. It is an internal implementation
|
||||
// detail, and does not aim to conform to [rand.req.urng].
|
||||
//
|
||||
// NOTE: There are alignment issues when used on ARM, for instance.
|
||||
// See the allocation code in PoolAlignedAlloc().
|
||||
class RandenPoolEntry {
|
||||
public:
|
||||
static constexpr size_t kState = RandenTraits::kStateBytes / sizeof(uint32_t);
|
||||
static constexpr size_t kCapacity =
|
||||
RandenTraits::kCapacityBytes / sizeof(uint32_t);
|
||||
|
||||
void Init(absl::Span<const uint32_t> data) {
|
||||
SpinLockHolder l(&mu_); // Always uncontested.
|
||||
std::copy(data.begin(), data.end(), std::begin(state_));
|
||||
next_ = kState;
|
||||
}
|
||||
|
||||
// Copy bytes into out.
|
||||
void Fill(uint8_t* out, size_t bytes) ABSL_LOCKS_EXCLUDED(mu_);
|
||||
|
||||
// Returns random bits from the buffer in units of T.
|
||||
template <typename T>
|
||||
inline T Generate() ABSL_LOCKS_EXCLUDED(mu_);
|
||||
|
||||
inline void MaybeRefill() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
|
||||
if (next_ >= kState) {
|
||||
next_ = kCapacity;
|
||||
impl_.Generate(state_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Randen URBG state.
|
||||
uint32_t state_[kState] ABSL_GUARDED_BY(mu_); // First to satisfy alignment.
|
||||
SpinLock mu_;
|
||||
const Randen impl_;
|
||||
size_t next_ ABSL_GUARDED_BY(mu_);
|
||||
};
|
||||
|
||||
template <>
|
||||
inline uint8_t RandenPoolEntry::Generate<uint8_t>() {
|
||||
SpinLockHolder l(&mu_);
|
||||
MaybeRefill();
|
||||
return static_cast<uint8_t>(state_[next_++]);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint16_t RandenPoolEntry::Generate<uint16_t>() {
|
||||
SpinLockHolder l(&mu_);
|
||||
MaybeRefill();
|
||||
return static_cast<uint16_t>(state_[next_++]);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint32_t RandenPoolEntry::Generate<uint32_t>() {
|
||||
SpinLockHolder l(&mu_);
|
||||
MaybeRefill();
|
||||
return state_[next_++];
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint64_t RandenPoolEntry::Generate<uint64_t>() {
|
||||
SpinLockHolder l(&mu_);
|
||||
if (next_ >= kState - 1) {
|
||||
next_ = kCapacity;
|
||||
impl_.Generate(state_);
|
||||
}
|
||||
auto p = state_ + next_;
|
||||
next_ += 2;
|
||||
|
||||
uint64_t result;
|
||||
std::memcpy(&result, p, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void RandenPoolEntry::Fill(uint8_t* out, size_t bytes) {
|
||||
SpinLockHolder l(&mu_);
|
||||
while (bytes > 0) {
|
||||
MaybeRefill();
|
||||
size_t remaining = (kState - next_) * sizeof(state_[0]);
|
||||
size_t to_copy = std::min(bytes, remaining);
|
||||
std::memcpy(out, &state_[next_], to_copy);
|
||||
out += to_copy;
|
||||
bytes -= to_copy;
|
||||
next_ += (to_copy + sizeof(state_[0]) - 1) / sizeof(state_[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Number of pooled urbg entries.
|
||||
static constexpr size_t kPoolSize = 8;
|
||||
|
||||
// Shared pool entries.
|
||||
static absl::once_flag pool_once;
|
||||
ABSL_CACHELINE_ALIGNED static RandenPoolEntry* shared_pools[kPoolSize];
|
||||
|
||||
// Returns an id in the range [0 ... kPoolSize), which indexes into the
|
||||
// pool of random engines.
|
||||
//
|
||||
// Each thread to access the pool is assigned a sequential ID (without reuse)
|
||||
// from the pool-id space; the id is cached in a thread_local variable.
|
||||
// This id is assigned based on the arrival-order of the thread to the
|
||||
// GetPoolID call; this has no binary, CL, or runtime stability because
|
||||
// on subsequent runs the order within the same program may be significantly
|
||||
// different. However, as other thread IDs are not assigned sequentially,
|
||||
// this is not expected to matter.
|
||||
size_t GetPoolID() {
|
||||
static_assert(kPoolSize >= 1,
|
||||
"At least one urbg instance is required for PoolURBG");
|
||||
|
||||
ABSL_CONST_INIT static std::atomic<uint64_t> sequence{0};
|
||||
|
||||
#ifdef ABSL_HAVE_THREAD_LOCAL
|
||||
static thread_local size_t my_pool_id = kPoolSize;
|
||||
if (ABSL_PREDICT_FALSE(my_pool_id == kPoolSize)) {
|
||||
my_pool_id = (sequence++ % kPoolSize);
|
||||
}
|
||||
return my_pool_id;
|
||||
#else
|
||||
static pthread_key_t tid_key = [] {
|
||||
pthread_key_t tmp_key;
|
||||
int err = pthread_key_create(&tmp_key, nullptr);
|
||||
if (err) {
|
||||
ABSL_RAW_LOG(FATAL, "pthread_key_create failed with %d", err);
|
||||
}
|
||||
return tmp_key;
|
||||
}();
|
||||
|
||||
// Store the value in the pthread_{get/set}specific. However an uninitialized
|
||||
// value is 0, so add +1 to distinguish from the null value.
|
||||
uintptr_t my_pool_id =
|
||||
reinterpret_cast<uintptr_t>(pthread_getspecific(tid_key));
|
||||
if (ABSL_PREDICT_FALSE(my_pool_id == 0)) {
|
||||
// No allocated ID, allocate the next value, cache it, and return.
|
||||
my_pool_id = (sequence++ % kPoolSize) + 1;
|
||||
int err = pthread_setspecific(tid_key, reinterpret_cast<void*>(my_pool_id));
|
||||
if (err) {
|
||||
ABSL_RAW_LOG(FATAL, "pthread_setspecific failed with %d", err);
|
||||
}
|
||||
}
|
||||
return my_pool_id - 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Allocate a RandenPoolEntry with at least 32-byte alignment, which is required
|
||||
// by ARM platform code.
|
||||
RandenPoolEntry* PoolAlignedAlloc() {
|
||||
constexpr size_t kAlignment =
|
||||
ABSL_CACHELINE_SIZE > 32 ? ABSL_CACHELINE_SIZE : 32;
|
||||
|
||||
// Not all the platforms that we build for have std::aligned_alloc, however
|
||||
// since we never free these objects, we can over allocate and munge the
|
||||
// pointers to the correct alignment.
|
||||
uintptr_t x = reinterpret_cast<uintptr_t>(
|
||||
new char[sizeof(RandenPoolEntry) + kAlignment]);
|
||||
auto y = x % kAlignment;
|
||||
void* aligned = reinterpret_cast<void*>(y == 0 ? x : (x + kAlignment - y));
|
||||
return new (aligned) RandenPoolEntry();
|
||||
}
|
||||
|
||||
// Allocate and initialize kPoolSize objects of type RandenPoolEntry.
|
||||
//
|
||||
// The initialization strategy is to initialize one object directly from
|
||||
// OS entropy, then to use that object to seed all of the individual
|
||||
// pool instances.
|
||||
void InitPoolURBG() {
|
||||
static constexpr size_t kSeedSize =
|
||||
RandenTraits::kStateBytes / sizeof(uint32_t);
|
||||
// Read the seed data from OS entropy once.
|
||||
uint32_t seed_material[kPoolSize * kSeedSize];
|
||||
if (!random_internal::ReadSeedMaterialFromOSEntropy(
|
||||
absl::MakeSpan(seed_material))) {
|
||||
random_internal::ThrowSeedGenException();
|
||||
}
|
||||
for (size_t i = 0; i < kPoolSize; i++) {
|
||||
shared_pools[i] = PoolAlignedAlloc();
|
||||
shared_pools[i]->Init(
|
||||
absl::MakeSpan(&seed_material[i * kSeedSize], kSeedSize));
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the pool entry for the current thread.
|
||||
RandenPoolEntry* GetPoolForCurrentThread() {
|
||||
absl::call_once(pool_once, InitPoolURBG);
|
||||
return shared_pools[GetPoolID()];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
template <typename T>
|
||||
typename RandenPool<T>::result_type RandenPool<T>::Generate() {
|
||||
auto* pool = GetPoolForCurrentThread();
|
||||
return pool->Generate<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void RandenPool<T>::Fill(absl::Span<result_type> data) {
|
||||
auto* pool = GetPoolForCurrentThread();
|
||||
pool->Fill(reinterpret_cast<uint8_t*>(data.data()),
|
||||
data.size() * sizeof(result_type));
|
||||
}
|
||||
|
||||
template class RandenPool<uint8_t>;
|
||||
template class RandenPool<uint16_t>;
|
||||
template class RandenPool<uint32_t>;
|
||||
template class RandenPool<uint64_t>;
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
131
Pods/abseil/absl/random/internal/pool_urbg.h
generated
Normal file
131
Pods/abseil/absl/random/internal/pool_urbg.h
generated
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_POOL_URBG_H_
|
||||
#define ABSL_RANDOM_INTERNAL_POOL_URBG_H_
|
||||
|
||||
#include <cinttypes>
|
||||
#include <limits>
|
||||
|
||||
#include "absl/random/internal/traits.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// RandenPool is a thread-safe random number generator [random.req.urbg] that
|
||||
// uses an underlying pool of Randen generators to generate values. Each thread
|
||||
// has affinity to one instance of the underlying pool generators. Concurrent
|
||||
// access is guarded by a spin-lock.
|
||||
template <typename T>
|
||||
class RandenPool {
|
||||
public:
|
||||
using result_type = T;
|
||||
static_assert(std::is_unsigned<result_type>::value,
|
||||
"RandenPool template argument must be a built-in unsigned "
|
||||
"integer type");
|
||||
|
||||
static constexpr result_type(min)() {
|
||||
return (std::numeric_limits<result_type>::min)();
|
||||
}
|
||||
|
||||
static constexpr result_type(max)() {
|
||||
return (std::numeric_limits<result_type>::max)();
|
||||
}
|
||||
|
||||
RandenPool() {}
|
||||
|
||||
// Returns a single value.
|
||||
inline result_type operator()() { return Generate(); }
|
||||
|
||||
// Fill data with random values.
|
||||
static void Fill(absl::Span<result_type> data);
|
||||
|
||||
protected:
|
||||
// Generate returns a single value.
|
||||
static result_type Generate();
|
||||
};
|
||||
|
||||
extern template class RandenPool<uint8_t>;
|
||||
extern template class RandenPool<uint16_t>;
|
||||
extern template class RandenPool<uint32_t>;
|
||||
extern template class RandenPool<uint64_t>;
|
||||
|
||||
// PoolURBG uses an underlying pool of random generators to implement a
|
||||
// thread-compatible [random.req.urbg] interface with an internal cache of
|
||||
// values.
|
||||
template <typename T, size_t kBufferSize>
|
||||
class PoolURBG {
|
||||
// Inheritance to access the protected static members of RandenPool.
|
||||
using unsigned_type = typename make_unsigned_bits<T>::type;
|
||||
using PoolType = RandenPool<unsigned_type>;
|
||||
using SpanType = absl::Span<unsigned_type>;
|
||||
|
||||
static constexpr size_t kInitialBuffer = kBufferSize + 1;
|
||||
static constexpr size_t kHalfBuffer = kBufferSize / 2;
|
||||
|
||||
public:
|
||||
using result_type = T;
|
||||
|
||||
static_assert(std::is_unsigned<result_type>::value,
|
||||
"PoolURBG must be parameterized by an unsigned integer type");
|
||||
|
||||
static_assert(kBufferSize > 1,
|
||||
"PoolURBG must be parameterized by a buffer-size > 1");
|
||||
|
||||
static_assert(kBufferSize <= 256,
|
||||
"PoolURBG must be parameterized by a buffer-size <= 256");
|
||||
|
||||
static constexpr result_type(min)() {
|
||||
return (std::numeric_limits<result_type>::min)();
|
||||
}
|
||||
|
||||
static constexpr result_type(max)() {
|
||||
return (std::numeric_limits<result_type>::max)();
|
||||
}
|
||||
|
||||
PoolURBG() : next_(kInitialBuffer) {}
|
||||
|
||||
// copy-constructor does not copy cache.
|
||||
PoolURBG(const PoolURBG&) : next_(kInitialBuffer) {}
|
||||
const PoolURBG& operator=(const PoolURBG&) {
|
||||
next_ = kInitialBuffer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move-constructor does move cache.
|
||||
PoolURBG(PoolURBG&&) = default;
|
||||
PoolURBG& operator=(PoolURBG&&) = default;
|
||||
|
||||
inline result_type operator()() {
|
||||
if (next_ >= kBufferSize) {
|
||||
next_ = (kBufferSize > 2 && next_ > kBufferSize) ? kHalfBuffer : 0;
|
||||
PoolType::Fill(SpanType(reinterpret_cast<unsigned_type*>(state_ + next_),
|
||||
kBufferSize - next_));
|
||||
}
|
||||
return state_[next_++];
|
||||
}
|
||||
|
||||
private:
|
||||
// Buffer size.
|
||||
size_t next_; // index within state_
|
||||
result_type state_[kBufferSize];
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_POOL_URBG_H_
|
||||
91
Pods/abseil/absl/random/internal/randen.cc
generated
Normal file
91
Pods/abseil/absl/random/internal/randen.cc
generated
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/random/internal/randen.h"
|
||||
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/random/internal/randen_detect.h"
|
||||
|
||||
// RANDen = RANDom generator or beetroots in Swiss High German.
|
||||
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
|
||||
// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
|
||||
//
|
||||
// High-level summary:
|
||||
// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is
|
||||
// a sponge-like random generator that requires a cryptographic permutation.
|
||||
// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by
|
||||
// achieving backtracking resistance with only one Permute() per buffer.
|
||||
//
|
||||
// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round
|
||||
// Function" constructs up to 1024-bit permutations using an improved
|
||||
// Generalized Feistel network with 2-round AES-128 functions. This Feistel
|
||||
// block shuffle achieves diffusion faster and is less vulnerable to
|
||||
// sliced-biclique attacks than the Type-2 cyclic shuffle.
|
||||
//
|
||||
// 3) "Improving the Generalized Feistel" and "New criterion for diffusion
|
||||
// property" extends the same kind of improved Feistel block shuffle to 16
|
||||
// branches, which enables a 2048-bit permutation.
|
||||
//
|
||||
// We combine these three ideas and also change Simpira's subround keys from
|
||||
// structured/low-entropy counters to digits of Pi.
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
namespace {
|
||||
|
||||
struct RandenState {
|
||||
const void* keys;
|
||||
bool has_crypto;
|
||||
};
|
||||
|
||||
RandenState GetRandenState() {
|
||||
static const RandenState state = []() {
|
||||
RandenState tmp;
|
||||
#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
// HW AES Dispatch.
|
||||
if (HasRandenHwAesImplementation() && CPUSupportsRandenHwAes()) {
|
||||
tmp.has_crypto = true;
|
||||
tmp.keys = RandenHwAes::GetKeys();
|
||||
} else {
|
||||
tmp.has_crypto = false;
|
||||
tmp.keys = RandenSlow::GetKeys();
|
||||
}
|
||||
#elif ABSL_HAVE_ACCELERATED_AES
|
||||
// HW AES is enabled.
|
||||
tmp.has_crypto = true;
|
||||
tmp.keys = RandenHwAes::GetKeys();
|
||||
#else
|
||||
// HW AES is disabled.
|
||||
tmp.has_crypto = false;
|
||||
tmp.keys = RandenSlow::GetKeys();
|
||||
#endif
|
||||
return tmp;
|
||||
}();
|
||||
return state;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Randen::Randen() {
|
||||
auto tmp = GetRandenState();
|
||||
keys_ = tmp.keys;
|
||||
#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
has_crypto_ = tmp.has_crypto;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
96
Pods/abseil/absl/random/internal/randen.h
generated
Normal file
96
Pods/abseil/absl/random/internal/randen.h
generated
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_RANDEN_H_
|
||||
#define ABSL_RANDOM_INTERNAL_RANDEN_H_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "absl/random/internal/platform.h"
|
||||
#include "absl/random/internal/randen_hwaes.h"
|
||||
#include "absl/random/internal/randen_slow.h"
|
||||
#include "absl/random/internal/randen_traits.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// RANDen = RANDom generator or beetroots in Swiss High German.
|
||||
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
|
||||
// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
|
||||
//
|
||||
// Randen implements the basic state manipulation methods.
|
||||
class Randen {
|
||||
public:
|
||||
static constexpr size_t kStateBytes = RandenTraits::kStateBytes;
|
||||
static constexpr size_t kCapacityBytes = RandenTraits::kCapacityBytes;
|
||||
static constexpr size_t kSeedBytes = RandenTraits::kSeedBytes;
|
||||
|
||||
~Randen() = default;
|
||||
|
||||
Randen();
|
||||
|
||||
// Generate updates the randen sponge. The outer portion of the sponge
|
||||
// (kCapacityBytes .. kStateBytes) may be consumed as PRNG state.
|
||||
// REQUIRES: state points to kStateBytes of state.
|
||||
inline void Generate(void* state) const {
|
||||
#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
// HW AES Dispatch.
|
||||
if (has_crypto_) {
|
||||
RandenHwAes::Generate(keys_, state);
|
||||
} else {
|
||||
RandenSlow::Generate(keys_, state);
|
||||
}
|
||||
#elif ABSL_HAVE_ACCELERATED_AES
|
||||
// HW AES is enabled.
|
||||
RandenHwAes::Generate(keys_, state);
|
||||
#else
|
||||
// HW AES is disabled.
|
||||
RandenSlow::Generate(keys_, state);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Absorb incorporates additional seed material into the randen sponge. After
|
||||
// absorb returns, Generate must be called before the state may be consumed.
|
||||
// REQUIRES: seed points to kSeedBytes of seed.
|
||||
// REQUIRES: state points to kStateBytes of state.
|
||||
inline void Absorb(const void* seed, void* state) const {
|
||||
#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
// HW AES Dispatch.
|
||||
if (has_crypto_) {
|
||||
RandenHwAes::Absorb(seed, state);
|
||||
} else {
|
||||
RandenSlow::Absorb(seed, state);
|
||||
}
|
||||
#elif ABSL_HAVE_ACCELERATED_AES
|
||||
// HW AES is enabled.
|
||||
RandenHwAes::Absorb(seed, state);
|
||||
#else
|
||||
// HW AES is disabled.
|
||||
RandenSlow::Absorb(seed, state);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
const void* keys_;
|
||||
#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
|
||||
bool has_crypto_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_RANDEN_H_
|
||||
229
Pods/abseil/absl/random/internal/randen_detect.cc
generated
Normal file
229
Pods/abseil/absl/random/internal/randen_detect.cc
generated
Normal file
@@ -0,0 +1,229 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
|
||||
// symbols from arbitrary system and other headers, since it may be built
|
||||
// with different flags from other targets, using different levels of
|
||||
// optimization, potentially introducing ODR violations.
|
||||
|
||||
#include "absl/random/internal/randen_detect.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "absl/random/internal/platform.h"
|
||||
|
||||
#if !defined(__UCLIBC__) && defined(__GLIBC__) && \
|
||||
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16))
|
||||
#define ABSL_HAVE_GETAUXVAL
|
||||
#endif
|
||||
|
||||
#if defined(ABSL_ARCH_X86_64)
|
||||
#define ABSL_INTERNAL_USE_X86_CPUID
|
||||
#elif defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \
|
||||
defined(ABSL_ARCH_AARCH64)
|
||||
#if defined(__ANDROID__)
|
||||
#define ABSL_INTERNAL_USE_ANDROID_GETAUXVAL
|
||||
#define ABSL_INTERNAL_USE_GETAUXVAL
|
||||
#elif defined(__linux__) && defined(ABSL_HAVE_GETAUXVAL)
|
||||
#define ABSL_INTERNAL_USE_LINUX_GETAUXVAL
|
||||
#define ABSL_INTERNAL_USE_GETAUXVAL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ABSL_INTERNAL_USE_X86_CPUID)
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <intrin.h> // NOLINT(build/include_order)
|
||||
#elif ABSL_HAVE_BUILTIN(__cpuid)
|
||||
// MSVC-equivalent __cpuid intrinsic declaration for clang-like compilers
|
||||
// for non-Windows build environments.
|
||||
extern void __cpuid(int[4], int);
|
||||
#else
|
||||
// MSVC-equivalent __cpuid intrinsic function.
|
||||
static void __cpuid(int cpu_info[4], int info_type) {
|
||||
__asm__ volatile("cpuid \n\t"
|
||||
: "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]),
|
||||
"=d"(cpu_info[3])
|
||||
: "a"(info_type), "c"(0));
|
||||
}
|
||||
#endif
|
||||
#endif // ABSL_INTERNAL_USE_X86_CPUID
|
||||
|
||||
// On linux, just use the c-library getauxval call.
|
||||
#if defined(ABSL_INTERNAL_USE_LINUX_GETAUXVAL)
|
||||
|
||||
extern "C" unsigned long getauxval(unsigned long type); // NOLINT(runtime/int)
|
||||
|
||||
static uint32_t GetAuxval(uint32_t hwcap_type) {
|
||||
return static_cast<uint32_t>(getauxval(hwcap_type));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// On android, probe the system's C library for getauxval().
|
||||
// This is the same technique used by the android NDK cpu features library
|
||||
// as well as the google open-source cpu_features library.
|
||||
//
|
||||
// TODO(absl-team): Consider implementing a fallback of directly reading
|
||||
// /proc/self/auxval.
|
||||
#if defined(ABSL_INTERNAL_USE_ANDROID_GETAUXVAL)
|
||||
#include <dlfcn.h>
|
||||
|
||||
static uint32_t GetAuxval(uint32_t hwcap_type) {
|
||||
// NOLINTNEXTLINE(runtime/int)
|
||||
typedef unsigned long (*getauxval_func_t)(unsigned long);
|
||||
|
||||
dlerror(); // Cleaning error state before calling dlopen.
|
||||
void* libc_handle = dlopen("libc.so", RTLD_NOW);
|
||||
if (!libc_handle) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t result = 0;
|
||||
void* sym = dlsym(libc_handle, "getauxval");
|
||||
if (sym) {
|
||||
getauxval_func_t func;
|
||||
memcpy(&func, &sym, sizeof(func));
|
||||
result = static_cast<uint32_t>((*func)(hwcap_type));
|
||||
}
|
||||
dlclose(libc_handle);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// The default return at the end of the function might be unreachable depending
|
||||
// on the configuration. Ignore that warning.
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunreachable-code-return"
|
||||
#endif
|
||||
|
||||
// CPUSupportsRandenHwAes returns whether the CPU is a microarchitecture
|
||||
// which supports the crpyto/aes instructions or extensions necessary to use the
|
||||
// accelerated RandenHwAes implementation.
|
||||
//
|
||||
// 1. For x86 it is sufficient to use the CPUID instruction to detect whether
|
||||
// the cpu supports AES instructions. Done.
|
||||
//
|
||||
// Fon non-x86 it is much more complicated.
|
||||
//
|
||||
// 2. When ABSL_INTERNAL_USE_GETAUXVAL is defined, use getauxval() (either
|
||||
// the direct c-library version, or the android probing version which loads
|
||||
// libc), and read the hardware capability bits.
|
||||
// This is based on the technique used by boringssl uses to detect
|
||||
// cpu capabilities, and should allow us to enable crypto in the android
|
||||
// builds where it is supported.
|
||||
//
|
||||
// 3. Use the default for the compiler architecture.
|
||||
//
|
||||
|
||||
bool CPUSupportsRandenHwAes() {
|
||||
#if defined(ABSL_INTERNAL_USE_X86_CPUID)
|
||||
// 1. For x86: Use CPUID to detect the required AES instruction set.
|
||||
int regs[4];
|
||||
__cpuid(reinterpret_cast<int*>(regs), 1);
|
||||
return regs[2] & (1 << 25); // AES
|
||||
|
||||
#elif defined(ABSL_INTERNAL_USE_GETAUXVAL)
|
||||
// 2. Use getauxval() to read the hardware bits and determine
|
||||
// cpu capabilities.
|
||||
|
||||
#define AT_HWCAP 16
|
||||
#define AT_HWCAP2 26
|
||||
#if defined(ABSL_ARCH_PPC)
|
||||
// For Power / PPC: Expect that the cpu supports VCRYPTO
|
||||
// See https://members.openpowerfoundation.org/document/dl/576
|
||||
// VCRYPTO should be present in POWER8 >= 2.07.
|
||||
// Uses Linux kernel constants from arch/powerpc/include/uapi/asm/cputable.h
|
||||
static const uint32_t kVCRYPTO = 0x02000000;
|
||||
const uint32_t hwcap = GetAuxval(AT_HWCAP2);
|
||||
return (hwcap & kVCRYPTO) != 0;
|
||||
|
||||
#elif defined(ABSL_ARCH_ARM)
|
||||
// For ARM: Require crypto+neon
|
||||
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500f/CIHBIBBA.html
|
||||
// Uses Linux kernel constants from arch/arm64/include/asm/hwcap.h
|
||||
static const uint32_t kNEON = 1 << 12;
|
||||
uint32_t hwcap = GetAuxval(AT_HWCAP);
|
||||
if ((hwcap & kNEON) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// And use it again to detect AES.
|
||||
static const uint32_t kAES = 1 << 0;
|
||||
const uint32_t hwcap2 = GetAuxval(AT_HWCAP2);
|
||||
return (hwcap2 & kAES) != 0;
|
||||
|
||||
#elif defined(ABSL_ARCH_AARCH64)
|
||||
// For AARCH64: Require crypto+neon
|
||||
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500f/CIHBIBBA.html
|
||||
static const uint32_t kNEON = 1 << 1;
|
||||
static const uint32_t kAES = 1 << 3;
|
||||
const uint32_t hwcap = GetAuxval(AT_HWCAP);
|
||||
return ((hwcap & kNEON) != 0) && ((hwcap & kAES) != 0);
|
||||
#endif
|
||||
|
||||
#else // ABSL_INTERNAL_USE_GETAUXVAL
|
||||
// 3. By default, assume that the compiler default.
|
||||
return ABSL_HAVE_ACCELERATED_AES ? true : false;
|
||||
|
||||
#endif
|
||||
// NOTE: There are some other techniques that may be worth trying:
|
||||
//
|
||||
// * Use an environment variable: ABSL_RANDOM_USE_HWAES
|
||||
//
|
||||
// * Rely on compiler-generated target-based dispatch.
|
||||
// Using x86/gcc it might look something like this:
|
||||
//
|
||||
// int __attribute__((target("aes"))) HasAes() { return 1; }
|
||||
// int __attribute__((target("default"))) HasAes() { return 0; }
|
||||
//
|
||||
// This does not work on all architecture/compiler combinations.
|
||||
//
|
||||
// * On Linux consider reading /proc/cpuinfo and/or /proc/self/auxv.
|
||||
// These files have lines which are easy to parse; for ARM/AARCH64 it is quite
|
||||
// easy to find the Features: line and extract aes / neon. Likewise for
|
||||
// PPC.
|
||||
//
|
||||
// * Fork a process and test for SIGILL:
|
||||
//
|
||||
// * Many architectures have instructions to read the ISA. Unfortunately
|
||||
// most of those require that the code is running in ring 0 /
|
||||
// protected-mode.
|
||||
//
|
||||
// There are several examples. e.g. Valgrind detects PPC ISA 2.07:
|
||||
// https://github.com/lu-zero/valgrind/blob/master/none/tests/ppc64/test_isa_2_07_part1.c
|
||||
//
|
||||
// MRS <Xt>, ID_AA64ISAR0_EL1 ; Read ID_AA64ISAR0_EL1 into Xt
|
||||
//
|
||||
// uint64_t val;
|
||||
// __asm __volatile("mrs %0, id_aa64isar0_el1" :"=&r" (val));
|
||||
//
|
||||
// * Use a CPUID-style heuristic database.
|
||||
//
|
||||
// * On Apple (__APPLE__), AES is available on Arm v8.
|
||||
// https://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
33
Pods/abseil/absl/random/internal/randen_detect.h
generated
Normal file
33
Pods/abseil/absl/random/internal/randen_detect.h
generated
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_
|
||||
#define ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// Returns whether the current CPU supports RandenHwAes implementation.
|
||||
// This typically involves supporting cryptographic extensions on whichever
|
||||
// platform is currently running.
|
||||
bool CPUSupportsRandenHwAes();
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_
|
||||
264
Pods/abseil/absl/random/internal/randen_engine.h
generated
Normal file
264
Pods/abseil/absl/random/internal/randen_engine.h
generated
Normal file
@@ -0,0 +1,264 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_
|
||||
#define ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/internal/endian.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/random/internal/iostream_state_saver.h"
|
||||
#include "absl/random/internal/randen.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// Deterministic pseudorandom byte generator with backtracking resistance
|
||||
// (leaking the state does not compromise prior outputs). Based on Reverie
|
||||
// (see "A Robust and Sponge-Like PRNG with Improved Efficiency") instantiated
|
||||
// with an improved Simpira-like permutation.
|
||||
// Returns values of type "T" (must be a built-in unsigned integer type).
|
||||
//
|
||||
// RANDen = RANDom generator or beetroots in Swiss High German.
|
||||
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
|
||||
// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
|
||||
template <typename T>
|
||||
class alignas(8) randen_engine {
|
||||
public:
|
||||
// C++11 URBG interface:
|
||||
using result_type = T;
|
||||
static_assert(std::is_unsigned<result_type>::value,
|
||||
"randen_engine template argument must be a built-in unsigned "
|
||||
"integer type");
|
||||
|
||||
static constexpr result_type(min)() {
|
||||
return (std::numeric_limits<result_type>::min)();
|
||||
}
|
||||
|
||||
static constexpr result_type(max)() {
|
||||
return (std::numeric_limits<result_type>::max)();
|
||||
}
|
||||
|
||||
randen_engine() : randen_engine(0) {}
|
||||
explicit randen_engine(result_type seed_value) { seed(seed_value); }
|
||||
|
||||
template <class SeedSequence,
|
||||
typename = typename absl::enable_if_t<
|
||||
!std::is_same<SeedSequence, randen_engine>::value>>
|
||||
explicit randen_engine(SeedSequence&& seq) {
|
||||
seed(seq);
|
||||
}
|
||||
|
||||
// alignment requirements dictate custom copy and move constructors.
|
||||
randen_engine(const randen_engine& other)
|
||||
: next_(other.next_), impl_(other.impl_) {
|
||||
std::memcpy(state(), other.state(), kStateSizeT * sizeof(result_type));
|
||||
}
|
||||
randen_engine& operator=(const randen_engine& other) {
|
||||
next_ = other.next_;
|
||||
impl_ = other.impl_;
|
||||
std::memcpy(state(), other.state(), kStateSizeT * sizeof(result_type));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Returns random bits from the buffer in units of result_type.
|
||||
result_type operator()() {
|
||||
// Refill the buffer if needed (unlikely).
|
||||
auto* begin = state();
|
||||
if (next_ >= kStateSizeT) {
|
||||
next_ = kCapacityT;
|
||||
impl_.Generate(begin);
|
||||
}
|
||||
return little_endian::ToHost(begin[next_++]);
|
||||
}
|
||||
|
||||
template <class SeedSequence>
|
||||
typename absl::enable_if_t<
|
||||
!std::is_convertible<SeedSequence, result_type>::value>
|
||||
seed(SeedSequence&& seq) {
|
||||
// Zeroes the state.
|
||||
seed();
|
||||
reseed(seq);
|
||||
}
|
||||
|
||||
void seed(result_type seed_value = 0) {
|
||||
next_ = kStateSizeT;
|
||||
// Zeroes the inner state and fills the outer state with seed_value to
|
||||
// mimic the behaviour of reseed
|
||||
auto* begin = state();
|
||||
std::fill(begin, begin + kCapacityT, 0);
|
||||
std::fill(begin + kCapacityT, begin + kStateSizeT, seed_value);
|
||||
}
|
||||
|
||||
// Inserts entropy into (part of) the state. Calling this periodically with
|
||||
// sufficient entropy ensures prediction resistance (attackers cannot predict
|
||||
// future outputs even if state is compromised).
|
||||
template <class SeedSequence>
|
||||
void reseed(SeedSequence& seq) {
|
||||
using sequence_result_type = typename SeedSequence::result_type;
|
||||
static_assert(sizeof(sequence_result_type) == 4,
|
||||
"SeedSequence::result_type must be 32-bit");
|
||||
constexpr size_t kBufferSize =
|
||||
Randen::kSeedBytes / sizeof(sequence_result_type);
|
||||
alignas(16) sequence_result_type buffer[kBufferSize];
|
||||
|
||||
// Randen::Absorb XORs the seed into state, which is then mixed by a call
|
||||
// to Randen::Generate. Seeding with only the provided entropy is preferred
|
||||
// to using an arbitrary generate() call, so use [rand.req.seed_seq]
|
||||
// size as a proxy for the number of entropy units that can be generated
|
||||
// without relying on seed sequence mixing...
|
||||
const size_t entropy_size = seq.size();
|
||||
if (entropy_size < kBufferSize) {
|
||||
// ... and only request that many values, or 256-bits, when unspecified.
|
||||
const size_t requested_entropy = (entropy_size == 0) ? 8u : entropy_size;
|
||||
std::fill(buffer + requested_entropy, buffer + kBufferSize, 0);
|
||||
seq.generate(buffer, buffer + requested_entropy);
|
||||
#ifdef ABSL_IS_BIG_ENDIAN
|
||||
// Randen expects the seed buffer to be in Little Endian; reverse it on
|
||||
// Big Endian platforms.
|
||||
for (sequence_result_type& e : buffer) {
|
||||
e = absl::little_endian::FromHost(e);
|
||||
}
|
||||
#endif
|
||||
// The Randen paper suggests preferentially initializing even-numbered
|
||||
// 128-bit vectors of the randen state (there are 16 such vectors).
|
||||
// The seed data is merged into the state offset by 128-bits, which
|
||||
// implies preferring seed bytes [16..31, ..., 208..223]. Since the
|
||||
// buffer is 32-bit values, we swap the corresponding buffer positions in
|
||||
// 128-bit chunks.
|
||||
size_t dst = kBufferSize;
|
||||
while (dst > 7) {
|
||||
// leave the odd bucket as-is.
|
||||
dst -= 4;
|
||||
size_t src = dst >> 1;
|
||||
// swap 128-bits into the even bucket
|
||||
std::swap(buffer[--dst], buffer[--src]);
|
||||
std::swap(buffer[--dst], buffer[--src]);
|
||||
std::swap(buffer[--dst], buffer[--src]);
|
||||
std::swap(buffer[--dst], buffer[--src]);
|
||||
}
|
||||
} else {
|
||||
seq.generate(buffer, buffer + kBufferSize);
|
||||
}
|
||||
impl_.Absorb(buffer, state());
|
||||
|
||||
// Generate will be called when operator() is called
|
||||
next_ = kStateSizeT;
|
||||
}
|
||||
|
||||
void discard(uint64_t count) {
|
||||
uint64_t step = std::min<uint64_t>(kStateSizeT - next_, count);
|
||||
count -= step;
|
||||
|
||||
constexpr uint64_t kRateT = kStateSizeT - kCapacityT;
|
||||
auto* begin = state();
|
||||
while (count > 0) {
|
||||
next_ = kCapacityT;
|
||||
impl_.Generate(*reinterpret_cast<result_type(*)[kStateSizeT]>(begin));
|
||||
step = std::min<uint64_t>(kRateT, count);
|
||||
count -= step;
|
||||
}
|
||||
next_ += step;
|
||||
}
|
||||
|
||||
bool operator==(const randen_engine& other) const {
|
||||
const auto* begin = state();
|
||||
return next_ == other.next_ &&
|
||||
std::equal(begin, begin + kStateSizeT, other.state());
|
||||
}
|
||||
|
||||
bool operator!=(const randen_engine& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
|
||||
const randen_engine<T>& engine) { // NOLINT(runtime/references)
|
||||
using numeric_type =
|
||||
typename random_internal::stream_format_type<result_type>::type;
|
||||
auto saver = random_internal::make_ostream_state_saver(os);
|
||||
auto* it = engine.state();
|
||||
for (auto* end = it + kStateSizeT; it < end; ++it) {
|
||||
// In the case that `elem` is `uint8_t`, it must be cast to something
|
||||
// larger so that it prints as an integer rather than a character. For
|
||||
// simplicity, apply the cast all circumstances.
|
||||
os << static_cast<numeric_type>(little_endian::FromHost(*it))
|
||||
<< os.fill();
|
||||
}
|
||||
os << engine.next_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
friend std::basic_istream<CharT, Traits>& operator>>(
|
||||
std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
|
||||
randen_engine<T>& engine) { // NOLINT(runtime/references)
|
||||
using numeric_type =
|
||||
typename random_internal::stream_format_type<result_type>::type;
|
||||
result_type state[kStateSizeT];
|
||||
size_t next;
|
||||
for (auto& elem : state) {
|
||||
// It is not possible to read uint8_t from wide streams, so it is
|
||||
// necessary to read a wider type and then cast it to uint8_t.
|
||||
numeric_type value;
|
||||
is >> value;
|
||||
elem = little_endian::ToHost(static_cast<result_type>(value));
|
||||
}
|
||||
is >> next;
|
||||
if (is.fail()) {
|
||||
return is;
|
||||
}
|
||||
std::memcpy(engine.state(), state, sizeof(state));
|
||||
engine.next_ = next;
|
||||
return is;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr size_t kStateSizeT =
|
||||
Randen::kStateBytes / sizeof(result_type);
|
||||
static constexpr size_t kCapacityT =
|
||||
Randen::kCapacityBytes / sizeof(result_type);
|
||||
|
||||
// Returns the state array pointer, which is aligned to 16 bytes.
|
||||
// The first kCapacityT are the `inner' sponge; the remainder are available.
|
||||
result_type* state() {
|
||||
return reinterpret_cast<result_type*>(
|
||||
(reinterpret_cast<uintptr_t>(&raw_state_) & 0xf) ? (raw_state_ + 8)
|
||||
: raw_state_);
|
||||
}
|
||||
const result_type* state() const {
|
||||
return const_cast<randen_engine*>(this)->state();
|
||||
}
|
||||
|
||||
// raw state array, manually aligned in state(). This overallocates
|
||||
// by 8 bytes since C++ does not guarantee extended heap alignment.
|
||||
alignas(8) char raw_state_[Randen::kStateBytes + 8];
|
||||
size_t next_; // index within state()
|
||||
Randen impl_;
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_
|
||||
526
Pods/abseil/absl/random/internal/randen_hwaes.cc
generated
Normal file
526
Pods/abseil/absl/random/internal/randen_hwaes.cc
generated
Normal file
@@ -0,0 +1,526 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
|
||||
// symbols from arbitrary system and other headers, since it may be built
|
||||
// with different flags from other targets, using different levels of
|
||||
// optimization, potentially introducing ODR violations.
|
||||
|
||||
#include "absl/random/internal/randen_hwaes.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/numeric/int128.h"
|
||||
#include "absl/random/internal/platform.h"
|
||||
#include "absl/random/internal/randen_traits.h"
|
||||
|
||||
// ABSL_RANDEN_HWAES_IMPL indicates whether this file will contain
|
||||
// a hardware accelerated implementation of randen, or whether it
|
||||
// will contain stubs that exit the process.
|
||||
#if ABSL_HAVE_ACCELERATED_AES
|
||||
// The following platforms have implemented RandenHwAes.
|
||||
#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) || \
|
||||
defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \
|
||||
defined(ABSL_ARCH_AARCH64)
|
||||
#define ABSL_RANDEN_HWAES_IMPL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(ABSL_RANDEN_HWAES_IMPL)
|
||||
// No accelerated implementation is supported.
|
||||
// The RandenHwAes functions are stubs that print an error and exit.
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// No accelerated implementation.
|
||||
bool HasRandenHwAesImplementation() { return false; }
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
const void* RandenHwAes::GetKeys() {
|
||||
// Attempted to dispatch to an unsupported dispatch target.
|
||||
const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
|
||||
fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
|
||||
exit(1);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
void RandenHwAes::Absorb(const void*, void*) {
|
||||
// Attempted to dispatch to an unsupported dispatch target.
|
||||
const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
|
||||
fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
void RandenHwAes::Generate(const void*, void*) {
|
||||
// Attempted to dispatch to an unsupported dispatch target.
|
||||
const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
|
||||
fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#else // defined(ABSL_RANDEN_HWAES_IMPL)
|
||||
//
|
||||
// Accelerated implementations are supported.
|
||||
// We need the per-architecture includes and defines.
|
||||
//
|
||||
namespace {
|
||||
|
||||
using absl::random_internal::RandenTraits;
|
||||
|
||||
} // namespace
|
||||
|
||||
// TARGET_CRYPTO defines a crypto attribute for each architecture.
|
||||
//
|
||||
// NOTE: Evaluate whether we should eliminate ABSL_TARGET_CRYPTO.
|
||||
#if (defined(__clang__) || defined(__GNUC__))
|
||||
#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
|
||||
#define ABSL_TARGET_CRYPTO __attribute__((target("aes")))
|
||||
#elif defined(ABSL_ARCH_PPC)
|
||||
#define ABSL_TARGET_CRYPTO __attribute__((target("crypto")))
|
||||
#else
|
||||
#define ABSL_TARGET_CRYPTO
|
||||
#endif
|
||||
#else
|
||||
#define ABSL_TARGET_CRYPTO
|
||||
#endif
|
||||
|
||||
#if defined(ABSL_ARCH_PPC)
|
||||
// NOTE: Keep in mind that PPC can operate in little-endian or big-endian mode,
|
||||
// however the PPC altivec vector registers (and thus the AES instructions)
|
||||
// always operate in big-endian mode.
|
||||
|
||||
#include <altivec.h>
|
||||
// <altivec.h> #defines vector __vector; in C++, this is bad form.
|
||||
#undef vector
|
||||
#undef bool
|
||||
|
||||
// Rely on the PowerPC AltiVec vector operations for accelerated AES
|
||||
// instructions. GCC support of the PPC vector types is described in:
|
||||
// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/PowerPC-AltiVec_002fVSX-Built-in-Functions.html
|
||||
//
|
||||
// Already provides operator^=.
|
||||
using Vector128 = __vector unsigned long long; // NOLINT(runtime/int)
|
||||
|
||||
namespace {
|
||||
inline ABSL_TARGET_CRYPTO Vector128 ReverseBytes(const Vector128& v) {
|
||||
// Reverses the bytes of the vector.
|
||||
const __vector unsigned char perm = {15, 14, 13, 12, 11, 10, 9, 8,
|
||||
7, 6, 5, 4, 3, 2, 1, 0};
|
||||
return vec_perm(v, v, perm);
|
||||
}
|
||||
|
||||
// WARNING: these load/store in native byte order. It is OK to load and then
|
||||
// store an unchanged vector, but interpreting the bits as a number or input
|
||||
// to AES will have undefined results.
|
||||
inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
|
||||
return vec_vsx_ld(0, reinterpret_cast<const Vector128*>(from));
|
||||
}
|
||||
|
||||
inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
|
||||
vec_vsx_st(v, 0, reinterpret_cast<Vector128*>(to));
|
||||
}
|
||||
|
||||
// One round of AES. "round_key" is a public constant for breaking the
|
||||
// symmetry of AES (ensures previously equal columns differ afterwards).
|
||||
inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
|
||||
const Vector128& round_key) {
|
||||
return Vector128(__builtin_crypto_vcipher(state, round_key));
|
||||
}
|
||||
|
||||
// Enables native loads in the round loop by pre-swapping.
|
||||
inline ABSL_TARGET_CRYPTO void SwapEndian(absl::uint128* state) {
|
||||
for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) {
|
||||
Vector128Store(ReverseBytes(Vector128Load(state + block)), state + block);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)
|
||||
|
||||
// Rely on the ARM NEON+Crypto advanced simd types, defined in <arm_neon.h>.
|
||||
// uint8x16_t is the user alias for underlying __simd128_uint8_t type.
|
||||
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0073a/IHI0073A_arm_neon_intrinsics_ref.pdf
|
||||
//
|
||||
// <arm_neon> defines the following
|
||||
//
|
||||
// typedef __attribute__((neon_vector_type(16))) uint8_t uint8x16_t;
|
||||
// typedef __attribute__((neon_vector_type(16))) int8_t int8x16_t;
|
||||
// typedef __attribute__((neon_polyvector_type(16))) int8_t poly8x16_t;
|
||||
//
|
||||
// vld1q_v
|
||||
// vst1q_v
|
||||
// vaeseq_v
|
||||
// vaesmcq_v
|
||||
#include <arm_neon.h>
|
||||
|
||||
// Already provides operator^=.
|
||||
using Vector128 = uint8x16_t;
|
||||
|
||||
namespace {
|
||||
|
||||
inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
|
||||
return vld1q_u8(reinterpret_cast<const uint8_t*>(from));
|
||||
}
|
||||
|
||||
inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
|
||||
vst1q_u8(reinterpret_cast<uint8_t*>(to), v);
|
||||
}
|
||||
|
||||
// One round of AES. "round_key" is a public constant for breaking the
|
||||
// symmetry of AES (ensures previously equal columns differ afterwards).
|
||||
inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
|
||||
const Vector128& round_key) {
|
||||
// It is important to always use the full round function - omitting the
|
||||
// final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf]
|
||||
// and does not help because we never decrypt.
|
||||
//
|
||||
// Note that ARM divides AES instructions differently than x86 / PPC,
|
||||
// And we need to skip the first AddRoundKey step and add an extra
|
||||
// AddRoundKey step to the end. Lucky for us this is just XOR.
|
||||
return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key;
|
||||
}
|
||||
|
||||
inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {}
|
||||
|
||||
} // namespace
|
||||
|
||||
#elif defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
|
||||
// On x86 we rely on the aesni instructions
|
||||
#include <immintrin.h>
|
||||
|
||||
namespace {
|
||||
|
||||
// Vector128 class is only wrapper for __m128i, benchmark indicates that it's
|
||||
// faster than using __m128i directly.
|
||||
class Vector128 {
|
||||
public:
|
||||
// Convert from/to intrinsics.
|
||||
inline explicit Vector128(const __m128i& v) : data_(v) {}
|
||||
|
||||
inline __m128i data() const { return data_; }
|
||||
|
||||
inline Vector128& operator^=(const Vector128& other) {
|
||||
data_ = _mm_xor_si128(data_, other.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
__m128i data_;
|
||||
};
|
||||
|
||||
inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
|
||||
return Vector128(_mm_load_si128(reinterpret_cast<const __m128i*>(from)));
|
||||
}
|
||||
|
||||
inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
|
||||
_mm_store_si128(reinterpret_cast<__m128i*>(to), v.data());
|
||||
}
|
||||
|
||||
// One round of AES. "round_key" is a public constant for breaking the
|
||||
// symmetry of AES (ensures previously equal columns differ afterwards).
|
||||
inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
|
||||
const Vector128& round_key) {
|
||||
// It is important to always use the full round function - omitting the
|
||||
// final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf]
|
||||
// and does not help because we never decrypt.
|
||||
return Vector128(_mm_aesenc_si128(state.data(), round_key.data()));
|
||||
}
|
||||
|
||||
inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#endif
|
||||
|
||||
// At this point, all of the platform-specific features have been defined /
|
||||
// implemented.
|
||||
//
|
||||
// REQUIRES: using Vector128 = ...
|
||||
// REQUIRES: Vector128 Vector128Load(void*) {...}
|
||||
// REQUIRES: void Vector128Store(Vector128, void*) {...}
|
||||
// REQUIRES: Vector128 AesRound(Vector128, Vector128) {...}
|
||||
// REQUIRES: void SwapEndian(uint64_t*) {...}
|
||||
//
|
||||
// PROVIDES: absl::random_internal::RandenHwAes::Absorb
|
||||
// PROVIDES: absl::random_internal::RandenHwAes::Generate
|
||||
namespace {
|
||||
|
||||
// Block shuffles applies a shuffle to the entire state between AES rounds.
|
||||
// Improved odd-even shuffle from "New criterion for diffusion property".
|
||||
inline ABSL_TARGET_CRYPTO void BlockShuffle(absl::uint128* state) {
|
||||
static_assert(RandenTraits::kFeistelBlocks == 16,
|
||||
"Expecting 16 FeistelBlocks.");
|
||||
|
||||
constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = {
|
||||
7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12};
|
||||
|
||||
const Vector128 v0 = Vector128Load(state + shuffle[0]);
|
||||
const Vector128 v1 = Vector128Load(state + shuffle[1]);
|
||||
const Vector128 v2 = Vector128Load(state + shuffle[2]);
|
||||
const Vector128 v3 = Vector128Load(state + shuffle[3]);
|
||||
const Vector128 v4 = Vector128Load(state + shuffle[4]);
|
||||
const Vector128 v5 = Vector128Load(state + shuffle[5]);
|
||||
const Vector128 v6 = Vector128Load(state + shuffle[6]);
|
||||
const Vector128 v7 = Vector128Load(state + shuffle[7]);
|
||||
const Vector128 w0 = Vector128Load(state + shuffle[8]);
|
||||
const Vector128 w1 = Vector128Load(state + shuffle[9]);
|
||||
const Vector128 w2 = Vector128Load(state + shuffle[10]);
|
||||
const Vector128 w3 = Vector128Load(state + shuffle[11]);
|
||||
const Vector128 w4 = Vector128Load(state + shuffle[12]);
|
||||
const Vector128 w5 = Vector128Load(state + shuffle[13]);
|
||||
const Vector128 w6 = Vector128Load(state + shuffle[14]);
|
||||
const Vector128 w7 = Vector128Load(state + shuffle[15]);
|
||||
|
||||
Vector128Store(v0, state + 0);
|
||||
Vector128Store(v1, state + 1);
|
||||
Vector128Store(v2, state + 2);
|
||||
Vector128Store(v3, state + 3);
|
||||
Vector128Store(v4, state + 4);
|
||||
Vector128Store(v5, state + 5);
|
||||
Vector128Store(v6, state + 6);
|
||||
Vector128Store(v7, state + 7);
|
||||
Vector128Store(w0, state + 8);
|
||||
Vector128Store(w1, state + 9);
|
||||
Vector128Store(w2, state + 10);
|
||||
Vector128Store(w3, state + 11);
|
||||
Vector128Store(w4, state + 12);
|
||||
Vector128Store(w5, state + 13);
|
||||
Vector128Store(w6, state + 14);
|
||||
Vector128Store(w7, state + 15);
|
||||
}
|
||||
|
||||
// Feistel round function using two AES subrounds. Very similar to F()
|
||||
// from Simpira v2, but with independent subround keys. Uses 17 AES rounds
|
||||
// per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in
|
||||
// parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel
|
||||
// XORs are 'free' (included in the second AES instruction).
|
||||
inline ABSL_TARGET_CRYPTO const absl::uint128* FeistelRound(
|
||||
absl::uint128* state,
|
||||
const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
|
||||
static_assert(RandenTraits::kFeistelBlocks == 16,
|
||||
"Expecting 16 FeistelBlocks.");
|
||||
|
||||
// MSVC does a horrible job at unrolling loops.
|
||||
// So we unroll the loop by hand to improve the performance.
|
||||
const Vector128 s0 = Vector128Load(state + 0);
|
||||
const Vector128 s1 = Vector128Load(state + 1);
|
||||
const Vector128 s2 = Vector128Load(state + 2);
|
||||
const Vector128 s3 = Vector128Load(state + 3);
|
||||
const Vector128 s4 = Vector128Load(state + 4);
|
||||
const Vector128 s5 = Vector128Load(state + 5);
|
||||
const Vector128 s6 = Vector128Load(state + 6);
|
||||
const Vector128 s7 = Vector128Load(state + 7);
|
||||
const Vector128 s8 = Vector128Load(state + 8);
|
||||
const Vector128 s9 = Vector128Load(state + 9);
|
||||
const Vector128 s10 = Vector128Load(state + 10);
|
||||
const Vector128 s11 = Vector128Load(state + 11);
|
||||
const Vector128 s12 = Vector128Load(state + 12);
|
||||
const Vector128 s13 = Vector128Load(state + 13);
|
||||
const Vector128 s14 = Vector128Load(state + 14);
|
||||
const Vector128 s15 = Vector128Load(state + 15);
|
||||
|
||||
// Encode even blocks with keys.
|
||||
const Vector128 e0 = AesRound(s0, Vector128Load(keys + 0));
|
||||
const Vector128 e2 = AesRound(s2, Vector128Load(keys + 1));
|
||||
const Vector128 e4 = AesRound(s4, Vector128Load(keys + 2));
|
||||
const Vector128 e6 = AesRound(s6, Vector128Load(keys + 3));
|
||||
const Vector128 e8 = AesRound(s8, Vector128Load(keys + 4));
|
||||
const Vector128 e10 = AesRound(s10, Vector128Load(keys + 5));
|
||||
const Vector128 e12 = AesRound(s12, Vector128Load(keys + 6));
|
||||
const Vector128 e14 = AesRound(s14, Vector128Load(keys + 7));
|
||||
|
||||
// Encode odd blocks with even output from above.
|
||||
const Vector128 o1 = AesRound(e0, s1);
|
||||
const Vector128 o3 = AesRound(e2, s3);
|
||||
const Vector128 o5 = AesRound(e4, s5);
|
||||
const Vector128 o7 = AesRound(e6, s7);
|
||||
const Vector128 o9 = AesRound(e8, s9);
|
||||
const Vector128 o11 = AesRound(e10, s11);
|
||||
const Vector128 o13 = AesRound(e12, s13);
|
||||
const Vector128 o15 = AesRound(e14, s15);
|
||||
|
||||
// Store odd blocks. (These will be shuffled later).
|
||||
Vector128Store(o1, state + 1);
|
||||
Vector128Store(o3, state + 3);
|
||||
Vector128Store(o5, state + 5);
|
||||
Vector128Store(o7, state + 7);
|
||||
Vector128Store(o9, state + 9);
|
||||
Vector128Store(o11, state + 11);
|
||||
Vector128Store(o13, state + 13);
|
||||
Vector128Store(o15, state + 15);
|
||||
|
||||
return keys + 8;
|
||||
}
|
||||
|
||||
// Cryptographic permutation based via type-2 Generalized Feistel Network.
|
||||
// Indistinguishable from ideal by chosen-ciphertext adversaries using less than
|
||||
// 2^64 queries if the round function is a PRF. This is similar to the b=8 case
|
||||
// of Simpira v2, but more efficient than its generic construction for b=16.
|
||||
inline ABSL_TARGET_CRYPTO void Permute(
|
||||
absl::uint128* state,
|
||||
const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
|
||||
// (Successfully unrolled; the first iteration jumps into the second half)
|
||||
#ifdef __clang__
|
||||
#pragma clang loop unroll_count(2)
|
||||
#endif
|
||||
for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) {
|
||||
keys = FeistelRound(state, keys);
|
||||
BlockShuffle(state);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
bool HasRandenHwAesImplementation() { return true; }
|
||||
|
||||
const void* ABSL_TARGET_CRYPTO RandenHwAes::GetKeys() {
|
||||
// Round keys for one AES per Feistel round and branch.
|
||||
// The canonical implementation uses first digits of Pi.
|
||||
#if defined(ABSL_ARCH_PPC)
|
||||
return kRandenRoundKeysBE;
|
||||
#else
|
||||
return kRandenRoundKeys;
|
||||
#endif
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void,
|
||||
void* state_void) {
|
||||
static_assert(RandenTraits::kCapacityBytes / sizeof(Vector128) == 1,
|
||||
"Unexpected Randen kCapacityBlocks");
|
||||
static_assert(RandenTraits::kStateBytes / sizeof(Vector128) == 16,
|
||||
"Unexpected Randen kStateBlocks");
|
||||
|
||||
auto* state = reinterpret_cast<absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>(
|
||||
state_void);
|
||||
const auto* seed =
|
||||
reinterpret_cast<const absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>(
|
||||
seed_void);
|
||||
|
||||
Vector128 b1 = Vector128Load(state + 1);
|
||||
b1 ^= Vector128Load(seed + 0);
|
||||
Vector128Store(b1, state + 1);
|
||||
|
||||
Vector128 b2 = Vector128Load(state + 2);
|
||||
b2 ^= Vector128Load(seed + 1);
|
||||
Vector128Store(b2, state + 2);
|
||||
|
||||
Vector128 b3 = Vector128Load(state + 3);
|
||||
b3 ^= Vector128Load(seed + 2);
|
||||
Vector128Store(b3, state + 3);
|
||||
|
||||
Vector128 b4 = Vector128Load(state + 4);
|
||||
b4 ^= Vector128Load(seed + 3);
|
||||
Vector128Store(b4, state + 4);
|
||||
|
||||
Vector128 b5 = Vector128Load(state + 5);
|
||||
b5 ^= Vector128Load(seed + 4);
|
||||
Vector128Store(b5, state + 5);
|
||||
|
||||
Vector128 b6 = Vector128Load(state + 6);
|
||||
b6 ^= Vector128Load(seed + 5);
|
||||
Vector128Store(b6, state + 6);
|
||||
|
||||
Vector128 b7 = Vector128Load(state + 7);
|
||||
b7 ^= Vector128Load(seed + 6);
|
||||
Vector128Store(b7, state + 7);
|
||||
|
||||
Vector128 b8 = Vector128Load(state + 8);
|
||||
b8 ^= Vector128Load(seed + 7);
|
||||
Vector128Store(b8, state + 8);
|
||||
|
||||
Vector128 b9 = Vector128Load(state + 9);
|
||||
b9 ^= Vector128Load(seed + 8);
|
||||
Vector128Store(b9, state + 9);
|
||||
|
||||
Vector128 b10 = Vector128Load(state + 10);
|
||||
b10 ^= Vector128Load(seed + 9);
|
||||
Vector128Store(b10, state + 10);
|
||||
|
||||
Vector128 b11 = Vector128Load(state + 11);
|
||||
b11 ^= Vector128Load(seed + 10);
|
||||
Vector128Store(b11, state + 11);
|
||||
|
||||
Vector128 b12 = Vector128Load(state + 12);
|
||||
b12 ^= Vector128Load(seed + 11);
|
||||
Vector128Store(b12, state + 12);
|
||||
|
||||
Vector128 b13 = Vector128Load(state + 13);
|
||||
b13 ^= Vector128Load(seed + 12);
|
||||
Vector128Store(b13, state + 13);
|
||||
|
||||
Vector128 b14 = Vector128Load(state + 14);
|
||||
b14 ^= Vector128Load(seed + 13);
|
||||
Vector128Store(b14, state + 14);
|
||||
|
||||
Vector128 b15 = Vector128Load(state + 15);
|
||||
b15 ^= Vector128Load(seed + 14);
|
||||
Vector128Store(b15, state + 15);
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void,
|
||||
void* state_void) {
|
||||
static_assert(RandenTraits::kCapacityBytes == sizeof(Vector128),
|
||||
"Capacity mismatch");
|
||||
|
||||
auto* state = reinterpret_cast<absl::uint128*>(state_void);
|
||||
const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void);
|
||||
|
||||
const Vector128 prev_inner = Vector128Load(state);
|
||||
|
||||
SwapEndian(state);
|
||||
|
||||
Permute(state, keys);
|
||||
|
||||
SwapEndian(state);
|
||||
|
||||
// Ensure backtracking resistance.
|
||||
Vector128 inner = Vector128Load(state);
|
||||
inner ^= prev_inner;
|
||||
Vector128Store(inner, state);
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // (ABSL_RANDEN_HWAES_IMPL)
|
||||
50
Pods/abseil/absl/random/internal/randen_hwaes.h
generated
Normal file
50
Pods/abseil/absl/random/internal/randen_hwaes.h
generated
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_
|
||||
#define ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
|
||||
// symbols from arbitrary system and other headers, since it may be built
|
||||
// with different flags from other targets, using different levels of
|
||||
// optimization, potentially introducing ODR violations.
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// RANDen = RANDom generator or beetroots in Swiss High German.
|
||||
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
|
||||
// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
|
||||
//
|
||||
// RandenHwAes implements the basic state manipulation methods.
|
||||
class RandenHwAes {
|
||||
public:
|
||||
static void Generate(const void* keys, void* state_void);
|
||||
static void Absorb(const void* seed_void, void* state_void);
|
||||
static const void* GetKeys();
|
||||
};
|
||||
|
||||
// HasRandenHwAesImplementation returns true when there is an accelerated
|
||||
// implementation, and false otherwise. If there is no implementation,
|
||||
// then attempting to use it will abort the program.
|
||||
bool HasRandenHwAesImplementation();
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_
|
||||
462
Pods/abseil/absl/random/internal/randen_round_keys.cc
generated
Normal file
462
Pods/abseil/absl/random/internal/randen_round_keys.cc
generated
Normal file
@@ -0,0 +1,462 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/random/internal/randen_traits.h"
|
||||
|
||||
// This file contains only the round keys for randen.
|
||||
//
|
||||
// "Nothing up my sleeve" numbers from the first hex digits of Pi, obtained
|
||||
// from http://hexpi.sourceforge.net/. The array was generated by following
|
||||
// Python script:
|
||||
|
||||
/*
|
||||
python >tmp.cc << EOF
|
||||
"""Generates Randen round keys array from pi-hex.62500.txt file."""
|
||||
import binascii
|
||||
|
||||
KEYS = 17 * 8
|
||||
|
||||
def chunks(l, n):
|
||||
"""Yield successive n-sized chunks from l."""
|
||||
for i in range(0, len(l), n):
|
||||
yield l[i:i + n]
|
||||
|
||||
def pairwise(t):
|
||||
"""Transforms sequence into sequence of pairs."""
|
||||
it = iter(t)
|
||||
return zip(it,it)
|
||||
|
||||
def digits_from_pi():
|
||||
"""Reads digits from hexpi.sourceforge.net file."""
|
||||
with open("pi-hex.62500.txt") as file:
|
||||
return file.read()
|
||||
|
||||
def digits_from_urandom():
|
||||
"""Reads digits from /dev/urandom."""
|
||||
with open("/dev/urandom") as file:
|
||||
return binascii.hexlify(file.read(KEYS * 16))
|
||||
|
||||
def print_row(b)
|
||||
print(" 0x{0}, 0x{1}, 0x{2}, 0x{3}, 0x{4}, 0x{5}, 0x{6}, 0x{7}, 0x{8}, 0x{9},
|
||||
0x{10}, 0x{11}, 0x{12}, 0x{13}, 0x{14}, 0x{15},".format(*b))
|
||||
|
||||
|
||||
digits = digits_from_pi()
|
||||
#digits = digits_from_urandom()
|
||||
|
||||
print("namespace {")
|
||||
print("static constexpr size_t kKeyBytes = {0};\n".format(KEYS * 16))
|
||||
print("}")
|
||||
|
||||
print("alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = {")
|
||||
|
||||
for i, u16 in zip(range(KEYS), chunks(digits, 32)):
|
||||
b = list(chunks(u16, 2))
|
||||
print_row(b)
|
||||
|
||||
print("};")
|
||||
|
||||
print("alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = {")
|
||||
|
||||
for i, u16 in zip(range(KEYS), chunks(digits, 32)):
|
||||
b = list(chunks(u16, 2))
|
||||
b.reverse()
|
||||
print_row(b)
|
||||
|
||||
print("};")
|
||||
|
||||
EOF
|
||||
|
||||
*/
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
namespace {
|
||||
static constexpr size_t kKeyBytes = 2176;
|
||||
}
|
||||
|
||||
alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = {
|
||||
0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, 0x13, 0x19, 0x8A, 0x2E,
|
||||
0x03, 0x70, 0x73, 0x44, 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0,
|
||||
0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89, 0x45, 0x28, 0x21, 0xE6,
|
||||
0x38, 0xD0, 0x13, 0x77, 0xBE, 0x54, 0x66, 0xCF, 0x34, 0xE9, 0x0C, 0x6C,
|
||||
0xC0, 0xAC, 0x29, 0xB7, 0xC9, 0x7C, 0x50, 0xDD, 0x3F, 0x84, 0xD5, 0xB5,
|
||||
0xB5, 0x47, 0x09, 0x17, 0x92, 0x16, 0xD5, 0xD9, 0x89, 0x79, 0xFB, 0x1B,
|
||||
0xD1, 0x31, 0x0B, 0xA6, 0x98, 0xDF, 0xB5, 0xAC, 0x2F, 0xFD, 0x72, 0xDB,
|
||||
0xD0, 0x1A, 0xDF, 0xB7, 0xB8, 0xE1, 0xAF, 0xED, 0x6A, 0x26, 0x7E, 0x96,
|
||||
0xBA, 0x7C, 0x90, 0x45, 0xF1, 0x2C, 0x7F, 0x99, 0x24, 0xA1, 0x99, 0x47,
|
||||
0xB3, 0x91, 0x6C, 0xF7, 0x08, 0x01, 0xF2, 0xE2, 0x85, 0x8E, 0xFC, 0x16,
|
||||
0x63, 0x69, 0x20, 0xD8, 0x71, 0x57, 0x4E, 0x69, 0xA4, 0x58, 0xFE, 0xA3,
|
||||
0xF4, 0x93, 0x3D, 0x7E, 0x0D, 0x95, 0x74, 0x8F, 0x72, 0x8E, 0xB6, 0x58,
|
||||
0x71, 0x8B, 0xCD, 0x58, 0x82, 0x15, 0x4A, 0xEE, 0x7B, 0x54, 0xA4, 0x1D,
|
||||
0xC2, 0x5A, 0x59, 0xB5, 0x9C, 0x30, 0xD5, 0x39, 0x2A, 0xF2, 0x60, 0x13,
|
||||
0xC5, 0xD1, 0xB0, 0x23, 0x28, 0x60, 0x85, 0xF0, 0xCA, 0x41, 0x79, 0x18,
|
||||
0xB8, 0xDB, 0x38, 0xEF, 0x8E, 0x79, 0xDC, 0xB0, 0x60, 0x3A, 0x18, 0x0E,
|
||||
0x6C, 0x9E, 0x0E, 0x8B, 0xB0, 0x1E, 0x8A, 0x3E, 0xD7, 0x15, 0x77, 0xC1,
|
||||
0xBD, 0x31, 0x4B, 0x27, 0x78, 0xAF, 0x2F, 0xDA, 0x55, 0x60, 0x5C, 0x60,
|
||||
0xE6, 0x55, 0x25, 0xF3, 0xAA, 0x55, 0xAB, 0x94, 0x57, 0x48, 0x98, 0x62,
|
||||
0x63, 0xE8, 0x14, 0x40, 0x55, 0xCA, 0x39, 0x6A, 0x2A, 0xAB, 0x10, 0xB6,
|
||||
0xB4, 0xCC, 0x5C, 0x34, 0x11, 0x41, 0xE8, 0xCE, 0xA1, 0x54, 0x86, 0xAF,
|
||||
0x7C, 0x72, 0xE9, 0x93, 0xB3, 0xEE, 0x14, 0x11, 0x63, 0x6F, 0xBC, 0x2A,
|
||||
0x2B, 0xA9, 0xC5, 0x5D, 0x74, 0x18, 0x31, 0xF6, 0xCE, 0x5C, 0x3E, 0x16,
|
||||
0x9B, 0x87, 0x93, 0x1E, 0xAF, 0xD6, 0xBA, 0x33, 0x6C, 0x24, 0xCF, 0x5C,
|
||||
0x7A, 0x32, 0x53, 0x81, 0x28, 0x95, 0x86, 0x77, 0x3B, 0x8F, 0x48, 0x98,
|
||||
0x6B, 0x4B, 0xB9, 0xAF, 0xC4, 0xBF, 0xE8, 0x1B, 0x66, 0x28, 0x21, 0x93,
|
||||
0x61, 0xD8, 0x09, 0xCC, 0xFB, 0x21, 0xA9, 0x91, 0x48, 0x7C, 0xAC, 0x60,
|
||||
0x5D, 0xEC, 0x80, 0x32, 0xEF, 0x84, 0x5D, 0x5D, 0xE9, 0x85, 0x75, 0xB1,
|
||||
0xDC, 0x26, 0x23, 0x02, 0xEB, 0x65, 0x1B, 0x88, 0x23, 0x89, 0x3E, 0x81,
|
||||
0xD3, 0x96, 0xAC, 0xC5, 0x0F, 0x6D, 0x6F, 0xF3, 0x83, 0xF4, 0x42, 0x39,
|
||||
0x2E, 0x0B, 0x44, 0x82, 0xA4, 0x84, 0x20, 0x04, 0x69, 0xC8, 0xF0, 0x4A,
|
||||
0x9E, 0x1F, 0x9B, 0x5E, 0x21, 0xC6, 0x68, 0x42, 0xF6, 0xE9, 0x6C, 0x9A,
|
||||
0x67, 0x0C, 0x9C, 0x61, 0xAB, 0xD3, 0x88, 0xF0, 0x6A, 0x51, 0xA0, 0xD2,
|
||||
0xD8, 0x54, 0x2F, 0x68, 0x96, 0x0F, 0xA7, 0x28, 0xAB, 0x51, 0x33, 0xA3,
|
||||
0x6E, 0xEF, 0x0B, 0x6C, 0x13, 0x7A, 0x3B, 0xE4, 0xBA, 0x3B, 0xF0, 0x50,
|
||||
0x7E, 0xFB, 0x2A, 0x98, 0xA1, 0xF1, 0x65, 0x1D, 0x39, 0xAF, 0x01, 0x76,
|
||||
0x66, 0xCA, 0x59, 0x3E, 0x82, 0x43, 0x0E, 0x88, 0x8C, 0xEE, 0x86, 0x19,
|
||||
0x45, 0x6F, 0x9F, 0xB4, 0x7D, 0x84, 0xA5, 0xC3, 0x3B, 0x8B, 0x5E, 0xBE,
|
||||
0xE0, 0x6F, 0x75, 0xD8, 0x85, 0xC1, 0x20, 0x73, 0x40, 0x1A, 0x44, 0x9F,
|
||||
0x56, 0xC1, 0x6A, 0xA6, 0x4E, 0xD3, 0xAA, 0x62, 0x36, 0x3F, 0x77, 0x06,
|
||||
0x1B, 0xFE, 0xDF, 0x72, 0x42, 0x9B, 0x02, 0x3D, 0x37, 0xD0, 0xD7, 0x24,
|
||||
0xD0, 0x0A, 0x12, 0x48, 0xDB, 0x0F, 0xEA, 0xD3, 0x49, 0xF1, 0xC0, 0x9B,
|
||||
0x07, 0x53, 0x72, 0xC9, 0x80, 0x99, 0x1B, 0x7B, 0x25, 0xD4, 0x79, 0xD8,
|
||||
0xF6, 0xE8, 0xDE, 0xF7, 0xE3, 0xFE, 0x50, 0x1A, 0xB6, 0x79, 0x4C, 0x3B,
|
||||
0x97, 0x6C, 0xE0, 0xBD, 0x04, 0xC0, 0x06, 0xBA, 0xC1, 0xA9, 0x4F, 0xB6,
|
||||
0x40, 0x9F, 0x60, 0xC4, 0x5E, 0x5C, 0x9E, 0xC2, 0x19, 0x6A, 0x24, 0x63,
|
||||
0x68, 0xFB, 0x6F, 0xAF, 0x3E, 0x6C, 0x53, 0xB5, 0x13, 0x39, 0xB2, 0xEB,
|
||||
0x3B, 0x52, 0xEC, 0x6F, 0x6D, 0xFC, 0x51, 0x1F, 0x9B, 0x30, 0x95, 0x2C,
|
||||
0xCC, 0x81, 0x45, 0x44, 0xAF, 0x5E, 0xBD, 0x09, 0xBE, 0xE3, 0xD0, 0x04,
|
||||
0xDE, 0x33, 0x4A, 0xFD, 0x66, 0x0F, 0x28, 0x07, 0x19, 0x2E, 0x4B, 0xB3,
|
||||
0xC0, 0xCB, 0xA8, 0x57, 0x45, 0xC8, 0x74, 0x0F, 0xD2, 0x0B, 0x5F, 0x39,
|
||||
0xB9, 0xD3, 0xFB, 0xDB, 0x55, 0x79, 0xC0, 0xBD, 0x1A, 0x60, 0x32, 0x0A,
|
||||
0xD6, 0xA1, 0x00, 0xC6, 0x40, 0x2C, 0x72, 0x79, 0x67, 0x9F, 0x25, 0xFE,
|
||||
0xFB, 0x1F, 0xA3, 0xCC, 0x8E, 0xA5, 0xE9, 0xF8, 0xDB, 0x32, 0x22, 0xF8,
|
||||
0x3C, 0x75, 0x16, 0xDF, 0xFD, 0x61, 0x6B, 0x15, 0x2F, 0x50, 0x1E, 0xC8,
|
||||
0xAD, 0x05, 0x52, 0xAB, 0x32, 0x3D, 0xB5, 0xFA, 0xFD, 0x23, 0x87, 0x60,
|
||||
0x53, 0x31, 0x7B, 0x48, 0x3E, 0x00, 0xDF, 0x82, 0x9E, 0x5C, 0x57, 0xBB,
|
||||
0xCA, 0x6F, 0x8C, 0xA0, 0x1A, 0x87, 0x56, 0x2E, 0xDF, 0x17, 0x69, 0xDB,
|
||||
0xD5, 0x42, 0xA8, 0xF6, 0x28, 0x7E, 0xFF, 0xC3, 0xAC, 0x67, 0x32, 0xC6,
|
||||
0x8C, 0x4F, 0x55, 0x73, 0x69, 0x5B, 0x27, 0xB0, 0xBB, 0xCA, 0x58, 0xC8,
|
||||
0xE1, 0xFF, 0xA3, 0x5D, 0xB8, 0xF0, 0x11, 0xA0, 0x10, 0xFA, 0x3D, 0x98,
|
||||
0xFD, 0x21, 0x83, 0xB8, 0x4A, 0xFC, 0xB5, 0x6C, 0x2D, 0xD1, 0xD3, 0x5B,
|
||||
0x9A, 0x53, 0xE4, 0x79, 0xB6, 0xF8, 0x45, 0x65, 0xD2, 0x8E, 0x49, 0xBC,
|
||||
0x4B, 0xFB, 0x97, 0x90, 0xE1, 0xDD, 0xF2, 0xDA, 0xA4, 0xCB, 0x7E, 0x33,
|
||||
0x62, 0xFB, 0x13, 0x41, 0xCE, 0xE4, 0xC6, 0xE8, 0xEF, 0x20, 0xCA, 0xDA,
|
||||
0x36, 0x77, 0x4C, 0x01, 0xD0, 0x7E, 0x9E, 0xFE, 0x2B, 0xF1, 0x1F, 0xB4,
|
||||
0x95, 0xDB, 0xDA, 0x4D, 0xAE, 0x90, 0x91, 0x98, 0xEA, 0xAD, 0x8E, 0x71,
|
||||
0x6B, 0x93, 0xD5, 0xA0, 0xD0, 0x8E, 0xD1, 0xD0, 0xAF, 0xC7, 0x25, 0xE0,
|
||||
0x8E, 0x3C, 0x5B, 0x2F, 0x8E, 0x75, 0x94, 0xB7, 0x8F, 0xF6, 0xE2, 0xFB,
|
||||
0xF2, 0x12, 0x2B, 0x64, 0x88, 0x88, 0xB8, 0x12, 0x90, 0x0D, 0xF0, 0x1C,
|
||||
0x4F, 0xAD, 0x5E, 0xA0, 0x68, 0x8F, 0xC3, 0x1C, 0xD1, 0xCF, 0xF1, 0x91,
|
||||
0xB3, 0xA8, 0xC1, 0xAD, 0x2F, 0x2F, 0x22, 0x18, 0xBE, 0x0E, 0x17, 0x77,
|
||||
0xEA, 0x75, 0x2D, 0xFE, 0x8B, 0x02, 0x1F, 0xA1, 0xE5, 0xA0, 0xCC, 0x0F,
|
||||
0xB5, 0x6F, 0x74, 0xE8, 0x18, 0xAC, 0xF3, 0xD6, 0xCE, 0x89, 0xE2, 0x99,
|
||||
0xB4, 0xA8, 0x4F, 0xE0, 0xFD, 0x13, 0xE0, 0xB7, 0x7C, 0xC4, 0x3B, 0x81,
|
||||
0xD2, 0xAD, 0xA8, 0xD9, 0x16, 0x5F, 0xA2, 0x66, 0x80, 0x95, 0x77, 0x05,
|
||||
0x93, 0xCC, 0x73, 0x14, 0x21, 0x1A, 0x14, 0x77, 0xE6, 0xAD, 0x20, 0x65,
|
||||
0x77, 0xB5, 0xFA, 0x86, 0xC7, 0x54, 0x42, 0xF5, 0xFB, 0x9D, 0x35, 0xCF,
|
||||
0xEB, 0xCD, 0xAF, 0x0C, 0x7B, 0x3E, 0x89, 0xA0, 0xD6, 0x41, 0x1B, 0xD3,
|
||||
0xAE, 0x1E, 0x7E, 0x49, 0x00, 0x25, 0x0E, 0x2D, 0x20, 0x71, 0xB3, 0x5E,
|
||||
0x22, 0x68, 0x00, 0xBB, 0x57, 0xB8, 0xE0, 0xAF, 0x24, 0x64, 0x36, 0x9B,
|
||||
0xF0, 0x09, 0xB9, 0x1E, 0x55, 0x63, 0x91, 0x1D, 0x59, 0xDF, 0xA6, 0xAA,
|
||||
0x78, 0xC1, 0x43, 0x89, 0xD9, 0x5A, 0x53, 0x7F, 0x20, 0x7D, 0x5B, 0xA2,
|
||||
0x02, 0xE5, 0xB9, 0xC5, 0x83, 0x26, 0x03, 0x76, 0x62, 0x95, 0xCF, 0xA9,
|
||||
0x11, 0xC8, 0x19, 0x68, 0x4E, 0x73, 0x4A, 0x41, 0xB3, 0x47, 0x2D, 0xCA,
|
||||
0x7B, 0x14, 0xA9, 0x4A, 0x1B, 0x51, 0x00, 0x52, 0x9A, 0x53, 0x29, 0x15,
|
||||
0xD6, 0x0F, 0x57, 0x3F, 0xBC, 0x9B, 0xC6, 0xE4, 0x2B, 0x60, 0xA4, 0x76,
|
||||
0x81, 0xE6, 0x74, 0x00, 0x08, 0xBA, 0x6F, 0xB5, 0x57, 0x1B, 0xE9, 0x1F,
|
||||
0xF2, 0x96, 0xEC, 0x6B, 0x2A, 0x0D, 0xD9, 0x15, 0xB6, 0x63, 0x65, 0x21,
|
||||
0xE7, 0xB9, 0xF9, 0xB6, 0xFF, 0x34, 0x05, 0x2E, 0xC5, 0x85, 0x56, 0x64,
|
||||
0x53, 0xB0, 0x2D, 0x5D, 0xA9, 0x9F, 0x8F, 0xA1, 0x08, 0xBA, 0x47, 0x99,
|
||||
0x6E, 0x85, 0x07, 0x6A, 0x4B, 0x7A, 0x70, 0xE9, 0xB5, 0xB3, 0x29, 0x44,
|
||||
0xDB, 0x75, 0x09, 0x2E, 0xC4, 0x19, 0x26, 0x23, 0xAD, 0x6E, 0xA6, 0xB0,
|
||||
0x49, 0xA7, 0xDF, 0x7D, 0x9C, 0xEE, 0x60, 0xB8, 0x8F, 0xED, 0xB2, 0x66,
|
||||
0xEC, 0xAA, 0x8C, 0x71, 0x69, 0x9A, 0x18, 0xFF, 0x56, 0x64, 0x52, 0x6C,
|
||||
0xC2, 0xB1, 0x9E, 0xE1, 0x19, 0x36, 0x02, 0xA5, 0x75, 0x09, 0x4C, 0x29,
|
||||
0xA0, 0x59, 0x13, 0x40, 0xE4, 0x18, 0x3A, 0x3E, 0x3F, 0x54, 0x98, 0x9A,
|
||||
0x5B, 0x42, 0x9D, 0x65, 0x6B, 0x8F, 0xE4, 0xD6, 0x99, 0xF7, 0x3F, 0xD6,
|
||||
0xA1, 0xD2, 0x9C, 0x07, 0xEF, 0xE8, 0x30, 0xF5, 0x4D, 0x2D, 0x38, 0xE6,
|
||||
0xF0, 0x25, 0x5D, 0xC1, 0x4C, 0xDD, 0x20, 0x86, 0x84, 0x70, 0xEB, 0x26,
|
||||
0x63, 0x82, 0xE9, 0xC6, 0x02, 0x1E, 0xCC, 0x5E, 0x09, 0x68, 0x6B, 0x3F,
|
||||
0x3E, 0xBA, 0xEF, 0xC9, 0x3C, 0x97, 0x18, 0x14, 0x6B, 0x6A, 0x70, 0xA1,
|
||||
0x68, 0x7F, 0x35, 0x84, 0x52, 0xA0, 0xE2, 0x86, 0xB7, 0x9C, 0x53, 0x05,
|
||||
0xAA, 0x50, 0x07, 0x37, 0x3E, 0x07, 0x84, 0x1C, 0x7F, 0xDE, 0xAE, 0x5C,
|
||||
0x8E, 0x7D, 0x44, 0xEC, 0x57, 0x16, 0xF2, 0xB8, 0xB0, 0x3A, 0xDA, 0x37,
|
||||
0xF0, 0x50, 0x0C, 0x0D, 0xF0, 0x1C, 0x1F, 0x04, 0x02, 0x00, 0xB3, 0xFF,
|
||||
0xAE, 0x0C, 0xF5, 0x1A, 0x3C, 0xB5, 0x74, 0xB2, 0x25, 0x83, 0x7A, 0x58,
|
||||
0xDC, 0x09, 0x21, 0xBD, 0xD1, 0x91, 0x13, 0xF9, 0x7C, 0xA9, 0x2F, 0xF6,
|
||||
0x94, 0x32, 0x47, 0x73, 0x22, 0xF5, 0x47, 0x01, 0x3A, 0xE5, 0xE5, 0x81,
|
||||
0x37, 0xC2, 0xDA, 0xDC, 0xC8, 0xB5, 0x76, 0x34, 0x9A, 0xF3, 0xDD, 0xA7,
|
||||
0xA9, 0x44, 0x61, 0x46, 0x0F, 0xD0, 0x03, 0x0E, 0xEC, 0xC8, 0xC7, 0x3E,
|
||||
0xA4, 0x75, 0x1E, 0x41, 0xE2, 0x38, 0xCD, 0x99, 0x3B, 0xEA, 0x0E, 0x2F,
|
||||
0x32, 0x80, 0xBB, 0xA1, 0x18, 0x3E, 0xB3, 0x31, 0x4E, 0x54, 0x8B, 0x38,
|
||||
0x4F, 0x6D, 0xB9, 0x08, 0x6F, 0x42, 0x0D, 0x03, 0xF6, 0x0A, 0x04, 0xBF,
|
||||
0x2C, 0xB8, 0x12, 0x90, 0x24, 0x97, 0x7C, 0x79, 0x56, 0x79, 0xB0, 0x72,
|
||||
0xBC, 0xAF, 0x89, 0xAF, 0xDE, 0x9A, 0x77, 0x1F, 0xD9, 0x93, 0x08, 0x10,
|
||||
0xB3, 0x8B, 0xAE, 0x12, 0xDC, 0xCF, 0x3F, 0x2E, 0x55, 0x12, 0x72, 0x1F,
|
||||
0x2E, 0x6B, 0x71, 0x24, 0x50, 0x1A, 0xDD, 0xE6, 0x9F, 0x84, 0xCD, 0x87,
|
||||
0x7A, 0x58, 0x47, 0x18, 0x74, 0x08, 0xDA, 0x17, 0xBC, 0x9F, 0x9A, 0xBC,
|
||||
0xE9, 0x4B, 0x7D, 0x8C, 0xEC, 0x7A, 0xEC, 0x3A, 0xDB, 0x85, 0x1D, 0xFA,
|
||||
0x63, 0x09, 0x43, 0x66, 0xC4, 0x64, 0xC3, 0xD2, 0xEF, 0x1C, 0x18, 0x47,
|
||||
0x32, 0x15, 0xD8, 0x08, 0xDD, 0x43, 0x3B, 0x37, 0x24, 0xC2, 0xBA, 0x16,
|
||||
0x12, 0xA1, 0x4D, 0x43, 0x2A, 0x65, 0xC4, 0x51, 0x50, 0x94, 0x00, 0x02,
|
||||
0x13, 0x3A, 0xE4, 0xDD, 0x71, 0xDF, 0xF8, 0x9E, 0x10, 0x31, 0x4E, 0x55,
|
||||
0x81, 0xAC, 0x77, 0xD6, 0x5F, 0x11, 0x19, 0x9B, 0x04, 0x35, 0x56, 0xF1,
|
||||
0xD7, 0xA3, 0xC7, 0x6B, 0x3C, 0x11, 0x18, 0x3B, 0x59, 0x24, 0xA5, 0x09,
|
||||
0xF2, 0x8F, 0xE6, 0xED, 0x97, 0xF1, 0xFB, 0xFA, 0x9E, 0xBA, 0xBF, 0x2C,
|
||||
0x1E, 0x15, 0x3C, 0x6E, 0x86, 0xE3, 0x45, 0x70, 0xEA, 0xE9, 0x6F, 0xB1,
|
||||
0x86, 0x0E, 0x5E, 0x0A, 0x5A, 0x3E, 0x2A, 0xB3, 0x77, 0x1F, 0xE7, 0x1C,
|
||||
0x4E, 0x3D, 0x06, 0xFA, 0x29, 0x65, 0xDC, 0xB9, 0x99, 0xE7, 0x1D, 0x0F,
|
||||
0x80, 0x3E, 0x89, 0xD6, 0x52, 0x66, 0xC8, 0x25, 0x2E, 0x4C, 0xC9, 0x78,
|
||||
0x9C, 0x10, 0xB3, 0x6A, 0xC6, 0x15, 0x0E, 0xBA, 0x94, 0xE2, 0xEA, 0x78,
|
||||
0xA6, 0xFC, 0x3C, 0x53, 0x1E, 0x0A, 0x2D, 0xF4, 0xF2, 0xF7, 0x4E, 0xA7,
|
||||
0x36, 0x1D, 0x2B, 0x3D, 0x19, 0x39, 0x26, 0x0F, 0x19, 0xC2, 0x79, 0x60,
|
||||
0x52, 0x23, 0xA7, 0x08, 0xF7, 0x13, 0x12, 0xB6, 0xEB, 0xAD, 0xFE, 0x6E,
|
||||
0xEA, 0xC3, 0x1F, 0x66, 0xE3, 0xBC, 0x45, 0x95, 0xA6, 0x7B, 0xC8, 0x83,
|
||||
0xB1, 0x7F, 0x37, 0xD1, 0x01, 0x8C, 0xFF, 0x28, 0xC3, 0x32, 0xDD, 0xEF,
|
||||
0xBE, 0x6C, 0x5A, 0xA5, 0x65, 0x58, 0x21, 0x85, 0x68, 0xAB, 0x97, 0x02,
|
||||
0xEE, 0xCE, 0xA5, 0x0F, 0xDB, 0x2F, 0x95, 0x3B, 0x2A, 0xEF, 0x7D, 0xAD,
|
||||
0x5B, 0x6E, 0x2F, 0x84, 0x15, 0x21, 0xB6, 0x28, 0x29, 0x07, 0x61, 0x70,
|
||||
0xEC, 0xDD, 0x47, 0x75, 0x61, 0x9F, 0x15, 0x10, 0x13, 0xCC, 0xA8, 0x30,
|
||||
0xEB, 0x61, 0xBD, 0x96, 0x03, 0x34, 0xFE, 0x1E, 0xAA, 0x03, 0x63, 0xCF,
|
||||
0xB5, 0x73, 0x5C, 0x90, 0x4C, 0x70, 0xA2, 0x39, 0xD5, 0x9E, 0x9E, 0x0B,
|
||||
0xCB, 0xAA, 0xDE, 0x14, 0xEE, 0xCC, 0x86, 0xBC, 0x60, 0x62, 0x2C, 0xA7,
|
||||
0x9C, 0xAB, 0x5C, 0xAB, 0xB2, 0xF3, 0x84, 0x6E, 0x64, 0x8B, 0x1E, 0xAF,
|
||||
0x19, 0xBD, 0xF0, 0xCA, 0xA0, 0x23, 0x69, 0xB9, 0x65, 0x5A, 0xBB, 0x50,
|
||||
0x40, 0x68, 0x5A, 0x32, 0x3C, 0x2A, 0xB4, 0xB3, 0x31, 0x9E, 0xE9, 0xD5,
|
||||
0xC0, 0x21, 0xB8, 0xF7, 0x9B, 0x54, 0x0B, 0x19, 0x87, 0x5F, 0xA0, 0x99,
|
||||
0x95, 0xF7, 0x99, 0x7E, 0x62, 0x3D, 0x7D, 0xA8, 0xF8, 0x37, 0x88, 0x9A,
|
||||
0x97, 0xE3, 0x2D, 0x77, 0x11, 0xED, 0x93, 0x5F, 0x16, 0x68, 0x12, 0x81,
|
||||
0x0E, 0x35, 0x88, 0x29, 0xC7, 0xE6, 0x1F, 0xD6, 0x96, 0xDE, 0xDF, 0xA1,
|
||||
0x78, 0x58, 0xBA, 0x99, 0x57, 0xF5, 0x84, 0xA5, 0x1B, 0x22, 0x72, 0x63,
|
||||
0x9B, 0x83, 0xC3, 0xFF, 0x1A, 0xC2, 0x46, 0x96, 0xCD, 0xB3, 0x0A, 0xEB,
|
||||
0x53, 0x2E, 0x30, 0x54, 0x8F, 0xD9, 0x48, 0xE4, 0x6D, 0xBC, 0x31, 0x28,
|
||||
0x58, 0xEB, 0xF2, 0xEF, 0x34, 0xC6, 0xFF, 0xEA, 0xFE, 0x28, 0xED, 0x61,
|
||||
0xEE, 0x7C, 0x3C, 0x73, 0x5D, 0x4A, 0x14, 0xD9, 0xE8, 0x64, 0xB7, 0xE3,
|
||||
0x42, 0x10, 0x5D, 0x14, 0x20, 0x3E, 0x13, 0xE0, 0x45, 0xEE, 0xE2, 0xB6,
|
||||
0xA3, 0xAA, 0xAB, 0xEA, 0xDB, 0x6C, 0x4F, 0x15, 0xFA, 0xCB, 0x4F, 0xD0,
|
||||
0xC7, 0x42, 0xF4, 0x42, 0xEF, 0x6A, 0xBB, 0xB5, 0x65, 0x4F, 0x3B, 0x1D,
|
||||
0x41, 0xCD, 0x21, 0x05, 0xD8, 0x1E, 0x79, 0x9E, 0x86, 0x85, 0x4D, 0xC7,
|
||||
0xE4, 0x4B, 0x47, 0x6A, 0x3D, 0x81, 0x62, 0x50, 0xCF, 0x62, 0xA1, 0xF2,
|
||||
0x5B, 0x8D, 0x26, 0x46, 0xFC, 0x88, 0x83, 0xA0, 0xC1, 0xC7, 0xB6, 0xA3,
|
||||
0x7F, 0x15, 0x24, 0xC3, 0x69, 0xCB, 0x74, 0x92, 0x47, 0x84, 0x8A, 0x0B,
|
||||
0x56, 0x92, 0xB2, 0x85, 0x09, 0x5B, 0xBF, 0x00, 0xAD, 0x19, 0x48, 0x9D,
|
||||
0x14, 0x62, 0xB1, 0x74, 0x23, 0x82, 0x0D, 0x00, 0x58, 0x42, 0x8D, 0x2A,
|
||||
0x0C, 0x55, 0xF5, 0xEA, 0x1D, 0xAD, 0xF4, 0x3E, 0x23, 0x3F, 0x70, 0x61,
|
||||
0x33, 0x72, 0xF0, 0x92, 0x8D, 0x93, 0x7E, 0x41, 0xD6, 0x5F, 0xEC, 0xF1,
|
||||
0x6C, 0x22, 0x3B, 0xDB, 0x7C, 0xDE, 0x37, 0x59, 0xCB, 0xEE, 0x74, 0x60,
|
||||
0x40, 0x85, 0xF2, 0xA7, 0xCE, 0x77, 0x32, 0x6E, 0xA6, 0x07, 0x80, 0x84,
|
||||
0x19, 0xF8, 0x50, 0x9E, 0xE8, 0xEF, 0xD8, 0x55, 0x61, 0xD9, 0x97, 0x35,
|
||||
0xA9, 0x69, 0xA7, 0xAA, 0xC5, 0x0C, 0x06, 0xC2, 0x5A, 0x04, 0xAB, 0xFC,
|
||||
0x80, 0x0B, 0xCA, 0xDC, 0x9E, 0x44, 0x7A, 0x2E, 0xC3, 0x45, 0x34, 0x84,
|
||||
0xFD, 0xD5, 0x67, 0x05, 0x0E, 0x1E, 0x9E, 0xC9, 0xDB, 0x73, 0xDB, 0xD3,
|
||||
0x10, 0x55, 0x88, 0xCD, 0x67, 0x5F, 0xDA, 0x79, 0xE3, 0x67, 0x43, 0x40,
|
||||
0xC5, 0xC4, 0x34, 0x65, 0x71, 0x3E, 0x38, 0xD8, 0x3D, 0x28, 0xF8, 0x9E,
|
||||
0xF1, 0x6D, 0xFF, 0x20, 0x15, 0x3E, 0x21, 0xE7, 0x8F, 0xB0, 0x3D, 0x4A,
|
||||
0xE6, 0xE3, 0x9F, 0x2B, 0xDB, 0x83, 0xAD, 0xF7, 0xE9, 0x3D, 0x5A, 0x68,
|
||||
0x94, 0x81, 0x40, 0xF7, 0xF6, 0x4C, 0x26, 0x1C, 0x94, 0x69, 0x29, 0x34,
|
||||
0x41, 0x15, 0x20, 0xF7, 0x76, 0x02, 0xD4, 0xF7, 0xBC, 0xF4, 0x6B, 0x2E,
|
||||
0xD4, 0xA1, 0x00, 0x68, 0xD4, 0x08, 0x24, 0x71, 0x33, 0x20, 0xF4, 0x6A,
|
||||
0x43, 0xB7, 0xD4, 0xB7, 0x50, 0x00, 0x61, 0xAF, 0x1E, 0x39, 0xF6, 0x2E,
|
||||
0x97, 0x24, 0x45, 0x46,
|
||||
};
|
||||
|
||||
alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = {
|
||||
0x44, 0x73, 0x70, 0x03, 0x2E, 0x8A, 0x19, 0x13, 0xD3, 0x08, 0xA3, 0x85,
|
||||
0x88, 0x6A, 0x3F, 0x24, 0x89, 0x6C, 0x4E, 0xEC, 0x98, 0xFA, 0x2E, 0x08,
|
||||
0xD0, 0x31, 0x9F, 0x29, 0x22, 0x38, 0x09, 0xA4, 0x6C, 0x0C, 0xE9, 0x34,
|
||||
0xCF, 0x66, 0x54, 0xBE, 0x77, 0x13, 0xD0, 0x38, 0xE6, 0x21, 0x28, 0x45,
|
||||
0x17, 0x09, 0x47, 0xB5, 0xB5, 0xD5, 0x84, 0x3F, 0xDD, 0x50, 0x7C, 0xC9,
|
||||
0xB7, 0x29, 0xAC, 0xC0, 0xAC, 0xB5, 0xDF, 0x98, 0xA6, 0x0B, 0x31, 0xD1,
|
||||
0x1B, 0xFB, 0x79, 0x89, 0xD9, 0xD5, 0x16, 0x92, 0x96, 0x7E, 0x26, 0x6A,
|
||||
0xED, 0xAF, 0xE1, 0xB8, 0xB7, 0xDF, 0x1A, 0xD0, 0xDB, 0x72, 0xFD, 0x2F,
|
||||
0xF7, 0x6C, 0x91, 0xB3, 0x47, 0x99, 0xA1, 0x24, 0x99, 0x7F, 0x2C, 0xF1,
|
||||
0x45, 0x90, 0x7C, 0xBA, 0x69, 0x4E, 0x57, 0x71, 0xD8, 0x20, 0x69, 0x63,
|
||||
0x16, 0xFC, 0x8E, 0x85, 0xE2, 0xF2, 0x01, 0x08, 0x58, 0xB6, 0x8E, 0x72,
|
||||
0x8F, 0x74, 0x95, 0x0D, 0x7E, 0x3D, 0x93, 0xF4, 0xA3, 0xFE, 0x58, 0xA4,
|
||||
0xB5, 0x59, 0x5A, 0xC2, 0x1D, 0xA4, 0x54, 0x7B, 0xEE, 0x4A, 0x15, 0x82,
|
||||
0x58, 0xCD, 0x8B, 0x71, 0xF0, 0x85, 0x60, 0x28, 0x23, 0xB0, 0xD1, 0xC5,
|
||||
0x13, 0x60, 0xF2, 0x2A, 0x39, 0xD5, 0x30, 0x9C, 0x0E, 0x18, 0x3A, 0x60,
|
||||
0xB0, 0xDC, 0x79, 0x8E, 0xEF, 0x38, 0xDB, 0xB8, 0x18, 0x79, 0x41, 0xCA,
|
||||
0x27, 0x4B, 0x31, 0xBD, 0xC1, 0x77, 0x15, 0xD7, 0x3E, 0x8A, 0x1E, 0xB0,
|
||||
0x8B, 0x0E, 0x9E, 0x6C, 0x94, 0xAB, 0x55, 0xAA, 0xF3, 0x25, 0x55, 0xE6,
|
||||
0x60, 0x5C, 0x60, 0x55, 0xDA, 0x2F, 0xAF, 0x78, 0xB6, 0x10, 0xAB, 0x2A,
|
||||
0x6A, 0x39, 0xCA, 0x55, 0x40, 0x14, 0xE8, 0x63, 0x62, 0x98, 0x48, 0x57,
|
||||
0x93, 0xE9, 0x72, 0x7C, 0xAF, 0x86, 0x54, 0xA1, 0xCE, 0xE8, 0x41, 0x11,
|
||||
0x34, 0x5C, 0xCC, 0xB4, 0xF6, 0x31, 0x18, 0x74, 0x5D, 0xC5, 0xA9, 0x2B,
|
||||
0x2A, 0xBC, 0x6F, 0x63, 0x11, 0x14, 0xEE, 0xB3, 0x5C, 0xCF, 0x24, 0x6C,
|
||||
0x33, 0xBA, 0xD6, 0xAF, 0x1E, 0x93, 0x87, 0x9B, 0x16, 0x3E, 0x5C, 0xCE,
|
||||
0xAF, 0xB9, 0x4B, 0x6B, 0x98, 0x48, 0x8F, 0x3B, 0x77, 0x86, 0x95, 0x28,
|
||||
0x81, 0x53, 0x32, 0x7A, 0x91, 0xA9, 0x21, 0xFB, 0xCC, 0x09, 0xD8, 0x61,
|
||||
0x93, 0x21, 0x28, 0x66, 0x1B, 0xE8, 0xBF, 0xC4, 0xB1, 0x75, 0x85, 0xE9,
|
||||
0x5D, 0x5D, 0x84, 0xEF, 0x32, 0x80, 0xEC, 0x5D, 0x60, 0xAC, 0x7C, 0x48,
|
||||
0xC5, 0xAC, 0x96, 0xD3, 0x81, 0x3E, 0x89, 0x23, 0x88, 0x1B, 0x65, 0xEB,
|
||||
0x02, 0x23, 0x26, 0xDC, 0x04, 0x20, 0x84, 0xA4, 0x82, 0x44, 0x0B, 0x2E,
|
||||
0x39, 0x42, 0xF4, 0x83, 0xF3, 0x6F, 0x6D, 0x0F, 0x9A, 0x6C, 0xE9, 0xF6,
|
||||
0x42, 0x68, 0xC6, 0x21, 0x5E, 0x9B, 0x1F, 0x9E, 0x4A, 0xF0, 0xC8, 0x69,
|
||||
0x68, 0x2F, 0x54, 0xD8, 0xD2, 0xA0, 0x51, 0x6A, 0xF0, 0x88, 0xD3, 0xAB,
|
||||
0x61, 0x9C, 0x0C, 0x67, 0xE4, 0x3B, 0x7A, 0x13, 0x6C, 0x0B, 0xEF, 0x6E,
|
||||
0xA3, 0x33, 0x51, 0xAB, 0x28, 0xA7, 0x0F, 0x96, 0x76, 0x01, 0xAF, 0x39,
|
||||
0x1D, 0x65, 0xF1, 0xA1, 0x98, 0x2A, 0xFB, 0x7E, 0x50, 0xF0, 0x3B, 0xBA,
|
||||
0xB4, 0x9F, 0x6F, 0x45, 0x19, 0x86, 0xEE, 0x8C, 0x88, 0x0E, 0x43, 0x82,
|
||||
0x3E, 0x59, 0xCA, 0x66, 0x73, 0x20, 0xC1, 0x85, 0xD8, 0x75, 0x6F, 0xE0,
|
||||
0xBE, 0x5E, 0x8B, 0x3B, 0xC3, 0xA5, 0x84, 0x7D, 0x06, 0x77, 0x3F, 0x36,
|
||||
0x62, 0xAA, 0xD3, 0x4E, 0xA6, 0x6A, 0xC1, 0x56, 0x9F, 0x44, 0x1A, 0x40,
|
||||
0x48, 0x12, 0x0A, 0xD0, 0x24, 0xD7, 0xD0, 0x37, 0x3D, 0x02, 0x9B, 0x42,
|
||||
0x72, 0xDF, 0xFE, 0x1B, 0x7B, 0x1B, 0x99, 0x80, 0xC9, 0x72, 0x53, 0x07,
|
||||
0x9B, 0xC0, 0xF1, 0x49, 0xD3, 0xEA, 0x0F, 0xDB, 0x3B, 0x4C, 0x79, 0xB6,
|
||||
0x1A, 0x50, 0xFE, 0xE3, 0xF7, 0xDE, 0xE8, 0xF6, 0xD8, 0x79, 0xD4, 0x25,
|
||||
0xC4, 0x60, 0x9F, 0x40, 0xB6, 0x4F, 0xA9, 0xC1, 0xBA, 0x06, 0xC0, 0x04,
|
||||
0xBD, 0xE0, 0x6C, 0x97, 0xB5, 0x53, 0x6C, 0x3E, 0xAF, 0x6F, 0xFB, 0x68,
|
||||
0x63, 0x24, 0x6A, 0x19, 0xC2, 0x9E, 0x5C, 0x5E, 0x2C, 0x95, 0x30, 0x9B,
|
||||
0x1F, 0x51, 0xFC, 0x6D, 0x6F, 0xEC, 0x52, 0x3B, 0xEB, 0xB2, 0x39, 0x13,
|
||||
0xFD, 0x4A, 0x33, 0xDE, 0x04, 0xD0, 0xE3, 0xBE, 0x09, 0xBD, 0x5E, 0xAF,
|
||||
0x44, 0x45, 0x81, 0xCC, 0x0F, 0x74, 0xC8, 0x45, 0x57, 0xA8, 0xCB, 0xC0,
|
||||
0xB3, 0x4B, 0x2E, 0x19, 0x07, 0x28, 0x0F, 0x66, 0x0A, 0x32, 0x60, 0x1A,
|
||||
0xBD, 0xC0, 0x79, 0x55, 0xDB, 0xFB, 0xD3, 0xB9, 0x39, 0x5F, 0x0B, 0xD2,
|
||||
0xCC, 0xA3, 0x1F, 0xFB, 0xFE, 0x25, 0x9F, 0x67, 0x79, 0x72, 0x2C, 0x40,
|
||||
0xC6, 0x00, 0xA1, 0xD6, 0x15, 0x6B, 0x61, 0xFD, 0xDF, 0x16, 0x75, 0x3C,
|
||||
0xF8, 0x22, 0x32, 0xDB, 0xF8, 0xE9, 0xA5, 0x8E, 0x60, 0x87, 0x23, 0xFD,
|
||||
0xFA, 0xB5, 0x3D, 0x32, 0xAB, 0x52, 0x05, 0xAD, 0xC8, 0x1E, 0x50, 0x2F,
|
||||
0xA0, 0x8C, 0x6F, 0xCA, 0xBB, 0x57, 0x5C, 0x9E, 0x82, 0xDF, 0x00, 0x3E,
|
||||
0x48, 0x7B, 0x31, 0x53, 0xC3, 0xFF, 0x7E, 0x28, 0xF6, 0xA8, 0x42, 0xD5,
|
||||
0xDB, 0x69, 0x17, 0xDF, 0x2E, 0x56, 0x87, 0x1A, 0xC8, 0x58, 0xCA, 0xBB,
|
||||
0xB0, 0x27, 0x5B, 0x69, 0x73, 0x55, 0x4F, 0x8C, 0xC6, 0x32, 0x67, 0xAC,
|
||||
0xB8, 0x83, 0x21, 0xFD, 0x98, 0x3D, 0xFA, 0x10, 0xA0, 0x11, 0xF0, 0xB8,
|
||||
0x5D, 0xA3, 0xFF, 0xE1, 0x65, 0x45, 0xF8, 0xB6, 0x79, 0xE4, 0x53, 0x9A,
|
||||
0x5B, 0xD3, 0xD1, 0x2D, 0x6C, 0xB5, 0xFC, 0x4A, 0x33, 0x7E, 0xCB, 0xA4,
|
||||
0xDA, 0xF2, 0xDD, 0xE1, 0x90, 0x97, 0xFB, 0x4B, 0xBC, 0x49, 0x8E, 0xD2,
|
||||
0x01, 0x4C, 0x77, 0x36, 0xDA, 0xCA, 0x20, 0xEF, 0xE8, 0xC6, 0xE4, 0xCE,
|
||||
0x41, 0x13, 0xFB, 0x62, 0x98, 0x91, 0x90, 0xAE, 0x4D, 0xDA, 0xDB, 0x95,
|
||||
0xB4, 0x1F, 0xF1, 0x2B, 0xFE, 0x9E, 0x7E, 0xD0, 0xE0, 0x25, 0xC7, 0xAF,
|
||||
0xD0, 0xD1, 0x8E, 0xD0, 0xA0, 0xD5, 0x93, 0x6B, 0x71, 0x8E, 0xAD, 0xEA,
|
||||
0x64, 0x2B, 0x12, 0xF2, 0xFB, 0xE2, 0xF6, 0x8F, 0xB7, 0x94, 0x75, 0x8E,
|
||||
0x2F, 0x5B, 0x3C, 0x8E, 0x1C, 0xC3, 0x8F, 0x68, 0xA0, 0x5E, 0xAD, 0x4F,
|
||||
0x1C, 0xF0, 0x0D, 0x90, 0x12, 0xB8, 0x88, 0x88, 0x77, 0x17, 0x0E, 0xBE,
|
||||
0x18, 0x22, 0x2F, 0x2F, 0xAD, 0xC1, 0xA8, 0xB3, 0x91, 0xF1, 0xCF, 0xD1,
|
||||
0xE8, 0x74, 0x6F, 0xB5, 0x0F, 0xCC, 0xA0, 0xE5, 0xA1, 0x1F, 0x02, 0x8B,
|
||||
0xFE, 0x2D, 0x75, 0xEA, 0xB7, 0xE0, 0x13, 0xFD, 0xE0, 0x4F, 0xA8, 0xB4,
|
||||
0x99, 0xE2, 0x89, 0xCE, 0xD6, 0xF3, 0xAC, 0x18, 0x05, 0x77, 0x95, 0x80,
|
||||
0x66, 0xA2, 0x5F, 0x16, 0xD9, 0xA8, 0xAD, 0xD2, 0x81, 0x3B, 0xC4, 0x7C,
|
||||
0x86, 0xFA, 0xB5, 0x77, 0x65, 0x20, 0xAD, 0xE6, 0x77, 0x14, 0x1A, 0x21,
|
||||
0x14, 0x73, 0xCC, 0x93, 0xA0, 0x89, 0x3E, 0x7B, 0x0C, 0xAF, 0xCD, 0xEB,
|
||||
0xCF, 0x35, 0x9D, 0xFB, 0xF5, 0x42, 0x54, 0xC7, 0x5E, 0xB3, 0x71, 0x20,
|
||||
0x2D, 0x0E, 0x25, 0x00, 0x49, 0x7E, 0x1E, 0xAE, 0xD3, 0x1B, 0x41, 0xD6,
|
||||
0x1E, 0xB9, 0x09, 0xF0, 0x9B, 0x36, 0x64, 0x24, 0xAF, 0xE0, 0xB8, 0x57,
|
||||
0xBB, 0x00, 0x68, 0x22, 0x7F, 0x53, 0x5A, 0xD9, 0x89, 0x43, 0xC1, 0x78,
|
||||
0xAA, 0xA6, 0xDF, 0x59, 0x1D, 0x91, 0x63, 0x55, 0xA9, 0xCF, 0x95, 0x62,
|
||||
0x76, 0x03, 0x26, 0x83, 0xC5, 0xB9, 0xE5, 0x02, 0xA2, 0x5B, 0x7D, 0x20,
|
||||
0x4A, 0xA9, 0x14, 0x7B, 0xCA, 0x2D, 0x47, 0xB3, 0x41, 0x4A, 0x73, 0x4E,
|
||||
0x68, 0x19, 0xC8, 0x11, 0xE4, 0xC6, 0x9B, 0xBC, 0x3F, 0x57, 0x0F, 0xD6,
|
||||
0x15, 0x29, 0x53, 0x9A, 0x52, 0x00, 0x51, 0x1B, 0x1F, 0xE9, 0x1B, 0x57,
|
||||
0xB5, 0x6F, 0xBA, 0x08, 0x00, 0x74, 0xE6, 0x81, 0x76, 0xA4, 0x60, 0x2B,
|
||||
0xB6, 0xF9, 0xB9, 0xE7, 0x21, 0x65, 0x63, 0xB6, 0x15, 0xD9, 0x0D, 0x2A,
|
||||
0x6B, 0xEC, 0x96, 0xF2, 0xA1, 0x8F, 0x9F, 0xA9, 0x5D, 0x2D, 0xB0, 0x53,
|
||||
0x64, 0x56, 0x85, 0xC5, 0x2E, 0x05, 0x34, 0xFF, 0x44, 0x29, 0xB3, 0xB5,
|
||||
0xE9, 0x70, 0x7A, 0x4B, 0x6A, 0x07, 0x85, 0x6E, 0x99, 0x47, 0xBA, 0x08,
|
||||
0x7D, 0xDF, 0xA7, 0x49, 0xB0, 0xA6, 0x6E, 0xAD, 0x23, 0x26, 0x19, 0xC4,
|
||||
0x2E, 0x09, 0x75, 0xDB, 0xFF, 0x18, 0x9A, 0x69, 0x71, 0x8C, 0xAA, 0xEC,
|
||||
0x66, 0xB2, 0xED, 0x8F, 0xB8, 0x60, 0xEE, 0x9C, 0x29, 0x4C, 0x09, 0x75,
|
||||
0xA5, 0x02, 0x36, 0x19, 0xE1, 0x9E, 0xB1, 0xC2, 0x6C, 0x52, 0x64, 0x56,
|
||||
0x65, 0x9D, 0x42, 0x5B, 0x9A, 0x98, 0x54, 0x3F, 0x3E, 0x3A, 0x18, 0xE4,
|
||||
0x40, 0x13, 0x59, 0xA0, 0xF5, 0x30, 0xE8, 0xEF, 0x07, 0x9C, 0xD2, 0xA1,
|
||||
0xD6, 0x3F, 0xF7, 0x99, 0xD6, 0xE4, 0x8F, 0x6B, 0x26, 0xEB, 0x70, 0x84,
|
||||
0x86, 0x20, 0xDD, 0x4C, 0xC1, 0x5D, 0x25, 0xF0, 0xE6, 0x38, 0x2D, 0x4D,
|
||||
0xC9, 0xEF, 0xBA, 0x3E, 0x3F, 0x6B, 0x68, 0x09, 0x5E, 0xCC, 0x1E, 0x02,
|
||||
0xC6, 0xE9, 0x82, 0x63, 0x86, 0xE2, 0xA0, 0x52, 0x84, 0x35, 0x7F, 0x68,
|
||||
0xA1, 0x70, 0x6A, 0x6B, 0x14, 0x18, 0x97, 0x3C, 0x5C, 0xAE, 0xDE, 0x7F,
|
||||
0x1C, 0x84, 0x07, 0x3E, 0x37, 0x07, 0x50, 0xAA, 0x05, 0x53, 0x9C, 0xB7,
|
||||
0x0D, 0x0C, 0x50, 0xF0, 0x37, 0xDA, 0x3A, 0xB0, 0xB8, 0xF2, 0x16, 0x57,
|
||||
0xEC, 0x44, 0x7D, 0x8E, 0xB2, 0x74, 0xB5, 0x3C, 0x1A, 0xF5, 0x0C, 0xAE,
|
||||
0xFF, 0xB3, 0x00, 0x02, 0x04, 0x1F, 0x1C, 0xF0, 0xF6, 0x2F, 0xA9, 0x7C,
|
||||
0xF9, 0x13, 0x91, 0xD1, 0xBD, 0x21, 0x09, 0xDC, 0x58, 0x7A, 0x83, 0x25,
|
||||
0xDC, 0xDA, 0xC2, 0x37, 0x81, 0xE5, 0xE5, 0x3A, 0x01, 0x47, 0xF5, 0x22,
|
||||
0x73, 0x47, 0x32, 0x94, 0x0E, 0x03, 0xD0, 0x0F, 0x46, 0x61, 0x44, 0xA9,
|
||||
0xA7, 0xDD, 0xF3, 0x9A, 0x34, 0x76, 0xB5, 0xC8, 0x2F, 0x0E, 0xEA, 0x3B,
|
||||
0x99, 0xCD, 0x38, 0xE2, 0x41, 0x1E, 0x75, 0xA4, 0x3E, 0xC7, 0xC8, 0xEC,
|
||||
0x08, 0xB9, 0x6D, 0x4F, 0x38, 0x8B, 0x54, 0x4E, 0x31, 0xB3, 0x3E, 0x18,
|
||||
0xA1, 0xBB, 0x80, 0x32, 0x79, 0x7C, 0x97, 0x24, 0x90, 0x12, 0xB8, 0x2C,
|
||||
0xBF, 0x04, 0x0A, 0xF6, 0x03, 0x0D, 0x42, 0x6F, 0x10, 0x08, 0x93, 0xD9,
|
||||
0x1F, 0x77, 0x9A, 0xDE, 0xAF, 0x89, 0xAF, 0xBC, 0x72, 0xB0, 0x79, 0x56,
|
||||
0x24, 0x71, 0x6B, 0x2E, 0x1F, 0x72, 0x12, 0x55, 0x2E, 0x3F, 0xCF, 0xDC,
|
||||
0x12, 0xAE, 0x8B, 0xB3, 0x17, 0xDA, 0x08, 0x74, 0x18, 0x47, 0x58, 0x7A,
|
||||
0x87, 0xCD, 0x84, 0x9F, 0xE6, 0xDD, 0x1A, 0x50, 0xFA, 0x1D, 0x85, 0xDB,
|
||||
0x3A, 0xEC, 0x7A, 0xEC, 0x8C, 0x7D, 0x4B, 0xE9, 0xBC, 0x9A, 0x9F, 0xBC,
|
||||
0x08, 0xD8, 0x15, 0x32, 0x47, 0x18, 0x1C, 0xEF, 0xD2, 0xC3, 0x64, 0xC4,
|
||||
0x66, 0x43, 0x09, 0x63, 0x51, 0xC4, 0x65, 0x2A, 0x43, 0x4D, 0xA1, 0x12,
|
||||
0x16, 0xBA, 0xC2, 0x24, 0x37, 0x3B, 0x43, 0xDD, 0x55, 0x4E, 0x31, 0x10,
|
||||
0x9E, 0xF8, 0xDF, 0x71, 0xDD, 0xE4, 0x3A, 0x13, 0x02, 0x00, 0x94, 0x50,
|
||||
0x6B, 0xC7, 0xA3, 0xD7, 0xF1, 0x56, 0x35, 0x04, 0x9B, 0x19, 0x11, 0x5F,
|
||||
0xD6, 0x77, 0xAC, 0x81, 0xFA, 0xFB, 0xF1, 0x97, 0xED, 0xE6, 0x8F, 0xF2,
|
||||
0x09, 0xA5, 0x24, 0x59, 0x3B, 0x18, 0x11, 0x3C, 0xB1, 0x6F, 0xE9, 0xEA,
|
||||
0x70, 0x45, 0xE3, 0x86, 0x6E, 0x3C, 0x15, 0x1E, 0x2C, 0xBF, 0xBA, 0x9E,
|
||||
0xFA, 0x06, 0x3D, 0x4E, 0x1C, 0xE7, 0x1F, 0x77, 0xB3, 0x2A, 0x3E, 0x5A,
|
||||
0x0A, 0x5E, 0x0E, 0x86, 0x25, 0xC8, 0x66, 0x52, 0xD6, 0x89, 0x3E, 0x80,
|
||||
0x0F, 0x1D, 0xE7, 0x99, 0xB9, 0xDC, 0x65, 0x29, 0x78, 0xEA, 0xE2, 0x94,
|
||||
0xBA, 0x0E, 0x15, 0xC6, 0x6A, 0xB3, 0x10, 0x9C, 0x78, 0xC9, 0x4C, 0x2E,
|
||||
0x3D, 0x2B, 0x1D, 0x36, 0xA7, 0x4E, 0xF7, 0xF2, 0xF4, 0x2D, 0x0A, 0x1E,
|
||||
0x53, 0x3C, 0xFC, 0xA6, 0xB6, 0x12, 0x13, 0xF7, 0x08, 0xA7, 0x23, 0x52,
|
||||
0x60, 0x79, 0xC2, 0x19, 0x0F, 0x26, 0x39, 0x19, 0x83, 0xC8, 0x7B, 0xA6,
|
||||
0x95, 0x45, 0xBC, 0xE3, 0x66, 0x1F, 0xC3, 0xEA, 0x6E, 0xFE, 0xAD, 0xEB,
|
||||
0xA5, 0x5A, 0x6C, 0xBE, 0xEF, 0xDD, 0x32, 0xC3, 0x28, 0xFF, 0x8C, 0x01,
|
||||
0xD1, 0x37, 0x7F, 0xB1, 0x3B, 0x95, 0x2F, 0xDB, 0x0F, 0xA5, 0xCE, 0xEE,
|
||||
0x02, 0x97, 0xAB, 0x68, 0x85, 0x21, 0x58, 0x65, 0x70, 0x61, 0x07, 0x29,
|
||||
0x28, 0xB6, 0x21, 0x15, 0x84, 0x2F, 0x6E, 0x5B, 0xAD, 0x7D, 0xEF, 0x2A,
|
||||
0x96, 0xBD, 0x61, 0xEB, 0x30, 0xA8, 0xCC, 0x13, 0x10, 0x15, 0x9F, 0x61,
|
||||
0x75, 0x47, 0xDD, 0xEC, 0x39, 0xA2, 0x70, 0x4C, 0x90, 0x5C, 0x73, 0xB5,
|
||||
0xCF, 0x63, 0x03, 0xAA, 0x1E, 0xFE, 0x34, 0x03, 0xA7, 0x2C, 0x62, 0x60,
|
||||
0xBC, 0x86, 0xCC, 0xEE, 0x14, 0xDE, 0xAA, 0xCB, 0x0B, 0x9E, 0x9E, 0xD5,
|
||||
0xCA, 0xF0, 0xBD, 0x19, 0xAF, 0x1E, 0x8B, 0x64, 0x6E, 0x84, 0xF3, 0xB2,
|
||||
0xAB, 0x5C, 0xAB, 0x9C, 0xB3, 0xB4, 0x2A, 0x3C, 0x32, 0x5A, 0x68, 0x40,
|
||||
0x50, 0xBB, 0x5A, 0x65, 0xB9, 0x69, 0x23, 0xA0, 0x99, 0xA0, 0x5F, 0x87,
|
||||
0x19, 0x0B, 0x54, 0x9B, 0xF7, 0xB8, 0x21, 0xC0, 0xD5, 0xE9, 0x9E, 0x31,
|
||||
0x77, 0x2D, 0xE3, 0x97, 0x9A, 0x88, 0x37, 0xF8, 0xA8, 0x7D, 0x3D, 0x62,
|
||||
0x7E, 0x99, 0xF7, 0x95, 0xD6, 0x1F, 0xE6, 0xC7, 0x29, 0x88, 0x35, 0x0E,
|
||||
0x81, 0x12, 0x68, 0x16, 0x5F, 0x93, 0xED, 0x11, 0x63, 0x72, 0x22, 0x1B,
|
||||
0xA5, 0x84, 0xF5, 0x57, 0x99, 0xBA, 0x58, 0x78, 0xA1, 0xDF, 0xDE, 0x96,
|
||||
0x54, 0x30, 0x2E, 0x53, 0xEB, 0x0A, 0xB3, 0xCD, 0x96, 0x46, 0xC2, 0x1A,
|
||||
0xFF, 0xC3, 0x83, 0x9B, 0xEA, 0xFF, 0xC6, 0x34, 0xEF, 0xF2, 0xEB, 0x58,
|
||||
0x28, 0x31, 0xBC, 0x6D, 0xE4, 0x48, 0xD9, 0x8F, 0xE3, 0xB7, 0x64, 0xE8,
|
||||
0xD9, 0x14, 0x4A, 0x5D, 0x73, 0x3C, 0x7C, 0xEE, 0x61, 0xED, 0x28, 0xFE,
|
||||
0xEA, 0xAB, 0xAA, 0xA3, 0xB6, 0xE2, 0xEE, 0x45, 0xE0, 0x13, 0x3E, 0x20,
|
||||
0x14, 0x5D, 0x10, 0x42, 0xB5, 0xBB, 0x6A, 0xEF, 0x42, 0xF4, 0x42, 0xC7,
|
||||
0xD0, 0x4F, 0xCB, 0xFA, 0x15, 0x4F, 0x6C, 0xDB, 0xC7, 0x4D, 0x85, 0x86,
|
||||
0x9E, 0x79, 0x1E, 0xD8, 0x05, 0x21, 0xCD, 0x41, 0x1D, 0x3B, 0x4F, 0x65,
|
||||
0x46, 0x26, 0x8D, 0x5B, 0xF2, 0xA1, 0x62, 0xCF, 0x50, 0x62, 0x81, 0x3D,
|
||||
0x6A, 0x47, 0x4B, 0xE4, 0x92, 0x74, 0xCB, 0x69, 0xC3, 0x24, 0x15, 0x7F,
|
||||
0xA3, 0xB6, 0xC7, 0xC1, 0xA0, 0x83, 0x88, 0xFC, 0x9D, 0x48, 0x19, 0xAD,
|
||||
0x00, 0xBF, 0x5B, 0x09, 0x85, 0xB2, 0x92, 0x56, 0x0B, 0x8A, 0x84, 0x47,
|
||||
0xEA, 0xF5, 0x55, 0x0C, 0x2A, 0x8D, 0x42, 0x58, 0x00, 0x0D, 0x82, 0x23,
|
||||
0x74, 0xB1, 0x62, 0x14, 0x41, 0x7E, 0x93, 0x8D, 0x92, 0xF0, 0x72, 0x33,
|
||||
0x61, 0x70, 0x3F, 0x23, 0x3E, 0xF4, 0xAD, 0x1D, 0x60, 0x74, 0xEE, 0xCB,
|
||||
0x59, 0x37, 0xDE, 0x7C, 0xDB, 0x3B, 0x22, 0x6C, 0xF1, 0xEC, 0x5F, 0xD6,
|
||||
0x9E, 0x50, 0xF8, 0x19, 0x84, 0x80, 0x07, 0xA6, 0x6E, 0x32, 0x77, 0xCE,
|
||||
0xA7, 0xF2, 0x85, 0x40, 0xC2, 0x06, 0x0C, 0xC5, 0xAA, 0xA7, 0x69, 0xA9,
|
||||
0x35, 0x97, 0xD9, 0x61, 0x55, 0xD8, 0xEF, 0xE8, 0x84, 0x34, 0x45, 0xC3,
|
||||
0x2E, 0x7A, 0x44, 0x9E, 0xDC, 0xCA, 0x0B, 0x80, 0xFC, 0xAB, 0x04, 0x5A,
|
||||
0xCD, 0x88, 0x55, 0x10, 0xD3, 0xDB, 0x73, 0xDB, 0xC9, 0x9E, 0x1E, 0x0E,
|
||||
0x05, 0x67, 0xD5, 0xFD, 0xD8, 0x38, 0x3E, 0x71, 0x65, 0x34, 0xC4, 0xC5,
|
||||
0x40, 0x43, 0x67, 0xE3, 0x79, 0xDA, 0x5F, 0x67, 0x4A, 0x3D, 0xB0, 0x8F,
|
||||
0xE7, 0x21, 0x3E, 0x15, 0x20, 0xFF, 0x6D, 0xF1, 0x9E, 0xF8, 0x28, 0x3D,
|
||||
0xF7, 0x40, 0x81, 0x94, 0x68, 0x5A, 0x3D, 0xE9, 0xF7, 0xAD, 0x83, 0xDB,
|
||||
0x2B, 0x9F, 0xE3, 0xE6, 0xF7, 0xD4, 0x02, 0x76, 0xF7, 0x20, 0x15, 0x41,
|
||||
0x34, 0x29, 0x69, 0x94, 0x1C, 0x26, 0x4C, 0xF6, 0x6A, 0xF4, 0x20, 0x33,
|
||||
0x71, 0x24, 0x08, 0xD4, 0x68, 0x00, 0xA1, 0xD4, 0x2E, 0x6B, 0xF4, 0xBC,
|
||||
0x46, 0x45, 0x24, 0x97, 0x2E, 0xF6, 0x39, 0x1E, 0xAF, 0x61, 0x00, 0x50,
|
||||
0xB7, 0xD4, 0xB7, 0x43,
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
471
Pods/abseil/absl/random/internal/randen_slow.cc
generated
Normal file
471
Pods/abseil/absl/random/internal/randen_slow.cc
generated
Normal file
@@ -0,0 +1,471 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/random/internal/randen_slow.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/internal/endian.h"
|
||||
#include "absl/numeric/int128.h"
|
||||
#include "absl/random/internal/platform.h"
|
||||
#include "absl/random/internal/randen_traits.h"
|
||||
|
||||
#if ABSL_HAVE_ATTRIBUTE(always_inline) || \
|
||||
(defined(__GNUC__) && !defined(__clang__))
|
||||
#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE \
|
||||
__attribute__((always_inline))
|
||||
#elif defined(_MSC_VER)
|
||||
// We can achieve something similar to attribute((always_inline)) with MSVC by
|
||||
// using the __forceinline keyword, however this is not perfect. MSVC is
|
||||
// much less aggressive about inlining, and even with the __forceinline keyword.
|
||||
#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE __forceinline
|
||||
#else
|
||||
#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// AES portions based on rijndael-alg-fst.c,
|
||||
// https://fastcrypto.org/front/misc/rijndael-alg-fst.c, and modified for
|
||||
// platform-endianness.
|
||||
//
|
||||
// Implementation of
|
||||
// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
||||
constexpr uint32_t te0[256] = {
|
||||
0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6,
|
||||
0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
|
||||
0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f,
|
||||
0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
|
||||
0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453,
|
||||
0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
|
||||
0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551,
|
||||
0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
|
||||
0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637,
|
||||
0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
|
||||
0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d,
|
||||
0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
|
||||
0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd,
|
||||
0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
|
||||
0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d,
|
||||
0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
|
||||
0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a,
|
||||
0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
|
||||
0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d,
|
||||
0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
|
||||
0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5,
|
||||
0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
|
||||
0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755,
|
||||
0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
|
||||
0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54,
|
||||
0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
|
||||
0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264,
|
||||
0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
|
||||
0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531,
|
||||
0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
|
||||
0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac,
|
||||
0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
|
||||
0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657,
|
||||
0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
|
||||
0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c,
|
||||
0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
|
||||
0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199,
|
||||
0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
|
||||
0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c,
|
||||
0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
|
||||
0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7,
|
||||
0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
|
||||
0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c,
|
||||
};
|
||||
|
||||
constexpr uint32_t te1[256] = {
|
||||
0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd,
|
||||
0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d,
|
||||
0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d,
|
||||
0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
|
||||
0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7,
|
||||
0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a,
|
||||
0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 0x3434685c, 0xa5a551f4,
|
||||
0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f,
|
||||
0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1,
|
||||
0x05050a0f, 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d,
|
||||
0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b, 0x83831d9e,
|
||||
0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb,
|
||||
0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e,
|
||||
0x2f2f5e71, 0x84841397, 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c,
|
||||
0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46,
|
||||
0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
|
||||
0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7,
|
||||
0x33336655, 0x85851194, 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81,
|
||||
0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe,
|
||||
0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
|
||||
0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a,
|
||||
0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f,
|
||||
0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2,
|
||||
0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695,
|
||||
0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e,
|
||||
0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c,
|
||||
0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, 0xe0e0db3b, 0x32326456,
|
||||
0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
|
||||
0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4,
|
||||
0xe4e4d337, 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7,
|
||||
0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa,
|
||||
0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018,
|
||||
0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1,
|
||||
0xb4b473c7, 0xc6c69751, 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21,
|
||||
0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42,
|
||||
0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12,
|
||||
0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958,
|
||||
0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233,
|
||||
0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22,
|
||||
0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
|
||||
0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731,
|
||||
0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11,
|
||||
0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a,
|
||||
};
|
||||
|
||||
constexpr uint32_t te2[256] = {
|
||||
0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b,
|
||||
0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b,
|
||||
0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82,
|
||||
0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
|
||||
0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4,
|
||||
0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26,
|
||||
0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 0x34685c34, 0xa551f4a5,
|
||||
0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15,
|
||||
0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196,
|
||||
0x050a0f05, 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2,
|
||||
0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09, 0x831d9e83,
|
||||
0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0,
|
||||
0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3,
|
||||
0x2f5e712f, 0x84139784, 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced,
|
||||
0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb,
|
||||
0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
|
||||
0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d,
|
||||
0x33665533, 0x85119485, 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f,
|
||||
0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3,
|
||||
0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
|
||||
0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff,
|
||||
0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec,
|
||||
0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7,
|
||||
0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573,
|
||||
0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a,
|
||||
0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14,
|
||||
0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, 0xe0db3be0, 0x32645632,
|
||||
0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
|
||||
0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495,
|
||||
0xe4d337e4, 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d,
|
||||
0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56,
|
||||
0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808,
|
||||
0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6,
|
||||
0xb473c7b4, 0xc69751c6, 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f,
|
||||
0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e,
|
||||
0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e,
|
||||
0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1,
|
||||
0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311,
|
||||
0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e,
|
||||
0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
|
||||
0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6,
|
||||
0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f,
|
||||
0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16,
|
||||
};
|
||||
|
||||
constexpr uint32_t te3[256] = {
|
||||
0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b,
|
||||
0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b,
|
||||
0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282,
|
||||
0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
|
||||
0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4,
|
||||
0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626,
|
||||
0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 0x685c3434, 0x51f4a5a5,
|
||||
0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515,
|
||||
0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696,
|
||||
0x0a0f0505, 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2,
|
||||
0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383,
|
||||
0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0,
|
||||
0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3,
|
||||
0x5e712f2f, 0x13978484, 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded,
|
||||
0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb,
|
||||
0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
|
||||
0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d,
|
||||
0x66553333, 0x11948585, 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f,
|
||||
0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3,
|
||||
0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
|
||||
0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff,
|
||||
0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec,
|
||||
0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7,
|
||||
0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373,
|
||||
0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a,
|
||||
0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414,
|
||||
0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 0xdb3be0e0, 0x64563232,
|
||||
0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
|
||||
0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595,
|
||||
0xd337e4e4, 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d,
|
||||
0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656,
|
||||
0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808,
|
||||
0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6,
|
||||
0x73c7b4b4, 0x9751c6c6, 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f,
|
||||
0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e,
|
||||
0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e,
|
||||
0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1,
|
||||
0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111,
|
||||
0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e,
|
||||
0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
|
||||
0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6,
|
||||
0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f,
|
||||
0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616,
|
||||
};
|
||||
|
||||
// Software implementation of the Vector128 class, using uint32_t
|
||||
// as an underlying vector register.
|
||||
struct alignas(16) Vector128 {
|
||||
uint32_t s[4];
|
||||
};
|
||||
|
||||
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128
|
||||
Vector128Load(const void* from) {
|
||||
Vector128 result;
|
||||
std::memcpy(result.s, from, sizeof(Vector128));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store(
|
||||
const Vector128& v, void* to) {
|
||||
std::memcpy(to, v.s, sizeof(Vector128));
|
||||
}
|
||||
|
||||
// One round of AES. "round_key" is a public constant for breaking the
|
||||
// symmetry of AES (ensures previously equal columns differ afterwards).
|
||||
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128
|
||||
AesRound(const Vector128& state, const Vector128& round_key) {
|
||||
Vector128 result;
|
||||
#ifdef ABSL_IS_LITTLE_ENDIAN
|
||||
result.s[0] = round_key.s[0] ^ //
|
||||
te0[uint8_t(state.s[0])] ^ //
|
||||
te1[uint8_t(state.s[1] >> 8)] ^ //
|
||||
te2[uint8_t(state.s[2] >> 16)] ^ //
|
||||
te3[uint8_t(state.s[3] >> 24)];
|
||||
result.s[1] = round_key.s[1] ^ //
|
||||
te0[uint8_t(state.s[1])] ^ //
|
||||
te1[uint8_t(state.s[2] >> 8)] ^ //
|
||||
te2[uint8_t(state.s[3] >> 16)] ^ //
|
||||
te3[uint8_t(state.s[0] >> 24)];
|
||||
result.s[2] = round_key.s[2] ^ //
|
||||
te0[uint8_t(state.s[2])] ^ //
|
||||
te1[uint8_t(state.s[3] >> 8)] ^ //
|
||||
te2[uint8_t(state.s[0] >> 16)] ^ //
|
||||
te3[uint8_t(state.s[1] >> 24)];
|
||||
result.s[3] = round_key.s[3] ^ //
|
||||
te0[uint8_t(state.s[3])] ^ //
|
||||
te1[uint8_t(state.s[0] >> 8)] ^ //
|
||||
te2[uint8_t(state.s[1] >> 16)] ^ //
|
||||
te3[uint8_t(state.s[2] >> 24)];
|
||||
#else
|
||||
result.s[0] = round_key.s[0] ^ //
|
||||
te0[uint8_t(state.s[0])] ^ //
|
||||
te1[uint8_t(state.s[3] >> 8)] ^ //
|
||||
te2[uint8_t(state.s[2] >> 16)] ^ //
|
||||
te3[uint8_t(state.s[1] >> 24)];
|
||||
result.s[1] = round_key.s[1] ^ //
|
||||
te0[uint8_t(state.s[1])] ^ //
|
||||
te1[uint8_t(state.s[0] >> 8)] ^ //
|
||||
te2[uint8_t(state.s[3] >> 16)] ^ //
|
||||
te3[uint8_t(state.s[2] >> 24)];
|
||||
result.s[2] = round_key.s[2] ^ //
|
||||
te0[uint8_t(state.s[2])] ^ //
|
||||
te1[uint8_t(state.s[1] >> 8)] ^ //
|
||||
te2[uint8_t(state.s[0] >> 16)] ^ //
|
||||
te3[uint8_t(state.s[3] >> 24)];
|
||||
result.s[3] = round_key.s[3] ^ //
|
||||
te0[uint8_t(state.s[3])] ^ //
|
||||
te1[uint8_t(state.s[2] >> 8)] ^ //
|
||||
te2[uint8_t(state.s[1] >> 16)] ^ //
|
||||
te3[uint8_t(state.s[0] >> 24)];
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
using ::absl::random_internal::RandenTraits;
|
||||
|
||||
// The improved Feistel block shuffle function for 16 blocks.
|
||||
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle(
|
||||
absl::uint128* state) {
|
||||
static_assert(RandenTraits::kFeistelBlocks == 16,
|
||||
"Feistel block shuffle only works for 16 blocks.");
|
||||
|
||||
constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = {
|
||||
7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12};
|
||||
|
||||
// The fully unrolled loop without the memcpy improves the speed by about
|
||||
// 30% over the equivalent:
|
||||
#if 0
|
||||
absl::uint128 source[RandenTraits::kFeistelBlocks];
|
||||
std::memcpy(source, state, sizeof(source));
|
||||
for (size_t i = 0; i < RandenTraits::kFeistelBlocks; i++) {
|
||||
const absl::uint128 v0 = source[shuffle[i]];
|
||||
state[i] = v0;
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
|
||||
const absl::uint128 v0 = state[shuffle[0]];
|
||||
const absl::uint128 v1 = state[shuffle[1]];
|
||||
const absl::uint128 v2 = state[shuffle[2]];
|
||||
const absl::uint128 v3 = state[shuffle[3]];
|
||||
const absl::uint128 v4 = state[shuffle[4]];
|
||||
const absl::uint128 v5 = state[shuffle[5]];
|
||||
const absl::uint128 v6 = state[shuffle[6]];
|
||||
const absl::uint128 v7 = state[shuffle[7]];
|
||||
const absl::uint128 w0 = state[shuffle[8]];
|
||||
const absl::uint128 w1 = state[shuffle[9]];
|
||||
const absl::uint128 w2 = state[shuffle[10]];
|
||||
const absl::uint128 w3 = state[shuffle[11]];
|
||||
const absl::uint128 w4 = state[shuffle[12]];
|
||||
const absl::uint128 w5 = state[shuffle[13]];
|
||||
const absl::uint128 w6 = state[shuffle[14]];
|
||||
const absl::uint128 w7 = state[shuffle[15]];
|
||||
state[0] = v0;
|
||||
state[1] = v1;
|
||||
state[2] = v2;
|
||||
state[3] = v3;
|
||||
state[4] = v4;
|
||||
state[5] = v5;
|
||||
state[6] = v6;
|
||||
state[7] = v7;
|
||||
state[8] = w0;
|
||||
state[9] = w1;
|
||||
state[10] = w2;
|
||||
state[11] = w3;
|
||||
state[12] = w4;
|
||||
state[13] = w5;
|
||||
state[14] = w6;
|
||||
state[15] = w7;
|
||||
}
|
||||
|
||||
// Feistel round function using two AES subrounds. Very similar to F()
|
||||
// from Simpira v2, but with independent subround keys. Uses 17 AES rounds
|
||||
// per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in
|
||||
// parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel
|
||||
// XORs are 'free' (included in the second AES instruction).
|
||||
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE const absl::uint128*
|
||||
FeistelRound(absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT state,
|
||||
const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
|
||||
for (size_t branch = 0; branch < RandenTraits::kFeistelBlocks; branch += 4) {
|
||||
const Vector128 s0 = Vector128Load(state + branch);
|
||||
const Vector128 s1 = Vector128Load(state + branch + 1);
|
||||
const Vector128 f0 = AesRound(s0, Vector128Load(keys));
|
||||
keys++;
|
||||
const Vector128 o1 = AesRound(f0, s1);
|
||||
Vector128Store(o1, state + branch + 1);
|
||||
|
||||
// Manually unroll this loop once. about 10% better than not unrolled.
|
||||
const Vector128 s2 = Vector128Load(state + branch + 2);
|
||||
const Vector128 s3 = Vector128Load(state + branch + 3);
|
||||
const Vector128 f2 = AesRound(s2, Vector128Load(keys));
|
||||
keys++;
|
||||
const Vector128 o3 = AesRound(f2, s3);
|
||||
Vector128Store(o3, state + branch + 3);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
// Cryptographic permutation based via type-2 Generalized Feistel Network.
|
||||
// Indistinguishable from ideal by chosen-ciphertext adversaries using less than
|
||||
// 2^64 queries if the round function is a PRF. This is similar to the b=8 case
|
||||
// of Simpira v2, but more efficient than its generic construction for b=16.
|
||||
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Permute(
|
||||
absl::uint128* state,
|
||||
const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
|
||||
for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) {
|
||||
keys = FeistelRound(state, keys);
|
||||
BlockShuffle(state);
|
||||
}
|
||||
}
|
||||
|
||||
// Enables native loads in the round loop by pre-swapping.
|
||||
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void SwapEndian(
|
||||
absl::uint128* state) {
|
||||
#ifdef ABSL_IS_BIG_ENDIAN
|
||||
for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) {
|
||||
uint64_t new_lo = absl::little_endian::ToHost64(
|
||||
static_cast<uint64_t>(state[block] >> 64));
|
||||
uint64_t new_hi = absl::little_endian::ToHost64(
|
||||
static_cast<uint64_t>((state[block] << 64) >> 64));
|
||||
state[block] = (static_cast<absl::uint128>(new_hi) << 64) | new_lo;
|
||||
}
|
||||
#else
|
||||
// Avoid warning about unused variable.
|
||||
(void)state;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
const void* RandenSlow::GetKeys() {
|
||||
// Round keys for one AES per Feistel round and branch.
|
||||
// The canonical implementation uses first digits of Pi.
|
||||
#ifdef ABSL_IS_LITTLE_ENDIAN
|
||||
return kRandenRoundKeys;
|
||||
#else
|
||||
return kRandenRoundKeysBE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void RandenSlow::Absorb(const void* seed_void, void* state_void) {
|
||||
auto* state =
|
||||
reinterpret_cast<uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>(state_void);
|
||||
const auto* seed =
|
||||
reinterpret_cast<const uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>(
|
||||
seed_void);
|
||||
|
||||
constexpr size_t kCapacityBlocks =
|
||||
RandenTraits::kCapacityBytes / sizeof(uint64_t);
|
||||
static_assert(
|
||||
kCapacityBlocks * sizeof(uint64_t) == RandenTraits::kCapacityBytes,
|
||||
"Not i*V");
|
||||
|
||||
for (size_t i = kCapacityBlocks;
|
||||
i < RandenTraits::kStateBytes / sizeof(uint64_t); ++i) {
|
||||
state[i] ^= seed[i - kCapacityBlocks];
|
||||
}
|
||||
}
|
||||
|
||||
void RandenSlow::Generate(const void* keys_void, void* state_void) {
|
||||
static_assert(RandenTraits::kCapacityBytes == sizeof(absl::uint128),
|
||||
"Capacity mismatch");
|
||||
|
||||
auto* state = reinterpret_cast<absl::uint128*>(state_void);
|
||||
const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void);
|
||||
|
||||
const absl::uint128 prev_inner = state[0];
|
||||
|
||||
SwapEndian(state);
|
||||
|
||||
Permute(state, keys);
|
||||
|
||||
SwapEndian(state);
|
||||
|
||||
// Ensure backtracking resistance.
|
||||
*state ^= prev_inner;
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
40
Pods/abseil/absl/random/internal/randen_slow.h
generated
Normal file
40
Pods/abseil/absl/random/internal/randen_slow.h
generated
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_
|
||||
#define ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// RANDen = RANDom generator or beetroots in Swiss High German.
|
||||
// RandenSlow implements the basic state manipulation methods for
|
||||
// architectures lacking AES hardware acceleration intrinsics.
|
||||
class RandenSlow {
|
||||
public:
|
||||
static void Generate(const void* keys, void* state_void);
|
||||
static void Absorb(const void* seed_void, void* state_void);
|
||||
static const void* GetKeys();
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_
|
||||
88
Pods/abseil/absl/random/internal/randen_traits.h
generated
Normal file
88
Pods/abseil/absl/random/internal/randen_traits.h
generated
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_
|
||||
#define ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_
|
||||
|
||||
// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
|
||||
// symbols from arbitrary system and other headers, since it may be built
|
||||
// with different flags from other targets, using different levels of
|
||||
// optimization, potentially introducing ODR violations.
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// RANDen = RANDom generator or beetroots in Swiss High German.
|
||||
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
|
||||
// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
|
||||
//
|
||||
// High-level summary:
|
||||
// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is
|
||||
// a sponge-like random generator that requires a cryptographic permutation.
|
||||
// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by
|
||||
// achieving backtracking resistance with only one Permute() per buffer.
|
||||
//
|
||||
// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round
|
||||
// Function" constructs up to 1024-bit permutations using an improved
|
||||
// Generalized Feistel network with 2-round AES-128 functions. This Feistel
|
||||
// block shuffle achieves diffusion faster and is less vulnerable to
|
||||
// sliced-biclique attacks than the Type-2 cyclic shuffle.
|
||||
//
|
||||
// 3) "Improving the Generalized Feistel" and "New criterion for diffusion
|
||||
// property" extends the same kind of improved Feistel block shuffle to 16
|
||||
// branches, which enables a 2048-bit permutation.
|
||||
//
|
||||
// Combine these three ideas and also change Simpira's subround keys from
|
||||
// structured/low-entropy counters to digits of Pi (or other random source).
|
||||
|
||||
// RandenTraits contains the basic algorithm traits, such as the size of the
|
||||
// state, seed, sponge, etc.
|
||||
struct RandenTraits {
|
||||
// Size of the entire sponge / state for the randen PRNG.
|
||||
static constexpr size_t kStateBytes = 256; // 2048-bit
|
||||
|
||||
// Size of the 'inner' (inaccessible) part of the sponge. Larger values would
|
||||
// require more frequent calls to RandenGenerate.
|
||||
static constexpr size_t kCapacityBytes = 16; // 128-bit
|
||||
|
||||
// Size of the default seed consumed by the sponge.
|
||||
static constexpr size_t kSeedBytes = kStateBytes - kCapacityBytes;
|
||||
|
||||
// Assuming 128-bit blocks, the number of blocks in the state.
|
||||
// Largest size for which security proofs are known.
|
||||
static constexpr size_t kFeistelBlocks = 16;
|
||||
|
||||
// Ensures SPRP security and two full subblock diffusions.
|
||||
// Must be > 4 * log2(kFeistelBlocks).
|
||||
static constexpr size_t kFeistelRounds = 16 + 1;
|
||||
|
||||
// Size of the key. A 128-bit key block is used for every-other
|
||||
// feistel block (Type-2 generalized Feistel network) in each round.
|
||||
static constexpr size_t kKeyBytes = 16 * kFeistelRounds * kFeistelBlocks / 2;
|
||||
};
|
||||
|
||||
// Randen key arrays. In randen_round_keys.cc
|
||||
extern const unsigned char kRandenRoundKeys[RandenTraits::kKeyBytes];
|
||||
extern const unsigned char kRandenRoundKeysBE[RandenTraits::kKeyBytes];
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_
|
||||
165
Pods/abseil/absl/random/internal/salted_seed_seq.h
generated
Normal file
165
Pods/abseil/absl/random/internal/salted_seed_seq.h
generated
Normal file
@@ -0,0 +1,165 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_
|
||||
#define ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/inlined_vector.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/random/internal/seed_material.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// This class conforms to the C++ Standard "Seed Sequence" concept
|
||||
// [rand.req.seedseq].
|
||||
//
|
||||
// A `SaltedSeedSeq` is meant to wrap an existing seed sequence and modify
|
||||
// generated sequence by mixing with extra entropy. This entropy may be
|
||||
// build-dependent or process-dependent. The implementation may change to be
|
||||
// have either or both kinds of entropy. If salt is not available sequence is
|
||||
// not modified.
|
||||
template <typename SSeq>
|
||||
class SaltedSeedSeq {
|
||||
public:
|
||||
using inner_sequence_type = SSeq;
|
||||
using result_type = typename SSeq::result_type;
|
||||
|
||||
SaltedSeedSeq() : seq_(absl::make_unique<SSeq>()) {}
|
||||
|
||||
template <typename Iterator>
|
||||
SaltedSeedSeq(Iterator begin, Iterator end)
|
||||
: seq_(absl::make_unique<SSeq>(begin, end)) {}
|
||||
|
||||
template <typename T>
|
||||
SaltedSeedSeq(std::initializer_list<T> il)
|
||||
: SaltedSeedSeq(il.begin(), il.end()) {}
|
||||
|
||||
SaltedSeedSeq(const SaltedSeedSeq&) = delete;
|
||||
SaltedSeedSeq& operator=(const SaltedSeedSeq&) = delete;
|
||||
|
||||
SaltedSeedSeq(SaltedSeedSeq&&) = default;
|
||||
SaltedSeedSeq& operator=(SaltedSeedSeq&&) = default;
|
||||
|
||||
template <typename RandomAccessIterator>
|
||||
void generate(RandomAccessIterator begin, RandomAccessIterator end) {
|
||||
using U = typename std::iterator_traits<RandomAccessIterator>::value_type;
|
||||
|
||||
// The common case is that generate is called with ContiguousIterators
|
||||
// to uint arrays. Such contiguous memory regions may be optimized,
|
||||
// which we detect here.
|
||||
using TagType = absl::conditional_t<
|
||||
(std::is_same<U, uint32_t>::value &&
|
||||
(std::is_pointer<RandomAccessIterator>::value ||
|
||||
std::is_same<RandomAccessIterator,
|
||||
typename std::vector<U>::iterator>::value)),
|
||||
ContiguousAndUint32Tag, DefaultTag>;
|
||||
if (begin != end) {
|
||||
generate_impl(TagType{}, begin, end, std::distance(begin, end));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename OutIterator>
|
||||
void param(OutIterator out) const {
|
||||
seq_->param(out);
|
||||
}
|
||||
|
||||
size_t size() const { return seq_->size(); }
|
||||
|
||||
private:
|
||||
struct ContiguousAndUint32Tag {};
|
||||
struct DefaultTag {};
|
||||
|
||||
// Generate which requires the iterators are contiguous pointers to uint32_t.
|
||||
// Fills the initial seed buffer the underlying SSeq::generate() call,
|
||||
// then mixes in the salt material.
|
||||
template <typename Contiguous>
|
||||
void generate_impl(ContiguousAndUint32Tag, Contiguous begin, Contiguous end,
|
||||
size_t n) {
|
||||
seq_->generate(begin, end);
|
||||
const uint32_t salt = absl::random_internal::GetSaltMaterial().value_or(0);
|
||||
auto span = absl::Span<uint32_t>(&*begin, n);
|
||||
MixIntoSeedMaterial(absl::MakeConstSpan(&salt, 1), span);
|
||||
}
|
||||
|
||||
// The uncommon case for generate is that it is called with iterators over
|
||||
// some other buffer type which is assignable from a 32-bit value. In this
|
||||
// case we allocate a temporary 32-bit buffer and then copy-assign back
|
||||
// to the initial inputs.
|
||||
template <typename RandomAccessIterator>
|
||||
void generate_impl(DefaultTag, RandomAccessIterator begin,
|
||||
RandomAccessIterator, size_t n) {
|
||||
// Allocates a seed buffer of `n` elements, generates the seed, then
|
||||
// copies the result into the `out` iterator.
|
||||
absl::InlinedVector<uint32_t, 8> data(n, 0);
|
||||
generate_impl(ContiguousAndUint32Tag{}, data.begin(), data.end(), n);
|
||||
std::copy(data.begin(), data.end(), begin);
|
||||
}
|
||||
|
||||
// Because [rand.req.seedseq] is not required to be copy-constructible,
|
||||
// copy-assignable nor movable, we wrap it with unique pointer to be able
|
||||
// to move SaltedSeedSeq.
|
||||
std::unique_ptr<SSeq> seq_;
|
||||
};
|
||||
|
||||
// is_salted_seed_seq indicates whether the type is a SaltedSeedSeq.
|
||||
template <typename T, typename = void>
|
||||
struct is_salted_seed_seq : public std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_salted_seed_seq<
|
||||
T, typename std::enable_if<std::is_same<
|
||||
T, SaltedSeedSeq<typename T::inner_sequence_type>>::value>::type>
|
||||
: public std::true_type {};
|
||||
|
||||
// MakeSaltedSeedSeq returns a salted variant of the seed sequence.
|
||||
// When provided with an existing SaltedSeedSeq, returns the input parameter,
|
||||
// otherwise constructs a new SaltedSeedSeq which embodies the original
|
||||
// non-salted seed parameters.
|
||||
template <
|
||||
typename SSeq, //
|
||||
typename EnableIf = absl::enable_if_t<is_salted_seed_seq<SSeq>::value>>
|
||||
SSeq MakeSaltedSeedSeq(SSeq&& seq) {
|
||||
return SSeq(std::forward<SSeq>(seq));
|
||||
}
|
||||
|
||||
template <
|
||||
typename SSeq, //
|
||||
typename EnableIf = absl::enable_if_t<!is_salted_seed_seq<SSeq>::value>>
|
||||
SaltedSeedSeq<typename std::decay<SSeq>::type> MakeSaltedSeedSeq(SSeq&& seq) {
|
||||
using sseq_type = typename std::decay<SSeq>::type;
|
||||
using result_type = typename sseq_type::result_type;
|
||||
|
||||
absl::InlinedVector<result_type, 8> data;
|
||||
seq.param(std::back_inserter(data));
|
||||
return SaltedSeedSeq<sseq_type>(data.begin(), data.end());
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_
|
||||
267
Pods/abseil/absl/random/internal/seed_material.cc
generated
Normal file
267
Pods/abseil/absl/random/internal/seed_material.cc
generated
Normal file
@@ -0,0 +1,267 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/random/internal/seed_material.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "absl/base/dynamic_annotations.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/strings/ascii.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/strip.h"
|
||||
|
||||
#if defined(__native_client__)
|
||||
|
||||
#include <nacl/nacl_random.h>
|
||||
#define ABSL_RANDOM_USE_NACL_SECURE_RANDOM 1
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
#define ABSL_RANDOM_USE_BCRYPT 1
|
||||
#pragma comment(lib, "bcrypt.lib")
|
||||
|
||||
#elif defined(__Fuchsia__)
|
||||
#include <zircon/syscalls.h>
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__GLIBC__) && \
|
||||
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
|
||||
// glibc >= 2.25 has getentropy()
|
||||
#define ABSL_RANDOM_USE_GET_ENTROPY 1
|
||||
#endif
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <sys/random.h>
|
||||
// Emscripten has getentropy, but it resides in a different header.
|
||||
#define ABSL_RANDOM_USE_GET_ENTROPY 1
|
||||
#endif
|
||||
|
||||
#if defined(ABSL_RANDOM_USE_BCRYPT)
|
||||
#include <bcrypt.h>
|
||||
|
||||
#ifndef BCRYPT_SUCCESS
|
||||
#define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#endif
|
||||
// Also link bcrypt; this can be done via linker options or:
|
||||
// #pragma comment(lib, "bcrypt.lib")
|
||||
#endif
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
namespace {
|
||||
|
||||
// Read OS Entropy for random number seeds.
|
||||
// TODO(absl-team): Possibly place a cap on how much entropy may be read at a
|
||||
// time.
|
||||
|
||||
#if defined(ABSL_RANDOM_USE_BCRYPT)
|
||||
|
||||
// On Windows potentially use the BCRYPT CNG API to read available entropy.
|
||||
bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
|
||||
BCRYPT_ALG_HANDLE hProvider;
|
||||
NTSTATUS ret;
|
||||
ret = BCryptOpenAlgorithmProvider(&hProvider, BCRYPT_RNG_ALGORITHM,
|
||||
MS_PRIMITIVE_PROVIDER, 0);
|
||||
if (!(BCRYPT_SUCCESS(ret))) {
|
||||
ABSL_RAW_LOG(ERROR, "Failed to open crypto provider.");
|
||||
return false;
|
||||
}
|
||||
ret = BCryptGenRandom(
|
||||
hProvider, // provider
|
||||
reinterpret_cast<UCHAR*>(values.data()), // buffer
|
||||
static_cast<ULONG>(sizeof(uint32_t) * values.size()), // bytes
|
||||
0); // flags
|
||||
BCryptCloseAlgorithmProvider(hProvider, 0);
|
||||
return BCRYPT_SUCCESS(ret);
|
||||
}
|
||||
|
||||
#elif defined(ABSL_RANDOM_USE_NACL_SECURE_RANDOM)
|
||||
|
||||
// On NaCL use nacl_secure_random to acquire bytes.
|
||||
bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
|
||||
auto buffer = reinterpret_cast<uint8_t*>(values.data());
|
||||
size_t buffer_size = sizeof(uint32_t) * values.size();
|
||||
|
||||
uint8_t* output_ptr = buffer;
|
||||
while (buffer_size > 0) {
|
||||
size_t nread = 0;
|
||||
const int error = nacl_secure_random(output_ptr, buffer_size, &nread);
|
||||
if (error != 0 || nread > buffer_size) {
|
||||
ABSL_RAW_LOG(ERROR, "Failed to read secure_random seed data: %d", error);
|
||||
return false;
|
||||
}
|
||||
output_ptr += nread;
|
||||
buffer_size -= nread;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif defined(__Fuchsia__)
|
||||
|
||||
bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
|
||||
auto buffer = reinterpret_cast<uint8_t*>(values.data());
|
||||
size_t buffer_size = sizeof(uint32_t) * values.size();
|
||||
zx_cprng_draw(buffer, buffer_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if defined(ABSL_RANDOM_USE_GET_ENTROPY)
|
||||
// On *nix, use getentropy() if supported. Note that libc may support
|
||||
// getentropy(), but the kernel may not, in which case this function will return
|
||||
// false.
|
||||
bool ReadSeedMaterialFromGetEntropy(absl::Span<uint32_t> values) {
|
||||
auto buffer = reinterpret_cast<uint8_t*>(values.data());
|
||||
size_t buffer_size = sizeof(uint32_t) * values.size();
|
||||
while (buffer_size > 0) {
|
||||
// getentropy() has a maximum permitted length of 256.
|
||||
size_t to_read = std::min<size_t>(buffer_size, 256);
|
||||
int result = getentropy(buffer, to_read);
|
||||
if (result < 0) {
|
||||
return false;
|
||||
}
|
||||
// https://github.com/google/sanitizers/issues/1173
|
||||
// MemorySanitizer can't see through getentropy().
|
||||
ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(buffer, to_read);
|
||||
buffer += to_read;
|
||||
buffer_size -= to_read;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif // defined(ABSL_RANDOM_GETENTROPY)
|
||||
|
||||
// On *nix, read entropy from /dev/urandom.
|
||||
bool ReadSeedMaterialFromDevURandom(absl::Span<uint32_t> values) {
|
||||
const char kEntropyFile[] = "/dev/urandom";
|
||||
|
||||
auto buffer = reinterpret_cast<uint8_t*>(values.data());
|
||||
size_t buffer_size = sizeof(uint32_t) * values.size();
|
||||
|
||||
int dev_urandom = open(kEntropyFile, O_RDONLY);
|
||||
bool success = (-1 != dev_urandom);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (success && buffer_size > 0) {
|
||||
ssize_t bytes_read = read(dev_urandom, buffer, buffer_size);
|
||||
int read_error = errno;
|
||||
success = (bytes_read > 0);
|
||||
if (success) {
|
||||
buffer += bytes_read;
|
||||
buffer_size -= static_cast<size_t>(bytes_read);
|
||||
} else if (bytes_read == -1 && read_error == EINTR) {
|
||||
success = true; // Need to try again.
|
||||
}
|
||||
}
|
||||
close(dev_urandom);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
|
||||
#if defined(ABSL_RANDOM_USE_GET_ENTROPY)
|
||||
if (ReadSeedMaterialFromGetEntropy(values)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
// Libc may support getentropy, but the kernel may not, so we still have
|
||||
// to fallback to ReadSeedMaterialFromDevURandom().
|
||||
return ReadSeedMaterialFromDevURandom(values);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ReadSeedMaterialFromOSEntropy(absl::Span<uint32_t> values) {
|
||||
assert(values.data() != nullptr);
|
||||
if (values.data() == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (values.empty()) {
|
||||
return true;
|
||||
}
|
||||
return ReadSeedMaterialFromOSEntropyImpl(values);
|
||||
}
|
||||
|
||||
void MixIntoSeedMaterial(absl::Span<const uint32_t> sequence,
|
||||
absl::Span<uint32_t> seed_material) {
|
||||
// Algorithm is based on code available at
|
||||
// https://gist.github.com/imneme/540829265469e673d045
|
||||
constexpr uint32_t kInitVal = 0x43b0d7e5;
|
||||
constexpr uint32_t kHashMul = 0x931e8875;
|
||||
constexpr uint32_t kMixMulL = 0xca01f9dd;
|
||||
constexpr uint32_t kMixMulR = 0x4973f715;
|
||||
constexpr uint32_t kShiftSize = sizeof(uint32_t) * 8 / 2;
|
||||
|
||||
uint32_t hash_const = kInitVal;
|
||||
auto hash = [&](uint32_t value) {
|
||||
value ^= hash_const;
|
||||
hash_const *= kHashMul;
|
||||
value *= hash_const;
|
||||
value ^= value >> kShiftSize;
|
||||
return value;
|
||||
};
|
||||
|
||||
auto mix = [&](uint32_t x, uint32_t y) {
|
||||
uint32_t result = kMixMulL * x - kMixMulR * y;
|
||||
result ^= result >> kShiftSize;
|
||||
return result;
|
||||
};
|
||||
|
||||
for (const auto& seq_val : sequence) {
|
||||
for (auto& elem : seed_material) {
|
||||
elem = mix(elem, hash(seq_val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
absl::optional<uint32_t> GetSaltMaterial() {
|
||||
// Salt must be common for all generators within the same process so read it
|
||||
// only once and store in static variable.
|
||||
static const auto salt_material = []() -> absl::optional<uint32_t> {
|
||||
uint32_t salt_value = 0;
|
||||
|
||||
if (random_internal::ReadSeedMaterialFromOSEntropy(
|
||||
MakeSpan(&salt_value, 1))) {
|
||||
return salt_value;
|
||||
}
|
||||
|
||||
return absl::nullopt;
|
||||
}();
|
||||
|
||||
return salt_material;
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
104
Pods/abseil/absl/random/internal/seed_material.h
generated
Normal file
104
Pods/abseil/absl/random/internal/seed_material.h
generated
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_
|
||||
#define ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/random/internal/fast_uniform_bits.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// Returns the number of 32-bit blocks needed to contain the given number of
|
||||
// bits.
|
||||
constexpr size_t SeedBitsToBlocks(size_t seed_size) {
|
||||
return (seed_size + 31) / 32;
|
||||
}
|
||||
|
||||
// Amount of entropy (measured in bits) used to instantiate a Seed Sequence,
|
||||
// with which to create a URBG.
|
||||
constexpr size_t kEntropyBitsNeeded = 256;
|
||||
|
||||
// Amount of entropy (measured in 32-bit blocks) used to instantiate a Seed
|
||||
// Sequence, with which to create a URBG.
|
||||
constexpr size_t kEntropyBlocksNeeded =
|
||||
random_internal::SeedBitsToBlocks(kEntropyBitsNeeded);
|
||||
|
||||
static_assert(kEntropyBlocksNeeded > 0,
|
||||
"Entropy used to seed URBGs must be nonzero.");
|
||||
|
||||
// Attempts to fill a span of uint32_t-values using an OS-provided source of
|
||||
// true entropy (eg. /dev/urandom) into an array of uint32_t blocks of data. The
|
||||
// resulting array may be used to initialize an instance of a class conforming
|
||||
// to the C++ Standard "Seed Sequence" concept [rand.req.seedseq].
|
||||
//
|
||||
// If values.data() == nullptr, the behavior is undefined.
|
||||
ABSL_MUST_USE_RESULT
|
||||
bool ReadSeedMaterialFromOSEntropy(absl::Span<uint32_t> values);
|
||||
|
||||
// Attempts to fill a span of uint32_t-values using variates generated by an
|
||||
// existing instance of a class conforming to the C++ Standard "Uniform Random
|
||||
// Bit Generator" concept [rand.req.urng]. The resulting data may be used to
|
||||
// initialize an instance of a class conforming to the C++ Standard
|
||||
// "Seed Sequence" concept [rand.req.seedseq].
|
||||
//
|
||||
// If urbg == nullptr or values.data() == nullptr, the behavior is undefined.
|
||||
template <typename URBG>
|
||||
ABSL_MUST_USE_RESULT bool ReadSeedMaterialFromURBG(
|
||||
URBG* urbg, absl::Span<uint32_t> values) {
|
||||
random_internal::FastUniformBits<uint32_t> distr;
|
||||
|
||||
assert(urbg != nullptr && values.data() != nullptr);
|
||||
if (urbg == nullptr || values.data() == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t& seed_value : values) {
|
||||
seed_value = distr(*urbg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mixes given sequence of values with into given sequence of seed material.
|
||||
// Time complexity of this function is O(sequence.size() *
|
||||
// seed_material.size()).
|
||||
//
|
||||
// Algorithm is based on code available at
|
||||
// https://gist.github.com/imneme/540829265469e673d045
|
||||
// by Melissa O'Neill.
|
||||
void MixIntoSeedMaterial(absl::Span<const uint32_t> sequence,
|
||||
absl::Span<uint32_t> seed_material);
|
||||
|
||||
// Returns salt value.
|
||||
//
|
||||
// Salt is obtained only once and stored in static variable.
|
||||
//
|
||||
// May return empty value if optaining the salt was not possible.
|
||||
absl::optional<uint32_t> GetSaltMaterial();
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_
|
||||
149
Pods/abseil/absl/random/internal/traits.h
generated
Normal file
149
Pods/abseil/absl/random/internal/traits.h
generated
Normal file
@@ -0,0 +1,149 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_TRAITS_H_
|
||||
#define ABSL_RANDOM_INTERNAL_TRAITS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/numeric/bits.h"
|
||||
#include "absl/numeric/int128.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// random_internal::is_widening_convertible<A, B>
|
||||
//
|
||||
// Returns whether a type A is widening-convertible to a type B.
|
||||
//
|
||||
// A is widening-convertible to B means:
|
||||
// A a = <any number>;
|
||||
// B b = a;
|
||||
// A c = b;
|
||||
// EXPECT_EQ(a, c);
|
||||
template <typename A, typename B>
|
||||
class is_widening_convertible {
|
||||
// As long as there are enough bits in the exact part of a number:
|
||||
// - unsigned can fit in float, signed, unsigned
|
||||
// - signed can fit in float, signed
|
||||
// - float can fit in float
|
||||
// So we define rank to be:
|
||||
// - rank(float) -> 2
|
||||
// - rank(signed) -> 1
|
||||
// - rank(unsigned) -> 0
|
||||
template <class T>
|
||||
static constexpr int rank() {
|
||||
return !std::numeric_limits<T>::is_integer +
|
||||
std::numeric_limits<T>::is_signed;
|
||||
}
|
||||
|
||||
public:
|
||||
// If an arithmetic-type B can represent at least as many digits as a type A,
|
||||
// and B belongs to a rank no lower than A, then A can be safely represented
|
||||
// by B through a widening-conversion.
|
||||
static constexpr bool value =
|
||||
std::numeric_limits<A>::digits <= std::numeric_limits<B>::digits &&
|
||||
rank<A>() <= rank<B>();
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsIntegral : std::is_integral<T> {};
|
||||
template <>
|
||||
struct IsIntegral<absl::int128> : std::true_type {};
|
||||
template <>
|
||||
struct IsIntegral<absl::uint128> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct MakeUnsigned : std::make_unsigned<T> {};
|
||||
template <>
|
||||
struct MakeUnsigned<absl::int128> {
|
||||
using type = absl::uint128;
|
||||
};
|
||||
template <>
|
||||
struct MakeUnsigned<absl::uint128> {
|
||||
using type = absl::uint128;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsUnsigned : std::is_unsigned<T> {};
|
||||
template <>
|
||||
struct IsUnsigned<absl::int128> : std::false_type {};
|
||||
template <>
|
||||
struct IsUnsigned<absl::uint128> : std::true_type {};
|
||||
|
||||
// unsigned_bits<N>::type returns the unsigned int type with the indicated
|
||||
// number of bits.
|
||||
template <size_t N>
|
||||
struct unsigned_bits;
|
||||
|
||||
template <>
|
||||
struct unsigned_bits<8> {
|
||||
using type = uint8_t;
|
||||
};
|
||||
template <>
|
||||
struct unsigned_bits<16> {
|
||||
using type = uint16_t;
|
||||
};
|
||||
template <>
|
||||
struct unsigned_bits<32> {
|
||||
using type = uint32_t;
|
||||
};
|
||||
template <>
|
||||
struct unsigned_bits<64> {
|
||||
using type = uint64_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unsigned_bits<128> {
|
||||
using type = absl::uint128;
|
||||
};
|
||||
|
||||
// 256-bit wrapper for wide multiplications.
|
||||
struct U256 {
|
||||
uint128 hi;
|
||||
uint128 lo;
|
||||
};
|
||||
template <>
|
||||
struct unsigned_bits<256> {
|
||||
using type = U256;
|
||||
};
|
||||
|
||||
template <typename IntType>
|
||||
struct make_unsigned_bits {
|
||||
using type = typename unsigned_bits<
|
||||
std::numeric_limits<typename MakeUnsigned<IntType>::type>::digits>::type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
int BitWidth(T v) {
|
||||
// Workaround for bit_width not supporting int128.
|
||||
// Don't hardcode `64` to make sure this code does not trigger compiler
|
||||
// warnings in smaller types.
|
||||
constexpr int half_bits = sizeof(T) * 8 / 2;
|
||||
if (sizeof(T) == 16 && (v >> half_bits) != 0) {
|
||||
return bit_width(static_cast<uint64_t>(v >> half_bits)) + half_bits;
|
||||
} else {
|
||||
return bit_width(static_cast<uint64_t>(v));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_TRAITS_H_
|
||||
244
Pods/abseil/absl/random/internal/uniform_helper.h
generated
Normal file
244
Pods/abseil/absl/random/internal/uniform_helper.h
generated
Normal file
@@ -0,0 +1,244 @@
|
||||
// Copyright 2019 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
|
||||
#define ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/random/internal/traits.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
template <typename IntType>
|
||||
class uniform_int_distribution;
|
||||
|
||||
template <typename RealType>
|
||||
class uniform_real_distribution;
|
||||
|
||||
// Interval tag types which specify whether the interval is open or closed
|
||||
// on either boundary.
|
||||
|
||||
namespace random_internal {
|
||||
template <typename T>
|
||||
struct TagTypeCompare {};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool operator==(TagTypeCompare<T>, TagTypeCompare<T>) {
|
||||
// Tags are mono-states. They always compare equal.
|
||||
return true;
|
||||
}
|
||||
template <typename T>
|
||||
constexpr bool operator!=(TagTypeCompare<T>, TagTypeCompare<T>) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace random_internal
|
||||
|
||||
struct IntervalClosedClosedTag
|
||||
: public random_internal::TagTypeCompare<IntervalClosedClosedTag> {};
|
||||
struct IntervalClosedOpenTag
|
||||
: public random_internal::TagTypeCompare<IntervalClosedOpenTag> {};
|
||||
struct IntervalOpenClosedTag
|
||||
: public random_internal::TagTypeCompare<IntervalOpenClosedTag> {};
|
||||
struct IntervalOpenOpenTag
|
||||
: public random_internal::TagTypeCompare<IntervalOpenOpenTag> {};
|
||||
|
||||
namespace random_internal {
|
||||
|
||||
// In the absence of an explicitly provided return-type, the template
|
||||
// "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on
|
||||
// the data-types of the endpoint-arguments {A lo, B hi}.
|
||||
//
|
||||
// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the
|
||||
// return-type, if one type can be implicitly converted into the other, in a
|
||||
// lossless way. The template "is_widening_convertible" implements the
|
||||
// compile-time logic for deciding if such a conversion is possible.
|
||||
//
|
||||
// If no such conversion between {A, B} exists, then the overload for
|
||||
// absl::Uniform() will be discarded, and the call will be ill-formed.
|
||||
// Return-type for absl::Uniform() when the return-type is inferred.
|
||||
template <typename A, typename B>
|
||||
using uniform_inferred_return_t =
|
||||
absl::enable_if_t<absl::disjunction<is_widening_convertible<A, B>,
|
||||
is_widening_convertible<B, A>>::value,
|
||||
typename std::conditional<
|
||||
is_widening_convertible<A, B>::value, B, A>::type>;
|
||||
|
||||
// The functions
|
||||
// uniform_lower_bound(tag, a, b)
|
||||
// and
|
||||
// uniform_upper_bound(tag, a, b)
|
||||
// are used as implementation-details for absl::Uniform().
|
||||
//
|
||||
// Conceptually,
|
||||
// [a, b] == [uniform_lower_bound(IntervalClosedClosed, a, b),
|
||||
// uniform_upper_bound(IntervalClosedClosed, a, b)]
|
||||
// (a, b) == [uniform_lower_bound(IntervalOpenOpen, a, b),
|
||||
// uniform_upper_bound(IntervalOpenOpen, a, b)]
|
||||
// [a, b) == [uniform_lower_bound(IntervalClosedOpen, a, b),
|
||||
// uniform_upper_bound(IntervalClosedOpen, a, b)]
|
||||
// (a, b] == [uniform_lower_bound(IntervalOpenClosed, a, b),
|
||||
// uniform_upper_bound(IntervalOpenClosed, a, b)]
|
||||
//
|
||||
template <typename IntType, typename Tag>
|
||||
typename absl::enable_if_t<
|
||||
absl::conjunction<
|
||||
IsIntegral<IntType>,
|
||||
absl::disjunction<std::is_same<Tag, IntervalOpenClosedTag>,
|
||||
std::is_same<Tag, IntervalOpenOpenTag>>>::value,
|
||||
IntType>
|
||||
uniform_lower_bound(Tag, IntType a, IntType) {
|
||||
return a < (std::numeric_limits<IntType>::max)() ? (a + 1) : a;
|
||||
}
|
||||
|
||||
template <typename FloatType, typename Tag>
|
||||
typename absl::enable_if_t<
|
||||
absl::conjunction<
|
||||
std::is_floating_point<FloatType>,
|
||||
absl::disjunction<std::is_same<Tag, IntervalOpenClosedTag>,
|
||||
std::is_same<Tag, IntervalOpenOpenTag>>>::value,
|
||||
FloatType>
|
||||
uniform_lower_bound(Tag, FloatType a, FloatType b) {
|
||||
return std::nextafter(a, b);
|
||||
}
|
||||
|
||||
template <typename NumType, typename Tag>
|
||||
typename absl::enable_if_t<
|
||||
absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
|
||||
std::is_same<Tag, IntervalClosedOpenTag>>::value,
|
||||
NumType>
|
||||
uniform_lower_bound(Tag, NumType a, NumType) {
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename IntType, typename Tag>
|
||||
typename absl::enable_if_t<
|
||||
absl::conjunction<
|
||||
IsIntegral<IntType>,
|
||||
absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>,
|
||||
std::is_same<Tag, IntervalOpenOpenTag>>>::value,
|
||||
IntType>
|
||||
uniform_upper_bound(Tag, IntType, IntType b) {
|
||||
return b > (std::numeric_limits<IntType>::min)() ? (b - 1) : b;
|
||||
}
|
||||
|
||||
template <typename FloatType, typename Tag>
|
||||
typename absl::enable_if_t<
|
||||
absl::conjunction<
|
||||
std::is_floating_point<FloatType>,
|
||||
absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>,
|
||||
std::is_same<Tag, IntervalOpenOpenTag>>>::value,
|
||||
FloatType>
|
||||
uniform_upper_bound(Tag, FloatType, FloatType b) {
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename IntType, typename Tag>
|
||||
typename absl::enable_if_t<
|
||||
absl::conjunction<
|
||||
IsIntegral<IntType>,
|
||||
absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
|
||||
std::is_same<Tag, IntervalOpenClosedTag>>>::value,
|
||||
IntType>
|
||||
uniform_upper_bound(Tag, IntType, IntType b) {
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename FloatType, typename Tag>
|
||||
typename absl::enable_if_t<
|
||||
absl::conjunction<
|
||||
std::is_floating_point<FloatType>,
|
||||
absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
|
||||
std::is_same<Tag, IntervalOpenClosedTag>>>::value,
|
||||
FloatType>
|
||||
uniform_upper_bound(Tag, FloatType, FloatType b) {
|
||||
return std::nextafter(b, (std::numeric_limits<FloatType>::max)());
|
||||
}
|
||||
|
||||
// Returns whether the bounds are valid for the underlying distribution.
|
||||
// Inputs must have already been resolved via uniform_*_bound calls.
|
||||
//
|
||||
// The c++ standard constraints in [rand.dist.uni.int] are listed as:
|
||||
// requires: lo <= hi.
|
||||
//
|
||||
// In the uniform_int_distrubtion, {lo, hi} are closed, closed. Thus:
|
||||
// [0, 0] is legal.
|
||||
// [0, 0) is not legal, but [0, 1) is, which translates to [0, 0].
|
||||
// (0, 1) is not legal, but (0, 2) is, which translates to [1, 1].
|
||||
// (0, 0] is not legal, but (0, 1] is, which translates to [1, 1].
|
||||
//
|
||||
// The c++ standard constraints in [rand.dist.uni.real] are listed as:
|
||||
// requires: lo <= hi.
|
||||
// requires: (hi - lo) <= numeric_limits<T>::max()
|
||||
//
|
||||
// In the uniform_real_distribution, {lo, hi} are closed, open, Thus:
|
||||
// [0, 0] is legal, which is [0, 0+epsilon).
|
||||
// [0, 0) is legal.
|
||||
// (0, 0) is not legal, but (0-epsilon, 0+epsilon) is.
|
||||
// (0, 0] is not legal, but (0, 0+epsilon] is.
|
||||
//
|
||||
template <typename FloatType>
|
||||
absl::enable_if_t<std::is_floating_point<FloatType>::value, bool>
|
||||
is_uniform_range_valid(FloatType a, FloatType b) {
|
||||
return a <= b && std::isfinite(b - a);
|
||||
}
|
||||
|
||||
template <typename IntType>
|
||||
absl::enable_if_t<IsIntegral<IntType>::value, bool>
|
||||
is_uniform_range_valid(IntType a, IntType b) {
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
// UniformDistribution selects either absl::uniform_int_distribution
|
||||
// or absl::uniform_real_distribution depending on the NumType parameter.
|
||||
template <typename NumType>
|
||||
using UniformDistribution =
|
||||
typename std::conditional<IsIntegral<NumType>::value,
|
||||
absl::uniform_int_distribution<NumType>,
|
||||
absl::uniform_real_distribution<NumType>>::type;
|
||||
|
||||
// UniformDistributionWrapper is used as the underlying distribution type
|
||||
// by the absl::Uniform template function. It selects the proper Abseil
|
||||
// uniform distribution and provides constructor overloads that match the
|
||||
// expected parameter order as well as adjusting distribution bounds based
|
||||
// on the tag.
|
||||
template <typename NumType>
|
||||
struct UniformDistributionWrapper : public UniformDistribution<NumType> {
|
||||
template <typename TagType>
|
||||
explicit UniformDistributionWrapper(TagType, NumType lo, NumType hi)
|
||||
: UniformDistribution<NumType>(
|
||||
uniform_lower_bound<NumType>(TagType{}, lo, hi),
|
||||
uniform_upper_bound<NumType>(TagType{}, lo, hi)) {}
|
||||
|
||||
explicit UniformDistributionWrapper(NumType lo, NumType hi)
|
||||
: UniformDistribution<NumType>(
|
||||
uniform_lower_bound<NumType>(IntervalClosedOpenTag(), lo, hi),
|
||||
uniform_upper_bound<NumType>(IntervalClosedOpenTag(), lo, hi)) {}
|
||||
|
||||
explicit UniformDistributionWrapper()
|
||||
: UniformDistribution<NumType>(std::numeric_limits<NumType>::lowest(),
|
||||
(std::numeric_limits<NumType>::max)()) {}
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
|
||||
96
Pods/abseil/absl/random/internal/wide_multiply.h
generated
Normal file
96
Pods/abseil/absl/random/internal/wide_multiply.h
generated
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2017 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
|
||||
#define ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_IA64)
|
||||
#include <intrin.h> // NOLINT(build/include_order)
|
||||
#pragma intrinsic(_umul128)
|
||||
#define ABSL_INTERNAL_USE_UMUL128 1
|
||||
#endif
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/numeric/bits.h"
|
||||
#include "absl/numeric/int128.h"
|
||||
#include "absl/random/internal/traits.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// wide_multiply<T> multiplies two N-bit values to a 2N-bit result.
|
||||
template <typename UIntType>
|
||||
struct wide_multiply {
|
||||
static constexpr size_t kN = std::numeric_limits<UIntType>::digits;
|
||||
using input_type = UIntType;
|
||||
using result_type = typename random_internal::unsigned_bits<kN * 2>::type;
|
||||
|
||||
static result_type multiply(input_type a, input_type b) {
|
||||
return static_cast<result_type>(a) * b;
|
||||
}
|
||||
|
||||
static input_type hi(result_type r) {
|
||||
return static_cast<input_type>(r >> kN);
|
||||
}
|
||||
static input_type lo(result_type r) { return static_cast<input_type>(r); }
|
||||
|
||||
static_assert(std::is_unsigned<UIntType>::value,
|
||||
"Class-template wide_multiply<> argument must be unsigned.");
|
||||
};
|
||||
|
||||
// MultiplyU128ToU256 multiplies two 128-bit values to a 256-bit value.
|
||||
inline U256 MultiplyU128ToU256(uint128 a, uint128 b) {
|
||||
const uint128 a00 = static_cast<uint64_t>(a);
|
||||
const uint128 a64 = a >> 64;
|
||||
const uint128 b00 = static_cast<uint64_t>(b);
|
||||
const uint128 b64 = b >> 64;
|
||||
|
||||
const uint128 c00 = a00 * b00;
|
||||
const uint128 c64a = a00 * b64;
|
||||
const uint128 c64b = a64 * b00;
|
||||
const uint128 c128 = a64 * b64;
|
||||
|
||||
const uint64_t carry =
|
||||
static_cast<uint64_t>(((c00 >> 64) + static_cast<uint64_t>(c64a) +
|
||||
static_cast<uint64_t>(c64b)) >>
|
||||
64);
|
||||
|
||||
return {c128 + (c64a >> 64) + (c64b >> 64) + carry,
|
||||
c00 + (c64a << 64) + (c64b << 64)};
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
struct wide_multiply<uint128> {
|
||||
using input_type = uint128;
|
||||
using result_type = U256;
|
||||
|
||||
static result_type multiply(input_type a, input_type b) {
|
||||
return MultiplyU128ToU256(a, b);
|
||||
}
|
||||
|
||||
static input_type hi(result_type r) { return r.hi; }
|
||||
static input_type lo(result_type r) { return r.lo; }
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
|
||||
Reference in New Issue
Block a user