#define MAX_NONCE (1<<26)
std::vector< std::pair > momentum_search( pow_seed_type head )
{
std::unordered_map found;
found.reserve( MAX_NONCE );
std::vector< std::pair > results;
for( uint32_t i = 0; i < MAX_NONCE; )
{
fc::sha512::encoder enc;
enc.write( (char*)&i, sizeof(i) );
enc.write( (char*)&head, sizeof(head) );
auto result = enc.result();
for( uint32_t x = 0; x < 8; ++x )
{
uint64_t birthday = result._hash[x] >> 14;
uint32_t nonce = i+x;
auto itr = found.find( birthday );
if( itr != found.end() )
{
results.push_back( std::make_pair( itr->second, nonce ) );
}
else
{
found[birthday] = nonce;
}
}
i += 8;
}
return results;
}
bool momentum_verify( pow_seed_type head, uint32_t a, uint32_t b )
{
uint32_t ia = (a / 8) * 8;
fc::sha512::encoder enca;
enca.write( (char*)&ia, sizeof(ia) );
enca.write( (char*)&head, sizeof(head) );
auto ar = enca.result();
uint32_t ib = (b / 8) * 8;
fc::sha512::encoder encb;
encb.write( (char*)&ib, sizeof(ib) );
encb.write( (char*)&head, sizeof(head) );
auto br = encb.result();
return (ar._hash[a%8]>>14) == (br._hash[b%8]>>14);
}
I have put together this code which is not optimized in the least, but I estimate once fully optimized will require 2^26 * 12 = 768 MB of RAM minimum and will run in one or two seconds on a Core i7. The nonce space is limited to 2^26 items and the collision difficulty is 50 bits which on average finds 2-3 pairs per run. This would require memory bandwidth of 512 MB/sec sustained. Assuming you built an ASIC for SHA512 it would be at most 100x faster given the highest memory bus speeds available.
To integrate this with a new blockchain you simply add 2 nonces to the block header, call momentum_verify and then use the existing sha256 difficulty from bitcoin to adjust the difficulty.