randen.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // 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. #ifndef ABSL_RANDOM_INTERNAL_RANDEN_H_
  15. #define ABSL_RANDOM_INTERNAL_RANDEN_H_
  16. #include <cstddef>
  17. #include "absl/random/internal/platform.h"
  18. #include "absl/random/internal/randen_hwaes.h"
  19. #include "absl/random/internal/randen_slow.h"
  20. #include "absl/random/internal/randen_traits.h"
  21. namespace absl {
  22. ABSL_NAMESPACE_BEGIN
  23. namespace random_internal {
  24. // RANDen = RANDom generator or beetroots in Swiss German.
  25. // 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
  26. // generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
  27. //
  28. // Randen implements the basic state manipulation methods.
  29. class Randen {
  30. public:
  31. static constexpr size_t kStateBytes = RandenTraits::kStateBytes;
  32. static constexpr size_t kCapacityBytes = RandenTraits::kCapacityBytes;
  33. static constexpr size_t kSeedBytes = RandenTraits::kSeedBytes;
  34. ~Randen() = default;
  35. Randen();
  36. // Generate updates the randen sponge. The outer portion of the sponge
  37. // (kCapacityBytes .. kStateBytes) may be consumed as PRNG state.
  38. template <typename T, size_t N>
  39. void Generate(T (&state)[N]) const {
  40. static_assert(N * sizeof(T) == kStateBytes,
  41. "Randen::Generate() requires kStateBytes of state");
  42. #if ABSL_RANDOM_INTERNAL_AES_DISPATCH
  43. // HW AES Dispatch.
  44. if (has_crypto_) {
  45. RandenHwAes::Generate(keys_, state);
  46. } else {
  47. RandenSlow::Generate(keys_, state);
  48. }
  49. #elif ABSL_HAVE_ACCELERATED_AES
  50. // HW AES is enabled.
  51. RandenHwAes::Generate(keys_, state);
  52. #else
  53. // HW AES is disabled.
  54. RandenSlow::Generate(keys_, state);
  55. #endif
  56. }
  57. // Absorb incorporates additional seed material into the randen sponge. After
  58. // absorb returns, Generate must be called before the state may be consumed.
  59. template <typename S, size_t M, typename T, size_t N>
  60. void Absorb(const S (&seed)[M], T (&state)[N]) const {
  61. static_assert(M * sizeof(S) == RandenTraits::kSeedBytes,
  62. "Randen::Absorb() requires kSeedBytes of seed");
  63. static_assert(N * sizeof(T) == RandenTraits::kStateBytes,
  64. "Randen::Absorb() requires kStateBytes of state");
  65. #if ABSL_RANDOM_INTERNAL_AES_DISPATCH
  66. // HW AES Dispatch.
  67. if (has_crypto_) {
  68. RandenHwAes::Absorb(seed, state);
  69. } else {
  70. RandenSlow::Absorb(seed, state);
  71. }
  72. #elif ABSL_HAVE_ACCELERATED_AES
  73. // HW AES is enabled.
  74. RandenHwAes::Absorb(seed, state);
  75. #else
  76. // HW AES is disabled.
  77. RandenSlow::Absorb(seed, state);
  78. #endif
  79. }
  80. private:
  81. const void* keys_;
  82. #if ABSL_RANDOM_INTERNAL_AES_DISPATCH
  83. bool has_crypto_;
  84. #endif
  85. };
  86. } // namespace random_internal
  87. ABSL_NAMESPACE_END
  88. } // namespace absl
  89. #endif // ABSL_RANDOM_INTERNAL_RANDEN_H_