You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
2.7 KiB

11 years ago
#include <boost/detail/endian.hpp>
#include <chrono>
#include <array>
#pragma warning(push)
#pragma warning(disable:4244)
11 years ago
#include <sha3.h>
#pragma warning(pop)
11 years ago
#include <random>
#include "Common.h"
#include "Dagger.h"
using namespace std;
using namespace std::chrono;
namespace eth
{
11 years ago
Dagger::Dagger()
11 years ago
{
}
Dagger::~Dagger()
{
}
u256 Dagger::bound(u256 const& _difficulty)
{
return (u256)((bigint(1) << 256) / _difficulty);
}
bool Dagger::verify(h256 const& _root, u256 const& _nonce, u256 const& _difficulty)
11 years ago
{
return eval(_root, _nonce) < bound(_difficulty);
}
11 years ago
bool Dagger::mine(u256& o_solution, h256 const& _root, u256 const& _difficulty, uint _msTimeout)
{
// restart search if root has changed
if (m_root != _root)
{
m_root = _root;
m_nonce = 0;
}
11 years ago
// compute bound
u256 const b = bound(_difficulty);
// evaluate until we run out of time
for (auto startTime = steady_clock::now(); (steady_clock::now() - startTime) < milliseconds(_msTimeout); m_nonce += 1)
{
if (eval(_root, m_nonce) < b)
{
o_solution = m_nonce;
return true;
}
}
return false;
11 years ago
}
template <class _T>
inline void update(_T& _sha, u256 const& _value)
11 years ago
{
int i = 0;
for (u256 v = _value; v; ++i, v >>= 8) {}
byte buf[32];
bytesRef bufRef(buf, i);
toBigEndian(_value, bufRef);
_sha.Update(buf, i);
11 years ago
}
template <class _T>
inline void update(_T& _sha, h256 const& _value)
11 years ago
{
int i = 0;
byte const* data = _value.data();
for (; i != 32 && data[i] == 0; ++i);
_sha.Update(data + i, 32 - i);
}
template <class _T>
inline h256 get(_T& _sha)
{
h256 ret;
_sha.TruncatedFinal(&ret[0], 32);
return ret;
11 years ago
}
h256 Dagger::node(h256 const& _root, h256 const& _xn, uint_fast32_t _L, uint_fast32_t _i)
11 years ago
{
if (_L == _i)
return _root;
11 years ago
u256 m = (_L == 9) ? 16 : 3;
CryptoPP::SHA3_256 bsha;
for (uint_fast32_t k = 0; k < m; ++k)
{
CryptoPP::SHA3_256 sha;
update(sha, _root);
update(sha, _xn);
11 years ago
update(sha, (u256)_L);
update(sha, (u256)_i);
update(sha, (u256)k);
uint_fast32_t pk = (uint_fast32_t)(u256)get(sha) & ((1 << ((_L - 1) * 3)) - 1);
auto u = node(_root, _xn, _L - 1, pk);
update(bsha, u);
11 years ago
}
return get(bsha);
}
h256 Dagger::eval(h256 const& _root, u256 const& _nonce)
11 years ago
{
h256 extranonce = _nonce >> 26; // with xn = floor(n / 2^26) -> assuming this is with xn = floor(N / 2^26)
11 years ago
CryptoPP::SHA3_256 bsha;
for (uint_fast32_t k = 0; k < 4; ++k)
{
//sha256(D || xn || i || k) -> sha256(D || xn || k) - there's no 'i' here!
CryptoPP::SHA3_256 sha;
update(sha, _root);
update(sha, extranonce);
update(sha, _nonce);
11 years ago
update(sha, (u256)k);
uint_fast32_t pk = (uint_fast32_t)(u256)get(sha) & 0x1ffffff; // mod 8^8 * 2 [ == mod 2^25 ?! ] [ == & ((1 << 25) - 1) ] [ == & 0x1ffffff ]
auto u = node(_root, extranonce, 9, pk);
update(bsha, u);
11 years ago
}
return get(bsha);
}
}