diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index 8ca793a74..a2907d2ed 100644 --- a/libdevcrypto/Common.cpp +++ b/libdevcrypto/Common.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #if ETH_HAVE_SECP256K1 #include @@ -309,78 +308,34 @@ h256 crypto::kdf(Secret const& _priv, h256 const& _hash) return s; } -mutex Nonce::s_x; -static string s_seedFile; - -Secret Nonce::get() -{ - // todo: atomic efface bit, periodic save, kdf, rr, rng - // todo: encrypt - Guard l(Nonce::s_x); - return Nonce::singleton().next(); -} - -void Nonce::reset() -{ - Guard l(Nonce::s_x); - Nonce::singleton().resetInternal(); -} - -void Nonce::setSeedFilePath(string const& _filePath) -{ - s_seedFile = _filePath; -} - -Nonce::~Nonce() -{ - Guard l(Nonce::s_x); - if (m_value) - // this might throw - resetInternal(); -} - -Nonce& Nonce::singleton() -{ - static Nonce s; - return s; -} - -void Nonce::initialiseIfNeeded() +string const& Nonce::seedFilePath(string const& _filePath) { - if (m_value) - return; - - bytesSec b = contentsSec(seedFile()); - if (b.size() == 32) - b.ref().populate(m_value.writable().ref()); - else - m_value = Secret::random(); - if (!m_value) - BOOST_THROW_EXCEPTION(InvalidState()); - - // prevent seed reuse if process terminates abnormally - // this might throw - writeFile(seedFile(), bytes()); + static mutex x_seedFile; + static string s_seedFile; + + Guard l(x_seedFile); + if (s_seedFile.empty()) + s_seedFile = _filePath.empty() ? getDataDir() + "/seed" : _filePath; + return s_seedFile; } Secret Nonce::next() { - initialiseIfNeeded(); - m_value = sha3(m_value); + Guard l(x_value); + if (!m_value) + { + bytesSec b = contentsSec(seedFilePath()); + if (b.size() == 32) + b.ref().populate(m_value.writable().ref()); + else + m_value = Secret::random(); + if (!m_value) + BOOST_THROW_EXCEPTION(InvalidState()); + + // prevent seed reuse if process terminates abnormally + // this might throw + writeFile(seedFilePath(), bytes()); + } + m_value = sha3Secure(m_value.ref()); return sha3(~m_value); } - -void Nonce::resetInternal() -{ - // this might throw - next(); - writeFile(seedFile(), m_value.ref()); - m_value.clear(); -} - -string const& Nonce::seedFile() -{ - if (s_seedFile.empty()) - s_seedFile = getDataDir() + "/seed"; - return s_seedFile; -} diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h index af25836a9..debeee8d6 100644 --- a/libdevcrypto/Common.h +++ b/libdevcrypto/Common.h @@ -28,6 +28,7 @@ #include #include #include +#include namespace dev { @@ -188,8 +189,8 @@ DEV_SIMPLE_EXCEPTION(InvalidState); h256 kdf(Secret const& _priv, h256 const& _hash); /** - * @brief Generator for nonce material. - *The Nonce class should only be used when a non-repeating nonce + * @brief Generator for non-repeating nonce material. + * The Nonce class should only be used when a non-repeating nonce * is required and, in its current form, not recommended for signatures. * This is primarily because the key-material for signatures is * encrypted on disk whereas the seed for Nonce is not. @@ -200,38 +201,22 @@ class Nonce { public: /// Returns the next nonce (might be read from a file). - static Secret get(); + static Secret get() { static Nonce s; return s.next(); } - /// Stores the current nonce in a file and resets Nonce to the uninitialised state. - static void reset(); - - /// Sets the location of the seed file to a non-default place. Used for testing. - static void setSeedFilePath(std::string const& _filePath); + /// @returns path of the seed file. FOR TESTS ONLY: optionally set path to @_filePath. + static std::string const& seedFilePath(std::string const& _filePath = std::string()); private: Nonce() = default; - ~Nonce(); - - /// @returns the singleton instance. - static Nonce& singleton(); - - /// Reads the last seed from the seed file. - void initialiseIfNeeded(); + + /// Destructor. IO operation may throw. + ~Nonce() { if (m_value && next()) dev::writeFile(seedFilePath(), m_value.ref()); } /// @returns the next nonce. Secret next(); - /// Stores the current seed in the seed file. - void resetInternal(); - - /// @returns the path of the seed file. - static std::string const& seedFile(); - + std::mutex x_value; Secret m_value; - - /// Mutex for the singleton object. - /// @note Every access to any private function has to be guarded by this mutex. - static std::mutex s_x; }; } diff --git a/test/TestUtils.cpp b/test/TestUtils.cpp index bd603a61f..60d5d6062 100644 --- a/test/TestUtils.cpp +++ b/test/TestUtils.cpp @@ -120,10 +120,6 @@ void ParallelClientBaseFixture::enumerateClients(std::function