#ifndef FORTUNA_GENERATOR_H #define FORTUNA_GENERATOR_H #include #include #include #include #include #include #include #include #include namespace fortuna { namespace generator { class Generator { public: std::chrono::milliseconds reseed_interval{100}; mutable std::recursive_mutex mtx; std::mutex crypt_mtx; std::mutex reseed_mtx; Generator(); // ad noexcept: perhaps _do_ throw* Generator(const Generator& Gen) = delete; // no Generator& operator=(const Generator& Gen) = delete; // copies ~Generator() noexcept; /* n is the number of random bytes to generate */ auto generate_random_data(const unsigned int& n) -> std::string; auto reseed(const std::string& s) -> void; [[optimize_for_synchronized]] auto time_to_reseed( const uint64_t& pool0_len, const unsigned int& min_p_size, const std::chrono::duration>& time_elapsed, const std::chrono::milliseconds& reseed_interval) const -> bool; auto is_seeded() const -> bool { std::lock_guard lg(mtx); return !(this->G.ctr == 0x00); } private: CryptoPP::CTR_Mode::Encryption enc; struct G_state { // 32*8 static constexpr const std::size_t k_length{32}; static constexpr const std::size_t ctr_len{16}; CryptoPP::FixedSizeSecBlock k; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" unsigned __int128 ctr; #pragma GCC diagnostic pop std::array counter; }; G_state G; void initialize_generator(); auto do_crypto() -> std::string; auto generate_blocks(unsigned int k_blocks) -> std::string; auto ctr_inc() -> void; protected: auto get_state() const -> Generator::G_state; }; // class generator } // namespace generator } // namespace fortuna #endif // FORTUNA_GENERATOR_H