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;
}
h256 Nonce::get(bool _commit)
mutex Nonce::s_x;
h256 Nonce::get()
{
// todo: atomic efface bit, periodic save, kdf, rr, rng
// todo: encrypt
static h256 s_seed;
static string s_seedFile(getDataDir() + "/seed");
static mutex s_x;
Guard l(s_x);
if (!s_seed)
Guard l(Nonce::s_x);
return Nonce::singleton().next();
}
// 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;
bytes b = contents(s_seedFile);
if (b.size() == 32)
memcpy(s_seed.data(), b.data(), 32);
else
{
// 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&) {}
// 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)
m_value[i] = byte(d(s_eng));
}
h256 prev(s_seed);
sha3(prev.ref(), s_seed.ref());
if (_commit)
try { writeFile(s_seedFile, s_seed.asBytes()); } catch (FileError const&) {}
return std::move(s_seed);
if (!m_value)
BOOST_THROW_EXCEPTION(InvalidState());
// prevent seed reuse if process terminates abnormally
// 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
#include <mutex>
#include <libdevcore/Common.h>
#include <libdevcore/FixedHash.h>
#include <libdevcore/Exceptions.h>
@ -180,14 +181,30 @@ struct InvalidState: public dev::Exception {};
h256 kdf(Secret const& _priv, h256 const& _hash);
/**
* @brief Generator for nonce material
* @brief Generator for nonce material.
*/
struct Nonce
{
static h256 get(bool _commit = false);
static h256 get();
private:
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.
DEV_SIMPLE_EXCEPTION_RLP(CryptoException);
DEV_SIMPLE_EXCEPTION(CryptoException);
}
}

Loading…
Cancel
Save