handle PRNG state in R_state + accumulator basis

* handle the PRNG state with R_state nested class
* add a private property R holding PRNG state to Fortuna
* add R_state properties as defined in Cryptography Engineering:
  * a generator instance
  * a reseed counter
  * 32 pools that the collected entropy is to be distributed over

* add initial definition of the Pool object and its initialization

* attempt to initialize PRNG in Fortuna constructor. wrap the
  initialization call in a try-catch block like a cultured person
* erase the string used to print data from random_data() after it's been
  used
This commit is contained in:
surtur 2021-12-04 00:19:22 +01:00
parent 72bb378709
commit a1cbbb209e
Signed by: wanderer
GPG Key ID: 19CE1EC1D9E0486D
7 changed files with 136 additions and 9 deletions

View File

@ -175,7 +175,7 @@ add_subdirectory(lib/fmt EXCLUDE_FROM_ALL)
endif(NOT CMAKE_EXE_LINKER_FLAGS MATCHES "-fuse-ld=lld")
endif()
add_executable(fortuna main.cpp generator.cpp generator.h fortuna.cpp fortuna.h)
add_executable(fortuna main.cpp generator.cpp generator.h fortuna.cpp fortuna.h accumulator.cpp accumulator.h pool.cpp pool.h)
# ref: https://cmake.org/pipermail/cmake/2016-May/063400.html
target_link_libraries(fortuna
PRIVATE cryptopp

12
accumulator.cpp Normal file
View File

@ -0,0 +1,12 @@
#ifndef FORTUNA_ACCUMULATOR_CPP
#define FORTUNA_ACCUMULATOR_CPP
#include "accumulator.h"
namespace fortuna {
namespace accumulator {
} //namespace accumulator
} //namespace fortuna
#endif//FORTUNA_ACCUMULATOR_CPP

17
accumulator.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef FORTUNA_ACCUMULATOR_H
#define FORTUNA_ACCUMULATOR_H
#include "pool.h"
namespace fortuna {
namespace accumulator {
class Accumulator {
public:
unsigned int init_pool_num{0};
}; //class Accumulator
} //namespace accumulator
} //namespace fortuna
#endif//FORTUNA_ACCUMULATOR_H

View File

@ -3,6 +3,7 @@
#include "fortuna.h"
#include <cryptopp/cryptlib.h>
#include <cryptopp/osrng.h>
#include <cryptopp/hex.h>
#include <cryptopp/filters.h>
@ -10,20 +11,22 @@
#include <cryptopp/ccm.h>
#include <fmt/core.h>
#include <cassert>
#include <cstring>
namespace fortuna {
Fortuna::Fortuna(){
try {
initialize_prng();
} catch(CryptoPP::Exception& e) {
fmt::print(stderr, "{}\n", e.what());
}
}
Fortuna::~Fortuna() = default;
auto Fortuna::random_data(unsigned int n_bytes) -> void {
std::string n{gen.generate_random_data(n_bytes)};
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.erase();
} //random_data
} // namespace fortuna

View File

@ -2,17 +2,66 @@
#define FORTUNA_FORTUNA_H
#include "generator.h"
#include "accumulator.h"
#include <fmt/core.h>
namespace fortuna {
class Fortuna {
public:
// in microseconds
static constexpr const unsigned int reseed_interval{10000};
static constexpr const char num_of_pools{32};
Fortuna();
~Fortuna();
auto random_data(unsigned int) -> void;
private:
generator::Generator gen;
};
auto set_reseed_ctr_to_null() -> void {
Fortuna::R.null_da_ctr();
}
auto initialize_prng() -> void {
// TODO(me): handle the reseeds here as per Cryptography Engineering,
// p. 153
set_reseed_ctr_to_null();
R.initialize_pools();
fmt::print("PRNG initialized\n");
};
// PRNG state
class R_state {
friend fortuna::Fortuna;
public:
R_state(){};
~R_state() = default;
protected:
auto null_da_ctr() -> void {
reseed_ctr = 0x00;
fmt::print("reseed_ctr set to 0x00\n");
}
auto initialize_pools() -> void {
for (unsigned int i = 0; i < num_of_pools; ++i) {
pools[i].initialize_pool(i);
}
}
private:
generator::Generator Gen;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
unsigned __int128 reseed_ctr;
#pragma GCC diagnostic pop
accumulator::Pool pools[num_of_pools];
}; // class R_state
fortuna::Fortuna::R_state R;
}; // class Fortuna
} // namespace fortuna

12
pool.cpp Normal file
View File

@ -0,0 +1,12 @@
#ifndef FORTUNA_POOL_CPP
#define FORTUNA_POOL_CPP
#include "pool.h"
namespace fortuna {
namespace accumulator {
} //namespace accumulator
} //namespace fortuna
#endif//FORTUNA_POOL_CPP

34
pool.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef FORTUNA_POOL_H
#define FORTUNA_POOL_H
#include <fmt/core.h>
namespace fortuna {
namespace accumulator {
class Pool {
public:
Pool(){};
~Pool() = default;
// TODO(me): this public setter should be fixed?
auto set_id(unsigned int id) -> void {
pool_id = id;
}
auto get_id() -> unsigned int;
auto initialize_pool(unsigned int id) -> void {
set_id(id);
fmt::print("Pool{{{}}} initialized to empty string\n", id);
}
private:
unsigned int pool_id{0};
}; // class Pool
} //namespace accumulator
} //namespace fortuna
#endif//FORTUNA_POOL_H