My Project 1.7.4
C++ Distributed Hash Table
rng.h
1/*
2 * Copyright (C) 2014-2017 Savoir-faire Linux Inc.
3 * Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include <random>
22#include <algorithm>
23#include <functional>
24
25namespace dht {
26namespace crypto {
27
28#ifndef _MSC_VER
29#ifdef _WIN32
30
35class random_device {
36public:
37 using result_type = std::random_device::result_type;
38 using pseudo_engine = std::mt19937_64;
39
45 static_assert(
46 sizeof(result_type) == 2 ||
47 sizeof(result_type) == 4 ||
48 sizeof(result_type) == 8,
49 "result_type must be 16, 32 or 64 bits");
50
51 random_device();
52
53 result_type operator()();
54
55 static constexpr result_type min() {
56 return std::numeric_limits<result_type>::lowest();
57 }
58
59 static constexpr result_type max() {
60 return std::numeric_limits<result_type>::max();
61 }
62
63 double entropy() const {
64 if (hasRdrand() or hasRdseed())
65 return 1.;
66 return 0.;
67 }
68
69 static bool hasRdrand() {
70 static const bool hasrdrand = _hasRdrand();
71 return hasrdrand;
72 }
73
74 static bool hasRdseed() {
75 static const bool hasrdseed = _hasRdseed();
76 return hasrdseed;
77 }
78
79private:
80 random_device& operator=(random_device&) = delete;
81
82 pseudo_engine gen;
83 std::uniform_int_distribution<result_type> dis {};
84
85 static bool hasIntelCpu();
86 static bool _hasRdrand();
87 static bool _hasRdseed();
88
89 struct CPUIDinfo {
90 unsigned int EAX;
91 unsigned int EBX;
92 unsigned int ECX;
93 unsigned int EDX;
94 CPUIDinfo(const unsigned int func, const unsigned int subfunc);
95 };
96 bool rdrandStep(result_type* r);
97 bool rdrand(result_type* r);
98 bool rdseedStep(result_type* r);
99 bool rdseed(result_type* r);
100};
101
102#else
103
104using random_device = std::random_device;
105
106#endif
107#else
108using random_device = std::random_device;
109#endif
110
111template<class T = std::mt19937, std::size_t N = T::state_size>
112auto getSeededRandomEngine () -> typename std::enable_if<!!N, T>::type {
113 typename T::result_type random_data[N];
114 random_device source;
115 std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
116 std::seed_seq seeds(std::begin(random_data), std::end(random_data));
117 T seededEngine (seeds);
118 return seededEngine;
119}
120
121}} // dht::crypto
Definition: callbacks.h:34