b0dre
Jr. Member
Offline
Activity: 61
Merit: 1
|
 |
April 01, 2025, 09:55:12 PM |
|
Error compiling!
#include <iostream> #include <array> #include <iomanip> #include <fstream> #include <sstream> #include <vector> #include <thread> #include <atomic> #include <chrono> #include <queue> #include <mutex> #include <cstring> #include <unordered_map> #include <cmath> #include <immintrin.h> #include <omp.h> #include <csignal> #include <random> #include <algorithm> #include <getopt.h>
#ifdef _WIN32 #include <windows.h> #else #include <unistd.h> #endif
// Include the required headers #include "sha256_avx2.h" #include "ripemd160_avx2.h" #include "SECP256K1.h" #include "Point.h" #include "Int.h" #include "IntGroup.h"
using namespace std;
// Cross-platform terminal functions void initConsole() { #ifdef _WIN32 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); DWORD mode = 0; GetConsoleMode(hConsole, &mode); SetConsoleMode(hConsole, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); #endif }
void clearTerminal() { #ifdef _WIN32 HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); COORD coord = {0, 0}; DWORD count; CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo(hStdOut, &csbi); FillConsoleOutputCharacter(hStdOut, ' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &count); SetConsoleCursorPosition(hStdOut, coord); #else std::cout << "\033[2J\033[H"; #endif std::cout.flush(); }
void moveCursorTo(int x, int y) { #ifdef _WIN32 HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); COORD coord = {(SHORT)x, (SHORT)y}; SetConsoleCursorPosition(hStdOut, coord); #else std::cout << "\033[" << y << ";" << x << "H"; #endif std::cout.flush(); }
// Configuration defaults int PUZZLE_NUM = 20; int WORKERS = max(1, (int)thread::hardware_concurrency()); int FLIP_COUNT = -1; const __uint128_t REPORT_INTERVAL = 10000000; static constexpr int POINTS_BATCH_SIZE = 512; static constexpr int HASH_BATCH_SIZE = 8;
// Historical puzzle data const unordered_map<int, tuple<int, string, string>> PUZZLE_DATA = { {20, {8, "b907c3a2a3b27789dfb509b730dd47703c272868", "357535"}}, {21, {9, "29a78213caa9eea824acf08022ab9dfc83414f56", "863317"}}, {22, {11, "7ff45303774ef7a52fffd8011981034b258cb86b", "1811764"}}, {23, {12, "d0a79df189fe1ad5c306cc70497b358415da579e", "3007503"}}, {24, {9, "0959e80121f36aea13b3bad361c15dac26189e2f", "5598802"}}, {25, {12, "2f396b29b27324300d0c59b17c3abc1835bd3dbb", "14428676"}}, {26, {14, "bfebb73562d4541b32a02ba664d140b5a574792f", "33185509"}}, {27, {13, "0c7aaf6caa7e5424b63d317f0f8f1f9fa40d5560", "54538862"}}, {28, {16, "1306b9e4ff56513a476841bac7ba48d69516b1da", "111949941"}}, {29, {18, "5a416cc9148f4a377b672c8ae5d3287adaafadec", "227634408"}}, {30, {16, "d39c4704664e1deb76c9331e637564c257d68a08", "400708894"}}, {31, {13, "d805f6f251f7479ebd853b3d0f4b9b2656d92f1d", "1033162084"}}, {32, {14, "9e42601eeaedc244e15f17375adb0e2cd08efdc9", "2102388551"}}, {33, {15, "4e15e5189752d1eaf444dfd6bff399feb0443977", "3093472814"}}, {34, {16, "f6d67d7983bf70450f295c9cb828daab265f1bfa", "7137437912"}}, {35, {19, "f6d8ce225ffbdecec170f8298c3fc28ae686df25", "14133072157"}}, {36, {14, "74b1e012be1521e5d8d75e745a26ced845ea3d37", "20112871792"}}, {37, {23, "28c30fb11ed1da72e7c4f89c0164756e8a021d", "42387769980"}}, {38, {21, "b190e2d40cfdeee2cee072954a2be89e7ba39364", "100251560595"}}, {39, {23, "0b304f2a79a027270276533fe1ed4eff30910876", "146971536592"}}, {40, {20, "95a156cd21b4a69de969eb6716864f4c8b82a82a", "323724968937"}}, {41, {25, "d1562eb37357f9e6fc41cb2359f4d3eda4032329", "1003651412950"}}, {42, {24, "8efb85f9c5b5db2d55973a04128dc7510075ae23", "1458252205147"}}, {43, {19, "f92044c7924e5525c61207972c253c9fc9f086f7", "2895374552463"}}, {44, {24, "80df54e1f612f2fc5bdc05c9d21a83aa8d20791e", "7409811047825"}}, {45, {21, "f0225bfc68a6e17e87cd8b5e60ae3be18f120753", "15404761757071"}}, {46, {24, "9a012260d01c5113df66c8a8438c9f7a1e3d5dac", "19996463086597"}}, {47, {27, "f828005d41b0f4fed4c8dca3b06011072cfb07d4", "51408670348612"}}, {48, {21, "8661cb56d9df0a61f01328b55af7e56a3fe7a2b2", "119666659114170"}}, {49, {30, "0d2f533966c6578e1111978ca698f8add7fffdf3", "191206974700443"}}, {50, {29, "de081b76f840e462fa2cdf360173dfaf4a976a47", "409118905032525"}}, {51, {25, "ef6419cffd7fad7027994354eb8efae223c2dbe7", "611140496167764"}}, {52, {27, "36af659edbe94453f6344e920d143f1778653ae7", "2058769515153876"}}, {53, {26, "2f4870ef54fa4b048c1365d42594cc7d3d269551", "4216495639600700"}}, {54, {30, "cb66763cf7fde659869ae7f06884d9a0f879a092", "6763683971478124"}}, {55, {31, "db53d9bbd1f3a83b094eeca7dd970bd85b492fa2", "9974455244496707"}}, {56, {31, "48214c5969ae9f43f75070cea1e2cb41d5bdcccd", "30045390491869460"}}, {57, {33, "328660ef43f66abe2653fa178452a5dfc594c2a1", "44218742292676575"}}, {58, {28, "8c2a6071f89c90c4dab5ab295d7729d1b54ea60f", "138245758910846492"}}, {59, {30, "b14ed3146f5b2c9bde1703deae9ef33af8110210", "199976667976342049"}}, {60, {31, "cdf8e5c7503a9d22642e3ecfc87817672787b9c5", "525070384258266191"}}, {61, {25, "68133e19b2dfb9034edf9830a200cfdf38c90cbd", "1135041350219496382"}}, {62, {35, "e26646db84b0602f32b34b5a62ca3cae1f91b779", "1425787542618654982"}}, {63, {34, "ef58afb697b094423ce90721fbb19a359ef7c50e", "3908372542507822062"}}, {64, {34, "3ee4133d991f52fdf6a25c9834e0745ac74248a4", "8993229949524469768"}}, {65, {37, "52e763a7ddc1aa4fa811578c491c1bc7fd570137", "17799667357578236628"}}, {66, {35, "20d45a6a762535700ce9e0b216e31994335db8a5", "30568377312064202855"}}, {67, {31, "739437bb3dd6d1983e66629c5f08c70e52769371", "46346217550346335726"}}, {68, {34, "e0b8a2baee1b77fc703455f39d51477451fc8cfc", "132656943602386256302"}} };
// Global variables vector<unsigned char> TARGET_HASH160_RAW(20); string TARGET_HASH160; Int BASE_KEY; atomic<bool> stop_event(false); mutex result_mutex; queue<tuple<string, __uint128_t, int>> results;
// 128-bit counter atomic<uint64_t> total_checked_high(0); atomic<uint64_t> total_checked_low(0); __uint128_t total_combinations = 0; vector<string> g_threadPrivateKeys; mutex progress_mutex;
// Performance tracking atomic<uint64_t> globalComparedCount(0); atomic<uint64_t> localComparedCount(0); double globalElapsedTime = 0.0; double mkeysPerSec = 0.0; chrono::time_point<chrono::high_resolution_clock> tStart;
// Helper functions __uint128_t load_128() { return (static_cast<__uint128_t>(total_checked_high.load()) << 64) | total_checked_low.load(); }
void increment_128() { uint64_t old_low = total_checked_low.fetch_add(1); if (old_low == UINT64_MAX) { total_checked_high.fetch_add(1); } }
static string formatElapsedTime(double seconds) { int hrs = static_cast<int>(seconds) 3600; int mins = (static_cast<int>(seconds) % 3600) 60; int secs = static_cast<int>(seconds) % 60; ostringstream oss; oss << setw(2) << setfill('0') << hrs << ":" << setw(2) << setfill('0') << mins << ":" << setw(2) << setfill('0') << secs; return oss.str(); }
static string to_string_128(__uint128_t value) { if (value == 0) return "0"; char buffer[50]; char* p = buffer + sizeof(buffer); *--p = '\0'; while (value != 0) { *--p = "0123456789"[value % 10]; value= 10; } return p; }
void signalHandler(int signum) { stop_event.store(true); cout << "\nInterrupt received, shutting down...\n"; }
class CombinationGenerator { int n, k; vector<int> current; mt19937_64 rng; public: CombinationGenerator(int n, int k, uint64_t seed = 0) : n(n), k(k), current(k), rng(seed) { if (k > n) k = n; for (int i = 0; i < k; ++i) current[i] = i; }
static __uint128_t combinations_count(int n, int k) { if (k > n) return 0; if (k * 2 > n) k = n - k; if (k == 0) return 1;
__uint128_t result = n; for(int i = 2; i <= k; ++i) { result *= (n - i + 1); result= i; } return result; }
const vector<int>& get() const { return current; } bool next() { int i = k - 1; while (i >= 0 && current[i] == n - k + i) --i; if (i < 0) return false; ++current[i]; for (int j = i + 1; j < k; ++j) current[j] = current[j-1] + 1; return true; } void unrank(__uint128_t rank) { __uint128_t total = combinations_count(n, k); if (rank >= total) { current.clear(); return; } current.resize(k); __uint128_t remaining_rank = rank; int a = n; int b = k; __uint128_t x = (total - 1) - rank; for (int i = 0; i < k; i++) { a = largest_a_where_comb_a_b_le_x(a, b, x); current[i] = (n - 1) - a; x -= combinations_count(a, b); b--; } }
private: int largest_a_where_comb_a_b_le_x(int a, int b, __uint128_t x) const { while (a >= b && combinations_count(a, b) > x) a--; return a; } };
static void computeHash160BatchBinSingle(int numKeys, uint8_t pubKeys[][33], uint8_t hashResults[][20]) { alignas(32) array<array<uint8_t, 64>, HASH_BATCH_SIZE> shaInputs; alignas(32) array<array<uint8_t, 32>, HASH_BATCH_SIZE> shaOutputs; alignas(32) array<array<uint8_t, 64>, HASH_BATCH_SIZE> ripemdInputs; alignas(32) array<array<uint8_t, 20>, HASH_BATCH_SIZE> ripemdOutputs;
const __uint128_t totalBatches = (numKeys + (HASH_BATCH_SIZE - 1)) HASH_BATCH_SIZE;
for (__uint128_t batch = 0; batch < totalBatches; batch++) { const __uint128_t batchCount = min<__uint128_t>(HASH_BATCH_SIZE, numKeys - batch * HASH_BATCH_SIZE);
/ Prepare SHA-256 input blocks for (__uint128_t i = 0; i < batchCount; i++) { memset(shaInputs[i].data(), 0, 64); memcpy(shaInputs[i].data(), pubKeys[batch * HASH_BATCH_SIZE + i], 33); shaInputs[i][33] = 0x80; *reinterpret_cast<uint32_t*>(&shaInputs[i][60]) = _byteswap_ulong(33 * 8); } if (batchCount < HASH_BATCH_SIZE) { static array<uint8_t, 64> shaPadding = {}; memset(shaPadding.data(), 0, 64); memcpy(shaPadding.data(), pubKeys[0], 33); shaPadding[33] = 0x80; *reinterpret_cast<uint32_t*>(&shaPadding[60]) = _byteswap_ulong(33 * 8); for (__uint128_t i = batchCount; i < HASH_BATCH_SIZE; i++) { memcpy(shaInputs[i].data(), shaPadding.data(), 64); } }
uint8_t* inPtr[HASH_BATCH_SIZE]; uint8_t* outPtr[HASH_BATCH_SIZE]; for (int i = 0; i < HASH_BATCH_SIZE; i++) { inPtr[i] = shaInputs[i].data(); outPtr[i] = shaOutputs[i].data(); }
sha256avx2_8B(inPtr[0], inPtr[1], inPtr[2], inPtr[3], inPtr[4], inPtr[5], inPtr[6], inPtr[7], outPtr[0], outPtr[1], outPtr[2], outPtr[3], outPtr[4], outPtr[5], outPtr[6], outPtr[7]);
for (__uint128_t i = 0; i < batchCount; i++) { memset(ripemdInputs[i].data(), 0, 64); memcpy(ripemdInputs[i].data(), shaOutputs[i].data(), 32); ripemdInputs[i][32] = 0x80; *reinterpret_cast<uint32_t*>(&ripemdInputs[i][60]) = _byteswap_ulong(256); }
if (batchCount < HASH_BATCH_SIZE) { static array<uint8_t, 64> ripemdPadding = {}; memset(ripemdPadding.data(), 0, 64); memcpy(ripemdPadding.data(), shaOutputs[0].data(), 32); ripemdPadding[32] = 0x80; *reinterpret_cast<uint32_t*>(&ripemdPadding[60]) = _byteswap_ulong(256); for (__uint128_t i = batchCount; i < HASH_BATCH_SIZE; i++) { memcpy(ripemdInputs[i].data(), ripemdPadding.data(), 64); } }
for (int i = 0; i < HASH_BATCH_SIZE; i++) { inPtr[i] = ripemdInputs[i].data(); outPtr[i] = ripemdOutputs[i].data(); }
ripemd160avx2::ripemd160avx2_32( inPtr[0], inPtr[1], inPtr[2], inPtr[3], inPtr[4], inPtr[5], inPtr[6], inPtr[7], outPtr[0], outPtr[1], outPtr[2], outPtr[3], outPtr[4], outPtr[5], outPtr[6], outPtr[7] );
for (__uint128_t i = 0; i < batchCount; i++) { memcpy(hashResults[batch * HASH_BATCH_SIZE + i], ripemdOutputs[i].data(), 20); } } }
void worker(Secp256K1* secp, int bit_length, int flip_count, int threadId, __uint128_t start, __uint128_t end) { const int fullBatchSize = 2 * POINTS_BATCH_SIZE; uint8_t localPubKeys[HASH_BATCH_SIZE][33]; uint8_t localHashResults[HASH_BATCH_SIZE][20]; int pointIndices[HASH_BATCH_SIZE]; / Precompute points vector<Point> plusPoints(POINTS_BATCH_SIZE); vector<Point> minusPoints(POINTS_BATCH_SIZE); for (int i = 0; i < POINTS_BATCH_SIZE; i++) { Int tmp; tmp.SetInt32(i); plusPoints[i] = secp->ComputePublicKey(&tmp); minusPoints[i] = plusPoints[i]; minusPoints[i].y.ModNeg(); }
/ Structure of Arrays vector<Int> deltaX(POINTS_BATCH_SIZE); IntGroup modGroup(POINTS_BATCH_SIZE); vector<Int> pointBatchX(fullBatchSize); vector<Int> pointBatchY(fullBatchSize);
/ Random number generation random_device rd; mt19937_64 rng(rd() + threadId); uniform_int_distribution<uint64_t> dist(0, UINT64_MAX);
CombinationGenerator gen(bit_length, flip_count, rd() + threadId); gen.unrank(start);
for (__uint128_t count = start; !stop_event.load() && count < end; ) { Int currentKey; currentKey.Set(&BASE_KEY); const vector<int>& flips = gen.get(); / Apply flips for (int pos : flips) { Int mask; mask.SetInt32(1); mask.ShiftL(pos); Int temp; temp.Set(¤tKey); temp.ShiftR(pos); temp.IsEven() ? currentKey.Add(&mask) : currentKey.Sub(&mask); }
/ Store private key string keyStr = currentKey.GetBase16(); keyStr = string(64 - keyStr.length(), '0') + keyStr; #pragma omp critical g_threadPrivateKeys[threadId] = keyStr;
/ Compute public key Point startPoint = secp->ComputePublicKey(¤tKey); Int startPointX = startPoint.x, startPointY = startPoint.y, startPointXNeg = startPointX; startPointXNeg.ModNeg();
/ Compute deltaX values for (int i = 0; i < POINTS_BATCH_SIZE; i += 4) { deltaX[i].ModSub(&plusPoints[i].x, &startPointX); deltaX[i+1].ModSub(&plusPoints[i+1].x, &startPointX); deltaX[i+2].ModSub(&plusPoints[i+2].x, &startPointX); deltaX[i+3].ModSub(&plusPoints[i+3].x, &startPointX); } modGroup.Set(deltaX.data()); modGroup.ModInv();
/ Process points for (int i = 0; i < POINTS_BATCH_SIZE; i += 4) { for (int j = 0; j < 4; j++) { / Plus points Int deltaY; deltaY.ModSub(&plusPoints[i+j].y, &startPointY); Int slope; slope.ModMulK1(&deltaY, &deltaX[i+j]); Int slopeSq; slopeSq.ModSquareK1(&slope); pointBatchX[i+j].Set(&startPointXNeg); pointBatchX[i+j].ModAdd(&slopeSq); pointBatchX[i+j].ModSub(&plusPoints[i+j].x); Int diffX; diffX.ModSub(&startPointX, &pointBatchX[i+j]); diffX.ModMulK1(&slope); pointBatchY[i+j].Set(&startPointY); pointBatchY[i+j].ModNeg(); pointBatchY[i+j].ModAdd(&diffX);
/ Minus points deltaY.ModSub(&minusPoints[i+j].y, &startPointY); slope.ModMulK1(&deltaY, &deltaX[i+j]); slopeSq.ModSquareK1(&slope); pointBatchX[POINTS_BATCH_SIZE+i+j].Set(&startPointXNeg); pointBatchX[POINTS_BATCH_SIZE+i+j].ModAdd(&slopeSq); pointBatchX[POINTS_BATCH_SIZE+i+j].ModSub(&minusPoints[i+j].x); diffX.ModSub(&startPointX, &pointBatchX[POINTS_BATCH_SIZE+i+j]); diffX.ModMulK1(&slope); pointBatchY[POINTS_BATCH_SIZE+i+j].Set(&startPointY); pointBatchY[POINTS_BATCH_SIZE+i+j].ModNeg(); pointBatchY[POINTS_BATCH_SIZE+i+j].ModAdd(&diffX); } }
/ Process keys in batches int localBatchCount = 0; for (int i = 0; i < fullBatchSize && localBatchCount < HASH_BATCH_SIZE; i++) { Point tempPoint; tempPoint.x.Set(&pointBatchX[i]); tempPoint.y.Set(&pointBatchY[i]); / Convert to compressed public key localPubKeys[localBatchCount][0] = tempPoint.y.IsEven() ? 0x02 : 0x03; for (int j = 0; j < 32; j++) { localPubKeys[localBatchCount][1 + j] = pointBatchX[i].GetByte(31 - j); } pointIndices[localBatchCount] = i; localBatchCount++;
if (localBatchCount == HASH_BATCH_SIZE) { computeHash160BatchBinSingle(localBatchCount, localPubKeys, localHashResults); localComparedCount += HASH_BATCH_SIZE; __m256i target = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(TARGET_HASH160_RAW.data()));
for (int j = 0; j < HASH_BATCH_SIZE; j++) { __m256i result = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(localHashResults[j])); int mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(result, target)); const int HASH160_MASK = (1 << 20) - 1; if ((mask & HASH160_MASK) == HASH160_MASK) { bool fullMatch = true; for (int k = 0; k < 20; k++) { if (localHashResults[j][k] != TARGET_HASH160_RAW[k]) { fullMatch = false; break; } } if (fullMatch) { auto tEndTime = chrono::high_resolution_clock::now(); globalElapsedTime = chrono::duration<double>(tEndTime - tStart).count(); mkeysPerSec = (double)(globalComparedCount + localComparedCount) globalElapsedTime 1e6; Int foundKey; foundKey.Set(¤tKey); int idx = pointIndices[j]; if (idx < POINTS_BATCH_SIZE) { Int offset; offset.SetInt32(idx); foundKey.Add(&offset); } else { Int offset; offset.SetInt32(idx - POINTS_BATCH_SIZE); foundKey.Sub(&offset); } string hexKey = foundKey.GetBase16(); hexKey = string(64 - hexKey.length(), '0') + hexKey; lock_guard<mutex> lock(result_mutex); results.push(make_tuple(hexKey, load_128(), flip_count)); stop_event.store(true); return; } } } increment_128(); localBatchCount = 0;
/ Progress reporting __uint128_t current_total = load_128(); if (current_total % REPORT_INTERVAL == 0 || count == end - 1) { auto now = chrono::high_resolution_clock::now(); globalElapsedTime = chrono::duration<double>(now - tStart).count(); globalComparedCount += localComparedCount; localComparedCount = 0; mkeysPerSec = (double)globalComparedCount globalElapsedTime 1e6; double progress = min(100.0, (double)current_total total_combinations * 100.0); lock_guard<mutex> lock(progress_mutex); moveCursorTo(0, 9); cout << "Progress: " << fixed << setprecision(6) << progress << "%\n"; cout << "Processed: " << to_string_128(current_total) << "\n"; cout << "Speed: " << fixed << setprecision(2) << mkeysPerSec << " Mkeys/s\n"; cout << "Elapsed Time: " << formatElapsedTime(globalElapsedTime) << "\n"; cout.flush();
if (current_total >= total_combinations) { stop_event.store(true); break; } } } }
if (!gen.next()) break; count++; }
if (!stop_event.load() && load_128() >= total_combinations) { stop_event.store(true); } }
void printUsage(const char* programName) { cout << "Usage: " << programName << " [options]\n"; cout << "Options:\n"; cout << " -p, --puzzle NUM Puzzle number to solve (default: 20)\n"; cout << " -t, --threads NUM Number of CPU cores to use (default: all)\n"; cout << " -f, --flips NUM Override default flip count for puzzle\n"; cout << " -h, --help Show this help message\n"; cout << "\nExample:\n"; cout << " " << programName << " -p 38 -t 8 -f 21\n"; }
int main(int argc, char* argv[]) { signal(SIGINT, signalHandler); / Parse command line arguments int opt; int option_index = 0; static struct option long_options[] = { {"puzzle", required_argument, 0, 'p'}, {"threads", required_argument, 0, 't'}, {"flips", required_argument, 0, 'f'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} };
while ((opt = getopt_long(argc, argv, "p:t:f:h", long_options, &option_index)) != -1) { switch (opt) { case 'p': PUZZLE_NUM = atoi(optarg); if (PUZZLE_NUM < 20 || PUZZLE_NUM > 68) { cerr << "Error: Puzzle number must be between 20 and 68\n"; return 1; } break; case 't': WORKERS = atoi(optarg); if (WORKERS < 1) { cerr << "Error: Thread count must be at least 1\n"; return 1; } break; case 'f': FLIP_COUNT = atoi(optarg); if (FLIP_COUNT < 1) { cerr << "Error: Flip count must be at least 1\n"; return 1; } break; case 'h': printUsage(argv[0]); return 0; default: printUsage(argv[0]); return 1; } }
tStart = chrono::high_resolution_clock::now();
Secp256K1 secp; secp.Init(); auto puzzle_it = PUZZLE_DATA.find(PUZZLE_NUM); if (puzzle_it == PUZZLE_DATA.end()) { cerr << "Error: Invalid puzzle number\n"; return 1; } auto [DEFAULT_FLIP_COUNT, TARGET_HASH160_HEX, PRIVATE_KEY_DECIMAL] = puzzle_it->second; if (FLIP_COUNT == -1) FLIP_COUNT = DEFAULT_FLIP_COUNT; TARGET_HASH160 = TARGET_HASH160_HEX; / Convert target hash to bytes for (__uint128_t i = 0; i < 20; i++) { TARGET_HASH160_RAW[i] = stoul(TARGET_HASH160.substr(i * 2, 2), nullptr, 16); } / Set base key BASE_KEY.SetBase10(const_cast<char*>(PRIVATE_KEY_DECIMAL.c_str())); / Verify base key Int testKey; testKey.SetBase10(const_cast<char*>(PRIVATE_KEY_DECIMAL.c_str())); if (!testKey.IsEqual(&BASE_KEY)) { cerr << "Base key initialization failed!\n"; return 1; }
if (BASE_KEY.GetBitLength() > PUZZLE_NUM) { cerr << "Base key exceeds puzzle bit length!\n"; return 1; } / Calculate total combinations total_combinations = CombinationGenerator::combinations_count(PUZZLE_NUM, FLIP_COUNT); / Format base key for display string paddedKey = BASE_KEY.GetBase16(); size_t firstNonZero = paddedKey.find_first_not_of('0'); paddedKey = paddedKey.substr(firstNonZero); paddedKey = "0x" + paddedKey;
/ Print initial header clearTerminal(); cout << "=======================================\n"; cout << "== Mutagen Puzzle Solver by Denevron ==\n"; cout << "=======================================\n"; cout << "Starting puzzle: " << PUZZLE_NUM << " (" << PUZZLE_NUM << "-bit)\n"; cout << "Target HASH160: " << TARGET_HASH160.substr(0, 10) << "..." << TARGET_HASH160.substr(TARGET_HASH160.length()-10) << "\n"; cout << "Base Key: " << paddedKey << "\n"; cout << "Flip count: " << FLIP_COUNT << " "; if (FLIP_COUNT != DEFAULT_FLIP_COUNT) { cout << "(override, default was " << DEFAULT_FLIP_COUNT << ")"; } cout << "\n"; cout << "Total combinations for C(" << PUZZLE_NUM << "," << FLIP_COUNT << "): " << to_string_128(total_combinations) << "\n"; cout << "Using: " << WORKERS << " threads\n"; / Print empty lines for progress display cout << "Progress: 0.000000%\n"; cout << "Processed: 0\n"; cout << "Speed: 0.00 Mkeys/s\n"; cout << "Elapsed Time: 00:00:00\n";
g_threadPrivateKeys.resize(WORKERS, "0"); vector<thread> threads; / Distribute work __uint128_t comb_per_thread = total_combinations WORKERS; __uint128_t remainder = total_combinations % WORKERS; for (int i = 0; i < WORKERS; i++) { __uint128_t start = i * comb_per_thread + min((__uint128_t)i, remainder); __uint128_t end = start + comb_per_thread + (i < remainder ? 1 : 0); threads.emplace_back(worker, &secp, PUZZLE_NUM, FLIP_COUNT, i, start, end); } for (auto& t : threads) { if (t.joinable()) t.join(); } if (!results.empty()) { auto [hex_key, checked, flips] = results.front(); globalElapsedTime = chrono::duration<double>(chrono::high_resolution_clock::now() - tStart).count(); mkeysPerSec = (double)globalComparedCount globalElapsedTime 1e6;
string compactHex = hex_key; size_t firstNonZero = compactHex.find_first_not_of('0'); compactHex = "0x" + compactHex.substr(firstNonZero);
cout << "=======================================\n"; cout << "=========== SOLUTION FOUND ============\n"; cout << "=======================================\n"; cout << "Private key: " << compactHex << "\n"; cout << "Checked " << to_string_128(checked) << " combinations\n"; cout << "Bit flips: " << flips << endl; cout << "Time: " << fixed << setprecision(2) << globalElapsedTime << " seconds (" << formatElapsedTime(globalElapsedTime) << ")\n"; cout << "Speed: " << fixed << setprecision(2) << mkeysPerSec << " Mkeys/s\n"; / Save solution ofstream out("puzzle_" + to_string(PUZZLE_NUM) + "_solution.txt"); if (out) { out << hex_key; out.close(); cout << "Solution saved to puzzle_" << PUZZLE_NUM << "_solution.txt\n"; } else { cerr << "Failed to save solution to file!\n"; } } else { __uint128_t final_count = load_128(); globalElapsedTime = chrono::duration<double>(chrono::high_resolution_clock::now() - tStart).count(); mkeysPerSec = (double)globalComparedCount globalElapsedTime 1e6; cout << "\n\nNo solution found. Checked " << to_string_128(load_128()) << " combinations\n"; cout << "Time: " << fixed << setprecision(2) << globalElapsedTime << " seconds (" << formatElapsedTime(globalElapsedTime) << ")\n"; cout << "Speed: " << fixed << setprecision(2) << mkeysPerSec << " Mkeys/s\n"; } return 0; }
test again mutagen.cpp: In function 'void computeHash160BatchBinSingle(int, uint8_t (*)[33], uint8_t (*)[20])': mutagen.cpp:280:63: error: '_byteswap_ulong' was not declared in this scope; did you mean '_byteswap_uint64'? 280 | *reinterpret_cast<uint32_t*>(&shaInputs[i][60]) = _byteswap_ulong(33 * 8); | ^~~~~~~~~~~~~~~ | _byteswap_uint64 mutagen.cpp:288:61: error: '_byteswap_ulong' was not declared in this scope; did you mean '_byteswap_uint64'? 288 | *reinterpret_cast<uint32_t*>(&shaPadding[60]) = _byteswap_ulong(33 * 8); | ^~~~~~~~~~~~~~~ | _byteswap_uint64 mutagen.cpp:310:66: error: '_byteswap_ulong' was not declared in this scope; did you mean '_byteswap_uint64'? 310 | *reinterpret_cast<uint32_t*>(&ripemdInputs[i][60]) = _byteswap_ulong(256); | ^~~~~~~~~~~~~~~ | _byteswap_uint64 mutagen.cpp:318:64: error: '_byteswap_ulong' was not declared in this scope; did you mean '_byteswap_uint64'? 318 | *reinterpret_cast<uint32_t*>(&ripemdPadding[60]) = _byteswap_ulong(256); | ^~~~~~~~~~~~~~~ | _byteswap_uint64
|