rand/rdrand: add rdrand generator
This commit is contained in:
parent
3a83851e90
commit
f86989bc67
@ -440,6 +440,8 @@ list (
|
||||
rand/mwc64x.hpp
|
||||
rand/pcg.cpp
|
||||
rand/pcg.hpp
|
||||
rand/rdrand.cpp
|
||||
rand/rdrand.hpp
|
||||
rand/system.hpp
|
||||
random.cpp
|
||||
random.hpp
|
||||
|
44
rand/rdrand.cpp
Normal file
44
rand/rdrand.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "rdrand.hpp"
|
||||
|
||||
using cruft::rand::rdrand;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
rdrand::rdrand ()
|
||||
{ ; }
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
rdrand::rdrand (std::string const &)
|
||||
: rdrand ()
|
||||
{ ; }
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
rdrand::result_type
|
||||
rdrand::operator() ()
|
||||
{
|
||||
uint64_t res;
|
||||
char success;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"rdrand %0;"
|
||||
"setc %1;"
|
||||
|
||||
: "=r" (res)
|
||||
, "=qm" (success)
|
||||
);
|
||||
|
||||
if (!__builtin_expect(success, 1))
|
||||
throw std::runtime_error ("no value available for rdrand");
|
||||
|
||||
return res;
|
||||
}
|
40
rand/rdrand.hpp
Normal file
40
rand/rdrand.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../posix/fd.hpp"
|
||||
|
||||
|
||||
namespace cruft::rand {
|
||||
/// Models std::random_device and is suitable as a drop-in replacement.
|
||||
///
|
||||
/// This implementation assumes that the CPU supports the `rdrand`
|
||||
/// instruction, and does not check that this is the case.
|
||||
///
|
||||
/// It is safe to instantiatate the object even if the instructions are
|
||||
/// not supported, but it is the users responsibility to prevent calls to
|
||||
/// the object if this is not the case.
|
||||
class rdrand {
|
||||
public:
|
||||
using result_type = unsigned;
|
||||
|
||||
rdrand ();
|
||||
rdrand (std::string const&);
|
||||
rdrand (rdrand const &) = delete;
|
||||
|
||||
rdrand& operator= (rdrand const&) = delete;
|
||||
|
||||
result_type operator() (void);
|
||||
|
||||
double entropy (void) const noexcept;
|
||||
|
||||
static constexpr result_type min (void) { return std::numeric_limits<result_type>::min (); }
|
||||
static constexpr result_type max (void) { return std::numeric_limits<result_type>::max (); }
|
||||
};
|
||||
}
|
@ -55,6 +55,7 @@ main (int,char**)
|
||||
test_buckets<cruft::rand::mwc64x> (tap, 0x1234u);
|
||||
test_buckets<cruft::rand::pcg_xsh_rr<>> (tap, 0x1234u);
|
||||
test_buckets<cruft::rand::system> (tap);
|
||||
test_buckets<cruft::rand::rdrand> (tap);
|
||||
|
||||
return tap.status ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user