Browse Source

Dagger algo.

cl-refactor
Gav Wood 11 years ago
parent
commit
d4448a9c7b
  1. 86
      libethereum/Dagger.cpp
  2. 26
      libethereum/Dagger.h
  3. 10
      test/main.cpp

86
libethereum/Dagger.cpp

@ -0,0 +1,86 @@
#include <boost/detail/endian.hpp>
#include <chrono>
#include <array>
#include <sha3.h>
#include <random>
#include "Common.h"
#include "Dagger.h"
using namespace std;
using namespace std::chrono;
using namespace eth;
Dagger::Dagger(u256 _hash): m_hash(_hash)
{
}
Dagger::~Dagger()
{
}
u256 Dagger::search(uint _msTimeout, u256 _diff)
{
static mt19937_64 s_engine((std::random_device())());
u256 bound = (u256)((bigint(1) << 256) / _diff);
auto start = steady_clock::now();
while (steady_clock::now() - start < milliseconds(_msTimeout))
for (uint sp = std::uniform_int_distribution<uint>()(s_engine), j = 0; j < 1000; ++j, ++sp)
if (eval(sp) < bound)
return sp;
return 0;
}
template <class _T>
inline void update(_T& _sha, u256 const& _value)
{
std::array<byte, 32> buf;
toBigEndian(_value, buf);
_sha.Update(buf.data(), 32);
}
template <class _T>
inline u256 get(_T& _sha)
{
byte buf[32];
_sha.TruncatedFinal(buf, 32);
return fromBigEndian<u256>(bytesConstRef(buf, 32));
}
u256 Dagger::node(uint_fast32_t _L, uint_fast32_t _i) const
{
if (!_L && !_i)
return m_hash;
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, m_hash);
update(sha, m_xn);
update(sha, (u256)_L);
update(sha, (u256)_i);
update(sha, (u256)k);
uint_fast32_t pk = (uint_fast32_t)get(sha) & ((1 << ((_L - 1) * 3)) - 1);
update(bsha, node(_L - 1, pk));
}
return get(bsha);
}
u256 Dagger::eval(u256 _N)
{
m_xn = _N >> 26; // with xn = floor(n / 2^26) -> assuming this is with xn = floor(N / 2^26)
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, m_hash);
update(sha, m_xn);
update(sha, _N);
update(sha, (u256)k);
uint_fast32_t pk = (uint_fast32_t)get(sha) & 0x1ffffff; // mod 8^8 * 2 [ == mod 2^25 ?! ] [ == & ((1 << 25) - 1) ] [ == & 0x1ffffff ]
update(bsha, node(9, pk));
}
return get(bsha);
}

26
libethereum/Dagger.h

@ -0,0 +1,26 @@
#pragma once
#include "Common.h"
namespace eth
{
/// Functions are not re-entrant. If you want to multi-thread, then use different classes for each thread.
class Dagger
{
public:
Dagger(u256 _hash);
~Dagger();
u256 node(uint_fast32_t _L, uint_fast32_t _i) const;
u256 eval(u256 _N);
u256 search(uint _msTimeout, u256 _diff);
private:
u256 m_hash;
u256 m_xn;
};
}

10
test/main.cpp

@ -21,18 +21,28 @@
*/
#include <random>
#include <chrono>
#include <Common.h>
#include <secp256k1.h>
#include "Dagger.h"
#include "RLP.h"
#include "Trie.h"
#include "State.h"
using namespace std;
using namespace std::chrono;
using namespace eth;
// TODO: utilise the shared testdata.
int main()
{
// Test dagger
{
Dagger d(1);
auto s = steady_clock::now();
cout << hex << d.eval(0);
cout << " " << dec << duration_cast<milliseconds>(steady_clock::now() - s).count() << " ms" << endl;
}
/*
// Test transaction.
bytes tx = fromUserHex("88005401010101010101010101010101010101010101011f0de0b6b3a76400001ce8d4a5100080181c373130a009ba1f10285d4e659568bfcfec85067855c5a3c150100815dad4ef98fd37cf0593828c89db94bd6c64e210a32ef8956eaa81ea9307194996a3b879441f5d");

Loading…
Cancel
Save