Browse Source

Nonce refactoring.

cl-refactor
chriseth 10 years ago
parent
commit
0b6a09b9cf
  1. 89
      libdevcrypto/Common.cpp
  2. 21
      libdevcrypto/Common.h
  3. 2
      libdevcrypto/Exceptions.h

89
libdevcrypto/Common.cpp

@ -254,42 +254,71 @@ h256 crypto::kdf(Secret const& _priv, h256 const& _hash)
return s; return s;
} }
h256 Nonce::get(bool _commit) mutex Nonce::s_x;
h256 Nonce::get()
{ {
// todo: atomic efface bit, periodic save, kdf, rr, rng // todo: atomic efface bit, periodic save, kdf, rr, rng
// todo: encrypt // todo: encrypt
static h256 s_seed; Guard l(Nonce::s_x);
static string s_seedFile(getDataDir() + "/seed"); return Nonce::singleton().next();
static mutex s_x; }
Guard l(s_x);
if (!s_seed) // get: Called for the first time: read seed hash from file (or generate)
// before destruction: increment current value and store
Nonce::~Nonce()
{
Guard l(Nonce::s_x);
// These might throw.
next();
commit();
}
Nonce& Nonce::singleton()
{
static Nonce s;
return s;
}
void Nonce::initialiseIfNeeded()
{
if (m_value)
return;
bytes b = contents(seedFile());
if (b.size() == 32)
memcpy(m_value.data(), b.data(), 32);
else
{ {
static Nonce s_nonce; // todo: replace w/entropy from user and system
bytes b = contents(s_seedFile); std::mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count());
if (b.size() == 32) std::uniform_int_distribution<uint16_t> d(0, 255);
memcpy(s_seed.data(), b.data(), 32); for (unsigned i = 0; i < 32; ++i)
else m_value[i] = byte(d(s_eng));
{
// todo: replace w/entropy from user and system
std::mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count());
std::uniform_int_distribution<uint16_t> d(0, 255);
for (unsigned i = 0; i < 32; ++i)
s_seed[i] = (byte)d(s_eng);
}
if (!s_seed)
BOOST_THROW_EXCEPTION(InvalidState());
// prevent seed reuse if process terminates abnormally
try { writeFile(s_seedFile, bytes()); } catch (FileError const&) {}
} }
h256 prev(s_seed); if (!m_value)
sha3(prev.ref(), s_seed.ref()); BOOST_THROW_EXCEPTION(InvalidState());
if (_commit)
try { writeFile(s_seedFile, s_seed.asBytes()); } catch (FileError const&) {} // prevent seed reuse if process terminates abnormally
return std::move(s_seed); // this might throw
writeFile(seedFile(), bytes());
} }
Nonce::~Nonce() h256 Nonce::next()
{
initialiseIfNeeded();
m_value = sha3(m_value);
return m_value;
}
void Nonce::commit()
{
// this might throw
writeFile(seedFile(), m_value.asBytes());
}
string Nonce::seedFile()
{ {
Nonce::get(true); return getDataDir() + "/seed";
} }

21
libdevcrypto/Common.h

@ -24,6 +24,7 @@
#pragma once #pragma once
#include <mutex>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/FixedHash.h> #include <libdevcore/FixedHash.h>
#include <libdevcore/Exceptions.h> #include <libdevcore/Exceptions.h>
@ -180,14 +181,30 @@ struct InvalidState: public dev::Exception {};
h256 kdf(Secret const& _priv, h256 const& _hash); h256 kdf(Secret const& _priv, h256 const& _hash);
/** /**
* @brief Generator for nonce material * @brief Generator for nonce material.
*/ */
struct Nonce struct Nonce
{ {
static h256 get(bool _commit = false); static h256 get();
private: private:
Nonce() {} Nonce() {}
~Nonce(); ~Nonce();
/// @returns the singleton instance.
static Nonce& singleton();
/// Reads the last seed from the seed file.
void initialiseIfNeeded();
/// @returns the next nonce.
h256 next();
/// Stores the current seed in the seed file.
void commit();
/// @returns the path of the seed file.
static std::string seedFile();
/// Mutex for the singleton object.
/// @note Every access to any private function has to be guarded by this mutex.
static std::mutex s_x;
h256 m_value;
}; };
} }

2
libdevcrypto/Exceptions.h

@ -29,7 +29,7 @@ namespace crypto
{ {
/// Rare malfunction of cryptographic functions. /// Rare malfunction of cryptographic functions.
DEV_SIMPLE_EXCEPTION_RLP(CryptoException); DEV_SIMPLE_EXCEPTION(CryptoException);
} }
} }

Loading…
Cancel
Save