blob: 9a3840b8f1607e357bdf5ccae4c21d1f78a5efee [file] [log] [blame]
Austin Schuh36244a12019-09-21 17:52:38 -07001// Copyright 2017 The Abseil Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef ABSL_RANDOM_INTERNAL_RANDEN_H_
16#define ABSL_RANDOM_INTERNAL_RANDEN_H_
17
18#include <cstddef>
19
20#include "absl/random/internal/platform.h"
21#include "absl/random/internal/randen_hwaes.h"
22#include "absl/random/internal/randen_slow.h"
23#include "absl/random/internal/randen_traits.h"
24
25namespace absl {
Austin Schuhb4691e92020-12-31 12:37:18 -080026ABSL_NAMESPACE_BEGIN
Austin Schuh36244a12019-09-21 17:52:38 -070027namespace random_internal {
28
Austin Schuhb4691e92020-12-31 12:37:18 -080029// RANDen = RANDom generator or beetroots in Swiss High German.
Austin Schuh36244a12019-09-21 17:52:38 -070030// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
31// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
32//
33// Randen implements the basic state manipulation methods.
34class Randen {
35 public:
36 static constexpr size_t kStateBytes = RandenTraits::kStateBytes;
37 static constexpr size_t kCapacityBytes = RandenTraits::kCapacityBytes;
38 static constexpr size_t kSeedBytes = RandenTraits::kSeedBytes;
39
40 ~Randen() = default;
41
42 Randen();
43
44 // Generate updates the randen sponge. The outer portion of the sponge
45 // (kCapacityBytes .. kStateBytes) may be consumed as PRNG state.
46 template <typename T, size_t N>
47 void Generate(T (&state)[N]) const {
48 static_assert(N * sizeof(T) == kStateBytes,
49 "Randen::Generate() requires kStateBytes of state");
50#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
51 // HW AES Dispatch.
52 if (has_crypto_) {
53 RandenHwAes::Generate(keys_, state);
54 } else {
55 RandenSlow::Generate(keys_, state);
56 }
57#elif ABSL_HAVE_ACCELERATED_AES
58 // HW AES is enabled.
59 RandenHwAes::Generate(keys_, state);
60#else
61 // HW AES is disabled.
62 RandenSlow::Generate(keys_, state);
63#endif
64 }
65
66 // Absorb incorporates additional seed material into the randen sponge. After
67 // absorb returns, Generate must be called before the state may be consumed.
68 template <typename S, size_t M, typename T, size_t N>
69 void Absorb(const S (&seed)[M], T (&state)[N]) const {
70 static_assert(M * sizeof(S) == RandenTraits::kSeedBytes,
71 "Randen::Absorb() requires kSeedBytes of seed");
72
73 static_assert(N * sizeof(T) == RandenTraits::kStateBytes,
74 "Randen::Absorb() requires kStateBytes of state");
75#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
76 // HW AES Dispatch.
77 if (has_crypto_) {
78 RandenHwAes::Absorb(seed, state);
79 } else {
80 RandenSlow::Absorb(seed, state);
81 }
82#elif ABSL_HAVE_ACCELERATED_AES
83 // HW AES is enabled.
84 RandenHwAes::Absorb(seed, state);
85#else
86 // HW AES is disabled.
87 RandenSlow::Absorb(seed, state);
88#endif
89 }
90
91 private:
92 const void* keys_;
93#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
94 bool has_crypto_;
95#endif
96};
97
98} // namespace random_internal
Austin Schuhb4691e92020-12-31 12:37:18 -080099ABSL_NAMESPACE_END
Austin Schuh36244a12019-09-21 17:52:38 -0700100} // namespace absl
101
102#endif // ABSL_RANDOM_INTERNAL_RANDEN_H_