diff --git a/src/Options.cpp b/src/Options.cpp index 3be979ec..5753880a 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -291,7 +291,8 @@ constexpr static const char *pow_variant_names[] = { "xtl", "msr", "xhv", - "rto" + "rto", + "xfh" }; constexpr static const char *asm_optimization_names[] = { @@ -1070,6 +1071,11 @@ bool Options::parsePowVariant(const char *powVariant) break; } + if (i == ARRAY_SIZE(pow_variant_names) - 1 && (!strcmp(powVariant, "freehaven") || !strcmp(powVariant, "faven"))) { + m_powVariant = POW_XFH; + break; + } + if (i == ARRAY_SIZE(pow_variant_names) - 1) { showUsage(1); return false; diff --git a/src/PowVariant.h b/src/PowVariant.h index 8a01bee8..b1ca313c 100644 --- a/src/PowVariant.h +++ b/src/PowVariant.h @@ -34,6 +34,7 @@ enum PowVariant POW_MSR, POW_XHV, POW_RTO, + POW_XFH, LAST_ITEM }; @@ -59,6 +60,8 @@ inline std::string getPowVariantName(PowVariant powVariant) return "xhv"; case POW_RTO: return "rto"; + case POW_XFH: + return "xfh"; case POW_AUTODETECT: default: return "-1"; @@ -124,6 +127,8 @@ inline PowVariant parseVariant(const std::string variant) powVariant = PowVariant::POW_XHV; } else if (variant == "rto" || variant == "arto") { powVariant = PowVariant::POW_RTO; + } else if (variant == "xfh" || variant == "freehaven" || variant == "faven") { + powVariant = PowVariant::POW_XFH; } return powVariant; diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index a92ee8a6..78131548 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -78,7 +78,9 @@ static void cryptonight_aesni(AsmOptimization asmOptimization, PowVariant powVer } } else if (powVersion == PowVariant::POW_RTO) { CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad); -}else { +} else if (powVersion == PowVariant::POW_XFH) { + CryptoNightMultiHash<0x20000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, scratchPad); +} else { CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad); } # endif @@ -126,6 +128,8 @@ static void cryptonight_softaes(AsmOptimization asmOptimization, PowVariant powV } } else if (powVersion == PowVariant::POW_RTO) { CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad); + } else if (powVersion == PowVariant::POW_XFH) { + CryptoNightMultiHash<0x20000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, scratchPad); } else { CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad); } @@ -508,6 +512,11 @@ bool CryptoNight::selfTest(int algo) cryptonight_hash_ctx[4](asmOptimization, PowVariant::POW_V2, test_input, 76, output, scratchPads); result = result && memcmp(output, test_output_v2, 160) == 0; #endif + + // cn xfh aka cn-heavy-superfast + + cryptonight_hash_ctx[0](asmOptimization, PowVariant::POW_XFH, test_input, 76, output, scratchPads); + result = result && memcmp(output, test_output_xfh, 32) == 0; } for (size_t i = 0; i < MAX_NUM_HASH_BLOCKS; ++i) { diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index 3f98992a..8cf0d637 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -116,6 +116,12 @@ const static uint8_t test_output_alloy[32] = { 0x5D, 0x77, 0x16, 0x21, 0x42, 0x97, 0x5C, 0xB8, 0x50, 0xC0, 0xA5, 0x1F, 0x64, 0x07, 0xBD, 0x33 }; +// CN XFH +const static uint8_t test_output_xfh[32] = { + 0x40, 0x86, 0x5A, 0xA8, 0x87, 0x41, 0xEC, 0x1D, 0xCC, 0xBD, 0x2B, 0xC6, 0xFF, 0x36, 0xB9, 0x4D, + 0x54, 0x71, 0x58, 0xDB, 0x94, 0x69, 0x8E, 0x3C, 0xA0, 0x3D, 0xE4, 0x81, 0x9A, 0x65, 0x9F, 0xEF +}; + // CN-LITE const static uint8_t test_output_v0_lite[160] = { 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,