Crypto++  7.0
Free C++ class library of cryptographic schemes
rdrand.h
Go to the documentation of this file.
1 // rdrand.h - written and placed in public domain by Jeffrey Walton and Uri Blumenthal.
2 
3 /// \file rdrand.h
4 /// \brief Classes for RDRAND and RDSEED
5 /// \since Crypto++ 5.6.3
6 
7 #ifndef CRYPTOPP_RDRAND_H
8 #define CRYPTOPP_RDRAND_H
9 
10 #include "cryptlib.h"
11 
12 // This class file provides both RDRAND and RDSEED. They were added at
13 // Crypto++ 5.6.3. At compile time, it uses CRYPTOPP_BOOL_{X86|X32|X64}
14 // to select an implementation or "throw NotImplemented". At runtime the
15 // constructor will throw RDRAND_Err or RDSEED_Err if a generator is
16 // is not available.
17 // The original classes accepted a retry count. Retries were superflous for
18 // RDRAND, and RDSEED encountered a failure about 1 in 256 bytes depending
19 // on the processor. Retries were removed at Crypto++ 6.0 because
20 // GenerateBlock unconditionally retries and always fulfills the request.
21 
22 // Throughput varies wildly depending on processor and manufacturer. A Core i5 or
23 // Core i7 RDRAND can generate at over 200 MiB/s. Its below the theroetical
24 // maximum, but it takes about 5 instructions to generate, retry and store a
25 // result. A low-end Celeron may perform RDRAND at about 7 MiB/s. RDSEED
26 // performs at about 1/4 to 1/2 the rate of RDRAND. AMD RDRAND performed poorly
27 // during testing with Athlon X4 845. The Bulldozer v4 only performed at 1 MiB/s.
28 
29 // Microsoft added RDRAND in August 2012, VS2012; RDSEED in October 2013, VS2013.
30 // GCC added RDRAND in December 2010, GCC 4.6. LLVM added RDRAND in July 2012,
31 // Clang 3.2. Intel added RDRAND in September 2011, ICC 12.1.
32 
33 NAMESPACE_BEGIN(CryptoPP)
34 
35 /// \brief Exception thrown when a RDRAND generator encounters
36 /// a generator related error.
37 /// \since Crypto++ 5.6.3
38 class RDRAND_Err : public Exception
39 {
40 public:
41  RDRAND_Err(const std::string &operation)
42  : Exception(OTHER_ERROR, "RDRAND: " + operation + " operation failed") {}
43 };
44 
45 /// \brief Hardware generated random numbers using RDRAND instruction
46 /// \sa MaurerRandomnessTest() for random bit generators
47 /// \since Crypto++ 5.6.3
49 {
50 public:
51  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "RDRAND"; }
52 
53  virtual ~RDRAND() {}
54 
55  /// \brief Construct a RDRAND generator
56  /// \details According to DJ of Intel, the Intel RDRAND circuit does not underflow.
57  /// If it did hypothetically underflow, then it would return 0 for the random value.
58  /// AMD's RDRAND implementation appears to provide the same behavior.
59  /// \throws RDRAND_Err if the random number generator is not available
60  RDRAND();
61 
62  /// \brief Generate random array of bytes
63  /// \param output the byte buffer
64  /// \param size the length of the buffer, in bytes
65  virtual void GenerateBlock(byte *output, size_t size);
66 
67  /// \brief Generate and discard n bytes
68  /// \param n the number of bytes to generate and discard
69  /// \details the RDSEED generator discards words, not bytes. If n is
70  /// not a multiple of a machine word, then it is rounded up to
71  /// that size.
72  virtual void DiscardBytes(size_t n);
73 
74  /// \brief Update RNG state with additional unpredictable values
75  /// \param input unused
76  /// \param length unused
77  /// \details The operation is a nop for this generator.
78  virtual void IncorporateEntropy(const byte *input, size_t length)
79  {
80  // Override to avoid the base class' throw.
81  CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length);
82  }
83 };
84 
85 /// \brief Exception thrown when a RDSEED generator encounters
86 /// a generator related error.
87 /// \since Crypto++ 5.6.3
88 class RDSEED_Err : public Exception
89 {
90 public:
91  RDSEED_Err(const std::string &operation)
92  : Exception(OTHER_ERROR, "RDSEED: " + operation + " operation failed") {}
93 };
94 
95 /// \brief Hardware generated random numbers using RDSEED instruction
96 /// \sa MaurerRandomnessTest() for random bit generators
97 /// \since Crypto++ 5.6.3
99 {
100 public:
101  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "RDSEED"; }
102 
103  virtual ~RDSEED() {}
104 
105  /// \brief Construct a RDSEED generator
106  /// \details Empirical testing under a 6th generaton i7 (6200U) shows RDSEED fails
107  /// to fulfill requests at about once every for every 256 bytes requested.
108  /// The generator runs about 4 times slower than RDRAND.
109  /// \throws RDSEED_Err if the random number generator is not available
110  RDSEED();
111 
112  /// \brief Generate random array of bytes
113  /// \param output the byte buffer
114  /// \param size the length of the buffer, in bytes
115  virtual void GenerateBlock(byte *output, size_t size);
116 
117  /// \brief Generate and discard n bytes
118  /// \param n the number of bytes to generate and discard
119  /// \details the RDSEED generator discards words, not bytes. If n is
120  /// not a multiple of a machine word, then it is rounded up to
121  /// that size.
122  virtual void DiscardBytes(size_t n);
123 
124  /// \brief Update RNG state with additional unpredictable values
125  /// \param input unused
126  /// \param length unused
127  /// \details The operation is a nop for this generator.
128  virtual void IncorporateEntropy(const byte *input, size_t length)
129  {
130  // Override to avoid the base class' throw.
131  CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length);
132  }
133 };
134 
135 NAMESPACE_END
136 
137 #endif // CRYPTOPP_RDRAND_H
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:155
Hardware generated random numbers using RDRAND instruction.
Definition: rdrand.h:48
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: rdrand.h:128
Abstract base classes that provide a uniform interface to this library.
Interface for random number generators.
Definition: cryptlib.h:1330
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: rdrand.h:78
Exception thrown when a RDRAND generator encounters a generator related error.
Definition: rdrand.h:38
virtual void DiscardBytes(size_t n)
Generate and discard n bytes.
Definition: rdrand.cpp:263
Hardware generated random numbers using RDSEED instruction.
Definition: rdrand.h:98
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: rdrand.cpp:215
Crypto++ library namespace.
Exception thrown when a RDSEED generator encounters a generator related error.
Definition: rdrand.h:88
RDRAND()
Construct a RDRAND generator.
Definition: rdrand.cpp:209