My Project 3.2.0
C++ Distributed Hash Table
Loading...
Searching...
No Matches
rng.h
1/*
2 * Copyright (C) 2014-2023 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#include <thread>
25#include <stdexcept>
26
27namespace dht {
28namespace crypto {
29
33template<class T = std::mt19937, std::size_t N = T::state_size+1>
34auto getSeededRandomEngine() -> typename std::enable_if<!!N, T>::type {
35 std::array<typename T::result_type, N> random_data;
36 constexpr auto gen = [](std::random_device& source) -> typename T::result_type {
37 for (unsigned j=0; j<64; j++) {
38 try {
39 return source();
40 } catch (...) {
41 std::this_thread::sleep_for(std::chrono::microseconds(500));
42 }
43 }
44 throw std::runtime_error("Can't generate random number");
45 };
46 for (unsigned i=0; i<8; i++) {
47 try {
48 std::random_device source;
49 for (auto& r : random_data)
50 r = gen(source);
51 std::seed_seq seed(
52 (std::seed_seq::result_type*)random_data.data(),
53 (std::seed_seq::result_type*)(random_data.data() + random_data.size()));
54 return T(seed);
55 } catch (...) {
56 std::this_thread::sleep_for(std::chrono::microseconds(500));
57 }
58 }
59 throw std::runtime_error("Can't seed random seed");
60}
61
65template<class T = std::mt19937, std::size_t N = T::state_size+1>
66auto getDerivedRandomEngine(T& source) -> typename std::enable_if<!!N, T>::type {
67 std::array<typename T::result_type, N> random_data;
68 std::generate(random_data.begin(), random_data.end(), std::ref(source));
69 std::seed_seq seed(
70 (std::seed_seq::result_type*)random_data.data(),
71 (std::seed_seq::result_type*)(random_data.data() + random_data.size()));
72 return T(seed);
73}
74
75}} // dht::crypto
auto getDerivedRandomEngine(T &source) -> typename std::enable_if<!!N, T >::type
Definition rng.h:66
auto getSeededRandomEngine() -> typename std::enable_if<!!N, T >::type
Definition rng.h:34