Skip to content

Commit

Permalink
Rework branching in mining algo, add modulo helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
who-biz committed Nov 24, 2019
1 parent a733e52 commit f274087
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 11 deletions.
117 changes: 117 additions & 0 deletions src/common/int-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,123 @@ static inline uint64_t add(uint64_t a, uint64_t b) {
else return add(a ^ b, (a & b) << 1);
}

static inline uint32_t mod3( uint32_t a ){
a = add(((a >> 2) & 0x33333333),(a & 0x33333333));
a = add(((a >> 4) & 0x07070707),(a & 0x07070707));
a = add(((a >> 8) & 0x000F000F),(a & 0x000F000F));
a = add(((a >> 16) ),(a & 0x0000001F));
a = add(((a >> 2) & 0x33333333),(a & 0x33333333));
a = add(((a >> 4) ),(a & 0x07070707));
a = add(((a >> 2) ),(a & 0x33333333));
if (a > 2) a = a - 3;
return a;
}

/*static inline uint32_t modular_pow3(uint32_t base, uint32_t exponent, uint32_t result)
{
result = 1;
base = mod3(base);
while (exponent > 0) {
if (exponent & 1)
result = mod3(result * base);
exponent = exponent >> 1;
base = mod3(base * base);
}
return result;
}*/

static inline uint32_t mod_mersenne(uint32_t const num, uint32_t const s) // s = (mersenne + 1), i.e. pow2
{
// https://graphics.stanford.edu/~seander/bithacks.html#ModulusDivisionParallel
const unsigned int M[] =
{
0x00000000, 0x55555555, 0x33333333, 0xc71c71c7,
0x0f0f0f0f, 0xc1f07c1f, 0x3f03f03f, 0xf01fc07f,
0x00ff00ff, 0x07fc01ff, 0x3ff003ff, 0xffc007ff,
0xff000fff, 0xfc001fff, 0xf0003fff, 0xc0007fff,
0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff
};

const unsigned int Q[][6] =
{
{ 0, 0, 0, 0, 0, 0}, {16, 8, 4, 2, 1, 1}, {16, 8, 4, 2, 2, 2},
{15, 6, 3, 3, 3, 3}, {16, 8, 4, 4, 4, 4}, {15, 5, 5, 5, 5, 5},
{12, 6, 6, 6 , 6, 6}, {14, 7, 7, 7, 7, 7}, {16, 8, 8, 8, 8, 8},
{ 9, 9, 9, 9, 9, 9}, {10, 10, 10, 10, 10, 10}, {11, 11, 11, 11, 11, 11},
{12, 12, 12, 12, 12, 12}, {13, 13, 13, 13, 13, 13}, {14, 14, 14, 14, 14, 14},
{15, 15, 15, 15, 15, 15}, {16, 16, 16, 16, 16, 16}, {17, 17, 17, 17, 17, 17},
{18, 18, 18, 18, 18, 18}, {19, 19, 19, 19, 19, 19}, {20, 20, 20, 20, 20, 20},
{21, 21, 21, 21, 21, 21}, {22, 22, 22, 22, 22, 22}, {23, 23, 23, 23, 23, 23},
{24, 24, 24, 24, 24, 24}, {25, 25, 25, 25, 25, 25}, {26, 26, 26, 26, 26, 26},
{27, 27, 27, 27, 27, 27}, {28, 28, 28, 28, 28, 28}, {29, 29, 29, 29, 29, 29},
{30, 30, 30, 30, 30, 30}, {31, 31, 31, 31, 31, 31}
};

const unsigned int R[][6] =
{
{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000ffff, 0x000000ff, 0x0000000f, 0x00000003, 0x00000001, 0x00000001},
{0x0000ffff, 0x000000ff, 0x0000000f, 0x00000003, 0x00000003, 0x00000003},
{0x00007fff, 0x0000003f, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
{0x0000ffff, 0x000000ff, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f},
{0x00007fff, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f},
{0x00000fff, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f},
{0x00003fff, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f},
{0x0000ffff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff},
{0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff},
{0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff},
{0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff},
{0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff},
{0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff},
{0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff},
{0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
{0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff},
{0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff},
{0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff},
{0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff},
{0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff},
{0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff},
{0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff},
{0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff},
{0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff},
{0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff},
{0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff},
{0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff},
{0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff},
{0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff},
{0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff},
{0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}
};

const unsigned int d = (1 << s) - 1;
unsigned int m;

m = (num & M[s]) + ((num >> s) & M[s]);

for (const unsigned int * q = &Q[s][0], * r = &R[s][0]; m > d; q++, r++)
{
m = (m >> *q) + (m & *r);
}

m = m == d ? 0 : m;
return m;
}

static inline uint32_t div3(uint32_t num)
{
uint32_t sum = 0;
while (num > 3) {
sum = add(num >> 2, sum);
num = add(num >> 2, num & 3);
}
if (num == 3)
sum = add(sum, 1);
return sum;
}

static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) {
// multiplier = ab = a * 2^32 + b
// multiplicand = cd = c * 2^32 + d
Expand Down
30 changes: 19 additions & 11 deletions src/cryptonote_basic/cryptonote_format_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -949,20 +949,28 @@ namespace cryptonote
uint32_t id_num = std::strtoul(subhash.c_str(), NULL, 16);

LOG_PRINT_L2("\nPRNG from previous block ID : " << id_num);
// guard against small probability of zero case
id_num = id_num < 1 ? 1 : id_num; // in previous hash's first 6 characters

if (id_num < 1) { // guard against small probability of zero case
id_num = 1; } // in previous hash's first 6 characters

const uint64_t m_stamp = b.timestamp;
bool two = false;
two = id_num && !(id_num & (id_num - 1));
if (two) {
uint64_t m_stamp = b.timestamp;
bool two = id_num && !(id_num & (id_num - 1));
if (!two) {
uint32_t m = add(id_num, 1);
bool mersenne = m && !(m & (m - 1));
if (!mersenne) {
if (!mod3(m_stamp) && !mod3(id_num)) {
// MWARNING("Encountered reducible operands, dividing by 3!");
uint32_t inner = div3(m_stamp) % div3(id_num);
its = add(cn_iters, (add(inner, height) & 0x7FFF));
}
its = add(cn_iters, (add(m_stamp % id_num, height) & 0x7FFF));
} else {
its = add(cn_iters,(add(mod_mersenne(m_stamp,m), height) & 0x7FFF));
}
} else {
its = add(cn_iters, (add(m_stamp & (id_num - 1), height) & 0x7FFF));
}
else if (!two) {
its = add(cn_iters, (add(m_stamp % id_num, height) & 0x7FFF));
}
LOG_PRINT_L2("\nIterations : "<< its);
LOG_PRINT_L2("\nIterations : "<< its);
}
crypto::cn_slow_hash(bd.data(), bd.size(), res, cn_variant, its);
return true;
Expand Down

0 comments on commit f274087

Please sign in to comment.