summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorNils Maier <maierman@web.de>2014-12-30 18:17:44 +0100
committerNils Maier <maierman@web.de>2015-01-20 22:37:24 +0100
commit81bdd5f61a8f8da53e22d68190be700902b7dbae (patch)
treef706934a5e5e208d8d09490d216fe03f10b38654 /test
parent747131a06c1f1d92a5312a103f4446fabedb6cf7 (diff)
Revise getRandom facilities
Use one of the following to provide random bytes: - Windows CryptGenRandom - Linux getrandom (syscall interface to urandom, without nasty corner cases such as file descriptor exhaustion or re-linked /dev/urandom) - std::device_random (C++ random device, which usually will be urandom) This also equalizes util::getRandom and SimpleRandomizer (the former will now use the latter) instead of having essentially two different PRNG interfaces with potentially different quality. Closes GH-320
Diffstat (limited to 'test')
-rw-r--r--test/UtilTest.cc48
1 files changed, 46 insertions, 2 deletions
diff --git a/test/UtilTest.cc b/test/UtilTest.cc
index 65b1d9c5..513aeefc 100644
--- a/test/UtilTest.cc
+++ b/test/UtilTest.cc
@@ -1,5 +1,6 @@
#include "util.h"
+#include <cmath>
#include <cstring>
#include <string>
#include <iostream>
@@ -1954,11 +1955,54 @@ void UtilTest::testCreateIndexPaths()
void UtilTest::testGenerateRandomData()
{
- unsigned char data1[20];
+ using namespace std;
+
+ // Simple sanity check
+ unsigned char data1[25];
+ memset(data1, 0, sizeof(data1));
util::generateRandomData(data1, sizeof(data1));
- unsigned char data2[20];
+
+ unsigned char data2[25];
+ memset(data2, 0, sizeof(data2));
util::generateRandomData(data2, sizeof(data2));
+
CPPUNIT_ASSERT(memcmp(data1, data2, sizeof(data1)) != 0);
+
+ // Simple stddev/mean tests
+ map<uint8_t, size_t> counts;
+ uint8_t bytes[1 << 20];
+ for (auto i = 0; i < 10; ++i) {
+ util::generateRandomData(bytes, sizeof(bytes));
+ for (auto b : bytes) {
+ counts[b]++;
+ }
+ }
+ CPPUNIT_ASSERT_MESSAGE("Should see all kinds of bytes", counts.size() == 256);
+ if (counts.size() != 256) {
+ throw std::domain_error(
+ "Would have expected to see at one of each possible byte value!");
+ }
+ double sum = accumulate(
+ counts.begin(),
+ counts.end(),
+ 0.0,
+ [](double total, const decltype(counts)::value_type & elem) {
+ return total + elem.second;
+ });
+ double mean = sum / counts.size();
+ vector<double> diff(counts.size());
+ transform(
+ counts.begin(),
+ counts.end(),
+ diff.begin(),
+ [&](const decltype(counts)::value_type & elem) -> double {
+ return (double)elem.second - mean;
+ });
+ double sq_sum = inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
+ double stddev = sqrt(sq_sum / counts.size());
+ cout << "stddev: " << fixed << stddev << endl;
+ CPPUNIT_ASSERT_MESSAGE("stddev makes sense (lower)", stddev <= 320);
+ CPPUNIT_ASSERT_MESSAGE("stddev makes sense (upper)", stddev >= 100);
}
void UtilTest::testFromHex()