QRandomGenerator: let qt_initial_random_value() return 128 bits of data
It's how much there is in Linux's AT_RANDOM block. I've also removed the check for validity. It's highly unlikely that 128 bits are bad. Change-Id: Id2983978ad544ff79911fffd16723161ea7ec315 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
parent
928ce402a4
commit
a5ff71578d
@ -1296,8 +1296,8 @@ quint64 QRandomGenerator::_fillRange(void *buffer, qptrdiff count)
|
|||||||
|
|
||||||
// helper function to call fillBuffer, since we need something to be
|
// helper function to call fillBuffer, since we need something to be
|
||||||
// argument-dependent
|
// argument-dependent
|
||||||
template <typename Generator, typename FillBufferType>
|
template <typename Generator, typename FillBufferType, typename T>
|
||||||
static qsizetype callFillBuffer(FillBufferType f, quintptr *v)
|
static qsizetype callFillBuffer(FillBufferType f, T *v)
|
||||||
{
|
{
|
||||||
if constexpr (std::is_member_function_pointer_v<FillBufferType>) {
|
if constexpr (std::is_member_function_pointer_v<FillBufferType>) {
|
||||||
// member function, need an object
|
// member function, need an object
|
||||||
@ -1318,45 +1318,29 @@ static qsizetype callFillBuffer(FillBufferType f, quintptr *v)
|
|||||||
Note: on some systems, this functionn may rerturn the same value every time
|
Note: on some systems, this functionn may rerturn the same value every time
|
||||||
it is called.
|
it is called.
|
||||||
*/
|
*/
|
||||||
quintptr qt_initial_random_value() noexcept
|
QRandomGenerator::InitialRandomData qt_initial_random_value() noexcept
|
||||||
{
|
{
|
||||||
auto acceptableSeed = [](size_t v) {
|
|
||||||
// two values are reserved: 0 to indicate uninitialized and 1 to
|
|
||||||
// indicate deterministic seed
|
|
||||||
return Q_LIKELY(v > 1);
|
|
||||||
};
|
|
||||||
quintptr v = 0;
|
|
||||||
|
|
||||||
#if QT_CONFIG(getauxval) && defined(AT_RANDOM)
|
#if QT_CONFIG(getauxval) && defined(AT_RANDOM)
|
||||||
// We actually have 16 bytes, but this will do
|
|
||||||
auto at_random_ptr = reinterpret_cast<size_t *>(getauxval(AT_RANDOM));
|
auto at_random_ptr = reinterpret_cast<size_t *>(getauxval(AT_RANDOM));
|
||||||
if (at_random_ptr) {
|
if (at_random_ptr)
|
||||||
v = qFromUnaligned<quintptr>(at_random_ptr);
|
return qFromUnaligned<QRandomGenerator::InitialRandomData>(at_random_ptr);
|
||||||
if (acceptableSeed(v))
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// bypass the hardware RNG, which would mean initializing qsimd.cpp
|
// bypass the hardware RNG, which would mean initializing qsimd.cpp
|
||||||
|
|
||||||
|
QRandomGenerator::InitialRandomData v;
|
||||||
for (int attempts = 16; attempts; --attempts) {
|
for (int attempts = 16; attempts; --attempts) {
|
||||||
using Generator = QRandomGenerator::SystemGenerator;
|
using Generator = QRandomGenerator::SystemGenerator;
|
||||||
auto fillBuffer = &Generator::fillBuffer;
|
auto fillBuffer = &Generator::fillBuffer;
|
||||||
if (callFillBuffer<Generator>(fillBuffer, &v) != sizeof(v))
|
if (callFillBuffer<Generator>(fillBuffer, &v) != sizeof(v))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// check if it is static
|
|
||||||
if (acceptableSeed(v))
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 u32[2] = {};
|
quint32 data[sizeof(v) / sizeof(quint32)];
|
||||||
forever {
|
fallback_fill(data, std::size(data));
|
||||||
fallback_fill(u32, sizeof(v) / sizeof(quint32));
|
memcpy(v.data, data, sizeof(v.data));
|
||||||
v = u32[0] | (quint64(u32[1]) << 32);
|
|
||||||
if (acceptableSeed(v))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +217,10 @@ protected:
|
|||||||
private:
|
private:
|
||||||
Q_CORE_EXPORT quint64 _fillRange(void *buffer, qptrdiff count);
|
Q_CORE_EXPORT quint64 _fillRange(void *buffer, qptrdiff count);
|
||||||
|
|
||||||
friend quintptr qt_initial_random_value() noexcept;
|
struct InitialRandomData {
|
||||||
|
quintptr data[16 / sizeof(quintptr)];
|
||||||
|
};
|
||||||
|
friend InitialRandomData qt_initial_random_value() noexcept;
|
||||||
friend class QRandomGenerator64;
|
friend class QRandomGenerator64;
|
||||||
struct SystemGenerator;
|
struct SystemGenerator;
|
||||||
struct SystemAndGlobalGenerators;
|
struct SystemAndGlobalGenerators;
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "qglobal_p.h"
|
#include "qglobal_p.h"
|
||||||
|
#include <qrandom.h>
|
||||||
#include <private/qsimd_p.h>
|
#include <private/qsimd_p.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -80,7 +81,7 @@ static const struct
|
|||||||
} qt_randomdevice_control;
|
} qt_randomdevice_control;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
quintptr qt_initial_random_value() noexcept;
|
QRandomGenerator::InitialRandomData qt_initial_random_value() noexcept;
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
@ -743,7 +743,8 @@ static size_t qt_create_qhash_seed(HashCreationMode mode)
|
|||||||
}
|
}
|
||||||
seed = 1; // QHashSeed::globalSeed subtracts 1
|
seed = 1; // QHashSeed::globalSeed subtracts 1
|
||||||
} else if (mode == Initial) {
|
} else if (mode == Initial) {
|
||||||
seed = qt_initial_random_value();
|
auto data = qt_initial_random_value();
|
||||||
|
seed = data.data[0] ^ data.data[1];
|
||||||
} else if (sizeof(seed) > sizeof(uint)) {
|
} else if (sizeof(seed) > sizeof(uint)) {
|
||||||
seed = QRandomGenerator::system()->generate64();
|
seed = QRandomGenerator::system()->generate64();
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user