Implemented CN-Heavy algo, Algo tests and fixed n-loop variants (#86)

* Debouncing of connection retry when connecting donation server fails
* When PoW variant is set on proxy, it will overrule local set PoW
* Implementation of cn_heavy algo
* Added self test for cn-heavy
* Fixed n-loop variant of powV2 and cn-heavy
* Fixed n-loop variant of powV2 and added cn-heavy for ARM
* Fixing n-loop for arm
* Limited cn-heavy to max hashfactor 3 on higher seltest fails.
* Removed a lot of casts
* Fixed algo selftest
This commit is contained in:
Ben Gräf 2018-04-07 21:20:24 +02:00 committed by GitHub
parent 06bb082041
commit 1ce9d2bf3c
17 changed files with 2682 additions and 450 deletions

View file

@ -34,7 +34,7 @@
#include "crypto/CryptoNight_test.h"
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
static void cryptonight_aesni(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
# if !defined(XMRIG_ARMv7)
if ((reinterpret_cast<const uint8_t*>(input)[0] > 6 && Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT) ||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
@ -46,7 +46,7 @@ static void cryptonight_aesni(const void *input, size_t size, void *output, cryp
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
static void cryptonight_softaes(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
if ((reinterpret_cast<const uint8_t*>(input)[0] > 6 && Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT) ||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
CryptoNightMultiHash<0x80000, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
@ -56,7 +56,7 @@ static void cryptonight_softaes(const void *input, size_t size, void *output, cr
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_lite_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
static void cryptonight_lite_aesni(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
# if !defined(XMRIG_ARMv7)
if ((reinterpret_cast<const uint8_t*>(input)[0] > 1 && Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT) ||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
@ -68,7 +68,7 @@ static void cryptonight_lite_aesni(const void *input, size_t size, void *output,
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_lite_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
static void cryptonight_lite_softaes(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
if ((reinterpret_cast<const uint8_t*>(input)[0] > 1 && Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT) ||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
@ -77,7 +77,20 @@ static void cryptonight_lite_softaes(const void *input, size_t size, void *outpu
}
}
void (*cryptonight_hash_ctx[MAX_NUM_HASH_BLOCKS])(const void *input, size_t size, void *output, cryptonight_ctx *ctx);
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_heavy_aesni(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
# if !defined(XMRIG_ARMv7)
CryptoNightMultiHash<0x40000, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
# endif
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_heavy_softaes(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
CryptoNightMultiHash<0x40000, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
}
void (*cryptonight_hash_ctx[MAX_NUM_HASH_BLOCKS])(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx);
template <size_t HASH_FACTOR>
void setCryptoNightHashMethods(Options::Algo algo, bool aesni)
@ -98,6 +111,14 @@ void setCryptoNightHashMethods(Options::Algo algo, bool aesni)
cryptonight_hash_ctx[HASH_FACTOR - 1] = cryptonight_lite_softaes<HASH_FACTOR>;
}
break;
case Options::ALGO_CRYPTONIGHT_HEAVY:
if (aesni) {
cryptonight_hash_ctx[HASH_FACTOR - 1] = cryptonight_heavy_aesni<HASH_FACTOR>;
} else {
cryptonight_hash_ctx[HASH_FACTOR - 1] = cryptonight_heavy_softaes<HASH_FACTOR>;
}
break;
}
// next iteration
setCryptoNightHashMethods<HASH_FACTOR-1>(algo, aesni);
@ -139,56 +160,92 @@ bool CryptoNight::selfTest(int algo)
return false;
}
char output[160];
uint8_t output[160];
auto ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16);
ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 6, 16);
bool resultV1Pow = true;
if (Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT || Options::i()->forcePowVersion() == Options::PowVersion::POW_V1) {
cryptonight_hash_ctx[0](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output, 96) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 3
cryptonight_hash_ctx[3](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output, 128) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 4
cryptonight_hash_ctx[4](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output, 160) == 0;
#endif
}
// monero/aeon v2 pow (monero/aeon blockchain version 7)
bool resultV2Pow = true;
if (Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT || Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
cryptonight_hash_ctx[0](test_input_monero_v2_pow_0, sizeof(test_input_monero_v2_pow_0), output, ctx);
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_monero_v2_pow_light[0] : test_output_monero_v2_pow[0], 32) == 0;
bool resultHeavy = true;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](test_input_monero_v2_pow_1, sizeof(test_input_monero_v2_pow_1), output, ctx);
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_monero_v2_pow_light[1] : test_output_monero_v2_pow[1], 32) == 0;
#endif
if (algo == Options::ALGO_CRYPTONIGHT_HEAVY)
{
cryptonight_hash_ctx[0](test_input, 76, output, ctx);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](test_input_monero_v2_pow_2, sizeof(test_input_monero_v2_pow_2), output, ctx);
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_monero_v2_pow_light[2] : test_output_monero_v2_pow[2], 32) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](test_input, 76, output, ctx);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](test_input, 76, output, ctx);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 96) == 0;
#endif
}
else {
if (Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT ||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V1) {
cryptonight_hash_ctx[0](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow &&
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow &&
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow &&
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
96) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 3
cryptonight_hash_ctx[3](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow &&
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
128) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 4
cryptonight_hash_ctx[4](test_input, 76, output, ctx);
resultV1Pow = resultV1Pow &&
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
160) == 0;
#endif
}
// monero/aeon v2 pow (monero/aeon blockchain version 7)
if (Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT ||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
cryptonight_hash_ctx[0](test_input_monero_v2_pow_0, sizeof(test_input_monero_v2_pow_0), output, ctx);
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE
? test_output_monero_v2_pow_light[0]
: test_output_monero_v2_pow[0], 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](test_input_monero_v2_pow_1, sizeof(test_input_monero_v2_pow_1), output, ctx);
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE
? test_output_monero_v2_pow_light[1]
: test_output_monero_v2_pow[1], 32) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](test_input_monero_v2_pow_2, sizeof(test_input_monero_v2_pow_2), output, ctx);
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE
? test_output_monero_v2_pow_light[2]
: test_output_monero_v2_pow[2], 32) == 0;
#endif
}
}
_mm_free(ctx->memory);
_mm_free(ctx);
return resultV1Pow && resultV2Pow;
return resultV1Pow && resultV2Pow & resultHeavy;
}

View file

@ -32,6 +32,7 @@
#define MEMORY 2097152 /* 2 MiB */
#define MEMORY_LITE 1048576 /* 1 MiB */
#define MEMORY_HEAVY 4194304 /* 4 MiB */
struct cryptonight_ctx {
alignas(16) uint8_t state[MAX_NUM_HASH_BLOCKS][208]; // 208 instead of 200 to maintain aligned to 16 byte boundaries

File diff suppressed because it is too large Load diff

View file

@ -64,11 +64,13 @@ const static uint8_t test_output[] = {
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00,
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00,
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00
@ -80,10 +82,12 @@ const static uint8_t test_output_light[] = {
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
@ -131,10 +135,22 @@ const static uint8_t test_output_monero_v2_pow_light[3][32] = {
0x03, 0xf5, 0x39, 0x53, 0x15, 0xde, 0x91, 0x9a, 0xcf, 0x1b, 0x97, 0xf0, 0xa8, 0x4f, 0xbd, 0x2d}
};
const static uint8_t test_output_heavy[] = {
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2,
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2,
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2
};
#endif /* __CRYPTONIGHT_TEST_H__ */

File diff suppressed because it is too large Load diff