fortuna: add generator service
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
158545f401
commit
3e4fb10414
44
fortuna.cpp
44
fortuna.cpp
|
@ -4,11 +4,13 @@
|
|||
#include "fortuna.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cryptopp/cryptlib.h>
|
||||
#include <fmt/chrono.h>
|
||||
|
||||
namespace fortuna {
|
||||
static constexpr const unsigned int min_pool_size{64};
|
||||
auto now{std::chrono::steady_clock::now()};
|
||||
|
||||
|
||||
Fortuna::Fortuna() {
|
||||
|
@ -17,14 +19,16 @@ namespace fortuna {
|
|||
} catch(CryptoPP::Exception& e) {
|
||||
fmt::print(stderr, "{}\n", e.what());
|
||||
}
|
||||
th_gen = std::thread(generator_service, &R.Gen);
|
||||
}
|
||||
Fortuna::~Fortuna() noexcept {
|
||||
th_gen.join();
|
||||
}
|
||||
Fortuna::~Fortuna() = default;
|
||||
|
||||
|
||||
auto Fortuna::random_data(unsigned int n_bytes) -> void {
|
||||
const auto start{std::chrono::system_clock::now()};
|
||||
fmt::print("random_data starting - {}\n", start);
|
||||
auto now{std::chrono::steady_clock::now()};
|
||||
auto elapsed {
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch() -
|
||||
|
@ -32,8 +36,12 @@ namespace fortuna {
|
|||
)
|
||||
};
|
||||
fmt::print("last_reseed: {} ago\n", elapsed);
|
||||
const int pools_to_use{ffsll(static_cast<int>(get_reseed_ctr()))};
|
||||
now = std::chrono::steady_clock::now();
|
||||
std::string s;
|
||||
// synchronise reads and writes to the between
|
||||
// {generator,accumulator,fortuna} service threads
|
||||
std::lock_guard<std::mutex> lg(mtx);
|
||||
const int pools_to_use{ffsll(static_cast<int>(get_reseed_ctr()))};
|
||||
|
||||
if (R.pools[0].get_s_length() >= min_pool_size && elapsed > R.Gen.reseed_interval) {
|
||||
for (int i = 0; i < static_cast<int>(pools_to_use); ++i) {
|
||||
|
@ -52,10 +60,15 @@ namespace fortuna {
|
|||
s.clear();
|
||||
}
|
||||
|
||||
std::string n{R.Gen.generate_random_data(n_bytes)};
|
||||
fmt::print("got you {} proper bytes from generate_random_data -> {}\n",
|
||||
n_bytes, n);
|
||||
n.clear();
|
||||
if (R.reseed_ctr == 0) {
|
||||
fmt::print("reseed ctr is 0, PRNG not seeded!\n");
|
||||
throw std::runtime_error("illegal state, PRNG not seeded");
|
||||
} else {
|
||||
std::string n{R.Gen.generate_random_data(n_bytes)};
|
||||
fmt::print("got you {} proper bytes from generate_random_data -> {}\n",
|
||||
n_bytes, n);
|
||||
n.clear();
|
||||
}
|
||||
|
||||
const auto end{std::chrono::system_clock::now()};
|
||||
std::chrono::duration<float> diff = end-start;
|
||||
|
@ -63,6 +76,23 @@ namespace fortuna {
|
|||
fmt::print("getting random data took {:.{}f}s\n", diff.count(), 12);
|
||||
} //random_data
|
||||
|
||||
auto Fortuna::generator_service(fortuna::generator::Generator* Gen) -> void {
|
||||
fmt::print("[i] fortuna: starting generator service\n");
|
||||
int i{0};
|
||||
uint sleep_time{1000}; // in ms
|
||||
auto now{fortuna::Util::current_time()};
|
||||
|
||||
while(true) {
|
||||
fmt::print("sleeping [{}]\n", i);
|
||||
++i;
|
||||
now = fortuna::Util::current_time();
|
||||
fmt::print("[*] g: @{}\n", now);
|
||||
std::this_thread::sleep_until(
|
||||
now + std::chrono::milliseconds(sleep_time)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fortuna
|
||||
|
||||
#endif//FORTUNA_FORTUNA_CPP
|
||||
|
|
16
fortuna.h
16
fortuna.h
|
@ -7,6 +7,8 @@
|
|||
#include <fmt/core.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
namespace fortuna {
|
||||
|
||||
|
@ -15,9 +17,11 @@ public:
|
|||
// in microseconds
|
||||
static constexpr const unsigned int reseed_interval{10000};
|
||||
static constexpr const char num_of_pools{32};
|
||||
std::mutex mtx;
|
||||
std::thread th_gen;
|
||||
|
||||
Fortuna();
|
||||
~Fortuna();
|
||||
~Fortuna() noexcept;
|
||||
|
||||
auto random_data(unsigned int) -> void;
|
||||
|
||||
|
@ -36,17 +40,27 @@ public:
|
|||
auto initialize_prng() -> void {
|
||||
// TODO(me): handle the reseeds here as per Cryptography Engineering,
|
||||
// p. 153
|
||||
std::lock_guard<std::mutex> lg(mtx);
|
||||
set_reseed_ctr_to_null();
|
||||
try {
|
||||
R.initialize_pools();
|
||||
fmt::print("pools initialized\n");
|
||||
accumulator.set_gen(R.Gen);
|
||||
// FIXME: bogus first reseed here, P_0 definitely hasn't collected
|
||||
// enough entropy by now
|
||||
incr_reseed_ctr();
|
||||
fmt::print("first reseed\n");
|
||||
R.Gen.reseed("fortuna");
|
||||
} catch(std::exception& e) {
|
||||
fmt::print("{}\n", e.what());
|
||||
}
|
||||
fmt::print("PRNG initialized\n");
|
||||
}
|
||||
|
||||
static auto generator_service(fortuna::generator::Generator*) -> void;
|
||||
|
||||
static auto seed_file_manager_service() -> void;
|
||||
|
||||
// PRNG state
|
||||
class R_state {
|
||||
friend fortuna::Fortuna;
|
||||
|
|
10
main.cpp
10
main.cpp
|
@ -1,10 +1,20 @@
|
|||
#include "fortuna.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
int main() {
|
||||
fmt::print("[*] doing evil stuff\n");
|
||||
fortuna::Fortuna f;
|
||||
try {
|
||||
f.random_data(4); // number of bytes requested
|
||||
using std::chrono_literals::operator""ms;
|
||||
std::this_thread::sleep_for(1000ms);
|
||||
f.random_data(4);
|
||||
std::this_thread::sleep_for(120ms);
|
||||
f.random_data(3);
|
||||
f.random_data(3);
|
||||
std::this_thread::sleep_for(10ms);
|
||||
f.random_data(3);
|
||||
} catch (std::exception& e) {
|
||||
fmt::print("[!] exiting due to \"{}\"\n", e.what());
|
||||
exit(0);
|
||||
|
|
Reference in New Issue