aboutsummaryrefslogtreecommitdiff
path: root/third_party/abseil-cpp/absl/random/internal
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/abseil-cpp/absl/random/internal')
-rw-r--r--third_party/abseil-cpp/absl/random/internal/BUILD.bazel107
-rw-r--r--third_party/abseil-cpp/absl/random/internal/distribution_caller.h66
-rw-r--r--third_party/abseil-cpp/absl/random/internal/distributions.h52
-rw-r--r--third_party/abseil-cpp/absl/random/internal/explicit_seed_seq.h1
-rw-r--r--third_party/abseil-cpp/absl/random/internal/explicit_seed_seq_test.cc49
-rw-r--r--third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h202
-rw-r--r--third_party/abseil-cpp/absl/random/internal/fast_uniform_bits_test.cc318
-rw-r--r--third_party/abseil-cpp/absl/random/internal/fastmath.h23
-rw-r--r--third_party/abseil-cpp/absl/random/internal/fastmath_test.cc13
-rw-r--r--third_party/abseil-cpp/absl/random/internal/gaussian_distribution_gentables.cc16
-rw-r--r--third_party/abseil-cpp/absl/random/internal/generate_real.h10
-rw-r--r--third_party/abseil-cpp/absl/random/internal/generate_real_test.cc9
-rw-r--r--third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h4
-rw-r--r--third_party/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc5
-rw-r--r--third_party/abseil-cpp/absl/random/internal/mock_helpers.h134
-rw-r--r--third_party/abseil-cpp/absl/random/internal/mock_overload_set.h39
-rw-r--r--third_party/abseil-cpp/absl/random/internal/mocking_bit_gen_base.h120
-rw-r--r--third_party/abseil-cpp/absl/random/internal/nanobenchmark.cc2
-rw-r--r--third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc2
-rw-r--r--third_party/abseil-cpp/absl/random/internal/pcg_engine.h7
-rw-r--r--third_party/abseil-cpp/absl/random/internal/pool_urbg.cc7
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen-keys.inc207
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen.cc2
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen.h2
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_detect.cc4
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_engine.h15
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc458
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_hwaes.h2
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc57
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc462
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_slow.cc669
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_slow.h9
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_slow_test.cc60
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_test.cc45
-rw-r--r--third_party/abseil-cpp/absl/random/internal/randen_traits.h33
-rw-r--r--third_party/abseil-cpp/absl/random/internal/seed_material.cc50
-rw-r--r--third_party/abseil-cpp/absl/random/internal/uniform_helper.h68
-rw-r--r--third_party/abseil-cpp/absl/random/internal/uniform_helper_test.cc279
-rw-r--r--third_party/abseil-cpp/absl/random/internal/wide_multiply.h12
-rw-r--r--third_party/abseil-cpp/absl/random/internal/wide_multiply_test.cc3
40 files changed, 2110 insertions, 1513 deletions
diff --git a/third_party/abseil-cpp/absl/random/internal/BUILD.bazel b/third_party/abseil-cpp/absl/random/internal/BUILD.bazel
index d7ad4efec9..e93eebb68d 100644
--- a/third_party/abseil-cpp/absl/random/internal/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/random/internal/BUILD.bazel
@@ -14,8 +14,6 @@
# limitations under the License.
#
-load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
-
# Internal-only implementation classes for Abseil Random
load(
"//absl:copts/configure_copts.bzl",
@@ -30,16 +28,13 @@ package(default_visibility = [
"//absl/random:__pkg__",
])
-licenses(["notice"]) # Apache 2.0
+licenses(["notice"])
cc_library(
name = "traits",
hdrs = ["traits.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
- visibility = [
- "//absl/random:__pkg__",
- ],
deps = ["//absl/base:config"],
)
@@ -48,24 +43,10 @@ cc_library(
hdrs = ["distribution_caller.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
- visibility = [
- "//absl/random:__pkg__",
- ],
- deps = ["//absl/base:config"],
-)
-
-cc_library(
- name = "distributions",
- hdrs = ["distributions.h"],
- copts = ABSL_DEFAULT_COPTS,
- linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
- ":distribution_caller",
- ":traits",
- ":uniform_helper",
- "//absl/base",
- "//absl/meta:type_traits",
- "//absl/strings",
+ "//absl/base:config",
+ "//absl/base:fast_type_id",
+ "//absl/utility",
],
)
@@ -76,10 +57,10 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
- visibility = [
- "//absl/random:__pkg__",
+ deps = [
+ "//absl/base:config",
+ "//absl/meta:type_traits",
],
- deps = ["//absl/base:config"],
)
cc_library(
@@ -92,12 +73,14 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS + select({
- "//absl:windows": ["-DEFAULTLIB:bcrypt.lib"],
+ "//absl:msvc_compiler": ["-DEFAULTLIB:bcrypt.lib"],
+ "//absl:clang-cl_compiler": ["-DEFAULTLIB:bcrypt.lib"],
"//conditions:default": [],
}),
deps = [
":fast_uniform_bits",
"//absl/base:core_headers",
+ "//absl/base:dynamic_annotations",
"//absl/base:raw_logging_internal",
"//absl/strings",
"//absl/types:optional",
@@ -115,7 +98,9 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = select({
- "//absl:windows": [],
+ "//absl:msvc_compiler": [],
+ "//absl:clang-cl_compiler": [],
+ "//absl:wasm": [],
"//conditions:default": ["-pthread"],
}) + ABSL_DEFAULT_LINKOPTS,
deps = [
@@ -140,7 +125,10 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
- deps = ["//absl/base:config"],
+ deps = [
+ "//absl/base:config",
+ "//absl/base:endian",
+ ],
)
cc_library(
@@ -191,8 +179,8 @@ cc_library(
deps = [
":fastmath",
":traits",
- "//absl/base:bits",
"//absl/meta:type_traits",
+ "//absl/numeric:bits",
],
)
@@ -203,7 +191,7 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
- deps = ["//absl/base:bits"],
+ deps = ["//absl/numeric:bits"],
)
cc_library(
@@ -213,8 +201,8 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":traits",
- "//absl/base:bits",
"//absl/base:config",
+ "//absl/numeric:bits",
"//absl/numeric:int128",
],
)
@@ -230,7 +218,6 @@ cc_library(
":seed_material",
"//absl/base:core_headers",
"//absl/meta:type_traits",
- "//absl/strings",
"//absl/types:optional",
"//absl/types:span",
],
@@ -246,6 +233,7 @@ cc_library(
":iostream_state_saver",
"//absl/base:config",
"//absl/meta:type_traits",
+ "//absl/numeric:bits",
"//absl/numeric:int128",
],
)
@@ -258,19 +246,22 @@ cc_library(
deps = [
":iostream_state_saver",
":randen",
+ "//absl/base:endian",
"//absl/meta:type_traits",
],
)
cc_library(
name = "platform",
+ srcs = [
+ "randen_round_keys.cc",
+ ],
hdrs = [
"randen_traits.h",
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
textual_hdrs = [
- "randen-keys.inc",
"platform.h",
],
deps = ["//absl/base:config"],
@@ -304,6 +295,8 @@ cc_library(
":platform",
"//absl/base:config",
"//absl/base:core_headers",
+ "//absl/base:endian",
+ "//absl/numeric:int128",
],
)
@@ -335,18 +328,16 @@ cc_library(
"randen_hwaes.h",
],
copts = ABSL_DEFAULT_COPTS + ABSL_RANDOM_RANDEN_COPTS + select({
- "//absl:windows": [],
+ "//absl:msvc_compiler": [],
+ "//absl:clang-cl_compiler": [],
"//conditions:default": ["-Wno-pass-failed"],
}),
- # copts in RANDEN_HWAES_COPTS can make this target unusable as a module
- # leading to a Clang diagnostic. Furthermore, it only has a private header
- # anyway and thus there wouldn't be any gain from using it as a module.
- features = ["-header_modules"],
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":platform",
"//absl/base:config",
"//absl/base:core_headers",
+ "//absl/numeric:int128",
],
)
@@ -419,8 +410,8 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":generate_real",
- "//absl/base:bits",
"//absl/flags:flag",
+ "//absl/numeric:bits",
"@com_google_googletest//:gtest_main",
],
)
@@ -504,12 +495,11 @@ cc_test(
)
cc_library(
- name = "mocking_bit_gen_base",
- hdrs = ["mocking_bit_gen_base.h"],
- linkopts = ABSL_DEFAULT_LINKOPTS,
+ name = "mock_helpers",
+ hdrs = ["mock_helpers.h"],
deps = [
- "//absl/random",
- "//absl/strings",
+ "//absl/base:fast_type_id",
+ "//absl/types:optional",
],
)
@@ -517,10 +507,8 @@ cc_library(
name = "mock_overload_set",
testonly = 1,
hdrs = ["mock_overload_set.h"],
- visibility = [
- "//absl/random:__pkg__",
- ],
deps = [
+ ":mock_helpers",
"//absl/random:mocking_bit_gen",
"@com_google_googletest//:gtest",
],
@@ -625,7 +613,9 @@ cc_test(
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ ":platform",
":randen_slow",
+ "//absl/base:endian",
"@com_google_googletest//:gtest_main",
],
)
@@ -634,7 +624,7 @@ cc_test(
name = "randen_hwaes_test",
size = "small",
srcs = ["randen_hwaes_test.cc"],
- copts = ABSL_TEST_COPTS,
+ copts = ABSL_TEST_COPTS + ABSL_RANDOM_RANDEN_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
tags = ABSL_RANDOM_NONPORTABLE_TAGS,
deps = [
@@ -655,7 +645,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":wide_multiply",
- "//absl/base:bits",
+ "//absl/numeric:bits",
"//absl/numeric:int128",
"@com_google_googletest//:gtest_main",
],
@@ -669,6 +659,7 @@ cc_library(
deps = [
":platform",
":randen_engine",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
],
@@ -680,6 +671,8 @@ cc_library(
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ ":traits",
+ "//absl/base:config",
"//absl/meta:type_traits",
],
)
@@ -705,6 +698,7 @@ cc_test(
cc_test(
name = "randen_benchmarks",
size = "medium",
+ timeout = "long",
srcs = ["randen_benchmarks.cc"],
copts = ABSL_TEST_COPTS + ABSL_RANDOM_RANDEN_COPTS,
flaky = 1,
@@ -725,7 +719,6 @@ cc_test(
cc_test(
name = "iostream_state_saver_test",
- size = "small",
srcs = ["iostream_state_saver_test.cc"],
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
@@ -733,3 +726,15 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
+
+cc_test(
+ name = "uniform_helper_test",
+ size = "small",
+ srcs = ["uniform_helper_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
+ deps = [
+ ":uniform_helper",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
diff --git a/third_party/abseil-cpp/absl/random/internal/distribution_caller.h b/third_party/abseil-cpp/absl/random/internal/distribution_caller.h
index 02603cf843..fc81b787eb 100644
--- a/third_party/abseil-cpp/absl/random/internal/distribution_caller.h
+++ b/third_party/abseil-cpp/absl/random/internal/distribution_caller.h
@@ -20,6 +20,8 @@
#include <utility>
#include "absl/base/config.h"
+#include "absl/base/internal/fast_type_id.h"
+#include "absl/utility/utility.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -30,27 +32,57 @@ namespace random_internal {
// to intercept such calls.
template <typename URBG>
struct DistributionCaller {
- // Call the provided distribution type. The parameters are expected
- // to be explicitly specified.
- // DistrT is the distribution type.
- // FormatT is the formatter type:
+ // SFINAE to detect whether the URBG type includes a member matching
+ // bool InvokeMock(base_internal::FastTypeIdType, void*, void*).
//
- // struct FormatT {
- // using result_type = distribution_t::result_type;
- // static std::string FormatCall(
- // const distribution_t& distr,
- // absl::Span<const result_type>);
- //
- // static std::string FormatExpectation(
- // absl::string_view match_args,
- // absl::Span<const result_t> results);
- // }
- //
- template <typename DistrT, typename FormatT, typename... Args>
- static typename DistrT::result_type Call(URBG* urbg, Args&&... args) {
+ // 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
diff --git a/third_party/abseil-cpp/absl/random/internal/distributions.h b/third_party/abseil-cpp/absl/random/internal/distributions.h
deleted file mode 100644
index d7e3c0161f..0000000000
--- a/third_party/abseil-cpp/absl/random/internal/distributions.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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_DISTRIBUTIONS_H_
-#define ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_
-
-#include <type_traits>
-
-#include "absl/meta/type_traits.h"
-#include "absl/random/internal/distribution_caller.h"
-#include "absl/random/internal/traits.h"
-#include "absl/random/internal/uniform_helper.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-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>;
-
-} // namespace random_internal
-ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_
diff --git a/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq.h b/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq.h
index 6a743eaf46..25f791535f 100644
--- a/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq.h
+++ b/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq.h
@@ -23,6 +23,7 @@
#include <vector>
#include "absl/base/config.h"
+#include "absl/base/internal/endian.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq_test.cc b/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq_test.cc
index a55ad73948..f867f610d0 100644
--- a/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq_test.cc
@@ -24,6 +24,8 @@
namespace {
+using ::absl::random_internal::ExplicitSeedSeq;
+
template <typename Sseq>
bool ConformsToInterface() {
// Check that the SeedSequence can be default-constructed.
@@ -64,14 +66,14 @@ TEST(SeedSequences, CheckInterfaces) {
EXPECT_TRUE(ConformsToInterface<std::seed_seq>());
// Abseil classes
- EXPECT_TRUE(ConformsToInterface<absl::random_internal::ExplicitSeedSeq>());
+ EXPECT_TRUE(ConformsToInterface<ExplicitSeedSeq>());
}
TEST(ExplicitSeedSeq, DefaultConstructorGeneratesZeros) {
const size_t kNumBlocks = 128;
uint32_t outputs[kNumBlocks];
- absl::random_internal::ExplicitSeedSeq seq;
+ ExplicitSeedSeq seq;
seq.generate(outputs, &outputs[kNumBlocks]);
for (uint32_t& seed : outputs) {
@@ -87,8 +89,7 @@ TEST(ExplicitSeeqSeq, SeedMaterialIsForwardedIdentically) {
for (uint32_t& seed : seed_material) {
seed = urandom();
}
- absl::random_internal::ExplicitSeedSeq seq(seed_material,
- &seed_material[kNumBlocks]);
+ ExplicitSeedSeq seq(seed_material, &seed_material[kNumBlocks]);
// Check that output is same as seed-material provided to constructor.
{
@@ -133,11 +134,10 @@ TEST(ExplicitSeedSeq, CopyAndMoveConstructors) {
for (uint32_t& entry : entropy) {
entry = urandom();
}
- absl::random_internal::ExplicitSeedSeq seq_from_entropy(std::begin(entropy),
- std::end(entropy));
+ ExplicitSeedSeq seq_from_entropy(std::begin(entropy), std::end(entropy));
// Copy constructor.
{
- absl::random_internal::ExplicitSeedSeq seq_copy(seq_from_entropy);
+ ExplicitSeedSeq seq_copy(seq_from_entropy);
EXPECT_EQ(seq_copy.size(), seq_from_entropy.size());
std::vector<uint32_t> seeds_1;
@@ -155,8 +155,7 @@ TEST(ExplicitSeedSeq, CopyAndMoveConstructors) {
for (uint32_t& entry : entropy) {
entry = urandom();
}
- absl::random_internal::ExplicitSeedSeq another_seq(std::begin(entropy),
- std::end(entropy));
+ ExplicitSeedSeq another_seq(std::begin(entropy), std::end(entropy));
std::vector<uint32_t> seeds_1;
seeds_1.resize(1000, 0);
@@ -202,3 +201,35 @@ TEST(ExplicitSeedSeq, CopyAndMoveConstructors) {
EXPECT_THAT(seeds_1, Each(Eq(0)));
}
}
+
+TEST(ExplicitSeedSeq, StdURBGGoldenTests) {
+ // Verify that for std::- URBG instances the results are stable across
+ // platforms (these should have deterministic output).
+ {
+ ExplicitSeedSeq seed_sequence{12, 34, 56};
+ std::minstd_rand rng(seed_sequence);
+
+ std::minstd_rand::result_type values[4] = {rng(), rng(), rng(), rng()};
+ EXPECT_THAT(values,
+ testing::ElementsAre(579252, 43785881, 464353103, 1501811174));
+ }
+
+ {
+ ExplicitSeedSeq seed_sequence{12, 34, 56};
+ std::mt19937 rng(seed_sequence);
+
+ std::mt19937::result_type values[4] = {rng(), rng(), rng(), rng()};
+ EXPECT_THAT(values, testing::ElementsAre(138416803, 151130212, 33817739,
+ 138416803));
+ }
+
+ {
+ ExplicitSeedSeq seed_sequence{12, 34, 56};
+ std::mt19937_64 rng(seed_sequence);
+
+ std::mt19937_64::result_type values[4] = {rng(), rng(), rng(), rng()};
+ EXPECT_THAT(values,
+ testing::ElementsAre(19738651785169348, 1464811352364190456,
+ 18054685302720800, 19738651785169348));
+ }
+}
diff --git a/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h b/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h
index f13c8729f7..425aaf7d83 100644
--- a/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h
+++ b/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h
@@ -21,6 +21,7 @@
#include <type_traits>
#include "absl/base/config.h"
+#include "absl/meta/type_traits.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -38,28 +39,17 @@ constexpr bool IsPowerOfTwoOrZero(UIntType n) {
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};
-}
-
-template <typename UIntType>
-constexpr UIntType LargestPowerOfTwoLessThanOrEqualTo(UIntType n) {
- return n < 2 ? n : 2 * LargestPowerOfTwoLessThanOrEqualTo(n / 2);
-}
-
-// Given a URBG generating values in the closed interval [Lo, Hi], returns the
-// largest power of two less than or equal to `Hi - Lo + 1`.
-template <typename URBG>
-constexpr typename URBG::result_type PowerOfTwoSubRangeSize() {
- return LargestPowerOfTwoLessThanOrEqualTo(RangeSize<URBG>());
+ : ((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 / 2);
+ return (n <= 1) ? 0 : 1 + IntegerLog2(n >> 1);
}
// Returns the number of bits of randomness returned through
@@ -68,18 +58,23 @@ template <typename URBG>
constexpr size_t NumBits() {
return RangeSize<URBG>() == 0
? std::numeric_limits<typename URBG::result_type>::digits
- : IntegerLog2(PowerOfTwoSubRangeSize<URBG>());
+ : 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(UIntType n) {
+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:
@@ -107,50 +102,16 @@ class FastUniformBits {
"Class-template FastUniformBits<> must be parameterized using "
"an unsigned type.");
- // PowerOfTwoVariate() generates a single random variate, always returning a
- // value in the half-open interval `[0, PowerOfTwoSubRangeSize<URBG>())`. If
- // the URBG already generates values in a power-of-two range, the generator
- // itself is used. Otherwise, we use rejection sampling on the largest
- // possible power-of-two-sized subrange.
- struct PowerOfTwoTag {};
- struct RejectionSamplingTag {};
- template <typename URBG>
- static typename URBG::result_type PowerOfTwoVariate(
- URBG& g) { // NOLINT(runtime/references)
- using tag =
- typename std::conditional<IsPowerOfTwoOrZero(RangeSize<URBG>()),
- PowerOfTwoTag, RejectionSamplingTag>::type;
- return PowerOfTwoVariate(g, tag{});
- }
-
- template <typename URBG>
- static typename URBG::result_type PowerOfTwoVariate(
- URBG& g, // NOLINT(runtime/references)
- PowerOfTwoTag) {
- return g() - (URBG::min)();
- }
-
- template <typename URBG>
- static typename URBG::result_type PowerOfTwoVariate(
- URBG& g, // NOLINT(runtime/references)
- RejectionSamplingTag) {
- // Use rejection sampling to ensure uniformity across the range.
- typename URBG::result_type u;
- do {
- u = g() - (URBG::min)();
- } while (u >= PowerOfTwoSubRangeSize<URBG>());
- return u;
- }
-
// Generate() generates a random value, dispatched on whether
- // the underlying URBG must loop over multiple calls or not.
+ // 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)
- std::true_type /* avoid_looping */);
+ SimplifiedLoopTag);
template <typename URBG>
result_type Generate(URBG& g, // NOLINT(runtime/references)
- std::false_type /* avoid_looping */);
+ RejectionLoopTag);
};
template <typename UIntType>
@@ -162,31 +123,47 @@ FastUniformBits<UIntType>::operator()(URBG& g) { // NOLINT(runtime/references)
// Y = (2 ^ kRange) - 1
static_assert((URBG::max)() > (URBG::min)(),
"URBG::max and URBG::min may not be equal.");
- using urbg_result_type = typename URBG::result_type;
- constexpr urbg_result_type kRangeMask =
- RangeSize<URBG>() == 0
- ? (std::numeric_limits<urbg_result_type>::max)()
- : static_cast<urbg_result_type>(PowerOfTwoSubRangeSize<URBG>() - 1);
- return Generate(g, std::integral_constant<bool, (kRangeMask >= (max)())>{});
+
+ 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)
- std::true_type /* avoid_looping */) {
- // The width of the result_type is less than than the width of the random bits
- // provided by URBG. Thus, generate a single value and then simply mask off
- // the required bits.
+ 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)();
- return PowerOfTwoVariate(g) & (max)();
+ result_type r = static_cast<result_type>(g() - kMin);
+ for (size_t n = 1; n < kIters; ++n) {
+ r = (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)
- std::false_type /* avoid_looping */) {
+ 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
@@ -199,21 +176,44 @@ FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
// `kSmallIters` and `kLargeIters` times respectively such
// that
//
- // `kTotalWidth == kSmallIters * kSmallWidth
- // + kLargeIters * kLargeWidth`
+ // `kResultBits == kSmallIters * kSmallBits
+ // + kLargeIters * kLargeBits`
//
- // where `kTotalWidth` is the total number of bits in `result_type`.
+ // where `kResultBits` is the total number of bits in `result_type`.
//
- constexpr size_t kTotalWidth = std::numeric_limits<result_type>::digits;
- constexpr size_t kUrbgWidth = NumBits<URBG>();
- constexpr size_t kTotalIters =
- kTotalWidth / kUrbgWidth + (kTotalWidth % kUrbgWidth != 0);
- constexpr size_t kSmallWidth = kTotalWidth / kTotalIters;
- constexpr size_t kLargeWidth = kSmallWidth + 1;
+ 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 `kLargeWidth == kSmallWidth + 1`, it follows that
+ // Because `kLargeBits == kSmallBits + 1`, it follows that
//
- // `kTotalWidth == kTotalIters * kSmallWidth + kLargeIters`
+ // `kResultBits == kSmallIters * kSmallBits + kLargeIters`
//
// and therefore
//
@@ -224,36 +224,40 @@ FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
// 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.
- constexpr size_t kLargeIters = kTotalWidth % kSmallWidth;
- constexpr size_t kSmallIters =
- (kTotalWidth - (kLargeWidth * kLargeIters)) / kSmallWidth;
+ static_assert(kResultBits == kSmallIters * kSmallBits +
+ (kTotalIters - kSmallIters) * kLargeBits,
+ "Error in looping constant calculations.");
- static_assert(
- kTotalWidth == kSmallIters * kSmallWidth + kLargeIters * kLargeWidth,
- "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);
- result_type s = 0;
+ static constexpr auto kMin = (URBG::min)();
- constexpr size_t kSmallShift = kSmallWidth % kTotalWidth;
- constexpr result_type kSmallMask = MaskFromShift(result_type{kSmallShift});
+ result_type s = 0;
for (size_t n = 0; n < kSmallIters; ++n) {
- s = (s << kSmallShift) +
- (static_cast<result_type>(PowerOfTwoVariate(g)) & kSmallMask);
- }
+ urbg_result_type v;
+ do {
+ v = g() - kMin;
+ } while (v >= kSmallRejection);
- constexpr size_t kLargeShift = kLargeWidth % kTotalWidth;
- constexpr result_type kLargeMask = MaskFromShift(result_type{kLargeShift});
- for (size_t n = 0; n < kLargeIters; ++n) {
- s = (s << kLargeShift) +
- (static_cast<result_type>(PowerOfTwoVariate(g)) & kLargeMask);
+ s = (s << kSmallShift) + static_cast<result_type>(v & kSmallMask);
}
- static_assert(
- kLargeShift == kSmallShift + 1 ||
- (kLargeShift == 0 &&
- kSmallShift == std::numeric_limits<result_type>::digits - 1),
- "Error in looping constant calculations");
+ 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;
}
diff --git a/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits_test.cc b/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits_test.cc
index f5b837e586..cee702df85 100644
--- a/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits_test.cc
@@ -34,8 +34,8 @@ TYPED_TEST(FastUniformBitsTypedTest, BasicTest) {
using Limits = std::numeric_limits<TypeParam>;
using FastBits = FastUniformBits<TypeParam>;
- EXPECT_EQ(0, FastBits::min());
- EXPECT_EQ(Limits::max(), FastBits::max());
+ EXPECT_EQ(0, (FastBits::min)());
+ EXPECT_EQ((Limits::max)(), (FastBits::max)());
constexpr int kIters = 10000;
std::random_device rd;
@@ -43,8 +43,8 @@ TYPED_TEST(FastUniformBitsTypedTest, BasicTest) {
FastBits fast;
for (int i = 0; i < kIters; i++) {
const auto v = fast(gen);
- EXPECT_LE(v, FastBits::max());
- EXPECT_GE(v, FastBits::min());
+ EXPECT_LE(v, (FastBits::max)());
+ EXPECT_GE(v, (FastBits::min)());
}
}
@@ -52,21 +52,26 @@ template <typename UIntType, UIntType Lo, UIntType Hi, UIntType Val = Lo>
struct FakeUrbg {
using result_type = UIntType;
+ FakeUrbg() = default;
+ explicit FakeUrbg(bool r) : reject(r) {}
+
static constexpr result_type(max)() { return Hi; }
static constexpr result_type(min)() { return Lo; }
- result_type operator()() { return Val; }
-};
+ result_type operator()() {
+ // when reject is set, return Hi half the time.
+ return ((++calls % 2) == 1 && reject) ? Hi : Val;
+ }
-using UrngOddbits = FakeUrbg<uint8_t, 1, 0xfe, 0x73>;
-using Urng4bits = FakeUrbg<uint8_t, 1, 0x10, 2>;
-using Urng31bits = FakeUrbg<uint32_t, 1, 0xfffffffe, 0x60070f03>;
-using Urng32bits = FakeUrbg<uint32_t, 0, 0xffffffff, 0x74010f01>;
+ bool reject = false;
+ size_t calls = 0;
+};
TEST(FastUniformBitsTest, IsPowerOfTwoOrZero) {
EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{0}));
EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{1}));
EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{2}));
EXPECT_FALSE(IsPowerOfTwoOrZero(uint8_t{3}));
+ EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{4}));
EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{16}));
EXPECT_FALSE(IsPowerOfTwoOrZero(uint8_t{17}));
EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits<uint8_t>::max)()));
@@ -75,6 +80,7 @@ TEST(FastUniformBitsTest, IsPowerOfTwoOrZero) {
EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{1}));
EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{2}));
EXPECT_FALSE(IsPowerOfTwoOrZero(uint16_t{3}));
+ EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{4}));
EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{16}));
EXPECT_FALSE(IsPowerOfTwoOrZero(uint16_t{17}));
EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits<uint16_t>::max)()));
@@ -91,181 +97,237 @@ TEST(FastUniformBitsTest, IsPowerOfTwoOrZero) {
EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{1}));
EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{2}));
EXPECT_FALSE(IsPowerOfTwoOrZero(uint64_t{3}));
+ EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{4}));
EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{64}));
EXPECT_FALSE(IsPowerOfTwoOrZero(uint64_t{17}));
EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits<uint64_t>::max)()));
}
TEST(FastUniformBitsTest, IntegerLog2) {
- EXPECT_EQ(IntegerLog2(uint16_t{0}), 0);
- EXPECT_EQ(IntegerLog2(uint16_t{1}), 0);
- EXPECT_EQ(IntegerLog2(uint16_t{2}), 1);
- EXPECT_EQ(IntegerLog2(uint16_t{3}), 1);
- EXPECT_EQ(IntegerLog2(uint16_t{4}), 2);
- EXPECT_EQ(IntegerLog2(uint16_t{5}), 2);
- EXPECT_EQ(IntegerLog2(std::numeric_limits<uint64_t>::max()), 63);
+ EXPECT_EQ(0, IntegerLog2(uint16_t{0}));
+ EXPECT_EQ(0, IntegerLog2(uint16_t{1}));
+ EXPECT_EQ(1, IntegerLog2(uint16_t{2}));
+ EXPECT_EQ(1, IntegerLog2(uint16_t{3}));
+ EXPECT_EQ(2, IntegerLog2(uint16_t{4}));
+ EXPECT_EQ(2, IntegerLog2(uint16_t{5}));
+ EXPECT_EQ(2, IntegerLog2(uint16_t{7}));
+ EXPECT_EQ(3, IntegerLog2(uint16_t{8}));
+ EXPECT_EQ(63, IntegerLog2((std::numeric_limits<uint64_t>::max)()));
}
TEST(FastUniformBitsTest, RangeSize) {
- EXPECT_EQ((RangeSize<FakeUrbg<uint8_t, 0, 3>>()), 4);
- EXPECT_EQ((RangeSize<FakeUrbg<uint8_t, 2, 2>>()), 1);
- EXPECT_EQ((RangeSize<FakeUrbg<uint8_t, 2, 5>>()), 4);
- EXPECT_EQ((RangeSize<FakeUrbg<uint8_t, 2, 6>>()), 5);
- EXPECT_EQ((RangeSize<FakeUrbg<uint8_t, 2, 10>>()), 9);
+ EXPECT_EQ(2, (RangeSize<FakeUrbg<uint8_t, 0, 1>>()));
+ EXPECT_EQ(3, (RangeSize<FakeUrbg<uint8_t, 0, 2>>()));
+ EXPECT_EQ(4, (RangeSize<FakeUrbg<uint8_t, 0, 3>>()));
+ // EXPECT_EQ(0, (RangeSize<FakeUrbg<uint8_t, 2, 2>>()));
+ EXPECT_EQ(4, (RangeSize<FakeUrbg<uint8_t, 2, 5>>()));
+ EXPECT_EQ(5, (RangeSize<FakeUrbg<uint8_t, 2, 6>>()));
+ EXPECT_EQ(9, (RangeSize<FakeUrbg<uint8_t, 2, 10>>()));
EXPECT_EQ(
- (RangeSize<FakeUrbg<uint8_t, 0, std::numeric_limits<uint8_t>::max()>>()),
- 0);
-
- EXPECT_EQ((RangeSize<FakeUrbg<uint16_t, 0, 3>>()), 4);
- EXPECT_EQ((RangeSize<FakeUrbg<uint16_t, 2, 2>>()), 1);
- EXPECT_EQ((RangeSize<FakeUrbg<uint16_t, 2, 5>>()), 4);
- EXPECT_EQ((RangeSize<FakeUrbg<uint16_t, 2, 6>>()), 5);
- EXPECT_EQ((RangeSize<FakeUrbg<uint16_t, 1000, 1017>>()), 18);
- EXPECT_EQ((RangeSize<
- FakeUrbg<uint16_t, 0, std::numeric_limits<uint16_t>::max()>>()),
- 0);
-
- EXPECT_EQ((RangeSize<FakeUrbg<uint32_t, 0, 3>>()), 4);
- EXPECT_EQ((RangeSize<FakeUrbg<uint32_t, 2, 2>>()), 1);
- EXPECT_EQ((RangeSize<FakeUrbg<uint32_t, 2, 5>>()), 4);
- EXPECT_EQ((RangeSize<FakeUrbg<uint32_t, 2, 6>>()), 5);
- EXPECT_EQ((RangeSize<FakeUrbg<uint32_t, 1000, 1017>>()), 18);
- EXPECT_EQ((RangeSize<FakeUrbg<uint32_t, 0, 0xffffffff>>()), 0);
- EXPECT_EQ((RangeSize<FakeUrbg<uint32_t, 1, 0xffffffff>>()), 0xffffffff);
- EXPECT_EQ((RangeSize<FakeUrbg<uint32_t, 1, 0xfffffffe>>()), 0xfffffffe);
- EXPECT_EQ((RangeSize<FakeUrbg<uint32_t, 2, 0xfffffffe>>()), 0xfffffffd);
- EXPECT_EQ((RangeSize<
- FakeUrbg<uint32_t, 0, std::numeric_limits<uint32_t>::max()>>()),
- 0);
-
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 0, 3>>()), 4);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 2, 2>>()), 1);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 2, 5>>()), 4);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 2, 6>>()), 5);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 1000, 1017>>()), 18);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 0, 0xffffffff>>()), 0x100000000ull);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 1, 0xffffffff>>()), 0xffffffffull);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 1, 0xfffffffe>>()), 0xfffffffeull);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 2, 0xfffffffe>>()), 0xfffffffdull);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 0, 0xffffffffffffffffull>>()), 0ull);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 1, 0xffffffffffffffffull>>()),
- 0xffffffffffffffffull);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 1, 0xfffffffffffffffeull>>()),
- 0xfffffffffffffffeull);
- EXPECT_EQ((RangeSize<FakeUrbg<uint64_t, 2, 0xfffffffffffffffeull>>()),
- 0xfffffffffffffffdull);
- EXPECT_EQ((RangeSize<
- FakeUrbg<uint64_t, 0, std::numeric_limits<uint64_t>::max()>>()),
- 0);
-}
+ 0, (RangeSize<
+ FakeUrbg<uint8_t, 0, (std::numeric_limits<uint8_t>::max)()>>()));
-TEST(FastUniformBitsTest, PowerOfTwoSubRangeSize) {
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint8_t, 0, 3>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint8_t, 2, 2>>()), 1);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint8_t, 2, 5>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint8_t, 2, 6>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint8_t, 2, 10>>()), 8);
- EXPECT_EQ((PowerOfTwoSubRangeSize<
- FakeUrbg<uint8_t, 0, std::numeric_limits<uint8_t>::max()>>()),
- 0);
-
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint16_t, 0, 3>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint16_t, 2, 2>>()), 1);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint16_t, 2, 5>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint16_t, 2, 6>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint16_t, 1000, 1017>>()), 16);
- EXPECT_EQ((PowerOfTwoSubRangeSize<
- FakeUrbg<uint16_t, 0, std::numeric_limits<uint16_t>::max()>>()),
- 0);
-
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint32_t, 0, 3>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint32_t, 2, 2>>()), 1);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint32_t, 2, 5>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint32_t, 2, 6>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint32_t, 1000, 1017>>()), 16);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint32_t, 0, 0xffffffff>>()), 0);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint32_t, 1, 0xffffffff>>()),
- 0x80000000);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint32_t, 1, 0xfffffffe>>()),
- 0x80000000);
- EXPECT_EQ((PowerOfTwoSubRangeSize<
- FakeUrbg<uint32_t, 0, std::numeric_limits<uint32_t>::max()>>()),
- 0);
-
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 0, 3>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 2, 2>>()), 1);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 2, 5>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 2, 6>>()), 4);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 1000, 1017>>()), 16);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 0, 0xffffffff>>()),
- 0x100000000ull);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 1, 0xffffffff>>()),
- 0x80000000ull);
- EXPECT_EQ((PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 1, 0xfffffffe>>()),
- 0x80000000ull);
+ EXPECT_EQ(4, (RangeSize<FakeUrbg<uint16_t, 0, 3>>()));
+ EXPECT_EQ(4, (RangeSize<FakeUrbg<uint16_t, 2, 5>>()));
+ EXPECT_EQ(5, (RangeSize<FakeUrbg<uint16_t, 2, 6>>()));
+ EXPECT_EQ(18, (RangeSize<FakeUrbg<uint16_t, 1000, 1017>>()));
EXPECT_EQ(
- (PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 0, 0xffffffffffffffffull>>()),
- 0);
+ 0, (RangeSize<
+ FakeUrbg<uint16_t, 0, (std::numeric_limits<uint16_t>::max)()>>()));
+
+ EXPECT_EQ(4, (RangeSize<FakeUrbg<uint32_t, 0, 3>>()));
+ EXPECT_EQ(4, (RangeSize<FakeUrbg<uint32_t, 2, 5>>()));
+ EXPECT_EQ(5, (RangeSize<FakeUrbg<uint32_t, 2, 6>>()));
+ EXPECT_EQ(18, (RangeSize<FakeUrbg<uint32_t, 1000, 1017>>()));
+ EXPECT_EQ(0, (RangeSize<FakeUrbg<uint32_t, 0, 0xffffffff>>()));
+ EXPECT_EQ(0xffffffff, (RangeSize<FakeUrbg<uint32_t, 1, 0xffffffff>>()));
+ EXPECT_EQ(0xfffffffe, (RangeSize<FakeUrbg<uint32_t, 1, 0xfffffffe>>()));
+ EXPECT_EQ(0xfffffffd, (RangeSize<FakeUrbg<uint32_t, 2, 0xfffffffe>>()));
EXPECT_EQ(
- (PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 1, 0xffffffffffffffffull>>()),
- 0x8000000000000000ull);
+ 0, (RangeSize<
+ FakeUrbg<uint32_t, 0, (std::numeric_limits<uint32_t>::max)()>>()));
+
+ EXPECT_EQ(4, (RangeSize<FakeUrbg<uint64_t, 0, 3>>()));
+ EXPECT_EQ(4, (RangeSize<FakeUrbg<uint64_t, 2, 5>>()));
+ EXPECT_EQ(5, (RangeSize<FakeUrbg<uint64_t, 2, 6>>()));
+ EXPECT_EQ(18, (RangeSize<FakeUrbg<uint64_t, 1000, 1017>>()));
+ EXPECT_EQ(0x100000000, (RangeSize<FakeUrbg<uint64_t, 0, 0xffffffff>>()));
+ EXPECT_EQ(0xffffffff, (RangeSize<FakeUrbg<uint64_t, 1, 0xffffffff>>()));
+ EXPECT_EQ(0xfffffffe, (RangeSize<FakeUrbg<uint64_t, 1, 0xfffffffe>>()));
+ EXPECT_EQ(0xfffffffd, (RangeSize<FakeUrbg<uint64_t, 2, 0xfffffffe>>()));
+ EXPECT_EQ(0, (RangeSize<FakeUrbg<uint64_t, 0, 0xffffffffffffffff>>()));
+ EXPECT_EQ(0xffffffffffffffff,
+ (RangeSize<FakeUrbg<uint64_t, 1, 0xffffffffffffffff>>()));
+ EXPECT_EQ(0xfffffffffffffffe,
+ (RangeSize<FakeUrbg<uint64_t, 1, 0xfffffffffffffffe>>()));
+ EXPECT_EQ(0xfffffffffffffffd,
+ (RangeSize<FakeUrbg<uint64_t, 2, 0xfffffffffffffffe>>()));
EXPECT_EQ(
- (PowerOfTwoSubRangeSize<FakeUrbg<uint64_t, 1, 0xfffffffffffffffeull>>()),
- 0x8000000000000000ull);
- EXPECT_EQ((PowerOfTwoSubRangeSize<
- FakeUrbg<uint64_t, 0, std::numeric_limits<uint64_t>::max()>>()),
- 0);
+ 0, (RangeSize<
+ FakeUrbg<uint64_t, 0, (std::numeric_limits<uint64_t>::max)()>>()));
}
-TEST(FastUniformBitsTest, Urng4_VariousOutputs) {
+// The constants need to be choosen so that an infinite rejection loop doesn't
+// happen...
+using Urng1_5bit = FakeUrbg<uint8_t, 0, 2, 0>; // ~1.5 bits (range 3)
+using Urng4bits = FakeUrbg<uint8_t, 1, 0x10, 2>;
+using Urng22bits = FakeUrbg<uint32_t, 0, 0x3fffff, 0x301020>;
+using Urng31bits = FakeUrbg<uint32_t, 1, 0xfffffffe, 0x60070f03>; // ~31.9 bits
+using Urng32bits = FakeUrbg<uint32_t, 0, 0xffffffff, 0x74010f01>;
+using Urng33bits =
+ FakeUrbg<uint64_t, 1, 0x1ffffffff, 0x013301033>; // ~32.9 bits
+using Urng63bits = FakeUrbg<uint64_t, 1, 0xfffffffffffffffe,
+ 0xfedcba9012345678>; // ~63.9 bits
+using Urng64bits =
+ FakeUrbg<uint64_t, 0, 0xffffffffffffffff, 0x123456780fedcba9>;
+
+TEST(FastUniformBitsTest, OutputsUpTo32Bits) {
// Tests that how values are composed; the single-bit deltas should be spread
// across each invocation.
+ Urng1_5bit urng1_5;
Urng4bits urng4;
+ Urng22bits urng22;
Urng31bits urng31;
Urng32bits urng32;
+ Urng33bits urng33;
+ Urng63bits urng63;
+ Urng64bits urng64;
// 8-bit types
{
FastUniformBits<uint8_t> fast8;
+ EXPECT_EQ(0x0, fast8(urng1_5));
EXPECT_EQ(0x11, fast8(urng4));
+ EXPECT_EQ(0x20, fast8(urng22));
EXPECT_EQ(0x2, fast8(urng31));
EXPECT_EQ(0x1, fast8(urng32));
+ EXPECT_EQ(0x32, fast8(urng33));
+ EXPECT_EQ(0x77, fast8(urng63));
+ EXPECT_EQ(0xa9, fast8(urng64));
}
// 16-bit types
{
FastUniformBits<uint16_t> fast16;
+ EXPECT_EQ(0x0, fast16(urng1_5));
EXPECT_EQ(0x1111, fast16(urng4));
- EXPECT_EQ(0xf02, fast16(urng31));
- EXPECT_EQ(0xf01, fast16(urng32));
+ EXPECT_EQ(0x1020, fast16(urng22));
+ EXPECT_EQ(0x0f02, fast16(urng31));
+ EXPECT_EQ(0x0f01, fast16(urng32));
+ EXPECT_EQ(0x1032, fast16(urng33));
+ EXPECT_EQ(0x5677, fast16(urng63));
+ EXPECT_EQ(0xcba9, fast16(urng64));
}
// 32-bit types
{
FastUniformBits<uint32_t> fast32;
+ EXPECT_EQ(0x0, fast32(urng1_5));
EXPECT_EQ(0x11111111, fast32(urng4));
+ EXPECT_EQ(0x08301020, fast32(urng22));
EXPECT_EQ(0x0f020f02, fast32(urng31));
EXPECT_EQ(0x74010f01, fast32(urng32));
+ EXPECT_EQ(0x13301032, fast32(urng33));
+ EXPECT_EQ(0x12345677, fast32(urng63));
+ EXPECT_EQ(0x0fedcba9, fast32(urng64));
}
+}
+
+TEST(FastUniformBitsTest, Outputs64Bits) {
+ // Tests that how values are composed; the single-bit deltas should be spread
+ // across each invocation.
+ FastUniformBits<uint64_t> fast64;
- // 64-bit types
{
- FastUniformBits<uint64_t> fast64;
+ FakeUrbg<uint8_t, 0, 1, 0> urng0;
+ FakeUrbg<uint8_t, 0, 1, 1> urng1;
+ Urng4bits urng4;
+ Urng22bits urng22;
+ Urng31bits urng31;
+ Urng32bits urng32;
+ Urng33bits urng33;
+ Urng63bits urng63;
+ Urng64bits urng64;
+
+ // somewhat degenerate cases only create a single bit.
+ EXPECT_EQ(0x0, fast64(urng0));
+ EXPECT_EQ(64, urng0.calls);
+ EXPECT_EQ(0xffffffffffffffff, fast64(urng1));
+ EXPECT_EQ(64, urng1.calls);
+
+ // less degenerate cases.
EXPECT_EQ(0x1111111111111111, fast64(urng4));
+ EXPECT_EQ(16, urng4.calls);
+ EXPECT_EQ(0x01020c0408301020, fast64(urng22));
+ EXPECT_EQ(3, urng22.calls);
EXPECT_EQ(0x387811c3c0870f02, fast64(urng31));
+ EXPECT_EQ(3, urng31.calls);
EXPECT_EQ(0x74010f0174010f01, fast64(urng32));
+ EXPECT_EQ(2, urng32.calls);
+ EXPECT_EQ(0x808194040cb01032, fast64(urng33));
+ EXPECT_EQ(3, urng33.calls);
+ EXPECT_EQ(0x1234567712345677, fast64(urng63));
+ EXPECT_EQ(2, urng63.calls);
+ EXPECT_EQ(0x123456780fedcba9, fast64(urng64));
+ EXPECT_EQ(1, urng64.calls);
+ }
+
+ // The 1.5 bit case is somewhat interesting in that the algorithm refinement
+ // causes one extra small sample. Comments here reference the names used in
+ // [rand.adapt.ibits] that correspond to this case.
+ {
+ Urng1_5bit urng1_5;
+
+ // w = 64
+ // R = 3
+ // m = 1
+ // n' = 64
+ // w0' = 1
+ // y0' = 2
+ // n = (1 <= 0) > 64 : 65 = 65
+ // n0 = 65 - (64%65) = 1
+ // n1 = 64
+ // w0 = 0
+ // y0 = 3
+ // w1 = 1
+ // y1 = 2
+ EXPECT_EQ(0x0, fast64(urng1_5));
+ EXPECT_EQ(65, urng1_5.calls);
+ }
+
+ // Validate rejections for non-power-of-2 cases.
+ {
+ Urng1_5bit urng1_5(true);
+ Urng31bits urng31(true);
+ Urng33bits urng33(true);
+ Urng63bits urng63(true);
+
+ // For 1.5 bits, there would be 1+2*64, except the first
+ // value was accepted and shifted off the end.
+ EXPECT_EQ(0, fast64(urng1_5));
+ EXPECT_EQ(128, urng1_5.calls);
+ EXPECT_EQ(0x387811c3c0870f02, fast64(urng31));
+ EXPECT_EQ(6, urng31.calls);
+ EXPECT_EQ(0x808194040cb01032, fast64(urng33));
+ EXPECT_EQ(6, urng33.calls);
+ EXPECT_EQ(0x1234567712345677, fast64(urng63));
+ EXPECT_EQ(4, urng63.calls);
}
}
TEST(FastUniformBitsTest, URBG32bitRegression) {
// Validate with deterministic 32-bit std::minstd_rand
// to ensure that operator() performs as expected.
+
+ EXPECT_EQ(2147483646, RangeSize<std::minstd_rand>());
+ EXPECT_EQ(30, IntegerLog2(RangeSize<std::minstd_rand>()));
+
std::minstd_rand gen(1);
FastUniformBits<uint64_t> fast64;
- EXPECT_EQ(0x05e47095f847c122ull, fast64(gen));
- EXPECT_EQ(0x8f82c1ba30b64d22ull, fast64(gen));
- EXPECT_EQ(0x3b971a3558155039ull, fast64(gen));
+ EXPECT_EQ(0x05e47095f8791f45, fast64(gen));
+ EXPECT_EQ(0x028be17e3c07c122, fast64(gen));
+ EXPECT_EQ(0x55d2847c1626e8c2, fast64(gen));
}
} // namespace
diff --git a/third_party/abseil-cpp/absl/random/internal/fastmath.h b/third_party/abseil-cpp/absl/random/internal/fastmath.h
index 6baeb5a7c9..963b7690f1 100644
--- a/third_party/abseil-cpp/absl/random/internal/fastmath.h
+++ b/third_party/abseil-cpp/absl/random/internal/fastmath.h
@@ -22,27 +22,22 @@
#include <cmath>
#include <cstdint>
-#include "absl/base/internal/bits.h"
+#include "absl/numeric/bits.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// Returns the position of the first bit set.
-inline int LeadingSetBit(uint64_t n) {
- return 64 - base_internal::CountLeadingZeros64(n);
-}
-
// 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 - base_internal::CountLeadingZeros64(n));
+ return (n <= 1) ? 0 : (63 - countl_zero(n));
}
inline int IntLog2Ceil(uint64_t n) {
- return (n <= 1) ? 0 : (64 - base_internal::CountLeadingZeros64(n - 1));
+ return (n <= 1) ? 0 : (64 - countl_zero(n - 1));
}
inline double StirlingLogFactorial(double n) {
@@ -55,18 +50,6 @@ inline double StirlingLogFactorial(double n) {
(1.0 / 360.0) * ninv * ninv * ninv;
}
-// Rotate value right.
-//
-// We only implement the uint32_t / uint64_t versions because
-// 1) those are the only ones we use, and
-// 2) those are the only ones where clang detects the rotate idiom correctly.
-inline constexpr uint32_t rotr(uint32_t value, uint8_t bits) {
- return (value >> (bits & 31)) | (value << ((-bits) & 31));
-}
-inline constexpr uint64_t rotr(uint64_t value, uint8_t bits) {
- return (value >> (bits & 63)) | (value << ((-bits) & 63));
-}
-
} // namespace random_internal
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/third_party/abseil-cpp/absl/random/internal/fastmath_test.cc b/third_party/abseil-cpp/absl/random/internal/fastmath_test.cc
index 65859c25de..0d6f9dc157 100644
--- a/third_party/abseil-cpp/absl/random/internal/fastmath_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/fastmath_test.cc
@@ -27,19 +27,6 @@
namespace {
-TEST(DistributionImplTest, LeadingSetBit) {
- using absl::random_internal::LeadingSetBit;
- constexpr uint64_t kZero = 0;
- EXPECT_EQ(0, LeadingSetBit(kZero));
- EXPECT_EQ(64, LeadingSetBit(~kZero));
-
- for (int index = 0; index < 64; index++) {
- uint64_t x = static_cast<uint64_t>(1) << index;
- EXPECT_EQ(index + 1, LeadingSetBit(x)) << index;
- EXPECT_EQ(index + 1, LeadingSetBit(x + x - 1)) << index;
- }
-}
-
TEST(FastMathTest, IntLog2FloorTest) {
using absl::random_internal::IntLog2Floor;
constexpr uint64_t kZero = 0;
diff --git a/third_party/abseil-cpp/absl/random/internal/gaussian_distribution_gentables.cc b/third_party/abseil-cpp/absl/random/internal/gaussian_distribution_gentables.cc
index a2bf03940f..a95333d55f 100644
--- a/third_party/abseil-cpp/absl/random/internal/gaussian_distribution_gentables.cc
+++ b/third_party/abseil-cpp/absl/random/internal/gaussian_distribution_gentables.cc
@@ -111,12 +111,9 @@ void TableGenerator::Print(std::ostream* os) {
"\n"
"#include \"absl/random/gaussian_distribution.h\"\n"
"\n"
- // "namespace " and "absl" are broken apart so as not to conflict with
- // script that adds the LTS inline namespace.
- "namespace "
- "absl {\n"
- "namespace "
- "random_internal {\n"
+ "namespace absl {\n"
+ "ABSL_NAMESPACE_BEGIN\n"
+ "namespace random_internal {\n"
"\n"
"const gaussian_distribution_base::Tables\n"
" gaussian_distribution_base::zg_ = {\n";
@@ -125,10 +122,9 @@ void TableGenerator::Print(std::ostream* os) {
FormatArrayContents(os, tables_.f);
*os << "};\n"
"\n"
- "} // namespace "
- "random_internal\n"
- "} // namespace "
- "absl\n"
+ "} // namespace random_internal\n"
+ "ABSL_NAMESPACE_END\n"
+ "} // namespace absl\n"
"\n"
"// clang-format on\n"
"// END GENERATED CODE";
diff --git a/third_party/abseil-cpp/absl/random/internal/generate_real.h b/third_party/abseil-cpp/absl/random/internal/generate_real.h
index 20f6d20807..d5fbb44c24 100644
--- a/third_party/abseil-cpp/absl/random/internal/generate_real.h
+++ b/third_party/abseil-cpp/absl/random/internal/generate_real.h
@@ -23,8 +23,8 @@
#include <limits>
#include <type_traits>
-#include "absl/base/internal/bits.h"
#include "absl/meta/type_traits.h"
+#include "absl/numeric/bits.h"
#include "absl/random/internal/fastmath.h"
#include "absl/random/internal/traits.h"
@@ -120,17 +120,15 @@ inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 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 = base_internal::CountLeadingZeros64(bits);
+ 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 =
- (std::is_same<SignedTag, GeneratePositiveTag>::value ? 0u : sign) |
- (static_cast<uint_type>(exp) << kExp) |
- (static_cast<uint_type>(bits) & kMask);
+ 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;
diff --git a/third_party/abseil-cpp/absl/random/internal/generate_real_test.cc b/third_party/abseil-cpp/absl/random/internal/generate_real_test.cc
index aa02f0c2c1..b099dbf35f 100644
--- a/third_party/abseil-cpp/absl/random/internal/generate_real_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/generate_real_test.cc
@@ -20,8 +20,8 @@
#include <string>
#include "gtest/gtest.h"
-#include "absl/base/internal/bits.h"
#include "absl/flags/flag.h"
+#include "absl/numeric/bits.h"
ABSL_FLAG(int64_t, absl_random_test_trials, 50000,
"Number of trials for the probability tests.");
@@ -413,14 +413,13 @@ TEST(GenerateRealTest, U64ToDoubleSignedTest) {
}
TEST(GenerateRealTest, ExhaustiveFloat) {
- using absl::base_internal::CountLeadingZeros64;
auto ToFloat = [](uint64_t a) {
return GenerateRealFromBits<float, GeneratePositiveTag, true>(a);
};
// Rely on RandU64ToFloat generating values from greatest to least when
- // supplied with uint64_t values from greatest (0xfff...) to least (0x0). Thus,
- // this algorithm stores the previous value, and if the new value is at
+ // supplied with uint64_t values from greatest (0xfff...) to least (0x0).
+ // Thus, this algorithm stores the previous value, and if the new value is at
// greater than or equal to the previous value, then there is a collision in
// the generation algorithm.
//
@@ -464,7 +463,7 @@ TEST(GenerateRealTest, ExhaustiveFloat) {
// Adjust decrement and check value based on how many leading 0
// bits are set in the current value.
- const int clz = CountLeadingZeros64(x);
+ const int clz = absl::countl_zero(x);
if (clz < kDig) {
dec <<= (kDig - clz);
chk = (~uint64_t(0)) >> (clz + 1);
diff --git a/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h b/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h
index 7378829a42..e6e242ee1e 100644
--- a/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h
+++ b/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h
@@ -192,8 +192,8 @@ struct stream_u128_helper<absl::uint128> {
template <typename OStream>
inline void write(absl::uint128 val, OStream& out) {
- uint64_t h = Uint128High64(val);
- uint64_t l = Uint128Low64(val);
+ uint64_t h = absl::Uint128High64(val);
+ uint64_t l = absl::Uint128Low64(val);
out << h << out.fill() << l;
}
};
diff --git a/third_party/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc b/third_party/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc
index 7bb8ad959c..6e66266cc0 100644
--- a/third_party/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc
@@ -14,6 +14,9 @@
#include "absl/random/internal/iostream_state_saver.h"
+#include <errno.h>
+#include <stdio.h>
+
#include <sstream>
#include <string>
@@ -272,7 +275,6 @@ TEST(IOStreamStateSaver, RoundTripDoubles) {
}
}
-#if !defined(__EMSCRIPTEN__)
TEST(IOStreamStateSaver, RoundTripLongDoubles) {
// Technically, C++ only guarantees that long double is at least as large as a
// double. Practically it varies from 64-bits to 128-bits.
@@ -350,7 +352,6 @@ TEST(IOStreamStateSaver, RoundTripLongDoubles) {
}
}
}
-#endif // !defined(__EMSCRIPTEN__)
TEST(StrToDTest, DoubleMin) {
const char kV[] = "2.22507385850720138e-308";
diff --git a/third_party/abseil-cpp/absl/random/internal/mock_helpers.h b/third_party/abseil-cpp/absl/random/internal/mock_helpers.h
new file mode 100644
index 0000000000..9d6ab21ef5
--- /dev/null
+++ b/third_party/abseil-cpp/absl/random/internal/mock_helpers.h
@@ -0,0 +1,134 @@
+//
+// 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_MOCK_HELPERS_H_
+#define ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_
+
+#include <tuple>
+#include <type_traits>
+
+#include "absl/base/internal/fast_type_id.h"
+#include "absl/types/optional.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace random_internal {
+
+// MockHelpers works in conjunction with MockOverloadSet, MockingBitGen, and
+// BitGenRef to enable the mocking capability for absl distribution functions.
+//
+// MockingBitGen registers mocks based on the typeid of a mock signature, KeyT,
+// which is used to generate a unique id.
+//
+// KeyT is a signature of the form:
+// result_type(discriminator_type, std::tuple<args...>)
+// The mocked function signature will be composed from KeyT as:
+// result_type(args...)
+//
+class MockHelpers {
+ using IdType = ::absl::base_internal::FastTypeIdType;
+
+ // Given a key signature type used to index the mock, extract the components.
+ // KeyT is expected to have the form:
+ // result_type(discriminator_type, arg_tuple_type)
+ template <typename KeyT>
+ struct KeySignature;
+
+ template <typename ResultT, typename DiscriminatorT, typename ArgTupleT>
+ struct KeySignature<ResultT(DiscriminatorT, ArgTupleT)> {
+ using result_type = ResultT;
+ using discriminator_type = DiscriminatorT;
+ using arg_tuple_type = ArgTupleT;
+ };
+
+ // Detector for InvokeMock.
+ template <class T>
+ using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock(
+ std::declval<IdType>(), std::declval<void*>(), std::declval<void*>()));
+
+ // Empty implementation of InvokeMock.
+ template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG,
+ typename... Args>
+ static absl::optional<ReturnT> InvokeMockImpl(char, URBG*, Args&&...) {
+ return absl::nullopt;
+ }
+
+ // Non-empty implementation of InvokeMock.
+ template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG,
+ typename = invoke_mock_t<URBG>, typename... Args>
+ static absl::optional<ReturnT> InvokeMockImpl(int, URBG* urbg,
+ Args&&... args) {
+ ArgTupleT arg_tuple(std::forward<Args>(args)...);
+ ReturnT result;
+ if (urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple,
+ &result)) {
+ return result;
+ }
+ return absl::nullopt;
+ }
+
+ public:
+ // InvokeMock is private; this provides access for some specialized use cases.
+ template <typename URBG>
+ static inline bool PrivateInvokeMock(URBG* urbg, IdType type,
+ void* args_tuple, void* result) {
+ return urbg->InvokeMock(type, args_tuple, result);
+ }
+
+ // Invoke a mock for the KeyT (may or may not be a signature).
+ //
+ // KeyT is used to generate a typeid-based lookup key for the mock.
+ // KeyT is a signature of the form:
+ // result_type(discriminator_type, std::tuple<args...>)
+ // The mocked function signature will be composed from KeyT as:
+ // result_type(args...)
+ //
+ // An instance of arg_tuple_type must be constructable from Args..., since
+ // the underlying mechanism requires a pointer to an argument tuple.
+ template <typename KeyT, typename URBG, typename... Args>
+ static auto MaybeInvokeMock(URBG* urbg, Args&&... args)
+ -> absl::optional<typename KeySignature<KeyT>::result_type> {
+ // Use function overloading to dispatch to the implemenation since
+ // more modern patterns (e.g. require + constexpr) are not supported in all
+ // compiler configurations.
+ return InvokeMockImpl<KeyT, typename KeySignature<KeyT>::result_type,
+ typename KeySignature<KeyT>::arg_tuple_type, URBG>(
+ 0, urbg, std::forward<Args>(args)...);
+ }
+
+ // Acquire a mock for the KeyT (may or may not be a signature).
+ //
+ // KeyT is used to generate a typeid-based lookup for the mock.
+ // KeyT is a signature of the form:
+ // result_type(discriminator_type, std::tuple<args...>)
+ // The mocked function signature will be composed from KeyT as:
+ // result_type(args...)
+ template <typename KeyT, typename MockURBG>
+ static auto MockFor(MockURBG& m)
+ -> decltype(m.template RegisterMock<
+ typename KeySignature<KeyT>::result_type,
+ typename KeySignature<KeyT>::arg_tuple_type>(
+ m, std::declval<IdType>())) {
+ return m.template RegisterMock<typename KeySignature<KeyT>::result_type,
+ typename KeySignature<KeyT>::arg_tuple_type>(
+ m, ::absl::base_internal::FastTypeId<KeyT>());
+ }
+};
+
+} // namespace random_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_
diff --git a/third_party/abseil-cpp/absl/random/internal/mock_overload_set.h b/third_party/abseil-cpp/absl/random/internal/mock_overload_set.h
index c2a30d89d5..0d9c6c120c 100644
--- a/third_party/abseil-cpp/absl/random/internal/mock_overload_set.h
+++ b/third_party/abseil-cpp/absl/random/internal/mock_overload_set.h
@@ -19,7 +19,7 @@
#include <type_traits>
#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include "absl/random/internal/mock_helpers.h"
#include "absl/random/mocking_bit_gen.h"
namespace absl {
@@ -35,17 +35,22 @@ struct MockSingleOverload;
// EXPECT_CALL(mock_single_overload, Call(...))` will expand to a call to
// `mock_single_overload.gmock_Call(...)`. Because expectations are stored on
// the MockingBitGen (an argument passed inside `Call(...)`), this forwards to
-// arguments to Mocking::Register.
+// arguments to MockingBitGen::Register.
+//
+// The underlying KeyT must match the KeyT constructed by DistributionCaller.
template <typename DistrT, typename Ret, typename... Args>
struct MockSingleOverload<DistrT, Ret(MockingBitGen&, Args...)> {
static_assert(std::is_same<typename DistrT::result_type, Ret>::value,
"Overload signature must have return type matching the "
- "distributions result type.");
- auto gmock_Call(
- absl::MockingBitGen& gen, // NOLINT(google-runtime-references)
- const ::testing::Matcher<Args>&... args)
- -> decltype(gen.Register<DistrT, Args...>(args...)) {
- return gen.Register<DistrT, Args...>(args...);
+ "distribution result_type.");
+ using KeyT = Ret(DistrT, std::tuple<Args...>);
+
+ template <typename MockURBG>
+ auto gmock_Call(MockURBG& gen, const ::testing::Matcher<Args>&... matchers)
+ -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...)) {
+ static_assert(std::is_base_of<MockingBitGen, MockURBG>::value,
+ "Mocking requires an absl::MockingBitGen");
+ return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...);
}
};
@@ -53,13 +58,17 @@ template <typename DistrT, typename Ret, typename Arg, typename... Args>
struct MockSingleOverload<DistrT, Ret(Arg, MockingBitGen&, Args...)> {
static_assert(std::is_same<typename DistrT::result_type, Ret>::value,
"Overload signature must have return type matching the "
- "distributions result type.");
- auto gmock_Call(
- const ::testing::Matcher<Arg>& arg,
- absl::MockingBitGen& gen, // NOLINT(google-runtime-references)
- const ::testing::Matcher<Args>&... args)
- -> decltype(gen.Register<DistrT, Arg, Args...>(arg, args...)) {
- return gen.Register<DistrT, Arg, Args...>(arg, args...);
+ "distribution result_type.");
+ using KeyT = Ret(DistrT, std::tuple<Arg, Args...>);
+
+ template <typename MockURBG>
+ auto gmock_Call(const ::testing::Matcher<Arg>& matcher, MockURBG& gen,
+ const ::testing::Matcher<Args>&... matchers)
+ -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher,
+ matchers...)) {
+ static_assert(std::is_base_of<MockingBitGen, MockURBG>::value,
+ "Mocking requires an absl::MockingBitGen");
+ return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, matchers...);
}
};
diff --git a/third_party/abseil-cpp/absl/random/internal/mocking_bit_gen_base.h b/third_party/abseil-cpp/absl/random/internal/mocking_bit_gen_base.h
deleted file mode 100644
index eeeae9d295..0000000000
--- a/third_party/abseil-cpp/absl/random/internal/mocking_bit_gen_base.h
+++ /dev/null
@@ -1,120 +0,0 @@
-//
-// 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_MOCKING_BIT_GEN_BASE_H_
-#define ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_
-
-#include <atomic>
-#include <deque>
-#include <string>
-#include <typeinfo>
-
-#include "absl/random/random.h"
-#include "absl/strings/str_cat.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// MockingBitGenExpectationFormatter is invoked to format unsatisfied mocks
-// and remaining results into a description string.
-template <typename DistrT, typename FormatT>
-struct MockingBitGenExpectationFormatter {
- std::string operator()(absl::string_view args) {
- return absl::StrCat(FormatT::FunctionName(), "(", args, ")");
- }
-};
-
-// MockingBitGenCallFormatter is invoked to format each distribution call
-// into a description string for the mock log.
-template <typename DistrT, typename FormatT>
-struct MockingBitGenCallFormatter {
- std::string operator()(const DistrT& dist,
- const typename DistrT::result_type& result) {
- return absl::StrCat(
- FormatT::FunctionName(), "(", FormatT::FormatArgs(dist), ") => {",
- FormatT::FormatResults(absl::MakeSpan(&result, 1)), "}");
- }
-};
-
-class MockingBitGenBase {
- template <typename>
- friend struct DistributionCaller;
- using generator_type = absl::BitGen;
-
- public:
- // URBG interface
- using result_type = generator_type::result_type;
- static constexpr result_type(min)() { return (generator_type::min)(); }
- static constexpr result_type(max)() { return (generator_type::max)(); }
- result_type operator()() { return gen_(); }
-
- MockingBitGenBase() : gen_(), observed_call_log_() {}
- virtual ~MockingBitGenBase() = default;
-
- protected:
- const std::deque<std::string>& observed_call_log() {
- return observed_call_log_;
- }
-
- // CallImpl is the type-erased virtual dispatch.
- // The type of dist is always distribution<T>,
- // The type of result is always distribution<T>::result_type.
- virtual bool CallImpl(const std::type_info& distr_type, void* dist_args,
- void* result) = 0;
-
- template <typename DistrT, typename ArgTupleT>
- static const std::type_info& GetTypeId() {
- return typeid(std::pair<absl::decay_t<DistrT>, absl::decay_t<ArgTupleT>>);
- }
-
- // Call the generating distribution function.
- // Invoked by DistributionCaller<>::Call<DistT, FormatT>.
- // DistT is the distribution type.
- // FormatT is the distribution formatter traits type.
- template <typename DistrT, typename FormatT, typename... Args>
- typename DistrT::result_type Call(Args&&... args) {
- using distr_result_type = typename DistrT::result_type;
- using ArgTupleT = std::tuple<absl::decay_t<Args>...>;
-
- ArgTupleT arg_tuple(std::forward<Args>(args)...);
- auto dist = absl::make_from_tuple<DistrT>(arg_tuple);
-
- distr_result_type result{};
- bool found_match =
- CallImpl(GetTypeId<DistrT, ArgTupleT>(), &arg_tuple, &result);
-
- if (!found_match) {
- result = dist(gen_);
- }
-
- // TODO(asoffer): Forwarding the args through means we no longer need to
- // extract them from the from the distribution in formatter traits. We can
- // just StrJoin them.
- observed_call_log_.push_back(
- MockingBitGenCallFormatter<DistrT, FormatT>{}(dist, result));
- return result;
- }
-
- private:
- generator_type gen_;
- std::deque<std::string> observed_call_log_;
-}; // namespace random_internal
-
-} // namespace random_internal
-ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_
diff --git a/third_party/abseil-cpp/absl/random/internal/nanobenchmark.cc b/third_party/abseil-cpp/absl/random/internal/nanobenchmark.cc
index 8fee77fcc7..c9181813f7 100644
--- a/third_party/abseil-cpp/absl/random/internal/nanobenchmark.cc
+++ b/third_party/abseil-cpp/absl/random/internal/nanobenchmark.cc
@@ -101,7 +101,7 @@ std::string BrandString() {
char brand_string[49];
uint32_t abcd[4];
- // Check if brand std::string is supported (it is on all reasonable Intel/AMD)
+ // Check if brand string is supported (it is on all reasonable Intel/AMD)
Cpuid(0x80000000U, 0, abcd);
if (abcd[0] < 0x80000004U) {
return std::string();
diff --git a/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc b/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc
index ab824ef55f..f1571e269f 100644
--- a/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc
@@ -53,7 +53,7 @@ void RunAll(const int argc, char* argv[]) {
// Avoid migrating between cores - important on multi-socket systems.
int cpu = -1;
if (argc == 2) {
- if (!SimpleAtoi(argv[1], &cpu)) {
+ if (!absl::SimpleAtoi(argv[1], &cpu)) {
ABSL_RAW_LOG(FATAL, "The optional argument must be a CPU number >= 0.\n");
}
}
diff --git a/third_party/abseil-cpp/absl/random/internal/pcg_engine.h b/third_party/abseil-cpp/absl/random/internal/pcg_engine.h
index 53c23fe1b4..8efaf2e09a 100644
--- a/third_party/abseil-cpp/absl/random/internal/pcg_engine.h
+++ b/third_party/abseil-cpp/absl/random/internal/pcg_engine.h
@@ -19,6 +19,7 @@
#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"
@@ -261,7 +262,7 @@ struct pcg_xsl_rr_128_64 {
uint64_t rotate = h >> 58u;
uint64_t s = Uint128Low64(state) ^ h;
#endif
- return random_internal::rotr(s, rotate);
+ return rotr(s, rotate);
}
};
@@ -281,8 +282,8 @@ struct pcg_xsh_rr_64_32 {
using state_type = uint64_t;
using result_type = uint32_t;
inline uint32_t operator()(uint64_t state) {
- return random_internal::rotr(
- static_cast<uint32_t>(((state >> 18) ^ state) >> 27), state >> 59);
+ return rotr(static_cast<uint32_t>(((state >> 18) ^ state) >> 27),
+ state >> 59);
}
};
diff --git a/third_party/abseil-cpp/absl/random/internal/pool_urbg.cc b/third_party/abseil-cpp/absl/random/internal/pool_urbg.cc
index 5bee530770..725100a415 100644
--- a/third_party/abseil-cpp/absl/random/internal/pool_urbg.cc
+++ b/third_party/abseil-cpp/absl/random/internal/pool_urbg.cc
@@ -194,11 +194,10 @@ RandenPoolEntry* PoolAlignedAlloc() {
// 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.
- void* memory = std::malloc(sizeof(RandenPoolEntry) + kAlignment);
- auto x = reinterpret_cast<intptr_t>(memory);
+ intptr_t x = reinterpret_cast<intptr_t>(
+ new char[sizeof(RandenPoolEntry) + kAlignment]);
auto y = x % kAlignment;
- void* aligned =
- (y == 0) ? memory : reinterpret_cast<void*>(x + kAlignment - y);
+ void* aligned = reinterpret_cast<void*>(y == 0 ? x : (x + kAlignment - y));
return new (aligned) RandenPoolEntry();
}
diff --git a/third_party/abseil-cpp/absl/random/internal/randen-keys.inc b/third_party/abseil-cpp/absl/random/internal/randen-keys.inc
deleted file mode 100644
index fa4b166835..0000000000
--- a/third_party/abseil-cpp/absl/random/internal/randen-keys.inc
+++ /dev/null
@@ -1,207 +0,0 @@
-// 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_KEYS_INC_
-#define ABSL_RANDOM_INTERNAL_RANDEN_KEYS_INC_
-
-// Textual header to include the randen_keys where necessary.
-// REQUIRES: struct u64x2{}
-//
-// PROVIDES: kKeys
-// PROVIDES: round_keys[]
-
-// "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 << EOF
-"""Generates Randen round keys array from pi-hex.62500.txt file."""
-import binascii
-
-KEYS = 136
-
-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))
-
-digits = digits_from_pi()
-print("static constexpr const size_t kRoundKeys = {0};\n".format(KEYS))
-print("alignas(16) constexpr const u64x2 round_keys[kRoundKeys] = {")
-
-for i, (hi, lo) in zip(range(KEYS), pairwise(chunks(digits, 16))):
- hi = "0x{0}ull".format(hi)
- lo = "0x{0}ull".format(lo)
- print(" u64x2({0}, {1}){2}".format(hi, lo, ',' if i+1 < KEYS else ''))
-
-print("};")
-EOF
-*/
-
-static constexpr const size_t kRoundKeys = 136;
-
-alignas(16) constexpr u64x2 round_keys[kRoundKeys] = {
- u64x2(0x243F6A8885A308D3ull, 0x13198A2E03707344ull),
- u64x2(0xA4093822299F31D0ull, 0x082EFA98EC4E6C89ull),
- u64x2(0x452821E638D01377ull, 0xBE5466CF34E90C6Cull),
- u64x2(0xC0AC29B7C97C50DDull, 0x3F84D5B5B5470917ull),
- u64x2(0x9216D5D98979FB1Bull, 0xD1310BA698DFB5ACull),
- u64x2(0x2FFD72DBD01ADFB7ull, 0xB8E1AFED6A267E96ull),
- u64x2(0xBA7C9045F12C7F99ull, 0x24A19947B3916CF7ull),
- u64x2(0x0801F2E2858EFC16ull, 0x636920D871574E69ull),
- u64x2(0xA458FEA3F4933D7Eull, 0x0D95748F728EB658ull),
- u64x2(0x718BCD5882154AEEull, 0x7B54A41DC25A59B5ull),
- u64x2(0x9C30D5392AF26013ull, 0xC5D1B023286085F0ull),
- u64x2(0xCA417918B8DB38EFull, 0x8E79DCB0603A180Eull),
- u64x2(0x6C9E0E8BB01E8A3Eull, 0xD71577C1BD314B27ull),
- u64x2(0x78AF2FDA55605C60ull, 0xE65525F3AA55AB94ull),
- u64x2(0x5748986263E81440ull, 0x55CA396A2AAB10B6ull),
- u64x2(0xB4CC5C341141E8CEull, 0xA15486AF7C72E993ull),
- u64x2(0xB3EE1411636FBC2Aull, 0x2BA9C55D741831F6ull),
- u64x2(0xCE5C3E169B87931Eull, 0xAFD6BA336C24CF5Cull),
- u64x2(0x7A32538128958677ull, 0x3B8F48986B4BB9AFull),
- u64x2(0xC4BFE81B66282193ull, 0x61D809CCFB21A991ull),
- u64x2(0x487CAC605DEC8032ull, 0xEF845D5DE98575B1ull),
- u64x2(0xDC262302EB651B88ull, 0x23893E81D396ACC5ull),
- u64x2(0x0F6D6FF383F44239ull, 0x2E0B4482A4842004ull),
- u64x2(0x69C8F04A9E1F9B5Eull, 0x21C66842F6E96C9Aull),
- u64x2(0x670C9C61ABD388F0ull, 0x6A51A0D2D8542F68ull),
- u64x2(0x960FA728AB5133A3ull, 0x6EEF0B6C137A3BE4ull),
- u64x2(0xBA3BF0507EFB2A98ull, 0xA1F1651D39AF0176ull),
- u64x2(0x66CA593E82430E88ull, 0x8CEE8619456F9FB4ull),
- u64x2(0x7D84A5C33B8B5EBEull, 0xE06F75D885C12073ull),
- u64x2(0x401A449F56C16AA6ull, 0x4ED3AA62363F7706ull),
- u64x2(0x1BFEDF72429B023Dull, 0x37D0D724D00A1248ull),
- u64x2(0xDB0FEAD349F1C09Bull, 0x075372C980991B7Bull),
- u64x2(0x25D479D8F6E8DEF7ull, 0xE3FE501AB6794C3Bull),
- u64x2(0x976CE0BD04C006BAull, 0xC1A94FB6409F60C4ull),
- u64x2(0x5E5C9EC2196A2463ull, 0x68FB6FAF3E6C53B5ull),
- u64x2(0x1339B2EB3B52EC6Full, 0x6DFC511F9B30952Cull),
- u64x2(0xCC814544AF5EBD09ull, 0xBEE3D004DE334AFDull),
- u64x2(0x660F2807192E4BB3ull, 0xC0CBA85745C8740Full),
- u64x2(0xD20B5F39B9D3FBDBull, 0x5579C0BD1A60320Aull),
- u64x2(0xD6A100C6402C7279ull, 0x679F25FEFB1FA3CCull),
- u64x2(0x8EA5E9F8DB3222F8ull, 0x3C7516DFFD616B15ull),
- u64x2(0x2F501EC8AD0552ABull, 0x323DB5FAFD238760ull),
- u64x2(0x53317B483E00DF82ull, 0x9E5C57BBCA6F8CA0ull),
- u64x2(0x1A87562EDF1769DBull, 0xD542A8F6287EFFC3ull),
- u64x2(0xAC6732C68C4F5573ull, 0x695B27B0BBCA58C8ull),
- u64x2(0xE1FFA35DB8F011A0ull, 0x10FA3D98FD2183B8ull),
- u64x2(0x4AFCB56C2DD1D35Bull, 0x9A53E479B6F84565ull),
- u64x2(0xD28E49BC4BFB9790ull, 0xE1DDF2DAA4CB7E33ull),
- u64x2(0x62FB1341CEE4C6E8ull, 0xEF20CADA36774C01ull),
- u64x2(0xD07E9EFE2BF11FB4ull, 0x95DBDA4DAE909198ull),
- u64x2(0xEAAD8E716B93D5A0ull, 0xD08ED1D0AFC725E0ull),
- u64x2(0x8E3C5B2F8E7594B7ull, 0x8FF6E2FBF2122B64ull),
- u64x2(0x8888B812900DF01Cull, 0x4FAD5EA0688FC31Cull),
- u64x2(0xD1CFF191B3A8C1ADull, 0x2F2F2218BE0E1777ull),
- u64x2(0xEA752DFE8B021FA1ull, 0xE5A0CC0FB56F74E8ull),
- u64x2(0x18ACF3D6CE89E299ull, 0xB4A84FE0FD13E0B7ull),
- u64x2(0x7CC43B81D2ADA8D9ull, 0x165FA26680957705ull),
- u64x2(0x93CC7314211A1477ull, 0xE6AD206577B5FA86ull),
- u64x2(0xC75442F5FB9D35CFull, 0xEBCDAF0C7B3E89A0ull),
- u64x2(0xD6411BD3AE1E7E49ull, 0x00250E2D2071B35Eull),
- u64x2(0x226800BB57B8E0AFull, 0x2464369BF009B91Eull),
- u64x2(0x5563911D59DFA6AAull, 0x78C14389D95A537Full),
- u64x2(0x207D5BA202E5B9C5ull, 0x832603766295CFA9ull),
- u64x2(0x11C819684E734A41ull, 0xB3472DCA7B14A94Aull),
- u64x2(0x1B5100529A532915ull, 0xD60F573FBC9BC6E4ull),
- u64x2(0x2B60A47681E67400ull, 0x08BA6FB5571BE91Full),
- u64x2(0xF296EC6B2A0DD915ull, 0xB6636521E7B9F9B6ull),
- u64x2(0xFF34052EC5855664ull, 0x53B02D5DA99F8FA1ull),
- u64x2(0x08BA47996E85076Aull, 0x4B7A70E9B5B32944ull),
- u64x2(0xDB75092EC4192623ull, 0xAD6EA6B049A7DF7Dull),
- u64x2(0x9CEE60B88FEDB266ull, 0xECAA8C71699A18FFull),
- u64x2(0x5664526CC2B19EE1ull, 0x193602A575094C29ull),
- u64x2(0xA0591340E4183A3Eull, 0x3F54989A5B429D65ull),
- u64x2(0x6B8FE4D699F73FD6ull, 0xA1D29C07EFE830F5ull),
- u64x2(0x4D2D38E6F0255DC1ull, 0x4CDD20868470EB26ull),
- u64x2(0x6382E9C6021ECC5Eull, 0x09686B3F3EBAEFC9ull),
- u64x2(0x3C9718146B6A70A1ull, 0x687F358452A0E286ull),
- u64x2(0xB79C5305AA500737ull, 0x3E07841C7FDEAE5Cull),
- u64x2(0x8E7D44EC5716F2B8ull, 0xB03ADA37F0500C0Dull),
- u64x2(0xF01C1F040200B3FFull, 0xAE0CF51A3CB574B2ull),
- u64x2(0x25837A58DC0921BDull, 0xD19113F97CA92FF6ull),
- u64x2(0x9432477322F54701ull, 0x3AE5E58137C2DADCull),
- u64x2(0xC8B576349AF3DDA7ull, 0xA94461460FD0030Eull),
- u64x2(0xECC8C73EA4751E41ull, 0xE238CD993BEA0E2Full),
- u64x2(0x3280BBA1183EB331ull, 0x4E548B384F6DB908ull),
- u64x2(0x6F420D03F60A04BFull, 0x2CB8129024977C79ull),
- u64x2(0x5679B072BCAF89AFull, 0xDE9A771FD9930810ull),
- u64x2(0xB38BAE12DCCF3F2Eull, 0x5512721F2E6B7124ull),
- u64x2(0x501ADDE69F84CD87ull, 0x7A5847187408DA17ull),
- u64x2(0xBC9F9ABCE94B7D8Cull, 0xEC7AEC3ADB851DFAull),
- u64x2(0x63094366C464C3D2ull, 0xEF1C18473215D808ull),
- u64x2(0xDD433B3724C2BA16ull, 0x12A14D432A65C451ull),
- u64x2(0x50940002133AE4DDull, 0x71DFF89E10314E55ull),
- u64x2(0x81AC77D65F11199Bull, 0x043556F1D7A3C76Bull),
- u64x2(0x3C11183B5924A509ull, 0xF28FE6ED97F1FBFAull),
- u64x2(0x9EBABF2C1E153C6Eull, 0x86E34570EAE96FB1ull),
- u64x2(0x860E5E0A5A3E2AB3ull, 0x771FE71C4E3D06FAull),
- u64x2(0x2965DCB999E71D0Full, 0x803E89D65266C825ull),
- u64x2(0x2E4CC9789C10B36Aull, 0xC6150EBA94E2EA78ull),
- u64x2(0xA6FC3C531E0A2DF4ull, 0xF2F74EA7361D2B3Dull),
- u64x2(0x1939260F19C27960ull, 0x5223A708F71312B6ull),
- u64x2(0xEBADFE6EEAC31F66ull, 0xE3BC4595A67BC883ull),
- u64x2(0xB17F37D1018CFF28ull, 0xC332DDEFBE6C5AA5ull),
- u64x2(0x6558218568AB9702ull, 0xEECEA50FDB2F953Bull),
- u64x2(0x2AEF7DAD5B6E2F84ull, 0x1521B62829076170ull),
- u64x2(0xECDD4775619F1510ull, 0x13CCA830EB61BD96ull),
- u64x2(0x0334FE1EAA0363CFull, 0xB5735C904C70A239ull),
- u64x2(0xD59E9E0BCBAADE14ull, 0xEECC86BC60622CA7ull),
- u64x2(0x9CAB5CABB2F3846Eull, 0x648B1EAF19BDF0CAull),
- u64x2(0xA02369B9655ABB50ull, 0x40685A323C2AB4B3ull),
- u64x2(0x319EE9D5C021B8F7ull, 0x9B540B19875FA099ull),
- u64x2(0x95F7997E623D7DA8ull, 0xF837889A97E32D77ull),
- u64x2(0x11ED935F16681281ull, 0x0E358829C7E61FD6ull),
- u64x2(0x96DEDFA17858BA99ull, 0x57F584A51B227263ull),
- u64x2(0x9B83C3FF1AC24696ull, 0xCDB30AEB532E3054ull),
- u64x2(0x8FD948E46DBC3128ull, 0x58EBF2EF34C6FFEAull),
- u64x2(0xFE28ED61EE7C3C73ull, 0x5D4A14D9E864B7E3ull),
- u64x2(0x42105D14203E13E0ull, 0x45EEE2B6A3AAABEAull),
- u64x2(0xDB6C4F15FACB4FD0ull, 0xC742F442EF6ABBB5ull),
- u64x2(0x654F3B1D41CD2105ull, 0xD81E799E86854DC7ull),
- u64x2(0xE44B476A3D816250ull, 0xCF62A1F25B8D2646ull),
- u64x2(0xFC8883A0C1C7B6A3ull, 0x7F1524C369CB7492ull),
- u64x2(0x47848A0B5692B285ull, 0x095BBF00AD19489Dull),
- u64x2(0x1462B17423820D00ull, 0x58428D2A0C55F5EAull),
- u64x2(0x1DADF43E233F7061ull, 0x3372F0928D937E41ull),
- u64x2(0xD65FECF16C223BDBull, 0x7CDE3759CBEE7460ull),
- u64x2(0x4085F2A7CE77326Eull, 0xA607808419F8509Eull),
- u64x2(0xE8EFD85561D99735ull, 0xA969A7AAC50C06C2ull),
- u64x2(0x5A04ABFC800BCADCull, 0x9E447A2EC3453484ull),
- u64x2(0xFDD567050E1E9EC9ull, 0xDB73DBD3105588CDull),
- u64x2(0x675FDA79E3674340ull, 0xC5C43465713E38D8ull),
- u64x2(0x3D28F89EF16DFF20ull, 0x153E21E78FB03D4Aull),
- u64x2(0xE6E39F2BDB83ADF7ull, 0xE93D5A68948140F7ull),
- u64x2(0xF64C261C94692934ull, 0x411520F77602D4F7ull),
- u64x2(0xBCF46B2ED4A10068ull, 0xD40824713320F46Aull),
- u64x2(0x43B7D4B7500061AFull, 0x1E39F62E97244546ull)};
-
-#endif // ABSL_RANDOM_INTERNAL_RANDEN_KEYS_INC_
diff --git a/third_party/abseil-cpp/absl/random/internal/randen.cc b/third_party/abseil-cpp/absl/random/internal/randen.cc
index 78a1e00c08..c1bc044435 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen.cc
@@ -17,7 +17,7 @@
#include "absl/base/internal/raw_logging.h"
#include "absl/random/internal/randen_detect.h"
-// RANDen = RANDom generator or beetroots in Swiss German.
+// 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.
//
diff --git a/third_party/abseil-cpp/absl/random/internal/randen.h b/third_party/abseil-cpp/absl/random/internal/randen.h
index c2834aaf3d..9a3840b8f1 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen.h
+++ b/third_party/abseil-cpp/absl/random/internal/randen.h
@@ -26,7 +26,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// RANDen = RANDom generator or beetroots in Swiss German.
+// 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.
//
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_detect.cc b/third_party/abseil-cpp/absl/random/internal/randen_detect.cc
index d63230c255..bbe7b96532 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_detect.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen_detect.cc
@@ -1,13 +1,13 @@
// Copyright 2017 The Abseil Authors.
//
-// Licensed under the Apache License, Version 2.0 (the"License");
+// 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,
+// 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.
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_engine.h b/third_party/abseil-cpp/absl/random/internal/randen_engine.h
index 6b33731336..372c3ac2bd 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_engine.h
+++ b/third_party/abseil-cpp/absl/random/internal/randen_engine.h
@@ -23,6 +23,7 @@
#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"
@@ -76,7 +77,7 @@ class alignas(16) randen_engine {
impl_.Generate(state_);
}
- return state_[next_++];
+ return little_endian::ToHost(state_[next_++]);
}
template <class SeedSequence>
@@ -120,6 +121,13 @@ class alignas(16) randen_engine {
const size_t requested_entropy = (entropy_size == 0) ? 8u : entropy_size;
std::fill(std::begin(buffer) + requested_entropy, std::end(buffer), 0);
seq.generate(std::begin(buffer), std::begin(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
@@ -181,7 +189,8 @@ class alignas(16) randen_engine {
// 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>(elem) << os.fill();
+ os << static_cast<numeric_type>(little_endian::FromHost(elem))
+ << os.fill();
}
os << engine.next_;
return os;
@@ -200,7 +209,7 @@ class alignas(16) randen_engine {
// necessary to read a wider type and then cast it to uint8_t.
numeric_type value;
is >> value;
- elem = static_cast<result_type>(value);
+ elem = little_endian::ToHost(static_cast<result_type>(value));
}
is >> next;
if (is.fail()) {
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc b/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc
index e23844f12e..fee6677cb4 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc
@@ -23,48 +23,20 @@
#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 defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
-// The platform.h directives are sufficient to indicate whether
-// we should build accelerated implementations for x86.
-#if (ABSL_HAVE_ACCELERATED_AES || ABSL_RANDOM_INTERNAL_AES_DISPATCH)
-#define ABSL_RANDEN_HWAES_IMPL 1
-#endif
-#elif defined(ABSL_ARCH_PPC)
-// The platform.h directives are sufficient to indicate whether
-// we should build accelerated implementations for PPC.
-//
-// NOTE: This has mostly been tested on 64-bit Power variants,
-// and not embedded cpus such as powerpc32-8540
#if ABSL_HAVE_ACCELERATED_AES
+// The following plaforms 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
-#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)
-// ARM is somewhat more complicated. We might support crypto natively...
-#if ABSL_HAVE_ACCELERATED_AES || \
- (defined(__ARM_NEON) && defined(__ARM_FEATURE_CRYPTO))
-#define ABSL_RANDEN_HWAES_IMPL 1
-
-#elif ABSL_RANDOM_INTERNAL_AES_DISPATCH && !defined(__APPLE__) && \
- (defined(__GNUC__) && __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 9)
-// ...or, on GCC, we can use an ASM directive to
-// instruct the assember to allow crypto instructions.
-#define ABSL_RANDEN_HWAES_IMPL 1
-#define ABSL_RANDEN_HWAES_IMPL_CRYPTO_DIRECTIVE 1
-#endif
-#else
-// HWAES is unsupported by these architectures / platforms:
-// __myriad2__
-// __mips__
-//
-// Other architectures / platforms are unknown.
-//
-// See the Abseil documentation on supported macros at:
-// https://abseil.io/docs/cpp/platforms/macros
#endif
#if !defined(ABSL_RANDEN_HWAES_IMPL)
@@ -115,8 +87,11 @@ ABSL_NAMESPACE_END
// Accelerated implementations are supported.
// We need the per-architecture includes and defines.
//
+namespace {
-#include "absl/random/internal/randen_traits.h"
+using absl::random_internal::RandenTraits;
+
+} // namespace
// TARGET_CRYPTO defines a crypto attribute for each architecture.
//
@@ -141,6 +116,7 @@ ABSL_NAMESPACE_END
#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:
@@ -150,7 +126,6 @@ ABSL_NAMESPACE_END
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,
@@ -177,14 +152,9 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
}
// Enables native loads in the round loop by pre-swapping.
-inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t* state) {
- using absl::random_internal::RandenTraits;
- constexpr size_t kLanes = 2;
- constexpr size_t kFeistelBlocks = RandenTraits::kFeistelBlocks;
-
- for (uint32_t branch = 0; branch < kFeistelBlocks; ++branch) {
- const Vector128 v = ReverseBytes(Vector128Load(state + kLanes * branch));
- Vector128Store(v, state + kLanes * branch);
+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);
}
}
@@ -192,22 +162,6 @@ inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t* state) {
#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)
-// This asm directive will cause the file to be compiled with crypto extensions
-// whether or not the cpu-architecture supports it.
-#if ABSL_RANDEN_HWAES_IMPL_CRYPTO_DIRECTIVE
-asm(".arch_extension crypto\n");
-
-// Override missing defines.
-#if !defined(__ARM_NEON)
-#define __ARM_NEON 1
-#endif
-
-#if !defined(__ARM_FEATURE_CRYPTO)
-#define __ARM_FEATURE_CRYPTO 1
-#endif
-
-#endif
-
// 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
@@ -251,13 +205,13 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key;
}
-inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t*) {}
+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 <wmmintrin.h>
+#include <immintrin.h>
namespace {
@@ -266,7 +220,7 @@ namespace {
class Vector128 {
public:
// Convert from/to intrinsics.
- inline explicit Vector128(const __m128i& Vector128) : data_(Vector128) {}
+ inline explicit Vector128(const __m128i& v) : data_(v) {}
inline __m128i data() const { return data_; }
@@ -297,39 +251,12 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
return Vector128(_mm_aesenc_si128(state.data(), round_key.data()));
}
-inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t*) {}
+inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {}
} // namespace
#endif
-namespace {
-
-// u64x2 is a 128-bit, (2 x uint64_t lanes) struct used to store
-// the randen_keys.
-struct alignas(16) u64x2 {
- constexpr u64x2(uint64_t hi, uint64_t lo)
-#if defined(ABSL_ARCH_PPC)
- // This has been tested with PPC running in little-endian mode;
- // We byte-swap the u64x2 structure from little-endian to big-endian
- // because altivec always runs in big-endian mode.
- : v{__builtin_bswap64(hi), __builtin_bswap64(lo)} {
-#else
- : v{lo, hi} {
-#endif
- }
-
- constexpr bool operator==(const u64x2& other) const {
- return v[0] == other.v[0] && v[1] == other.v[1];
- }
-
- constexpr bool operator!=(const u64x2& other) const {
- return !(*this == other);
- }
-
- uint64_t v[2];
-}; // namespace
-
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
@@ -338,7 +265,6 @@ struct alignas(16) u64x2 {
// At this point, all of the platform-specific features have been defined /
// implemented.
//
-// REQUIRES: using u64x2 = ...
// REQUIRES: using Vector128 = ...
// REQUIRES: Vector128 Vector128Load(void*) {...}
// REQUIRES: void Vector128Store(Vector128, void*) {...}
@@ -347,94 +273,50 @@ struct alignas(16) u64x2 {
//
// PROVIDES: absl::random_internal::RandenHwAes::Absorb
// PROVIDES: absl::random_internal::RandenHwAes::Generate
-
-// RANDen = RANDom generator or beetroots in Swiss 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.
-
-// Randen constants.
-using absl::random_internal::RandenTraits;
-constexpr size_t kStateBytes = RandenTraits::kStateBytes;
-constexpr size_t kCapacityBytes = RandenTraits::kCapacityBytes;
-constexpr size_t kFeistelBlocks = RandenTraits::kFeistelBlocks;
-constexpr size_t kFeistelRounds = RandenTraits::kFeistelRounds;
-constexpr size_t kFeistelFunctions = RandenTraits::kFeistelFunctions;
-
-// Independent keys (272 = 2.1 KiB) for the first AES subround of each function.
-constexpr size_t kKeys = kFeistelRounds * kFeistelFunctions;
-
-// INCLUDE keys.
-#include "absl/random/internal/randen-keys.inc"
-
-static_assert(kKeys == kRoundKeys, "kKeys and kRoundKeys must be equal");
-static_assert(round_keys[kKeys - 1] != u64x2(0, 0),
- "Too few round_keys initializers");
-
-// Number of uint64_t lanes per 128-bit vector;
-constexpr size_t kLanes = 2;
+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(uint64_t* state) {
- static_assert(kFeistelBlocks == 16, "Expecting 16 FeistelBlocks.");
-
- constexpr size_t shuffle[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 loop.
- const Vector128 v0 = Vector128Load(state + kLanes * shuffle[0]);
- const Vector128 v1 = Vector128Load(state + kLanes * shuffle[1]);
- const Vector128 v2 = Vector128Load(state + kLanes * shuffle[2]);
- const Vector128 v3 = Vector128Load(state + kLanes * shuffle[3]);
- const Vector128 v4 = Vector128Load(state + kLanes * shuffle[4]);
- const Vector128 v5 = Vector128Load(state + kLanes * shuffle[5]);
- const Vector128 v6 = Vector128Load(state + kLanes * shuffle[6]);
- const Vector128 v7 = Vector128Load(state + kLanes * shuffle[7]);
- const Vector128 w0 = Vector128Load(state + kLanes * shuffle[8]);
- const Vector128 w1 = Vector128Load(state + kLanes * shuffle[9]);
- const Vector128 w2 = Vector128Load(state + kLanes * shuffle[10]);
- const Vector128 w3 = Vector128Load(state + kLanes * shuffle[11]);
- const Vector128 w4 = Vector128Load(state + kLanes * shuffle[12]);
- const Vector128 w5 = Vector128Load(state + kLanes * shuffle[13]);
- const Vector128 w6 = Vector128Load(state + kLanes * shuffle[14]);
- const Vector128 w7 = Vector128Load(state + kLanes * shuffle[15]);
-
- Vector128Store(v0, state + kLanes * 0);
- Vector128Store(v1, state + kLanes * 1);
- Vector128Store(v2, state + kLanes * 2);
- Vector128Store(v3, state + kLanes * 3);
- Vector128Store(v4, state + kLanes * 4);
- Vector128Store(v5, state + kLanes * 5);
- Vector128Store(v6, state + kLanes * 6);
- Vector128Store(v7, state + kLanes * 7);
- Vector128Store(w0, state + kLanes * 8);
- Vector128Store(w1, state + kLanes * 9);
- Vector128Store(w2, state + kLanes * 10);
- Vector128Store(w3, state + kLanes * 11);
- Vector128Store(w4, state + kLanes * 12);
- Vector128Store(w5, state + kLanes * 13);
- Vector128Store(w6, state + kLanes * 14);
- Vector128Store(w7, state + kLanes * 15);
+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()
@@ -442,28 +324,30 @@ inline ABSL_TARGET_CRYPTO void BlockShuffle(uint64_t* state) {
// 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 u64x2* FeistelRound(
- uint64_t* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
- static_assert(kFeistelBlocks == 16, "Expecting 16 FeistelBlocks.");
+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 + kLanes * 0);
- const Vector128 s1 = Vector128Load(state + kLanes * 1);
- const Vector128 s2 = Vector128Load(state + kLanes * 2);
- const Vector128 s3 = Vector128Load(state + kLanes * 3);
- const Vector128 s4 = Vector128Load(state + kLanes * 4);
- const Vector128 s5 = Vector128Load(state + kLanes * 5);
- const Vector128 s6 = Vector128Load(state + kLanes * 6);
- const Vector128 s7 = Vector128Load(state + kLanes * 7);
- const Vector128 s8 = Vector128Load(state + kLanes * 8);
- const Vector128 s9 = Vector128Load(state + kLanes * 9);
- const Vector128 s10 = Vector128Load(state + kLanes * 10);
- const Vector128 s11 = Vector128Load(state + kLanes * 11);
- const Vector128 s12 = Vector128Load(state + kLanes * 12);
- const Vector128 s13 = Vector128Load(state + kLanes * 13);
- const Vector128 s14 = Vector128Load(state + kLanes * 14);
- const Vector128 s15 = Vector128Load(state + kLanes * 15);
+ 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));
@@ -486,14 +370,14 @@ inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound(
const Vector128 o15 = AesRound(e14, s15);
// Store odd blocks. (These will be shuffled later).
- Vector128Store(o1, state + kLanes * 1);
- Vector128Store(o3, state + kLanes * 3);
- Vector128Store(o5, state + kLanes * 5);
- Vector128Store(o7, state + kLanes * 7);
- Vector128Store(o9, state + kLanes * 9);
- Vector128Store(o11, state + kLanes * 11);
- Vector128Store(o13, state + kLanes * 13);
- Vector128Store(o15, state + kLanes * 15);
+ 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;
}
@@ -503,16 +387,14 @@ inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound(
// 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(
- const void* ABSL_RANDOM_INTERNAL_RESTRICT keys, uint64_t* state) {
- const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys128 =
- static_cast<const u64x2*>(keys);
-
+ 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 < kFeistelRounds; ++round) {
- keys128 = FeistelRound(state, keys128);
+ for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) {
+ keys = FeistelRound(state, keys);
BlockShuffle(state);
}
}
@@ -528,96 +410,102 @@ 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.
- return round_keys;
+#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) {
- auto* state = static_cast<uint64_t*>(state_void);
- const auto* seed = static_cast<const uint64_t*>(seed_void);
-
- constexpr size_t kCapacityBlocks = kCapacityBytes / sizeof(Vector128);
- constexpr size_t kStateBlocks = kStateBytes / sizeof(Vector128);
-
- static_assert(kCapacityBlocks * sizeof(Vector128) == kCapacityBytes,
- "Not i*V");
- static_assert(kCapacityBlocks == 1, "Unexpected Randen kCapacityBlocks");
- static_assert(kStateBlocks == 16, "Unexpected Randen kStateBlocks");
-
- Vector128 b1 = Vector128Load(state + kLanes * 1);
- b1 ^= Vector128Load(seed + kLanes * 0);
- Vector128Store(b1, state + kLanes * 1);
-
- Vector128 b2 = Vector128Load(state + kLanes * 2);
- b2 ^= Vector128Load(seed + kLanes * 1);
- Vector128Store(b2, state + kLanes * 2);
-
- Vector128 b3 = Vector128Load(state + kLanes * 3);
- b3 ^= Vector128Load(seed + kLanes * 2);
- Vector128Store(b3, state + kLanes * 3);
-
- Vector128 b4 = Vector128Load(state + kLanes * 4);
- b4 ^= Vector128Load(seed + kLanes * 3);
- Vector128Store(b4, state + kLanes * 4);
-
- Vector128 b5 = Vector128Load(state + kLanes * 5);
- b5 ^= Vector128Load(seed + kLanes * 4);
- Vector128Store(b5, state + kLanes * 5);
-
- Vector128 b6 = Vector128Load(state + kLanes * 6);
- b6 ^= Vector128Load(seed + kLanes * 5);
- Vector128Store(b6, state + kLanes * 6);
-
- Vector128 b7 = Vector128Load(state + kLanes * 7);
- b7 ^= Vector128Load(seed + kLanes * 6);
- Vector128Store(b7, state + kLanes * 7);
-
- Vector128 b8 = Vector128Load(state + kLanes * 8);
- b8 ^= Vector128Load(seed + kLanes * 7);
- Vector128Store(b8, state + kLanes * 8);
-
- Vector128 b9 = Vector128Load(state + kLanes * 9);
- b9 ^= Vector128Load(seed + kLanes * 8);
- Vector128Store(b9, state + kLanes * 9);
-
- Vector128 b10 = Vector128Load(state + kLanes * 10);
- b10 ^= Vector128Load(seed + kLanes * 9);
- Vector128Store(b10, state + kLanes * 10);
-
- Vector128 b11 = Vector128Load(state + kLanes * 11);
- b11 ^= Vector128Load(seed + kLanes * 10);
- Vector128Store(b11, state + kLanes * 11);
-
- Vector128 b12 = Vector128Load(state + kLanes * 12);
- b12 ^= Vector128Load(seed + kLanes * 11);
- Vector128Store(b12, state + kLanes * 12);
-
- Vector128 b13 = Vector128Load(state + kLanes * 13);
- b13 ^= Vector128Load(seed + kLanes * 12);
- Vector128Store(b13, state + kLanes * 13);
-
- Vector128 b14 = Vector128Load(state + kLanes * 14);
- b14 ^= Vector128Load(seed + kLanes * 13);
- Vector128Store(b14, state + kLanes * 14);
-
- Vector128 b15 = Vector128Load(state + kLanes * 15);
- b15 ^= Vector128Load(seed + kLanes * 14);
- Vector128Store(b15, state + kLanes * 15);
+ 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 ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void,
void* state_void) {
- static_assert(kCapacityBytes == sizeof(Vector128), "Capacity mismatch");
+ static_assert(RandenTraits::kCapacityBytes == sizeof(Vector128),
+ "Capacity mismatch");
- auto* state = static_cast<uint64_t*>(state_void);
+ 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(keys, state);
+ Permute(state, keys);
SwapEndian(state);
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_hwaes.h b/third_party/abseil-cpp/absl/random/internal/randen_hwaes.h
index bce36b5226..71a7f69f25 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_hwaes.h
+++ b/third_party/abseil-cpp/absl/random/internal/randen_hwaes.h
@@ -26,7 +26,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// RANDen = RANDom generator or beetroots in Swiss German.
+// 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.
//
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc b/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc
index a7cbd46b2d..2348b55c35 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc
@@ -27,42 +27,39 @@ namespace {
using absl::random_internal::RandenHwAes;
using absl::random_internal::RandenTraits;
-struct randen {
- static constexpr size_t kStateSizeT =
- RandenTraits::kStateBytes / sizeof(uint64_t);
- uint64_t state[kStateSizeT];
- static constexpr size_t kSeedSizeT =
- RandenTraits::kSeedBytes / sizeof(uint32_t);
- uint32_t seed[kSeedSizeT];
-};
-
TEST(RandenHwAesTest, Default) {
EXPECT_TRUE(absl::random_internal::CPUSupportsRandenHwAes());
- constexpr uint64_t kGolden[] = {
- 0x6c6534090ee6d3ee, 0x044e2b9b9d5333c6, 0xc3c14f134e433977,
- 0xdda9f47cd90410ee, 0x887bf3087fd8ca10, 0xf0b780f545c72912,
- 0x15dbb1d37696599f, 0x30ec63baff3c6d59, 0xb29f73606f7f20a6,
- 0x02808a316f49a54c, 0x3b8feaf9d5c8e50e, 0x9cbf605e3fd9de8a,
- 0xc970ae1a78183bbb, 0xd8b2ffd356301ed5, 0xf4b327fe0fc73c37,
- 0xcdfd8d76eb8f9a19, 0xc3a506eb91420c9d, 0xd5af05dd3eff9556,
- 0x48db1bb78f83c4a1, 0x7023920e0d6bfe8c, 0x58d3575834956d42,
- 0xed1ef4c26b87b840, 0x8eef32a23e0b2df3, 0x497cabf3431154fc,
- 0x4e24370570029a8b, 0xd88b5749f090e5ea, 0xc651a582a970692f,
- 0x78fcec2cbb6342f5, 0x463cb745612f55db, 0x352ee4ad1816afe3,
- 0x026ff374c101da7e, 0x811ef0821c3de851,
+ constexpr uint8_t kGolden[] = {
+ 0xee, 0xd3, 0xe6, 0x0e, 0x09, 0x34, 0x65, 0x6c, 0xc6, 0x33, 0x53, 0x9d,
+ 0x9b, 0x2b, 0x4e, 0x04, 0x77, 0x39, 0x43, 0x4e, 0x13, 0x4f, 0xc1, 0xc3,
+ 0xee, 0x10, 0x04, 0xd9, 0x7c, 0xf4, 0xa9, 0xdd, 0x10, 0xca, 0xd8, 0x7f,
+ 0x08, 0xf3, 0x7b, 0x88, 0x12, 0x29, 0xc7, 0x45, 0xf5, 0x80, 0xb7, 0xf0,
+ 0x9f, 0x59, 0x96, 0x76, 0xd3, 0xb1, 0xdb, 0x15, 0x59, 0x6d, 0x3c, 0xff,
+ 0xba, 0x63, 0xec, 0x30, 0xa6, 0x20, 0x7f, 0x6f, 0x60, 0x73, 0x9f, 0xb2,
+ 0x4c, 0xa5, 0x49, 0x6f, 0x31, 0x8a, 0x80, 0x02, 0x0e, 0xe5, 0xc8, 0xd5,
+ 0xf9, 0xea, 0x8f, 0x3b, 0x8a, 0xde, 0xd9, 0x3f, 0x5e, 0x60, 0xbf, 0x9c,
+ 0xbb, 0x3b, 0x18, 0x78, 0x1a, 0xae, 0x70, 0xc9, 0xd5, 0x1e, 0x30, 0x56,
+ 0xd3, 0xff, 0xb2, 0xd8, 0x37, 0x3c, 0xc7, 0x0f, 0xfe, 0x27, 0xb3, 0xf4,
+ 0x19, 0x9a, 0x8f, 0xeb, 0x76, 0x8d, 0xfd, 0xcd, 0x9d, 0x0c, 0x42, 0x91,
+ 0xeb, 0x06, 0xa5, 0xc3, 0x56, 0x95, 0xff, 0x3e, 0xdd, 0x05, 0xaf, 0xd5,
+ 0xa1, 0xc4, 0x83, 0x8f, 0xb7, 0x1b, 0xdb, 0x48, 0x8c, 0xfe, 0x6b, 0x0d,
+ 0x0e, 0x92, 0x23, 0x70, 0x42, 0x6d, 0x95, 0x34, 0x58, 0x57, 0xd3, 0x58,
+ 0x40, 0xb8, 0x87, 0x6b, 0xc2, 0xf4, 0x1e, 0xed, 0xf3, 0x2d, 0x0b, 0x3e,
+ 0xa2, 0x32, 0xef, 0x8e, 0xfc, 0x54, 0x11, 0x43, 0xf3, 0xab, 0x7c, 0x49,
+ 0x8b, 0x9a, 0x02, 0x70, 0x05, 0x37, 0x24, 0x4e, 0xea, 0xe5, 0x90, 0xf0,
+ 0x49, 0x57, 0x8b, 0xd8, 0x2f, 0x69, 0x70, 0xa9, 0x82, 0xa5, 0x51, 0xc6,
+ 0xf5, 0x42, 0x63, 0xbb, 0x2c, 0xec, 0xfc, 0x78, 0xdb, 0x55, 0x2f, 0x61,
+ 0x45, 0xb7, 0x3c, 0x46, 0xe3, 0xaf, 0x16, 0x18, 0xad, 0xe4, 0x2e, 0x35,
+ 0x7e, 0xda, 0x01, 0xc1, 0x74, 0xf3, 0x6f, 0x02, 0x51, 0xe8, 0x3d, 0x1c,
+ 0x82, 0xf0, 0x1e, 0x81,
};
- alignas(16) randen d;
- memset(d.state, 0, sizeof(d.state));
- RandenHwAes::Generate(RandenHwAes::GetKeys(), d.state);
+ alignas(16) uint8_t state[RandenTraits::kStateBytes];
+ std::memset(state, 0, sizeof(state));
- uint64_t* id = d.state;
- for (const auto& elem : kGolden) {
- auto a = absl::StrFormat("%#x", elem);
- auto b = absl::StrFormat("%#x", *id++);
- EXPECT_EQ(a, b);
- }
+ RandenHwAes::Generate(RandenHwAes::GetKeys(), state);
+ EXPECT_EQ(0, std::memcmp(state, kGolden, sizeof(state)));
}
} // namespace
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc b/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc
new file mode 100644
index 0000000000..5fb3ca556d
--- /dev/null
+++ b/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc
@@ -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
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_slow.cc b/third_party/abseil-cpp/absl/random/internal/randen_slow.cc
index 8d07458254..9bfd2a4092 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_slow.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen_slow.cc
@@ -19,7 +19,10 @@
#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__))
@@ -37,369 +40,303 @@
namespace {
// AES portions based on rijndael-alg-fst.c,
-// https://fastcrypto.org/front/misc/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] = {
- 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd,
- 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
- 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d,
- 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
- 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7,
- 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
- 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4,
- 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
- 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1,
- 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
- 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e,
- 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
- 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e,
- 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
- 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46,
- 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
- 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7,
- 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
- 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe,
- 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
- 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a,
- 0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
- 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2,
- 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
- 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e,
- 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
- 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256,
- 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
- 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4,
- 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
- 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa,
- 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
- 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1,
- 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
- 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42,
- 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
- 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158,
- 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
- 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22,
- 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
- 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631,
- 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
- 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
+ 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] = {
- 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b,
- 0xb1de6f6f, 0x5491c5c5, 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b,
- 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, 0x458fcaca, 0x9d1f8282,
- 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
- 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4,
- 0x96e47272, 0x5b9bc0c0, 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
- 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, 0x5c683434, 0xf451a5a5,
- 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
- 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696,
- 0x0f0a0505, 0xb52f9a9a, 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
- 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, 0x1b120909, 0x9e1d8383,
- 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
- 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3,
- 0x715e2f2f, 0x97138484, 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded,
- 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, 0xbed46a6a, 0x468dcbcb,
- 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
- 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d,
- 0x55663333, 0x94118585, 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f,
- 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, 0xf3a25151, 0xfe5da3a3,
- 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
- 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff,
- 0x0efdf3f3, 0x6dbfd2d2, 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
- 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, 0x5793c4c4, 0xf255a7a7,
- 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
- 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a,
- 0xab3b9090, 0x830b8888, 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
- 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, 0x3bdbe0e0, 0x56643232,
- 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
- 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595,
- 0x37d3e4e4, 0x8bf27979, 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
- 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, 0xb4d86c6c, 0xfaac5656,
- 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
- 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6,
- 0xc773b4b4, 0x5197c6c6, 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
- 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, 0x90e07070, 0x427c3e3e,
- 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
- 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1,
- 0x273a1d1d, 0xb9279e9e, 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
- 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, 0xb62d9b9b, 0x223c1e1e,
- 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
- 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6,
- 0xc6844242, 0xb8d06868, 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
- 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
+ 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] = {
- 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b,
- 0x6fb1de6f, 0xc55491c5, 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b,
- 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, 0xca458fca, 0x829d1f82,
- 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
- 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4,
- 0x7296e472, 0xc05b9bc0, 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
- 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, 0x345c6834, 0xa5f451a5,
- 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
- 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796,
- 0x050f0a05, 0x9ab52f9a, 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
- 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, 0x091b1209, 0x839e1d83,
- 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
- 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3,
- 0x2f715e2f, 0x84971384, 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed,
- 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, 0x6abed46a, 0xcb468dcb,
- 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
- 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d,
- 0x33556633, 0x85941185, 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f,
- 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, 0x51f3a251, 0xa3fe5da3,
- 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
- 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff,
- 0xf30efdf3, 0xd26dbfd2, 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec,
- 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, 0xc45793c4, 0xa7f255a7,
- 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
- 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a,
- 0x90ab3b90, 0x88830b88, 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
- 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, 0xe03bdbe0, 0x32566432,
- 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
- 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195,
- 0xe437d3e4, 0x798bf279, 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
- 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, 0x6cb4d86c, 0x56faac56,
- 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
- 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6,
- 0xb4c773b4, 0xc65197c6, 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
- 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, 0x7090e070, 0x3e427c3e,
- 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
- 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1,
- 0x1d273a1d, 0x9eb9279e, 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
- 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, 0x9bb62d9b, 0x1e223c1e,
- 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
- 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6,
- 0x42c68442, 0x68b8d068, 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f,
- 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
+ 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] = {
- 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6,
- 0x6f6fb1de, 0xc5c55491, 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56,
- 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, 0xcaca458f, 0x82829d1f,
- 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
- 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753,
- 0x727296e4, 0xc0c05b9b, 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
- 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, 0x34345c68, 0xa5a5f451,
- 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
- 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137,
- 0x05050f0a, 0x9a9ab52f, 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
- 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, 0x09091b12, 0x83839e1d,
- 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
- 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd,
- 0x2f2f715e, 0x84849713, 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1,
- 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, 0x6a6abed4, 0xcbcb468d,
- 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
- 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a,
- 0x33335566, 0x85859411, 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe,
- 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, 0x5151f3a2, 0xa3a3fe5d,
- 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
- 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5,
- 0xf3f30efd, 0xd2d26dbf, 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3,
- 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, 0xc4c45793, 0xa7a7f255,
- 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
- 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54,
- 0x9090ab3b, 0x8888830b, 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
- 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, 0xe0e03bdb, 0x32325664,
- 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
- 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431,
- 0xe4e437d3, 0x79798bf2, 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
- 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, 0x6c6cb4d8, 0x5656faac,
- 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
- 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157,
- 0xb4b4c773, 0xc6c65197, 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
- 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, 0x707090e0, 0x3e3e427c,
- 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
- 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899,
- 0x1d1d273a, 0x9e9eb927, 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
- 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, 0x9b9bb62d, 0x1e1e223c,
- 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
- 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7,
- 0x4242c684, 0x6868b8d0, 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e,
- 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
-};
-
-struct alignas(16) u64x2 {
- constexpr u64x2() : v{0, 0} {};
- constexpr u64x2(uint64_t hi, uint64_t lo) : v{lo, hi} {}
-
- uint64_t v[2];
+ 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 Vector128 {
- inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128& operator^=(
- const Vector128& other) {
- s[0] ^= other.s[0];
- s[1] ^= other.s[1];
- s[2] ^= other.s[2];
- s[3] ^= other.s[3];
- return *this;
- }
-
+struct alignas(16) Vector128 {
uint32_t s[4];
};
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128
-Vector128Load(const void* ABSL_RANDOM_INTERNAL_RESTRICT from) {
+Vector128Load(const void* from) {
Vector128 result;
- const uint8_t* ABSL_RANDOM_INTERNAL_RESTRICT src =
- reinterpret_cast<const uint8_t*>(from);
-
- result.s[0] = static_cast<uint32_t>(src[0]) << 24 |
- static_cast<uint32_t>(src[1]) << 16 |
- static_cast<uint32_t>(src[2]) << 8 |
- static_cast<uint32_t>(src[3]);
- result.s[1] = static_cast<uint32_t>(src[4]) << 24 |
- static_cast<uint32_t>(src[5]) << 16 |
- static_cast<uint32_t>(src[6]) << 8 |
- static_cast<uint32_t>(src[7]);
- result.s[2] = static_cast<uint32_t>(src[8]) << 24 |
- static_cast<uint32_t>(src[9]) << 16 |
- static_cast<uint32_t>(src[10]) << 8 |
- static_cast<uint32_t>(src[11]);
- result.s[3] = static_cast<uint32_t>(src[12]) << 24 |
- static_cast<uint32_t>(src[13]) << 16 |
- static_cast<uint32_t>(src[14]) << 8 |
- static_cast<uint32_t>(src[15]);
+ std::memcpy(result.s, from, sizeof(Vector128));
return result;
}
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store(
- const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) {
- uint8_t* dst = reinterpret_cast<uint8_t*>(to);
- dst[0] = static_cast<uint8_t>(v.s[0] >> 24);
- dst[1] = static_cast<uint8_t>(v.s[0] >> 16);
- dst[2] = static_cast<uint8_t>(v.s[0] >> 8);
- dst[3] = static_cast<uint8_t>(v.s[0]);
- dst[4] = static_cast<uint8_t>(v.s[1] >> 24);
- dst[5] = static_cast<uint8_t>(v.s[1] >> 16);
- dst[6] = static_cast<uint8_t>(v.s[1] >> 8);
- dst[7] = static_cast<uint8_t>(v.s[1]);
- dst[8] = static_cast<uint8_t>(v.s[2] >> 24);
- dst[9] = static_cast<uint8_t>(v.s[2] >> 16);
- dst[10] = static_cast<uint8_t>(v.s[2] >> 8);
- dst[11] = static_cast<uint8_t>(v.s[2]);
- dst[12] = static_cast<uint8_t>(v.s[3] >> 24);
- dst[13] = static_cast<uint8_t>(v.s[3] >> 16);
- dst[14] = static_cast<uint8_t>(v.s[3] >> 8);
- dst[15] = static_cast<uint8_t>(v.s[3]);
+ 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) {
- // clang-format off
Vector128 result;
- result.s[0] = round_key.s[0] ^
- te0[uint8_t(state.s[0] >> 24)] ^
- te1[uint8_t(state.s[1] >> 16)] ^
- te2[uint8_t(state.s[2] >> 8)] ^
- te3[uint8_t(state.s[3])];
- result.s[1] = round_key.s[1] ^
- te0[uint8_t(state.s[1] >> 24)] ^
- te1[uint8_t(state.s[2] >> 16)] ^
- te2[uint8_t(state.s[3] >> 8)] ^
- te3[uint8_t(state.s[0])];
- result.s[2] = round_key.s[2] ^
- te0[uint8_t(state.s[2] >> 24)] ^
- te1[uint8_t(state.s[3] >> 16)] ^
- te2[uint8_t(state.s[0] >> 8)] ^
- te3[uint8_t(state.s[1])];
- result.s[3] = round_key.s[3] ^
- te0[uint8_t(state.s[3] >> 24)] ^
- te1[uint8_t(state.s[0] >> 16)] ^
- te2[uint8_t(state.s[1] >> 8)] ^
- te3[uint8_t(state.s[2])];
+#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;
- // clang-format on
}
-// RANDen = RANDom generator or beetroots in Swiss 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.
-
-// Randen constants.
-constexpr size_t kFeistelBlocks = 16;
-constexpr size_t kFeistelFunctions = kFeistelBlocks / 2; // = 8
-constexpr size_t kFeistelRounds = 16 + 1; // > 4 * log2(kFeistelBlocks)
-constexpr size_t kKeys = kFeistelRounds * kFeistelFunctions;
-
-// INCLUDE keys.
-#include "absl/random/internal/randen-keys.inc"
-
-static_assert(kKeys == kRoundKeys, "kKeys and kRoundKeys must be equal");
-
-// 2 uint64_t lanes per Vector128
-static constexpr size_t kLanes = 2;
+using ::absl::random_internal::RandenTraits;
// The improved Feistel block shuffle function for 16 blocks.
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle(
- uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state_u64) {
- static_assert(kFeistelBlocks == 16,
+ absl::uint128* state) {
+ static_assert(RandenTraits::kFeistelBlocks == 16,
"Feistel block shuffle only works for 16 blocks.");
- constexpr size_t shuffle[kFeistelBlocks] = {7, 2, 13, 4, 11, 8, 3, 6,
- 15, 0, 9, 10, 1, 14, 5, 12};
-
- u64x2* ABSL_RANDOM_INTERNAL_RESTRICT state =
- reinterpret_cast<u64x2*>(state_u64);
+ 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 (leaving code here as a comment):
- if (false) {
- u64x2 source[kFeistelBlocks];
- std::memcpy(source, state, sizeof(source));
- for (size_t i = 0; i < kFeistelBlocks; i++) {
- const u64x2 v0 = source[shuffle[i]];
- state[i] = v0;
- }
+ // 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 u64x2 v0 = state[shuffle[0]];
- const u64x2 v1 = state[shuffle[1]];
- const u64x2 v2 = state[shuffle[2]];
- const u64x2 v3 = state[shuffle[3]];
- const u64x2 v4 = state[shuffle[4]];
- const u64x2 v5 = state[shuffle[5]];
- const u64x2 v6 = state[shuffle[6]];
- const u64x2 v7 = state[shuffle[7]];
- const u64x2 w0 = state[shuffle[8]];
- const u64x2 w1 = state[shuffle[9]];
- const u64x2 w2 = state[shuffle[10]];
- const u64x2 w3 = state[shuffle[11]];
- const u64x2 w4 = state[shuffle[12]];
- const u64x2 w5 = state[shuffle[13]];
- const u64x2 w6 = state[shuffle[14]];
- const u64x2 w7 = state[shuffle[15]];
+ 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;
@@ -423,24 +360,24 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle(
// 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 u64x2* FeistelRound(
- uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state,
- const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
- for (size_t branch = 0; branch < kFeistelBlocks; branch += 4) {
- const Vector128 s0 = Vector128Load(state + kLanes * branch);
- const Vector128 s1 = Vector128Load(state + kLanes * (branch + 1));
+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 + kLanes * (branch + 1));
+ Vector128Store(o1, state + branch + 1);
// Manually unroll this loop once. about 10% better than not unrolled.
- const Vector128 s2 = Vector128Load(state + kLanes * (branch + 2));
- const Vector128 s3 = Vector128Load(state + kLanes * (branch + 3));
+ 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 + kLanes * (branch + 3));
+ Vector128Store(o3, state + branch + 3);
}
return keys;
}
@@ -450,15 +387,31 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE const u64x2* FeistelRound(
// 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(
- const void* keys, uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) {
- const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys128 =
- static_cast<const u64x2*>(keys);
- for (size_t round = 0; round < kFeistelRounds; ++round) {
- keys128 = FeistelRound(state, keys128);
+ 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 {
@@ -468,37 +421,49 @@ 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.
- return round_keys;
+#ifdef ABSL_IS_LITTLE_ENDIAN
+ return kRandenRoundKeys;
+#else
+ return kRandenRoundKeysBE;
+#endif
}
void RandenSlow::Absorb(const void* seed_void, void* state_void) {
- uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state =
- reinterpret_cast<uint64_t*>(state_void);
- const uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT seed =
- reinterpret_cast<const uint64_t*>(seed_void);
-
- constexpr size_t kCapacityBlocks = kCapacityBytes / sizeof(uint64_t);
- static_assert(kCapacityBlocks * sizeof(uint64_t) == kCapacityBytes,
- "Not i*V");
- for (size_t i = kCapacityBlocks; i < kStateBytes / sizeof(uint64_t); ++i) {
+ 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* state_void) {
- static_assert(kCapacityBytes == sizeof(Vector128), "Capacity mismatch");
+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];
- uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state =
- reinterpret_cast<uint64_t*>(state_void);
+ SwapEndian(state);
- const Vector128 prev_inner = Vector128Load(state);
+ Permute(state, keys);
- Permute(keys, state);
+ SwapEndian(state);
// Ensure backtracking resistance.
- Vector128 inner = Vector128Load(state);
- inner ^= prev_inner;
- Vector128Store(inner, state);
+ *state ^= prev_inner;
}
} // namespace random_internal
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_slow.h b/third_party/abseil-cpp/absl/random/internal/randen_slow.h
index 72f92b54ad..532c3a8991 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_slow.h
+++ b/third_party/abseil-cpp/absl/random/internal/randen_slow.h
@@ -23,18 +23,11 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// RANDen = RANDom generator or beetroots in Swiss German.
+// 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:
- // 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
-
static void Generate(const void* keys, void* state_void);
static void Absorb(const void* seed_void, void* state_void);
static const void* GetKeys();
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_slow_test.cc b/third_party/abseil-cpp/absl/random/internal/randen_slow_test.cc
index c07155d8dd..ed6039586c 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_slow_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen_slow_test.cc
@@ -17,45 +17,45 @@
#include <cstring>
#include "gtest/gtest.h"
+#include "absl/base/internal/endian.h"
+#include "absl/random/internal/randen_traits.h"
namespace {
using absl::random_internal::RandenSlow;
-
-// Local state parameters.
-constexpr size_t kSeedBytes =
- RandenSlow::kStateBytes - RandenSlow::kCapacityBytes;
-constexpr size_t kStateSizeT = RandenSlow::kStateBytes / sizeof(uint64_t);
-constexpr size_t kSeedSizeT = kSeedBytes / sizeof(uint32_t);
-
-struct randen {
- uint64_t state[kStateSizeT];
- uint32_t seed[kSeedSizeT];
-};
+using absl::random_internal::RandenTraits;
TEST(RandenSlowTest, Default) {
- constexpr uint64_t kGolden[] = {
- 0x6c6534090ee6d3ee, 0x044e2b9b9d5333c6, 0xc3c14f134e433977,
- 0xdda9f47cd90410ee, 0x887bf3087fd8ca10, 0xf0b780f545c72912,
- 0x15dbb1d37696599f, 0x30ec63baff3c6d59, 0xb29f73606f7f20a6,
- 0x02808a316f49a54c, 0x3b8feaf9d5c8e50e, 0x9cbf605e3fd9de8a,
- 0xc970ae1a78183bbb, 0xd8b2ffd356301ed5, 0xf4b327fe0fc73c37,
- 0xcdfd8d76eb8f9a19, 0xc3a506eb91420c9d, 0xd5af05dd3eff9556,
- 0x48db1bb78f83c4a1, 0x7023920e0d6bfe8c, 0x58d3575834956d42,
- 0xed1ef4c26b87b840, 0x8eef32a23e0b2df3, 0x497cabf3431154fc,
- 0x4e24370570029a8b, 0xd88b5749f090e5ea, 0xc651a582a970692f,
- 0x78fcec2cbb6342f5, 0x463cb745612f55db, 0x352ee4ad1816afe3,
- 0x026ff374c101da7e, 0x811ef0821c3de851,
+ constexpr uint8_t kGolden[] = {
+ 0xee, 0xd3, 0xe6, 0x0e, 0x09, 0x34, 0x65, 0x6c, 0xc6, 0x33, 0x53, 0x9d,
+ 0x9b, 0x2b, 0x4e, 0x04, 0x77, 0x39, 0x43, 0x4e, 0x13, 0x4f, 0xc1, 0xc3,
+ 0xee, 0x10, 0x04, 0xd9, 0x7c, 0xf4, 0xa9, 0xdd, 0x10, 0xca, 0xd8, 0x7f,
+ 0x08, 0xf3, 0x7b, 0x88, 0x12, 0x29, 0xc7, 0x45, 0xf5, 0x80, 0xb7, 0xf0,
+ 0x9f, 0x59, 0x96, 0x76, 0xd3, 0xb1, 0xdb, 0x15, 0x59, 0x6d, 0x3c, 0xff,
+ 0xba, 0x63, 0xec, 0x30, 0xa6, 0x20, 0x7f, 0x6f, 0x60, 0x73, 0x9f, 0xb2,
+ 0x4c, 0xa5, 0x49, 0x6f, 0x31, 0x8a, 0x80, 0x02, 0x0e, 0xe5, 0xc8, 0xd5,
+ 0xf9, 0xea, 0x8f, 0x3b, 0x8a, 0xde, 0xd9, 0x3f, 0x5e, 0x60, 0xbf, 0x9c,
+ 0xbb, 0x3b, 0x18, 0x78, 0x1a, 0xae, 0x70, 0xc9, 0xd5, 0x1e, 0x30, 0x56,
+ 0xd3, 0xff, 0xb2, 0xd8, 0x37, 0x3c, 0xc7, 0x0f, 0xfe, 0x27, 0xb3, 0xf4,
+ 0x19, 0x9a, 0x8f, 0xeb, 0x76, 0x8d, 0xfd, 0xcd, 0x9d, 0x0c, 0x42, 0x91,
+ 0xeb, 0x06, 0xa5, 0xc3, 0x56, 0x95, 0xff, 0x3e, 0xdd, 0x05, 0xaf, 0xd5,
+ 0xa1, 0xc4, 0x83, 0x8f, 0xb7, 0x1b, 0xdb, 0x48, 0x8c, 0xfe, 0x6b, 0x0d,
+ 0x0e, 0x92, 0x23, 0x70, 0x42, 0x6d, 0x95, 0x34, 0x58, 0x57, 0xd3, 0x58,
+ 0x40, 0xb8, 0x87, 0x6b, 0xc2, 0xf4, 0x1e, 0xed, 0xf3, 0x2d, 0x0b, 0x3e,
+ 0xa2, 0x32, 0xef, 0x8e, 0xfc, 0x54, 0x11, 0x43, 0xf3, 0xab, 0x7c, 0x49,
+ 0x8b, 0x9a, 0x02, 0x70, 0x05, 0x37, 0x24, 0x4e, 0xea, 0xe5, 0x90, 0xf0,
+ 0x49, 0x57, 0x8b, 0xd8, 0x2f, 0x69, 0x70, 0xa9, 0x82, 0xa5, 0x51, 0xc6,
+ 0xf5, 0x42, 0x63, 0xbb, 0x2c, 0xec, 0xfc, 0x78, 0xdb, 0x55, 0x2f, 0x61,
+ 0x45, 0xb7, 0x3c, 0x46, 0xe3, 0xaf, 0x16, 0x18, 0xad, 0xe4, 0x2e, 0x35,
+ 0x7e, 0xda, 0x01, 0xc1, 0x74, 0xf3, 0x6f, 0x02, 0x51, 0xe8, 0x3d, 0x1c,
+ 0x82, 0xf0, 0x1e, 0x81,
};
- alignas(16) randen d;
- std::memset(d.state, 0, sizeof(d.state));
- RandenSlow::Generate(RandenSlow::GetKeys(), d.state);
+ alignas(16) uint8_t state[RandenTraits::kStateBytes];
+ std::memset(state, 0, sizeof(state));
- uint64_t* id = d.state;
- for (const auto& elem : kGolden) {
- EXPECT_EQ(elem, *id++);
- }
+ RandenSlow::Generate(RandenSlow::GetKeys(), state);
+ EXPECT_EQ(0, std::memcmp(state, kGolden, sizeof(state)));
}
} // namespace
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_test.cc b/third_party/abseil-cpp/absl/random/internal/randen_test.cc
index c186fe0d68..92773b8d9a 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/randen_test.cc
@@ -23,9 +23,6 @@ namespace {
using absl::random_internal::Randen;
-// Local state parameters.
-constexpr size_t kStateSizeT = Randen::kStateBytes / sizeof(uint64_t);
-
TEST(RandenTest, CopyAndMove) {
static_assert(std::is_copy_constructible<Randen>::value,
"Randen must be copy constructible");
@@ -41,30 +38,38 @@ TEST(RandenTest, CopyAndMove) {
}
TEST(RandenTest, Default) {
- constexpr uint64_t kGolden[] = {
- 0x6c6534090ee6d3ee, 0x044e2b9b9d5333c6, 0xc3c14f134e433977,
- 0xdda9f47cd90410ee, 0x887bf3087fd8ca10, 0xf0b780f545c72912,
- 0x15dbb1d37696599f, 0x30ec63baff3c6d59, 0xb29f73606f7f20a6,
- 0x02808a316f49a54c, 0x3b8feaf9d5c8e50e, 0x9cbf605e3fd9de8a,
- 0xc970ae1a78183bbb, 0xd8b2ffd356301ed5, 0xf4b327fe0fc73c37,
- 0xcdfd8d76eb8f9a19, 0xc3a506eb91420c9d, 0xd5af05dd3eff9556,
- 0x48db1bb78f83c4a1, 0x7023920e0d6bfe8c, 0x58d3575834956d42,
- 0xed1ef4c26b87b840, 0x8eef32a23e0b2df3, 0x497cabf3431154fc,
- 0x4e24370570029a8b, 0xd88b5749f090e5ea, 0xc651a582a970692f,
- 0x78fcec2cbb6342f5, 0x463cb745612f55db, 0x352ee4ad1816afe3,
- 0x026ff374c101da7e, 0x811ef0821c3de851,
+ constexpr uint8_t kGolden[] = {
+ 0xee, 0xd3, 0xe6, 0x0e, 0x09, 0x34, 0x65, 0x6c, 0xc6, 0x33, 0x53, 0x9d,
+ 0x9b, 0x2b, 0x4e, 0x04, 0x77, 0x39, 0x43, 0x4e, 0x13, 0x4f, 0xc1, 0xc3,
+ 0xee, 0x10, 0x04, 0xd9, 0x7c, 0xf4, 0xa9, 0xdd, 0x10, 0xca, 0xd8, 0x7f,
+ 0x08, 0xf3, 0x7b, 0x88, 0x12, 0x29, 0xc7, 0x45, 0xf5, 0x80, 0xb7, 0xf0,
+ 0x9f, 0x59, 0x96, 0x76, 0xd3, 0xb1, 0xdb, 0x15, 0x59, 0x6d, 0x3c, 0xff,
+ 0xba, 0x63, 0xec, 0x30, 0xa6, 0x20, 0x7f, 0x6f, 0x60, 0x73, 0x9f, 0xb2,
+ 0x4c, 0xa5, 0x49, 0x6f, 0x31, 0x8a, 0x80, 0x02, 0x0e, 0xe5, 0xc8, 0xd5,
+ 0xf9, 0xea, 0x8f, 0x3b, 0x8a, 0xde, 0xd9, 0x3f, 0x5e, 0x60, 0xbf, 0x9c,
+ 0xbb, 0x3b, 0x18, 0x78, 0x1a, 0xae, 0x70, 0xc9, 0xd5, 0x1e, 0x30, 0x56,
+ 0xd3, 0xff, 0xb2, 0xd8, 0x37, 0x3c, 0xc7, 0x0f, 0xfe, 0x27, 0xb3, 0xf4,
+ 0x19, 0x9a, 0x8f, 0xeb, 0x76, 0x8d, 0xfd, 0xcd, 0x9d, 0x0c, 0x42, 0x91,
+ 0xeb, 0x06, 0xa5, 0xc3, 0x56, 0x95, 0xff, 0x3e, 0xdd, 0x05, 0xaf, 0xd5,
+ 0xa1, 0xc4, 0x83, 0x8f, 0xb7, 0x1b, 0xdb, 0x48, 0x8c, 0xfe, 0x6b, 0x0d,
+ 0x0e, 0x92, 0x23, 0x70, 0x42, 0x6d, 0x95, 0x34, 0x58, 0x57, 0xd3, 0x58,
+ 0x40, 0xb8, 0x87, 0x6b, 0xc2, 0xf4, 0x1e, 0xed, 0xf3, 0x2d, 0x0b, 0x3e,
+ 0xa2, 0x32, 0xef, 0x8e, 0xfc, 0x54, 0x11, 0x43, 0xf3, 0xab, 0x7c, 0x49,
+ 0x8b, 0x9a, 0x02, 0x70, 0x05, 0x37, 0x24, 0x4e, 0xea, 0xe5, 0x90, 0xf0,
+ 0x49, 0x57, 0x8b, 0xd8, 0x2f, 0x69, 0x70, 0xa9, 0x82, 0xa5, 0x51, 0xc6,
+ 0xf5, 0x42, 0x63, 0xbb, 0x2c, 0xec, 0xfc, 0x78, 0xdb, 0x55, 0x2f, 0x61,
+ 0x45, 0xb7, 0x3c, 0x46, 0xe3, 0xaf, 0x16, 0x18, 0xad, 0xe4, 0x2e, 0x35,
+ 0x7e, 0xda, 0x01, 0xc1, 0x74, 0xf3, 0x6f, 0x02, 0x51, 0xe8, 0x3d, 0x1c,
+ 0x82, 0xf0, 0x1e, 0x81,
};
- alignas(16) uint64_t state[kStateSizeT];
+ alignas(16) uint8_t state[Randen::kStateBytes];
std::memset(state, 0, sizeof(state));
Randen r;
r.Generate(state);
- auto id = std::begin(state);
- for (const auto& elem : kGolden) {
- EXPECT_EQ(elem, *id++);
- }
+ EXPECT_EQ(0, std::memcmp(state, kGolden, sizeof(state)));
}
} // namespace
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_traits.h b/third_party/abseil-cpp/absl/random/internal/randen_traits.h
index 2b8bbe7383..120022c9fb 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_traits.h
+++ b/third_party/abseil-cpp/absl/random/internal/randen_traits.h
@@ -28,10 +28,29 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// RANDen = RANDom generator or beetroots in Swiss German.
+// 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 {
@@ -45,17 +64,23 @@ struct RandenTraits {
// 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;
- // Type-2 generalized Feistel => one round function for every two blocks.
- static constexpr size_t kFeistelFunctions = kFeistelBlocks / 2; // = 8
-
// 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
diff --git a/third_party/abseil-cpp/absl/random/internal/seed_material.cc b/third_party/abseil-cpp/absl/random/internal/seed_material.cc
index 4d38a57419..c03cad8502 100644
--- a/third_party/abseil-cpp/absl/random/internal/seed_material.cc
+++ b/third_party/abseil-cpp/absl/random/internal/seed_material.cc
@@ -28,6 +28,7 @@
#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"
@@ -50,6 +51,18 @@
#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>
@@ -122,8 +135,32 @@ bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
#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 ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
+bool ReadSeedMaterialFromDevURandom(absl::Span<uint32_t> values) {
const char kEntropyFile[] = "/dev/urandom";
auto buffer = reinterpret_cast<uint8_t*>(values.data());
@@ -150,6 +187,17 @@ bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
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
diff --git a/third_party/abseil-cpp/absl/random/internal/uniform_helper.h b/third_party/abseil-cpp/absl/random/internal/uniform_helper.h
index 663107cb3a..1243bc1c62 100644
--- a/third_party/abseil-cpp/absl/random/internal/uniform_helper.h
+++ b/third_party/abseil-cpp/absl/random/internal/uniform_helper.h
@@ -19,10 +19,13 @@
#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;
@@ -58,6 +61,26 @@ 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
@@ -82,7 +105,7 @@ typename absl::enable_if_t<
std::is_same<Tag, IntervalOpenOpenTag>>>::value,
IntType>
uniform_lower_bound(Tag, IntType a, IntType) {
- return a + 1;
+ return a < (std::numeric_limits<IntType>::max)() ? (a + 1) : a;
}
template <typename FloatType, typename Tag>
@@ -113,7 +136,7 @@ typename absl::enable_if_t<
std::is_same<Tag, IntervalOpenOpenTag>>>::value,
IntType>
uniform_upper_bound(Tag, IntType, IntType b) {
- return b - 1;
+ return b > (std::numeric_limits<IntType>::min)() ? (b - 1) : b;
}
template <typename FloatType, typename Tag>
@@ -149,12 +172,53 @@ 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<std::is_integral<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<std::is_integral<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 distribtuion bounds based
+// on the tag.
template <typename NumType>
struct UniformDistributionWrapper : public UniformDistribution<NumType> {
template <typename TagType>
diff --git a/third_party/abseil-cpp/absl/random/internal/uniform_helper_test.cc b/third_party/abseil-cpp/absl/random/internal/uniform_helper_test.cc
new file mode 100644
index 0000000000..173c49b0b7
--- /dev/null
+++ b/third_party/abseil-cpp/absl/random/internal/uniform_helper_test.cc
@@ -0,0 +1,279 @@
+// 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/uniform_helper.h"
+
+#include <cmath>
+#include <cstdint>
+#include <random>
+
+#include "gtest/gtest.h"
+
+namespace {
+
+using absl::IntervalClosedClosedTag;
+using absl::IntervalClosedOpenTag;
+using absl::IntervalOpenClosedTag;
+using absl::IntervalOpenOpenTag;
+using absl::random_internal::uniform_inferred_return_t;
+using absl::random_internal::uniform_lower_bound;
+using absl::random_internal::uniform_upper_bound;
+
+class UniformHelperTest : public testing::Test {};
+
+TEST_F(UniformHelperTest, UniformBoundFunctionsGeneral) {
+ constexpr IntervalClosedClosedTag IntervalClosedClosed;
+ constexpr IntervalClosedOpenTag IntervalClosedOpen;
+ constexpr IntervalOpenClosedTag IntervalOpenClosed;
+ constexpr IntervalOpenOpenTag IntervalOpenOpen;
+
+ // absl::uniform_int_distribution natively assumes IntervalClosedClosed
+ // absl::uniform_real_distribution natively assumes IntervalClosedOpen
+
+ EXPECT_EQ(uniform_lower_bound(IntervalOpenClosed, 0, 100), 1);
+ EXPECT_EQ(uniform_lower_bound(IntervalOpenOpen, 0, 100), 1);
+ EXPECT_GT(uniform_lower_bound<float>(IntervalOpenClosed, 0, 1.0), 0);
+ EXPECT_GT(uniform_lower_bound<float>(IntervalOpenOpen, 0, 1.0), 0);
+ EXPECT_GT(uniform_lower_bound<double>(IntervalOpenClosed, 0, 1.0), 0);
+ EXPECT_GT(uniform_lower_bound<double>(IntervalOpenOpen, 0, 1.0), 0);
+
+ EXPECT_EQ(uniform_lower_bound(IntervalClosedClosed, 0, 100), 0);
+ EXPECT_EQ(uniform_lower_bound(IntervalClosedOpen, 0, 100), 0);
+ EXPECT_EQ(uniform_lower_bound<float>(IntervalClosedClosed, 0, 1.0), 0);
+ EXPECT_EQ(uniform_lower_bound<float>(IntervalClosedOpen, 0, 1.0), 0);
+ EXPECT_EQ(uniform_lower_bound<double>(IntervalClosedClosed, 0, 1.0), 0);
+ EXPECT_EQ(uniform_lower_bound<double>(IntervalClosedOpen, 0, 1.0), 0);
+
+ EXPECT_EQ(uniform_upper_bound(IntervalOpenOpen, 0, 100), 99);
+ EXPECT_EQ(uniform_upper_bound(IntervalClosedOpen, 0, 100), 99);
+ EXPECT_EQ(uniform_upper_bound<float>(IntervalOpenOpen, 0, 1.0), 1.0);
+ EXPECT_EQ(uniform_upper_bound<float>(IntervalClosedOpen, 0, 1.0), 1.0);
+ EXPECT_EQ(uniform_upper_bound<double>(IntervalOpenOpen, 0, 1.0), 1.0);
+ EXPECT_EQ(uniform_upper_bound<double>(IntervalClosedOpen, 0, 1.0), 1.0);
+
+ EXPECT_EQ(uniform_upper_bound(IntervalOpenClosed, 0, 100), 100);
+ EXPECT_EQ(uniform_upper_bound(IntervalClosedClosed, 0, 100), 100);
+ EXPECT_GT(uniform_upper_bound<float>(IntervalOpenClosed, 0, 1.0), 1.0);
+ EXPECT_GT(uniform_upper_bound<float>(IntervalClosedClosed, 0, 1.0), 1.0);
+ EXPECT_GT(uniform_upper_bound<double>(IntervalOpenClosed, 0, 1.0), 1.0);
+ EXPECT_GT(uniform_upper_bound<double>(IntervalClosedClosed, 0, 1.0), 1.0);
+
+ // Negative value tests
+ EXPECT_EQ(uniform_lower_bound(IntervalOpenClosed, -100, -1), -99);
+ EXPECT_EQ(uniform_lower_bound(IntervalOpenOpen, -100, -1), -99);
+ EXPECT_GT(uniform_lower_bound<float>(IntervalOpenClosed, -2.0, -1.0), -2.0);
+ EXPECT_GT(uniform_lower_bound<float>(IntervalOpenOpen, -2.0, -1.0), -2.0);
+ EXPECT_GT(uniform_lower_bound<double>(IntervalOpenClosed, -2.0, -1.0), -2.0);
+ EXPECT_GT(uniform_lower_bound<double>(IntervalOpenOpen, -2.0, -1.0), -2.0);
+
+ EXPECT_EQ(uniform_lower_bound(IntervalClosedClosed, -100, -1), -100);
+ EXPECT_EQ(uniform_lower_bound(IntervalClosedOpen, -100, -1), -100);
+ EXPECT_EQ(uniform_lower_bound<float>(IntervalClosedClosed, -2.0, -1.0), -2.0);
+ EXPECT_EQ(uniform_lower_bound<float>(IntervalClosedOpen, -2.0, -1.0), -2.0);
+ EXPECT_EQ(uniform_lower_bound<double>(IntervalClosedClosed, -2.0, -1.0),
+ -2.0);
+ EXPECT_EQ(uniform_lower_bound<double>(IntervalClosedOpen, -2.0, -1.0), -2.0);
+
+ EXPECT_EQ(uniform_upper_bound(IntervalOpenOpen, -100, -1), -2);
+ EXPECT_EQ(uniform_upper_bound(IntervalClosedOpen, -100, -1), -2);
+ EXPECT_EQ(uniform_upper_bound<float>(IntervalOpenOpen, -2.0, -1.0), -1.0);
+ EXPECT_EQ(uniform_upper_bound<float>(IntervalClosedOpen, -2.0, -1.0), -1.0);
+ EXPECT_EQ(uniform_upper_bound<double>(IntervalOpenOpen, -2.0, -1.0), -1.0);
+ EXPECT_EQ(uniform_upper_bound<double>(IntervalClosedOpen, -2.0, -1.0), -1.0);
+
+ EXPECT_EQ(uniform_upper_bound(IntervalOpenClosed, -100, -1), -1);
+ EXPECT_EQ(uniform_upper_bound(IntervalClosedClosed, -100, -1), -1);
+ EXPECT_GT(uniform_upper_bound<float>(IntervalOpenClosed, -2.0, -1.0), -1.0);
+ EXPECT_GT(uniform_upper_bound<float>(IntervalClosedClosed, -2.0, -1.0), -1.0);
+ EXPECT_GT(uniform_upper_bound<double>(IntervalOpenClosed, -2.0, -1.0), -1.0);
+ EXPECT_GT(uniform_upper_bound<double>(IntervalClosedClosed, -2.0, -1.0),
+ -1.0);
+
+ EXPECT_GT(uniform_lower_bound(IntervalOpenClosed, 1.0, 2.0), 1.0);
+ EXPECT_LT(uniform_lower_bound(IntervalOpenClosed, 1.0, +0.0), 1.0);
+ EXPECT_LT(uniform_lower_bound(IntervalOpenClosed, 1.0, -0.0), 1.0);
+ EXPECT_LT(uniform_lower_bound(IntervalOpenClosed, 1.0, -1.0), 1.0);
+}
+
+TEST_F(UniformHelperTest, UniformBoundFunctionsIntBounds) {
+ // Verifies the saturating nature of uniform_lower_bound and
+ // uniform_upper_bound
+ constexpr IntervalOpenOpenTag IntervalOpenOpen;
+
+ // uint max.
+ constexpr auto m = (std::numeric_limits<uint64_t>::max)();
+
+ EXPECT_EQ(1, uniform_lower_bound(IntervalOpenOpen, 0u, 0u));
+ EXPECT_EQ(m, uniform_lower_bound(IntervalOpenOpen, m, m));
+ EXPECT_EQ(m, uniform_lower_bound(IntervalOpenOpen, m - 1, m - 1));
+ EXPECT_EQ(0, uniform_upper_bound(IntervalOpenOpen, 0u, 0u));
+ EXPECT_EQ(m - 1, uniform_upper_bound(IntervalOpenOpen, m, m));
+
+ // int min/max
+ constexpr auto l = (std::numeric_limits<int64_t>::min)();
+ constexpr auto r = (std::numeric_limits<int64_t>::max)();
+ EXPECT_EQ(1, uniform_lower_bound(IntervalOpenOpen, 0, 0));
+ EXPECT_EQ(l + 1, uniform_lower_bound(IntervalOpenOpen, l, l));
+ EXPECT_EQ(r, uniform_lower_bound(IntervalOpenOpen, r - 1, r - 1));
+ EXPECT_EQ(r, uniform_lower_bound(IntervalOpenOpen, r, r));
+ EXPECT_EQ(-1, uniform_upper_bound(IntervalOpenOpen, 0, 0));
+ EXPECT_EQ(l, uniform_upper_bound(IntervalOpenOpen, l, l));
+ EXPECT_EQ(r - 1, uniform_upper_bound(IntervalOpenOpen, r, r));
+}
+
+TEST_F(UniformHelperTest, UniformBoundFunctionsRealBounds) {
+ // absl::uniform_real_distribution natively assumes IntervalClosedOpen;
+ // use the inverse here so each bound has to change.
+ constexpr IntervalOpenClosedTag IntervalOpenClosed;
+
+ // Edge cases: the next value toward itself is itself.
+ EXPECT_EQ(1.0, uniform_lower_bound(IntervalOpenClosed, 1.0, 1.0));
+ EXPECT_EQ(1.0f, uniform_lower_bound(IntervalOpenClosed, 1.0f, 1.0f));
+
+ // rightmost and leftmost finite values.
+ constexpr auto r = (std::numeric_limits<double>::max)();
+ const auto re = std::nexttoward(r, 0.0);
+ constexpr auto l = -r;
+ const auto le = std::nexttoward(l, 0.0);
+
+ EXPECT_EQ(l, uniform_lower_bound(IntervalOpenClosed, l, l)); // (l,l)
+ EXPECT_EQ(r, uniform_lower_bound(IntervalOpenClosed, r, r)); // (r,r)
+ EXPECT_EQ(le, uniform_lower_bound(IntervalOpenClosed, l, r)); // (l,r)
+ EXPECT_EQ(le, uniform_lower_bound(IntervalOpenClosed, l, 0.0)); // (l, 0)
+ EXPECT_EQ(le, uniform_lower_bound(IntervalOpenClosed, l, le)); // (l, le)
+ EXPECT_EQ(r, uniform_lower_bound(IntervalOpenClosed, re, r)); // (re, r)
+
+ EXPECT_EQ(le, uniform_upper_bound(IntervalOpenClosed, l, l)); // (l,l)
+ EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, r, r)); // (r,r)
+ EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, l, r)); // (l,r)
+ EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, l, re)); // (l,re)
+ EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, 0.0, r)); // (0, r)
+ EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, re, r)); // (re, r)
+ EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, le, re)); // (le, re)
+
+ const double e = std::nextafter(1.0, 2.0); // 1 + epsilon
+ const double f = std::nextafter(1.0, 0.0); // 1 - epsilon
+
+ // (1.0, 1.0 + epsilon)
+ EXPECT_EQ(e, uniform_lower_bound(IntervalOpenClosed, 1.0, e));
+ EXPECT_EQ(std::nextafter(e, 2.0),
+ uniform_upper_bound(IntervalOpenClosed, 1.0, e));
+
+ // (1.0-epsilon, 1.0)
+ EXPECT_EQ(1.0, uniform_lower_bound(IntervalOpenClosed, f, 1.0));
+ EXPECT_EQ(e, uniform_upper_bound(IntervalOpenClosed, f, 1.0));
+
+ // denorm cases.
+ const double g = std::numeric_limits<double>::denorm_min();
+ const double h = std::nextafter(g, 1.0);
+
+ // (0, denorm_min)
+ EXPECT_EQ(g, uniform_lower_bound(IntervalOpenClosed, 0.0, g));
+ EXPECT_EQ(h, uniform_upper_bound(IntervalOpenClosed, 0.0, g));
+
+ // (denorm_min, 1.0)
+ EXPECT_EQ(h, uniform_lower_bound(IntervalOpenClosed, g, 1.0));
+ EXPECT_EQ(e, uniform_upper_bound(IntervalOpenClosed, g, 1.0));
+
+ // Edge cases: invalid bounds.
+ EXPECT_EQ(f, uniform_lower_bound(IntervalOpenClosed, 1.0, -1.0));
+}
+
+struct Invalid {};
+
+template <typename A, typename B>
+auto InferredUniformReturnT(int) -> uniform_inferred_return_t<A, B>;
+
+template <typename, typename>
+Invalid InferredUniformReturnT(...);
+
+// Given types <A, B, Expect>, CheckArgsInferType() verifies that
+//
+// uniform_inferred_return_t<A, B> and
+// uniform_inferred_return_t<B, A>
+//
+// returns the type "Expect".
+//
+// This interface can also be used to assert that a given inferred return types
+// are invalid. Writing:
+//
+// CheckArgsInferType<float, int, Invalid>()
+//
+// will assert that this overload does not exist.
+template <typename A, typename B, typename Expect>
+void CheckArgsInferType() {
+ static_assert(
+ absl::conjunction<
+ std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>,
+ std::is_same<Expect,
+ decltype(InferredUniformReturnT<B, A>(0))>>::value,
+ "");
+}
+
+TEST_F(UniformHelperTest, UniformTypeInference) {
+ // Infers common types.
+ CheckArgsInferType<uint16_t, uint16_t, uint16_t>();
+ CheckArgsInferType<uint32_t, uint32_t, uint32_t>();
+ CheckArgsInferType<uint64_t, uint64_t, uint64_t>();
+ CheckArgsInferType<int16_t, int16_t, int16_t>();
+ CheckArgsInferType<int32_t, int32_t, int32_t>();
+ CheckArgsInferType<int64_t, int64_t, int64_t>();
+ CheckArgsInferType<float, float, float>();
+ CheckArgsInferType<double, double, double>();
+
+ // Properly promotes uint16_t.
+ CheckArgsInferType<uint16_t, uint32_t, uint32_t>();
+ CheckArgsInferType<uint16_t, uint64_t, uint64_t>();
+ CheckArgsInferType<uint16_t, int32_t, int32_t>();
+ CheckArgsInferType<uint16_t, int64_t, int64_t>();
+ CheckArgsInferType<uint16_t, float, float>();
+ CheckArgsInferType<uint16_t, double, double>();
+
+ // Properly promotes int16_t.
+ CheckArgsInferType<int16_t, int32_t, int32_t>();
+ CheckArgsInferType<int16_t, int64_t, int64_t>();
+ CheckArgsInferType<int16_t, float, float>();
+ CheckArgsInferType<int16_t, double, double>();
+
+ // Invalid (u)int16_t-pairings do not compile.
+ // See "CheckArgsInferType" comments above, for how this is achieved.
+ CheckArgsInferType<uint16_t, int16_t, Invalid>();
+ CheckArgsInferType<int16_t, uint32_t, Invalid>();
+ CheckArgsInferType<int16_t, uint64_t, Invalid>();
+
+ // Properly promotes uint32_t.
+ CheckArgsInferType<uint32_t, uint64_t, uint64_t>();
+ CheckArgsInferType<uint32_t, int64_t, int64_t>();
+ CheckArgsInferType<uint32_t, double, double>();
+
+ // Properly promotes int32_t.
+ CheckArgsInferType<int32_t, int64_t, int64_t>();
+ CheckArgsInferType<int32_t, double, double>();
+
+ // Invalid (u)int32_t-pairings do not compile.
+ CheckArgsInferType<uint32_t, int32_t, Invalid>();
+ CheckArgsInferType<int32_t, uint64_t, Invalid>();
+ CheckArgsInferType<int32_t, float, Invalid>();
+ CheckArgsInferType<uint32_t, float, Invalid>();
+
+ // Invalid (u)int64_t-pairings do not compile.
+ CheckArgsInferType<uint64_t, int64_t, Invalid>();
+ CheckArgsInferType<int64_t, float, Invalid>();
+ CheckArgsInferType<int64_t, double, Invalid>();
+
+ // Properly promotes float.
+ CheckArgsInferType<float, double, double>();
+}
+
+} // namespace
diff --git a/third_party/abseil-cpp/absl/random/internal/wide_multiply.h b/third_party/abseil-cpp/absl/random/internal/wide_multiply.h
index 6e4cf1be0a..b6e6c4b6aa 100644
--- a/third_party/abseil-cpp/absl/random/internal/wide_multiply.h
+++ b/third_party/abseil-cpp/absl/random/internal/wide_multiply.h
@@ -26,7 +26,7 @@
#endif
#include "absl/base/config.h"
-#include "absl/base/internal/bits.h"
+#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h"
#include "absl/random/internal/traits.h"
@@ -38,9 +38,9 @@ namespace random_internal {
// MultiplyU64ToU128 multiplies two 64-bit values to a 128-bit value.
// If an intrinsic is available, it is used, otherwise use native 32-bit
// multiplies to construct the result.
-inline uint128 MultiplyU64ToU128(uint64_t a, uint64_t b) {
+inline absl::uint128 MultiplyU64ToU128(uint64_t a, uint64_t b) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
- return uint128(static_cast<__uint128_t>(a) * b);
+ return absl::uint128(static_cast<__uint128_t>(a) * b);
#elif defined(ABSL_INTERNAL_USE_UMUL128)
// uint64_t * uint64_t => uint128 multiply using imul intrinsic on MSVC.
uint64_t high = 0;
@@ -93,14 +93,14 @@ struct wide_multiply {
template <>
struct wide_multiply<uint64_t> {
using input_type = uint64_t;
- using result_type = uint128;
+ using result_type = absl::uint128;
static result_type multiply(uint64_t a, uint64_t b) {
return MultiplyU64ToU128(a, b);
}
- static uint64_t hi(result_type r) { return Uint128High64(r); }
- static uint64_t lo(result_type r) { return Uint128Low64(r); }
+ static uint64_t hi(result_type r) { return absl::Uint128High64(r); }
+ static uint64_t lo(result_type r) { return absl::Uint128Low64(r); }
};
#endif
diff --git a/third_party/abseil-cpp/absl/random/internal/wide_multiply_test.cc b/third_party/abseil-cpp/absl/random/internal/wide_multiply_test.cc
index 922603f226..e276cb51cf 100644
--- a/third_party/abseil-cpp/absl/random/internal/wide_multiply_test.cc
+++ b/third_party/abseil-cpp/absl/random/internal/wide_multiply_test.cc
@@ -15,7 +15,6 @@
#include "absl/random/internal/wide_multiply.h"
#include "gtest/gtest.h"
-#include "absl/base/internal/bits.h"
#include "absl/numeric/int128.h"
using absl::random_internal::MultiplyU64ToU128;
@@ -28,7 +27,7 @@ TEST(WideMultiplyTest, MultiplyU64ToU128Test) {
EXPECT_EQ(absl::uint128(0), MultiplyU64ToU128(0, 0));
- // Max uint64
+ // Max uint64_t
EXPECT_EQ(MultiplyU64ToU128(kMax, kMax),
absl::MakeUint128(0xfffffffffffffffe, 0x0000000000000001));
EXPECT_EQ(absl::MakeUint128(0, kMax), MultiplyU64ToU128(kMax, 1));