MCPcopy Create free account
hub / github.com/ElementsProject/elements / GetRdRand

Function GetRdRand

src/random.cpp:110–139  ·  view source on GitHub ↗

Read 64 bits of entropy using rdrand. * * Must only be called when RdRand is supported. */

Source from the content-addressed store, hash-verified

108 * Must only be called when RdRand is supported.
109 */
110static uint64_t GetRdRand() noexcept
111{
112 // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce this risk.
113#ifdef __i386__
114 uint8_t ok;
115 // Initialize to 0 to silence a compiler warning that r1 or r2 may be used
116 // uninitialized. Even if rdrand fails (!ok) it will set the output to 0,
117 // but there is no way that the compiler could know that.
118 uint32_t r1 = 0, r2 = 0;
119 for (int i = 0; i < 10; ++i) {
120 __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %eax
121 if (ok) break;
122 }
123 for (int i = 0; i < 10; ++i) {
124 __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r2), "=q"(ok) :: "cc"); // rdrand %eax
125 if (ok) break;
126 }
127 return (((uint64_t)r2) << 32) | r1;
128#elif defined(__x86_64__) || defined(__amd64__)
129 uint8_t ok;
130 uint64_t r1 = 0; // See above why we initialize to 0.
131 for (int i = 0; i < 10; ++i) {
132 __asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %rax
133 if (ok) break;
134 }
135 return r1;
136#else
137#error "RdRand is only supported on x86 and x86_64"
138#endif
139}
140
141/** Read 64 bits of entropy using rdseed.
142 *

Callers 2

SeedHardwareFastFunction · 0.85
SeedHardwareSlowFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected