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