Skip to content
/ qTox Public
forked from qTox/qTox

Commit

Permalink
fix: Usage of random
Browse files Browse the repository at this point in the history
- Seed random in Core Thread. Core Thread didn't seed random, resulting
  in always using the same bootstrap nodes, even when you restart qTox
  or change profiles.

- Use QDateTime::currentMSecsSinceEpoch() for seeding random. It
  provides a bigger range of numbers than QTime::currentTime().msec()
  does, and the latter somehow managed to result in approximately the
  same first random number being generated, within a certain range.

- Use something a it more sensible than a mod operation to bound random
  numbers within a range. It's not perfect either, but a lot better.
  Using mod on random skews its distribution too much.

- Use QRandomGenerator's bounded() function to generate random values
  within a range.

- Enable QRandomGenerator's usage starting with Qt 5.10.0.
  QRandomGenerator is present since Qt 5.10.0, not 5.15.0.

- Bootstrap off every 5th node instead of two consecutive nodes. It's
  likely that two consecutive nodes will have the same owner, which
  makes some attacks more likely. The node selection algorithm should be
  scraped and redone from scratch to be honest though.
  • Loading branch information
nurupo committed Jun 4, 2020
1 parent 9da1e3b commit f5f4223
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
17 changes: 12 additions & 5 deletions src/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
#include "util/strongtype.h"

#include <QCoreApplication>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
#include <QRandomGenerator>
#else
#include <QDateTime>
#endif
#include <QRegularExpression>
#include <QString>
Expand Down Expand Up @@ -667,6 +669,10 @@ void Core::onStarted()
{
ASSERT_CORE_THREAD;

#if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch()));
#endif

// One time initialization stuff
QString name = getUsername();
if (!name.isEmpty()) {
Expand Down Expand Up @@ -795,10 +801,10 @@ void Core::bootstrapDht()
}

int i = 0;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
static int j = QRandomGenerator::global()->generate() % listSize;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
static int j = QRandomGenerator::global()->bounded(listSize);
#else
static int j = qrand() % listSize;
static int j = static_cast<int>((static_cast<double>(qrand()) / static_cast<double>(RAND_MAX+1l)) * listSize);
#endif
// i think the more we bootstrap, the more we jitter because the more we overwrite nodes
while (i < 2) {
Expand Down Expand Up @@ -827,7 +833,8 @@ void Core::bootstrapDht()
PARSE_ERR(error);
}

++j;
// bootstrap off every 5th node (+ a special case to avoid cycles when listSize % 5 == 0)
j += 5 + !(listSize % 5);
++i;
}
}
Expand Down
23 changes: 11 additions & 12 deletions src/widget/form/settings/privacyform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
#include <QDebug>
#include <QFile>
#include <QMessageBox>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
#include <QRandomGenerator>
#else
#include <QDateTime>
#endif

#include "src/core/core.h"
Expand Down Expand Up @@ -102,19 +104,16 @@ void PrivacyForm::showEvent(QShowEvent*)

void PrivacyForm::on_randomNosapamButton_clicked()
{
QTime time = QTime::currentTime();
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
QRandomGenerator(static_cast<uint>(time.msec()));
#else
qsrand(static_cast<uint>(time.msec()));
#endif

uint32_t newNospam{0};
for (int i = 0; i < 4; ++i)
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
newNospam = (newNospam << 8) + (QRandomGenerator::global()->generate() % 256); // Generate byte by byte. For some reason.

#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
// guarantees to give a random 32-bit unsigned integer
newNospam = QRandomGenerator::global()->generate();
#else
newNospam = (newNospam << 8) + (qrand() % 256); // Generate byte by byte. For some reason.
qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch()));
for (int i = 0; i < 4; ++i)
// Generate byte by byte, as qrand() is guaranteed to have only 15 bits of randomness (RAND_MAX is guaranteed to be 2^15)
newNospam = (newNospam << 8) + (static_cast<int>((static_cast<double>(qrand()) / static_cast<double>(RAND_MAX+1l)) * 256));
#endif

core->setNospam(newNospam);
Expand Down

0 comments on commit f5f4223

Please sign in to comment.