Prepare XMRig-HAC fork for public release

- Add DragonX coin and rx/hush algorithm support
- Update branding to XMRig-HAC / dragonx.is
- Update repository URLs to git.hush.is
- Replace example wallet addresses with placeholders
- Update .gitignore for build directories
- Document fork changes in README and CHANGELOG
This commit is contained in:
dan_s
2026-02-26 23:48:10 -06:00
parent d49e9a5199
commit 67b9cde59e
24 changed files with 291 additions and 52 deletions

View File

@@ -24,7 +24,34 @@
#include <algorithm>
#include <cstring>
#include <openssl/sha.h>
#ifdef XMRIG_FEATURE_TLS
# include <openssl/sha.h>
#else
// Standalone SHA-256 for non-TLS builds (Windows cross-compile)
# ifdef _WIN32
# include <windows.h>
# include <bcrypt.h>
static void SHA256(const uint8_t* data, size_t len, uint8_t* out) {
BCRYPT_ALG_HANDLE hAlg = nullptr;
BCRYPT_HASH_HANDLE hHash = nullptr;
BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA256_ALGORITHM, nullptr, 0);
BCryptCreateHash(hAlg, &hHash, nullptr, 0, nullptr, 0, 0);
BCryptHashData(hHash, const_cast<PUCHAR>(data), static_cast<ULONG>(len), 0);
BCryptFinishHash(hHash, out, 32, 0);
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
}
# else
# include "crypto/ghostrider/sph_sha2.h"
static void SHA256(const uint8_t* data, size_t len, uint8_t* out) {
sph_sha256_context ctx;
sph_sha256_init(&ctx);
sph_sha256(&ctx, data, len);
sph_sha256_close(&ctx, out);
}
# endif
#endif
namespace xmrig {
@@ -344,11 +371,25 @@ bool HushClient::parseBlockTemplate(const rapidjson::Value &result)
const uint64_t keyHeight = getKeyHeight(m_height);
if (keyHeight != m_keyHeight || m_keyBlockHash.isEmpty()) {
if (keyHeight == 0) {
// Use genesis key - chain-specific initial seed
// For HACs this is typically: hash(magic + symbol + rpcport)
m_keyBlockHash = "0000000000000000000000000000000000000000000000000000000000000000";
// Use chain-specific initial RandomX key.
// Daemon computes: sprintf("%08x%s%08x", ASSETCHAINS_MAGIC, SYMBOL, RPCPORT)
// and passes the raw ASCII bytes to randomx_init_cache().
// We hex-encode those bytes (zero-padded to 32) for setSeedHash().
char initialKey[81];
const uint32_t magic = 2387029918u; // DRAGONX ASSETCHAINS_MAGIC
const char* symbol = "DRAGONX";
const uint16_t rpcPort = 21769;
snprintf(initialKey, sizeof(initialKey), "%08x%s%08x", magic, symbol, (uint32_t)rpcPort);
const size_t keyLen = strlen(initialKey);
// Hex-encode only the actual key bytes (no zero-padding).
// The daemon passes strlen(initialKey) bytes to randomx_init_cache(),
// so we must match that exact length.
char hexBuf[163]; // max 81 bytes * 2 + 1
for (size_t i = 0; i < keyLen; i++) snprintf(hexBuf + i*2, 3, "%02x", (uint8_t)initialKey[i]);
hexBuf[keyLen * 2] = '\0';
m_keyBlockHash = hexBuf;
m_keyHeight = 0;
LOG_INFO("%s " CYAN("using genesis RandomX key for height %u"), tag(), m_height);
LOG_INFO("%s " CYAN("using initial RandomX key \"%s\" for height %u"), tag(), initialKey, m_height);
} else {
LOG_INFO("%s " CYAN("fetching RandomX key block hash at height %u"), tag(), keyHeight);
getBlockHash(keyHeight);
@@ -504,9 +545,19 @@ bool HushClient::parseResponse(int64_t id, const rapidjson::Value &result, const
case REQ_KEYHASH:
if (result.IsString()) {
m_keyBlockHash = result.GetString();
// getblockhash returns display-order (big-endian) hex, but the daemon
// passes uint256 internal bytes (little-endian) to randomx_init_cache().
// Reverse the bytes so setSeedHash() produces the correct LE byte order.
const char* displayHash = result.GetString();
std::vector<uint8_t> hashBytes(32);
Cvt::fromHex(hashBytes.data(), 32, displayHash, 64);
std::reverse(hashBytes.begin(), hashBytes.end());
char reversedHex[65];
for (size_t i = 0; i < 32; i++) snprintf(reversedHex + i*2, 3, "%02x", hashBytes[i]);
reversedHex[64] = '\0';
m_keyBlockHash = reversedHex;
m_keyHeight = m_pendingKeyHeight;
LOG_INFO("%s " GREEN("RandomX key block %u: %.16s..."),
LOG_INFO("%s " GREEN("RandomX key block %u: %.16s... (reversed to LE)"),
tag(), m_keyHeight, m_keyBlockHash.data());
// Now get the block template again with the key
m_pendingRequest = REQ_NONE;
@@ -741,8 +792,8 @@ std::string HushClient::serializeBlockHex(uint32_t nonce, const uint8_t* solutio
void HushClient::sha256d(const uint8_t* data, size_t len, uint8_t* out)
{
uint8_t hash1[32];
SHA256(data, len, hash1);
SHA256(hash1, 32, out);
::SHA256(data, len, hash1);
::SHA256(hash1, 32, out);
}
std::vector<uint8_t> HushClient::serializeHeader(uint32_t nonce, const uint8_t* solution) const