randen.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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 High 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. // REQUIRES: state points to kStateBytes of state.
  39. inline void Generate(void* state) const {
  40. #if ABSL_RANDOM_INTERNAL_AES_DISPATCH
  41. // HW AES Dispatch.
  42. if (has_crypto_) {
  43. RandenHwAes::Generate(keys_, state);
  44. } else {
  45. RandenSlow::Generate(keys_, state);
  46. }
  47. #elif ABSL_HAVE_ACCELERATED_AES
  48. // HW AES is enabled.
  49. RandenHwAes::Generate(keys_, state);
  50. #else
  51. // HW AES is disabled.
  52. RandenSlow::Generate(keys_, state);
  53. #endif
  54. }
  55. // Absorb incorporates additional seed material into the randen sponge. After
  56. // absorb returns, Generate must be called before the state may be consumed.
  57. // REQUIRES: seed points to kSeedBytes of seed.
  58. // REQUIRES: state points to kStateBytes of state.
  59. inline void Absorb(const void* seed, void* state) const {
  60. #if ABSL_RANDOM_INTERNAL_AES_DISPATCH
  61. // HW AES Dispatch.
  62. if (has_crypto_) {
  63. RandenHwAes::Absorb(seed, state);
  64. } else {
  65. RandenSlow::Absorb(seed, state);
  66. }
  67. #elif ABSL_HAVE_ACCELERATED_AES
  68. // HW AES is enabled.
  69. RandenHwAes::Absorb(seed, state);
  70. #else
  71. // HW AES is disabled.
  72. RandenSlow::Absorb(seed, state);
  73. #endif
  74. }
  75. private:
  76. const void* keys_;
  77. #if ABSL_RANDOM_INTERNAL_AES_DISPATCH
  78. bool has_crypto_;
  79. #endif
  80. };
  81. } // namespace random_internal
  82. ABSL_NAMESPACE_END
  83. } // namespace absl
  84. #endif // ABSL_RANDOM_INTERNAL_RANDEN_H_