#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 uint64_t& 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 == this->null_blk); } private: static constexpr const std::size_t ctr_len{16}; static constexpr const std::array null_blk{ std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, std::byte{0x00}, }; // used for comparison with G.ctr in is_seeded() and generate_blocks() CryptoPP::CTR_Mode::Encryption enc; struct G_state { static constexpr const std::size_t k_length{32}; CryptoPP::FixedSizeSecBlock k; std::array ctr; }; 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