Features of 1.6.5 (#140)

* Hashrate improve -> add autodetection mode for cpu-affinity
* Hashrate improve, more stable hashrates -> refactor memory allocation
* Add TubeV4 support (cn-heavy + ipbc mod + soft-aes mod)
* Update ccp-httpd lib to fix stop/freeze of cc communication on some miners
* Fix cn-heavy on arm processors
This commit is contained in:
Ben Gräf 2018-06-26 20:25:38 +02:00 committed by GitHub
parent 7897f8f645
commit 90699d58ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 5525 additions and 3114 deletions

View file

@ -34,88 +34,94 @@
#include "crypto/CryptoNight_test.h"
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
static void cryptonight_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
# if !defined(XMRIG_ARMv7)
if (powVersion == PowVariant::POW_V1) {
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_ALLOY) {
CryptoNightMultiHash<0x100000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
CryptoNightMultiHash<0x100000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_XTL) {
CryptoNightMultiHash<0x80000, POW_XLT_V4_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
CryptoNightMultiHash<0x80000, POW_XLT_V4_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_MSR) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_RTO) {
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad);
}else {
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
}
# endif
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
static void cryptonight_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
if (powVersion == PowVariant::POW_V1) {
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_ALLOY) {
CryptoNightMultiHash<0x100000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
CryptoNightMultiHash<0x100000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_XTL) {
CryptoNightMultiHash<0x80000, POW_XLT_V4_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
CryptoNightMultiHash<0x80000, POW_XLT_V4_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_MSR) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_RTO) {
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad);
} else {
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
}
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_lite_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
static void cryptonight_lite_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
# if !defined(XMRIG_ARMv7)
if (powVersion == PowVariant::POW_V1) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
} else if (powVersion == PowVariant::POW_IPBC) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_TUBE) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad);
} else {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
}
# endif
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_lite_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
static void cryptonight_lite_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
if (powVersion == PowVariant::POW_V1) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
} else if (powVersion == PowVariant::POW_IPBC) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
} else if (powVersion == PowVariant::POW_TUBE) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad);
} else {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
}
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_heavy_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
static void cryptonight_heavy_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
# if !defined(XMRIG_ARMv7)
if (powVersion == PowVariant::POW_XHV) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, scratchPad);
}
else if (powVersion == PowVariant::POW_TUBE) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavyTube(input, size, output, scratchPad);
}
else {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, scratchPad);
}
# endif
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_heavy_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
static void cryptonight_heavy_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
if (powVersion == PowVariant::POW_XHV) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, scratchPad);
}
else if (powVersion == PowVariant::POW_TUBE) {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavyTube(input, size, output, scratchPad);
}
else {
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, scratchPad);
}
}
void (*cryptonight_hash_ctx[MAX_NUM_HASH_BLOCKS])(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx);
void (*cryptonight_hash_ctx[MAX_NUM_HASH_BLOCKS])(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad);
template <size_t HASH_FACTOR>
void setCryptoNightHashMethods(Options::Algo algo, bool aesni)
@ -161,9 +167,9 @@ bool CryptoNight::init(int algo, bool aesni)
return selfTest(algo);
}
void CryptoNight::hash(size_t factor, PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx)
void CryptoNight::hash(size_t factor, PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad)
{
cryptonight_hash_ctx[factor-1](powVersion, input, size, output, ctx);
cryptonight_hash_ctx[factor-1](powVersion, input, size, output, scratchPad);
}
bool CryptoNight::selfTest(int algo)
@ -187,8 +193,14 @@ bool CryptoNight::selfTest(int algo)
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);
ScratchPad* scratchPads [MAX_NUM_HASH_BLOCKS];
for (size_t i = 0; i < MAX_NUM_HASH_BLOCKS; ++i) {
ScratchPad* scratchPad = static_cast<ScratchPad *>(_mm_malloc(sizeof(ScratchPad), 4096));
scratchPad->memory = (uint8_t *) _mm_malloc(MEMORY * 6, 16);
scratchPads[i] = scratchPad;
}
bool result = true;
bool resultLite = true;
@ -197,188 +209,206 @@ bool CryptoNight::selfTest(int algo)
if (algo == Options::ALGO_CRYPTONIGHT_HEAVY) {
// cn-heavy
cryptonight_hash_ctx[0](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[0](PowVariant::POW_V0, test_input, 76, output, scratchPads);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, scratchPads);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, scratchPads);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 96) == 0;
#endif
// cn-heavy haven
cryptonight_hash_ctx[0](PowVariant::POW_XHV, test_input, 76, output, ctx);
cryptonight_hash_ctx[0](PowVariant::POW_XHV, test_input, 76, output, scratchPads);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_haven, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](PowVariant::POW_XHV, test_input, 76, output, ctx);
cryptonight_hash_ctx[1](PowVariant::POW_XHV, test_input, 76, output, scratchPads);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_haven, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](PowVariant::POW_XHV, test_input, 76, output, ctx);
cryptonight_hash_ctx[2](PowVariant::POW_XHV, test_input, 76, output, scratchPads);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_haven, 96) == 0;
#endif
// cn-heavy bittube
cryptonight_hash_ctx[0](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_tube, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_tube, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_tube, 96) == 0;
#endif
} else if (algo == Options::ALGO_CRYPTONIGHT_LITE) {
// cn-lite v0
cryptonight_hash_ctx[0](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[0](PowVariant::POW_V0, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v0_lite, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v0_lite, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v0_lite, 96) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 3
cryptonight_hash_ctx[3](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[3](PowVariant::POW_V0, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v0_lite, 128) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 4
cryptonight_hash_ctx[4](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[4](PowVariant::POW_V0, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v0_lite, 160) == 0;
#endif
// cn-lite v7 tests
cryptonight_hash_ctx[0](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[0](PowVariant::POW_V1, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v1_lite, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[1](PowVariant::POW_V1, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v1_lite, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[2](PowVariant::POW_V1, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v1_lite, 96) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 3
cryptonight_hash_ctx[3](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[3](PowVariant::POW_V1, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v1_lite, 128) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 4
cryptonight_hash_ctx[4](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[4](PowVariant::POW_V1, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_v1_lite, 160) == 0;
#endif
// cn-lite ibpc tests
cryptonight_hash_ctx[0](PowVariant::POW_IPBC, test_input, 76, output, ctx);
cryptonight_hash_ctx[0](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](PowVariant::POW_IPBC, test_input, 76, output, ctx);
cryptonight_hash_ctx[1](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](PowVariant::POW_IPBC, test_input, 76, output, ctx);
cryptonight_hash_ctx[2](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 96) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 3
cryptonight_hash_ctx[3](PowVariant::POW_IPBC, test_input, 76, output, ctx);
cryptonight_hash_ctx[3](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 128) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 4
cryptonight_hash_ctx[4](PowVariant::POW_IPBC, test_input, 76, output, ctx);
cryptonight_hash_ctx[4](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 160) == 0;
#endif
} else {
// cn v0
cryptonight_hash_ctx[0](PowVariant::POW_V0,test_input, 76, output, ctx);
cryptonight_hash_ctx[0](PowVariant::POW_V0,test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v0, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v0, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v0, 96) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 3
cryptonight_hash_ctx[3](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[3](PowVariant::POW_V0, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v0, 128) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 4
cryptonight_hash_ctx[4](PowVariant::POW_V0, test_input, 76, output, ctx);
cryptonight_hash_ctx[4](PowVariant::POW_V0, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v0, 160) == 0;
#endif
// cn v7
cryptonight_hash_ctx[0](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[0](PowVariant::POW_V1, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v1, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[1](PowVariant::POW_V1, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v1, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[2](PowVariant::POW_V1, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v1, 96) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 3
cryptonight_hash_ctx[3](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[3](PowVariant::POW_V1, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v1, 128) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 4
cryptonight_hash_ctx[4](PowVariant::POW_V1, test_input, 76, output, ctx);
cryptonight_hash_ctx[4](PowVariant::POW_V1, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_v1, 160) == 0;
#endif
// cn xtl
cryptonight_hash_ctx[0](PowVariant::POW_XTL,test_input, 76, output, ctx);
cryptonight_hash_ctx[0](PowVariant::POW_XTL,test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_xtl, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](PowVariant::POW_XTL, test_input, 76, output, ctx);
cryptonight_hash_ctx[1](PowVariant::POW_XTL, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_xtl, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](PowVariant::POW_XTL, test_input, 76, output, ctx);
cryptonight_hash_ctx[2](PowVariant::POW_XTL, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_xtl, 96) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 3
cryptonight_hash_ctx[3](PowVariant::POW_XTL, test_input, 76, output, ctx);
cryptonight_hash_ctx[3](PowVariant::POW_XTL, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_xtl, 128) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 4
cryptonight_hash_ctx[4](PowVariant::POW_XTL, test_input, 76, output, ctx);
cryptonight_hash_ctx[4](PowVariant::POW_XTL, test_input, 76, output, scratchPads);
result = result && memcmp(output, test_output_xtl, 160) == 0;
#endif
}
_mm_free(ctx->memory);
_mm_free(ctx);
for (size_t i = 0; i < MAX_NUM_HASH_BLOCKS; ++i) {
_mm_free(scratchPads[i]->memory);
_mm_free(scratchPads[i]);
}
return result && resultLite & resultHeavy;
}

View file

@ -37,8 +37,8 @@
#define POW_DEFAULT_INDEX_SHIFT 3
#define POW_XLT_V4_INDEX_SHIFT 4
struct cryptonight_ctx {
alignas(16) uint8_t state[MAX_NUM_HASH_BLOCKS][208]; // 208 instead of 200 to maintain aligned to 16 byte boundaries
struct ScratchPad {
alignas(16) uint8_t state[208]; // 208 instead of 200 to maintain aligned to 16 byte boundaries
alignas(16) uint8_t* memory;
};
@ -51,7 +51,7 @@ class CryptoNight
public:
static bool init(int algo, bool aesni);
static void hash(size_t factor, PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
static void hash(size_t factor, PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPads);
private:
static bool selfTest(int algo);

File diff suppressed because it is too large Load diff

View file

@ -158,7 +158,7 @@ const static uint8_t test_output_heavy[160] = {
};
// CN-Heavy Haven
const static uint8_t test_output_heavy_haven[160] = {
const static uint8_t test_output_heavy_haven[96] = {
0x5A, 0xC3, 0xF7, 0x85, 0xC4, 0x90, 0xC5, 0x85, 0x50, 0xEC, 0x95, 0xD2, 0x72, 0x65, 0x63, 0x57,
0x7E, 0x7C, 0x1C, 0x21, 0x2D, 0x0C, 0xDE, 0x59, 0x12, 0x73, 0x20, 0x1E, 0x44, 0xFD, 0xD5, 0xB6,
0x1F, 0x4E, 0xB2, 0x0A, 0x36, 0x51, 0x4B, 0xF5, 0x4D, 0xC9, 0xE0, 0x90, 0x2C, 0x16, 0x47, 0x3F,
@ -167,4 +167,14 @@ const static uint8_t test_output_heavy_haven[160] = {
0x8F, 0x28, 0x0B, 0xCE, 0x2C, 0xEE, 0xDD, 0x88, 0x94, 0x35, 0x48, 0x51, 0xAE, 0xC8, 0x9C, 0x0B
};
// CN-Heavy Tube
const static uint8_t test_output_heavy_tube[96] = {
0xfe, 0x53, 0x35, 0x20, 0x76, 0xea, 0xe6, 0x89, 0xfa, 0x3b, 0x4f, 0xda, 0x61, 0x46, 0x34, 0xcf,
0xc3, 0x12, 0xee, 0x0c, 0x38, 0x7d, 0xf2, 0xb8, 0xb7, 0x4d, 0xa2, 0xa1, 0x59, 0x74, 0x12, 0x35,
0xcd, 0x3f, 0x29, 0xdf, 0x07, 0x4a, 0x14, 0xad, 0x0b, 0x98, 0x99, 0x37, 0xca, 0x14, 0x68, 0xa3,
0x8d, 0xae, 0x86, 0xc1, 0xa3, 0x54, 0x05, 0xbe, 0xea, 0x6d, 0x29, 0x24, 0x0c, 0x82, 0x97, 0x74,
0xa0, 0x64, 0x77, 0xcd, 0x8d, 0x8a, 0xc3, 0x10, 0xb4, 0x89, 0x0e, 0xbb, 0x7d, 0xe6, 0x32, 0x8f,
0xf4, 0x2d, 0xb6, 0x9e, 0x8a, 0xf9, 0xf8, 0xee, 0x2c, 0xd0, 0x74, 0xed, 0xa9, 0xaa, 0xa1, 0xfb
};
#endif /* __CRYPTONIGHT_TEST_H__ */

File diff suppressed because it is too large Load diff

View file

@ -1189,6 +1189,12 @@ FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b)
return vreinterpretq_m128i_u32(vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
}
// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers in b for greater than. https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx
FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b)
{
return vreinterpretq_m128i_u32(vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
}
// Compares the four 32-bit floats in a and b to check if any values are NaN. Ordered compare between each value returns true for "orderable" and false for "not orderable" (NaN). https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx
// see also:
// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean

View file

@ -105,12 +105,29 @@ static inline __m128i soft_aesenc(const uint32_t* in, __m128i key)
return _mm_xor_si128(out, key);
}
static inline __m128i soft_aesenc(__m128i in, __m128i key)
{
uint32_t x0, x1, x2, x3;
x0 = _mm_cvtsi128_si32(in);
x1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0x55));
x2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xAA));
x3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xFF));
__m128i out = _mm_set_epi32(
(saes_table[0][x3 & 0xff] ^ saes_table[1][(x0 >> 8) & 0xff] ^ saes_table[2][(x1 >> 16) & 0xff] ^ saes_table[3][x2 >> 24]),
(saes_table[0][x2 & 0xff] ^ saes_table[1][(x3 >> 8) & 0xff] ^ saes_table[2][(x0 >> 16) & 0xff] ^ saes_table[3][x1 >> 24]),
(saes_table[0][x1 & 0xff] ^ saes_table[1][(x2 >> 8) & 0xff] ^ saes_table[2][(x3 >> 16) & 0xff] ^ saes_table[3][x0 >> 24]),
(saes_table[0][x0 & 0xff] ^ saes_table[1][(x1 >> 8) & 0xff] ^ saes_table[2][(x2 >> 16) & 0xff] ^ saes_table[3][x3 >> 24]));
return _mm_xor_si128(out, key);
}
static inline uint32_t sub_word(uint32_t key)
{
return (saes_sbox[key >> 24 ] << 24) |
(saes_sbox[(key >> 16) & 0xff] << 16 ) |
(saes_sbox[(key >> 8) & 0xff] << 8 ) |
saes_sbox[key & 0xff];
return (saes_sbox[key >> 24 ] << 24) |
(saes_sbox[(key >> 16) & 0xff] << 16 ) |
(saes_sbox[(key >> 8) & 0xff] << 8 ) |
saes_sbox[key & 0xff];
}
#if defined(__clang__) || defined(XMRIG_ARM)