Bitcoin Forum
April 21, 2026, 04:16:41 PM *
News: Latest Bitcoin Core release: 30.2 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 ... 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 [422] 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 ... 652 »
  Print  
Author Topic: Bitcoin puzzle transaction ~32 BTC prize to who solves it  (Read 380466 times)
nomachine
Full Member
***
Offline Offline

Activity: 812
Merit: 134



View Profile
March 31, 2025, 06:16:41 AM
 #8421

But when they finally realize they were throwed into delusion ....

I go fishing when I reach that stage, without a phone or internet. When I forget everything, I sit down at the PC again. In between, I grill fish or read books.   Wink

That's the right attitude !

 But i guess some people expect they have big chance to win in this lottery and  this is their chance to improve life financially ... i guess they can be very dissapointed at some point.

Yeah, but if you don't participate in the lottery, you can't win.
I have no illusions—this is an impossible mission. I'm just here for fun because I don't need wealth. I've been relatively rich and gone bankrupt several times. There is no amount of money that can't be gambled away or spent.

BTC: bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 420
Merit: 8


View Profile
March 31, 2025, 06:26:10 AM
Last edit: March 31, 2025, 08:17:17 AM by Akito S. M. Hosana
 #8422

Yeah, but if you don't participate in the lottery, you can't win.

You can't even lose if you don't participate.

I've been relatively rich and gone bankrupt several times. There is no amount of money that can't be gambled away or spent.

I've been broke all my life and have nothing to stake.  Tongue


But we love useless scripts—I’m even a collector  Grin

Can you add a random generator to CombinationGenerator with the unrank algorithm? I have a feeling that the whole puzzle is generated this way. If only you could reset the random seed to 2015.  Grin
nomachine
Full Member
***
Offline Offline

Activity: 812
Merit: 134



View Profile
March 31, 2025, 08:59:11 AM
 #8423

CombinationGenerator with the unrank algorithm?

I'll do that too, but don't ask me tomorrow for the 'stride' option, searching for a prefix by length, or for the script to output the moon phases during the day  Smiley

BTC: bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
AlanJohnson
Member
**
Offline Offline

Activity: 185
Merit: 11


View Profile
March 31, 2025, 09:19:55 AM
 #8424

For all who wants to face the truth i made that simple page:

http://jastrzeblu.cluster021.hosting.ovh.net/

It estimates the time to solve the puzzle blindly checking private keys... just enter your speed and select a puzzle...

(It does not calculate for BSGS or Kangaroo of course)

Denevron
Newbie
*
Offline Offline

Activity: 121
Merit: 0


View Profile
March 31, 2025, 11:17:37 AM
 #8425

Probabilities, skips, jumps, random selections, combinations, bit flips, base58 voodoos - guys

People need something to do in their free time if they have it to spare.
It's better than doing drugs, joining a local gang, or staring at their phones, waging troll wars to ruin others' smiles out of pure spite.   Grin


The program is on my github, it is at the initial stage of development)
There is also a Python version there.

https://github.com/MikeWazovksy/Mutagen

Thank you for your help @nomachine


Code:
#include <iostream>
#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 <openssl/ec.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <openssl/bn.h>
#include <openssl/obj_mac.h>
#include <openssl/evp.h>

using namespace std;

// Configuration
const string TARGET_HASH160 = "b907c3a2a3b27789dfb509b730dd47703c272868";
const string BASE_KEY = "000000000000000000000000000000000000000000000000000000000005749f";
const int PUZZLE_NUM = 20;
const int WORKERS = thread::hardware_concurrency();
const size_t REPORT_INTERVAL = 10000;

// Historical flip counts
const unordered_map<int, int> FLIP_TABLE = {
     {20, 8},   {21, 9},  {22, 11}, {23, 12},  {24, 9},  {25, 12}, {26, 14}, {27, 13},
    {28, 16}, {29, 18}, {30, 16}, {31, 13}, {32, 14}, {33, 15}, {34, 16}, {35, 19},
    {36, 14}, {37, 23}, {38, 21}, {39, 23}, {40, 20}, {41, 25}, {42, 24}, {43, 19},
    {44, 24}, {45, 21}, {46, 24}, {47, 27}, {48, 21}, {49, 30}, {50, 29}, {51, 25},
    {52, 27}, {53, 26}, {54, 30}, {55, 31}, {56, 31}, {57, 33}, {58, 28}, {59, 30},
    {60, 31}, {61, 25}, {62, 35}, {63, 34}, {64, 34}, {65, 37}, {66, 35}, {67, 31},
    {68, 34}
};

// Global variables
vector<unsigned char> TARGET_HASH160_RAW(20);
atomic<bool> stop_event(false);
mutex result_mutex;
queue<tuple<string, size_t, int>> results;
atomic<size_t> total_checked(0);
size_t total_combinations = 0;

// Convert hex string to raw bytes
vector<unsigned char> hex_to_bytes(const string& hex) {
    vector<unsigned char> bytes;
    for (size_t i = 0; i < hex.length(); i += 2) {
        string byteString = hex.substr(i, 2);
        unsigned char byte = static_cast<unsigned char>(strtoul(byteString.c_str(), nullptr, 16));
        bytes.push_back(byte);
    }
    return bytes;
}

// Get only the last n bits of a BIGNUM
BIGNUM* get_last_n_bits(BIGNUM* num, int n) {
    BIGNUM* result = BN_new();
    BN_zero(result);
    
    for (int i = 0; i < n; ++i) {
        if (BN_is_bit_set(num, i)) {
            BN_set_bit(result, i);
        }
    }
    return result;
}

// Predict flip count
int predict_flips(int puzzle_num) {
    if (FLIP_TABLE.count(puzzle_num)) {
        return FLIP_TABLE.at(puzzle_num);
    }
    return 34; // Default for puzzle 68
}

// Binomial coefficient calculation
size_t combinations_count(int n, int k) {
    if (k > n) return 0;
    if (k * 2 > n) k = n - k;
    if (k == 0) return 1;

    size_t result = n;
    for(int i = 2; i <= k; ++i) {
        result *= (n - i + 1);
        result /= i;
    }
    return result;
}

// Memory-efficient combination generator
class CombinationGenerator {
    int n, k;
    vector<int> current;
public:
    CombinationGenerator(int n, int k) : n(n), k(k), current(k) {
        for (int i = 0; i < k; ++i) current[i] = i;
    }
  
    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;
    }
  
    const vector<int>& get() const { return current; }
};

// Fast BIGNUM XOR for n bits
void bn_xor_nbits(BIGNUM* r, const BIGNUM* a, const BIGNUM* b, int n) {
    BN_copy(r, a);
    for (int i = 0; i < n; ++i) {
        if (BN_is_bit_set(a, i) != BN_is_bit_set(b, i))
            BN_set_bit(r, i);
        else
            BN_clear_bit(r, i);
    }
}

// Worker function
void worker(BIGNUM* base_bn, int bit_length, int flip_count, size_t start, size_t end) {
    // One-time allocations
    BIGNUM* trimmed_base = get_last_n_bits(base_bn, bit_length);
    BIGNUM* current = BN_new();
    BIGNUM* mask = BN_new();
    EC_KEY* key = EC_KEY_new_by_curve_name(NID_secp256k1);
    const EC_GROUP* group = EC_KEY_get0_group(key);
    EC_POINT* pub = EC_POINT_new(group);
    unsigned char pubkey[33];
    unsigned char sha256[SHA256_DIGEST_LENGTH];
    unsigned char ripemd160[RIPEMD160_DIGEST_LENGTH];
    
    CombinationGenerator gen(bit_length, flip_count);
    for (size_t i = 0; i < start && gen.next(); ++i);

    size_t count = 0;
    do {
        // 1. Build mask
        BN_zero(mask);
        for (int pos : gen.get()) BN_set_bit(mask, pos);

        // 2. XOR operation
        bn_xor_nbits(current, trimmed_base, mask, bit_length);

        // 3. Set private key
        if (!EC_KEY_set_private_key(key, current)) continue;

        // 4. Generate public key
        if (!EC_POINT_mul(group, pub, current, nullptr, nullptr, nullptr)) continue;

        // 5. Get compressed pubkey
        if (EC_POINT_point2oct(group, pub, POINT_CONVERSION_COMPRESSED, pubkey, 33, nullptr) != 33) continue;

        // 6. Compute hashes
        SHA256(pubkey, 33, sha256);
        RIPEMD160(sha256, SHA256_DIGEST_LENGTH, ripemd160);

        // 7. Compare raw bytes
        if (memcmp(ripemd160, TARGET_HASH160_RAW.data(), 20) == 0) {
            char* hex_key = BN_bn2hex(current);
            lock_guard<mutex> lock(result_mutex);
            results.push(make_tuple(hex_key, total_checked.load(), flip_count));
            OPENSSL_free(hex_key);
            stop_event.store(true);
            break;
        }

        if (++total_checked % REPORT_INTERVAL == 0) {
            double progress = (double)total_checked / total_combinations * 100;
            cout << "Progress: " << fixed << setprecision(6) << progress << "% (";
            cout << total_checked << "/" << total_combinations << ")\r";
            cout.flush();
        }
          
    } while (gen.next() && (count++ < (end-start)) && !stop_event.load());

    // Cleanup
    EC_POINT_free(pub);
    EC_KEY_free(key);
    BN_free(mask);
    BN_free(current);
    BN_free(trimmed_base);
}

int main() {
    // Convert target hash to raw bytes
    TARGET_HASH160_RAW = hex_to_bytes(TARGET_HASH160);

    cout << "=======================================\n";
    cout << "== Mutagen Puzzle Solver by Denevron ==\n";
    cout << "=======================================\n";
  
    BIGNUM* base_bn = BN_new();
    BN_hex2bn(&base_bn, BASE_KEY.c_str());
  
    const int bit_length = PUZZLE_NUM;
    const int flip_count = predict_flips(PUZZLE_NUM);
    total_combinations = combinations_count(bit_length, flip_count);
  
    cout << "Searching Puzzle " << PUZZLE_NUM << " (" << bit_length << "-bit)\n";
    cout << "Base Key: " << BASE_KEY.substr(0, 10) << "..." << BASE_KEY.substr(BASE_KEY.length()-10) << "\n";
    cout << "Target HASH160: " << TARGET_HASH160.substr(0, 10) << "..." << TARGET_HASH160.substr(TARGET_HASH160.length()-10) << "\n";
    cout << "Predicted Flip Count: " << flip_count << " bits\n";
    cout << "Total Combinations: " << total_combinations << "\n";
    cout << "Using " << WORKERS << " workers...\n";
  
    auto start_time = chrono::high_resolution_clock::now();
    vector<thread> threads;
    size_t chunk = total_combinations / WORKERS;
  
    for (int i = 0; i < WORKERS; ++i) {
        size_t start = i * chunk;
        size_t end = (i == WORKERS-1) ? total_combinations : start + chunk;
        threads.emplace_back(worker, base_bn, bit_length, flip_count, start, end);
    }
  
    for (auto& t : threads) t.join();
    BN_free(base_bn);
  
    if (!results.empty()) {
        auto [hex_key, checked, flips] = results.front();
        auto elapsed = chrono::duration_cast<chrono::seconds>(
            chrono::high_resolution_clock::now() - start_time).count();
      
        cout << "\n=======================================\n";
        cout << "=========== SOLUTION FOUND ============\n";
        cout << "=======================================\n";
        cout << "Private Key: " << hex_key << "\n";
        cout << "Search Time: " << elapsed << " seconds\n";
        cout << "Keys Checked: " << checked << "\n";
        cout << "Bit Flips: " << flips << endl;
      
        ofstream out("puzzle_" + to_string(PUZZLE_NUM) + "_solution.txt");
        out << hex_key;
        out.close();
        cout << "Solution saved to puzzle_" << PUZZLE_NUM << "_solution.txt\n";
    } else {
        cout << "\nSolution not found. Checked " << total_checked << " combinations\n";
    }
  
    return 0;
}


Quote
# ./mutagen
=======================================
== Mutagen Puzzle Solver by Denevron ==
=======================================
Searching Puzzle 20 (20-bit)
Base Key: 0000000000...000005749f
Target HASH160: b907c3a2a3...703c272868
Predicted Flip Count: 8 bits
Total Combinations: 125970
Using 12 workers...
Progress: 47.630388% (60000/125970)
=======================================
=========== SOLUTION FOUND ============
=======================================
Private Key: 0D2C55
Search Time: 3 seconds
Keys Checked: 63547
Bit Flips: 8
Solution saved to puzzle_20_solution.txt


And so on, it can be improved infinitely. But the main question here is the number of possible combinations, which grow exponentially.

But we love useless scripts—I’m even a collector  Grin

Well, there is no need to improve it forever, because you will simply get tired of doing it  Grin
and whether it is useless and the idea itself, time will tell)
Desyationer
Jr. Member
*
Offline Offline

Activity: 64
Merit: 2


View Profile
March 31, 2025, 11:29:51 AM
 #8426

This is truly unfortunate… Each conversion of a number into a Bitcoin address requires around 1,700 simple operations. Even if this process could be optimized to a single basic operation, brute-forcing the 68th range would still take at least six months, even on the most powerful GPUs like the RTX 4090 or 5090. As far as I know, all existing brute-force programs such as KeyHunt and BitCrack utilize only the CUDA cores of GPUs. However, there is an untapped source of power tensor cores which remain unused. The theoretical performance of CUDA cores is around ~80 TFLOPS for the RTX 4090 and ~100 TFLOPS for the RTX 5090, while tensor cores offer significantly higher performance: 285 TFLOPS for the RTX 4090 and 400 TFLOPS for the RTX 5090.  If tensor cores could be utilized, the speed of brute-force calculations could be increased several times over. In theory, tensor cores are also capable of handling matrix multiplications and similar computations. Currently, the maximum speed achievable using publicly available CUDA-based programs from GitHub with an RTX 5090 is around 9GKeys per second.
kTimesG
Full Member
***
Offline Offline

Activity: 812
Merit: 247


View Profile
March 31, 2025, 11:53:32 AM
 #8427

This is truly unfortunate… Each conversion of a number into a Bitcoin address requires around 1,700 simple operations. Even if this process could be optimized to a single basic operation, brute-forcing the 68th range would still take at least six months, even on the most powerful GPUs like the RTX 4090 or 5090. As far as I know, all existing brute-force programs such as KeyHunt and BitCrack utilize only the CUDA cores of GPUs. However, there is an untapped source of power tensor cores which remain unused. The theoretical performance of CUDA cores is around ~80 TFLOPS for the RTX 4090 and ~100 TFLOPS for the RTX 5090, while tensor cores offer significantly higher performance: 285 TFLOPS for the RTX 4090 and 400 TFLOPS for the RTX 5090.  If tensor cores could be utilized, the speed of brute-force calculations could be increased several times over. In theory, tensor cores are also capable of handling matrix multiplications and similar computations. Currently, the maximum speed achievable using publicly available CUDA-based programs from GitHub with an RTX 5090 is around 9GKeys per second.

Tensor cores only do 8-bit and 16-bit float ops (e.g. extremely low precision for floating point numbers). So those TFLOPS you see are relative to these kind of numbers, not 32-bit integers/floats. We'd need some Bernstein-level genius mind to help us make use of them when dealing with ECC. They can potentially be put to use to accelerate the inversion, but this requires coming up with a new inversion algorithm. Something that can work via approximations instead of exact values, to find the inverse faster.

Off the grid, training pigeons to broadcast signed messages.
Desyationer
Jr. Member
*
Offline Offline

Activity: 64
Merit: 2


View Profile
March 31, 2025, 12:05:26 PM
 #8428

This is truly unfortunate… Each conversion of a number into a Bitcoin address requires around 1,700 simple operations. Even if this process could be optimized to a single basic operation, brute-forcing the 68th range would still take at least six months, even on the most powerful GPUs like the RTX 4090 or 5090. As far as I know, all existing brute-force programs such as KeyHunt and BitCrack utilize only the CUDA cores of GPUs. However, there is an untapped source of power tensor cores which remain unused. The theoretical performance of CUDA cores is around ~80 TFLOPS for the RTX 4090 and ~100 TFLOPS for the RTX 5090, while tensor cores offer significantly higher performance: 285 TFLOPS for the RTX 4090 and 400 TFLOPS for the RTX 5090.  If tensor cores could be utilized, the speed of brute-force calculations could be increased several times over. In theory, tensor cores are also capable of handling matrix multiplications and similar computations. Currently, the maximum speed achievable using publicly available CUDA-based programs from GitHub with an RTX 5090 is around 9GKeys per second.

Tensor cores only do 8-bit and 16-bit float ops (e.g. extremely low precision for floating point numbers). So those TFLOPS you see are relative to these kind of numbers, not 32-bit integers/floats. We'd need some Bernstein-level genius mind to help us make use of them when dealing with ECC. They can potentially be put to use to accelerate the inversion, but this requires coming up with a new inversion algorithm. Something that can work via approximations instead of exact values, to find the inverse faster.

I wasn't aware of such limitations of tensor cores now it makes sense why they haven't been used for key enumeration yet. I'm curious, if it were possible to leverage them at least for auxiliary inversion, what theoretical speedup could be expected?
kTimesG
Full Member
***
Offline Offline

Activity: 812
Merit: 247


View Profile
March 31, 2025, 01:51:45 PM
 #8429

I wasn't aware of such limitations of tensor cores now it makes sense why they haven't been used for key enumeration yet. I'm curious, if it were possible to leverage them at least for auxiliary inversion, what theoretical speedup could be expected?

If the inversion step is commented out of the code (basically making it a no-op and ignoring that the addition results are incorrect), the speed of EC public key addition, on a GPU, doubles, more or less. So the maximum speedup of the EC workload would be at most 100%, but this assumes an ideal condition that inversion is offloaded entirely to Tensor cores, which is unrealistic. No one can know for sure, until an implementation actually takes advantage of those cores, but we need an algorithm to exist first Smiley

I ignored everything related to the hashing workload here.

Off the grid, training pigeons to broadcast signed messages.
POD5
Member
**
Offline Offline

Activity: 335
Merit: 10

Keep smiling if you're loosing!


View Profile
March 31, 2025, 02:33:00 PM
 #8430

You can use this to both control RAM and thread usage. Count is not working properly.


Code:
// g++ -O3 -march=native -std=c++17 mutagenT.cpp -lssl -lcrypto -lpthread -o mutagenT
// ./mutagenT -t 8  # Use 8 threads

#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <thread>
#include <atomic>
#include <chrono>
#include <queue>
#include <mutex>
#include <unordered_map>
#include <cmath>
#include <fstream>
#include <openssl/ec.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <openssl/bn.h>
#include <openssl/obj_mac.h>
#include <openssl/evp.h>
#include <cstring> // For memset
#include <algorithm> // For min/max

using namespace std;

// Configuration
const string TARGET_HASH160 = "e0b8a2baee1b77fc703455f39d51477451fc8cfc";
const string BASE_KEY = "00000000000000000000000000000000000000000000000730fc235c1942c1ae";
const int PUZZLE_NUM = 68;
int WORKERS = thread::hardware_concurrency(); // Now modifiable via -t flag
const string PROGRESS_FILE = "mutagen_checkpoint.txt";

// Historical flip counts
const unordered_map<int, int> FLIP_TABLE = {
    {20, 8}, {21, 9}, {22, 11}, {23, 12}, {24, 9}, {25, 12}, {26, 14}, {27, 13},
    {28, 16}, {29, 18}, {30, 16}, {31, 13}, {32, 14}, {33, 15}, {34, 16}, {35, 19},
    {36, 14}, {37, 23}, {38, 21}, {39, 23}, {40, 20}, {41, 25}, {42, 24}, {43, 19},
    {44, 24}, {45, 21}, {46, 24}, {47, 27}, {48, 21}, {49, 30}, {50, 29}, {51, 25},
    {52, 27}, {53, 26}, {54, 30}, {55, 31}, {56, 31}, {57, 33}, {58, 28}, {59, 30},
    {60, 31}, {61, 25}, {62, 35}, {63, 34}, {64, 34}, {65, 37}, {66, 35}, {67, 31},
    {68, 34}
};

// Global variables
atomic<bool> stop_event(false);
mutex result_mutex;
queue<tuple<string, size_t, int>> results;

// Save progress to file
void save_progress(size_t current_index, int flip_count) {
    ofstream out(PROGRESS_FILE);
    out << current_index << " " << flip_count;
    out.close();
}

// Load progress from file
bool load_progress(size_t &saved_index, int &flip_count) {
    ifstream in(PROGRESS_FILE);
    if (!in) return false;
    in >> saved_index >> flip_count;
    in.close();
    return true;
}

// Predict flip count
int predict_flips(int puzzle_num) {
    if (FLIP_TABLE.count(puzzle_num)) {
        return FLIP_TABLE.at(puzzle_num);
    }
    return 8; // Default
}

// Binomial coefficient (n choose k)
size_t combinations_count(int n, int k) {
    if (k > n) return 0;
    if (k * 2 > n) k = n - k;
    if (k == 0) return 1;

    size_t result = n;
    for(int i = 2; i <= k; ++i) {
        result *= (n - i + 1);
        result /= i;
    }
    return result;
}

// Generate combinations on-the-fly (avoids storing all in RAM)
void generate_combinations(int n, int k, size_t start, size_t end, function<void(const vector<int>&)> callback) {
    vector<int> current(k);
    for (int i = 0; i < k; ++i) current[i] = i;

    size_t count = 0;
    while (count < end) {
        if (count >= start) {
            callback(current);
        }

        int i = k - 1;
        while (i >= 0 && current[i] == n - k + i) --i;
        if (i < 0) break;

        ++current[i];
        for (int j = i + 1; j < k; ++j) current[j] = current[j - 1] + 1;
        ++count;
    }
}

// Convert BIGNUM to hex string
string bn_to_hex(const BIGNUM* bn) {
    char* hex = BN_bn2hex(bn);
    string result(hex);
    OPENSSL_free(hex);
    return result;
}

// XOR operation for BIGNUM (optimized)
void bn_xor(BIGNUM* result, const BIGNUM* a, const BIGNUM* b) {
    BN_copy(result, a);
    for (int i = 0; i < max(BN_num_bits(a), BN_num_bits(b)); ++i) {
        if (BN_is_bit_set(a, i) != BN_is_bit_set(b, i)) {
            BN_set_bit(result, i);
        } else {
            BN_clear_bit(result, i);
        }
    }
}

// Compute HASH160 (optimized to reuse buffers)
string compute_hash160(const BIGNUM* priv_key) {
    EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
    if (!ec_key) return "";

    if (!EC_KEY_set_private_key(ec_key, priv_key)) {
        EC_KEY_free(ec_key);
        return "";
    }

    unsigned char pubkey[33]; // Compressed pubkey
    EC_POINT* pub_point = EC_POINT_new(EC_KEY_get0_group(ec_key));
    if (!pub_point || !EC_POINT_mul(EC_KEY_get0_group(ec_key), pub_point, priv_key, nullptr, nullptr, nullptr)) {
        EC_POINT_free(pub_point);
        EC_KEY_free(ec_key);
        return "";
    }

    EC_POINT_point2oct(EC_KEY_get0_group(ec_key), pub_point, POINT_CONVERSION_COMPRESSED, pubkey, sizeof(pubkey), nullptr);
    EC_POINT_free(pub_point);
    EC_KEY_free(ec_key);

    unsigned char sha256[SHA256_DIGEST_LENGTH];
    SHA256(pubkey, sizeof(pubkey), sha256);

    unsigned char ripemd160[RIPEMD160_DIGEST_LENGTH];
    RIPEMD160(sha256, SHA256_DIGEST_LENGTH, ripemd160);

    stringstream ss;
    for (int i = 0; i < RIPEMD160_DIGEST_LENGTH; ++i) {
        ss << hex << setw(2) << setfill('0') << (int)ripemd160[i];
    }
    return ss.str();
}

// Worker function (optimized for RAM)
void worker(const BIGNUM* base_bn, int bit_length, int flip_count, size_t start_index, size_t end_index) {
    BIGNUM* current_bn = BN_new();
    BIGNUM* flip_mask = BN_new();

    generate_combinations(bit_length, flip_count, start_index, end_index, [&](const vector<int>& combo) {
        BN_zero(flip_mask);
        for (int pos : combo) {
            BN_set_bit(flip_mask, pos);
        }
       
        bn_xor(current_bn, base_bn, flip_mask);

        string hash160 = compute_hash160(current_bn);
        if (hash160 == TARGET_HASH160) {
            string hex_key = bn_to_hex(current_bn);
            lock_guard<mutex> lock(result_mutex);
            results.push(make_tuple(hex_key, start_index + 1, flip_count));
            stop_event.store(true);
        }
    });

    BN_free(current_bn);
    BN_free(flip_mask);
}

// Parse command-line arguments
void parse_args(int argc, char* argv[]) {
    for (int i = 1; i < argc; ++i) {
        if (strcmp(argv[i], "-t") == 0 && i + 1 < argc) {
            WORKERS = max(1, min(256, atoi(argv[i + 1])));
            ++i;
        }
    }
}

// Parallel search (optimized)
void parallel_search() {
    BIGNUM* base_bn = BN_new();
    BN_hex2bn(&base_bn, BASE_KEY.c_str());

    int flip_count = predict_flips(PUZZLE_NUM);
    size_t total_combs = combinations_count(PUZZLE_NUM, flip_count);

    size_t start_from = 0;
    if (load_progress(start_from, flip_count)) {
        cout << "Resuming from index: " << start_from << endl;
    }

    cout << "Searching Puzzle " << PUZZLE_NUM << " (256-bit)" << endl;
    cout << "Base Key: " << BASE_KEY << endl;
    cout << "Target HASH160: " << TARGET_HASH160 << endl;
    cout << "Predicted Flip Count: " << flip_count << " bits" << endl;
    cout << "Total Possible Combinations: " << total_combs << endl;
    cout << "Using " << WORKERS << " workers..." << endl;

    vector<thread> threads;
    size_t chunk_size = (total_combs - start_from) / WORKERS;
    auto start_time = chrono::high_resolution_clock::now();

    for (int i = 0; i < WORKERS; ++i) {
        size_t start = start_from + (i * chunk_size);
        size_t end = (i == WORKERS - 1) ? total_combs : start + chunk_size;
        threads.emplace_back([=]() {
            worker(base_bn, PUZZLE_NUM, flip_count, start, end);
            if (i == 0) { // Only thread 0 saves progress
                static atomic<size_t> last_saved(0);
                if (start - last_saved >= 100000) {
                    save_progress(start, flip_count);
                    last_saved = start;
                }
            }
        });
    }

    for (auto& t : threads) t.join();
    BN_free(base_bn);

    if (!results.empty()) {
        auto [hex_key, checked, flips] = results.front();
        auto elapsed = chrono::duration_cast<chrono::seconds>(
            chrono::high_resolution_clock::now() - start_time).count();

        cout << "\nFound solution!" << endl;
        cout << "Private Key: " << hex_key << endl;
        cout << "Bit Flips: " << flips << endl;
        cout << "Checked " << checked << " combinations in "
             << elapsed << " seconds (" << (checked/elapsed) << " keys/sec)" << endl;

        ofstream out("solution.txt");
        out << hex_key;
        out.close();
    } else {
        cout << "\nSolution not found. Try adjusting flip count." << endl;
    }
}

int main(int argc, char* argv[]) {
    parse_args(argc, argv); // Parse -t <threads>

    #if OPENSSL_VERSION_NUMBER < 0x10100000L
    OpenSSL_add_all_algorithms();
    #endif

    parallel_search();

    #if OPENSSL_VERSION_NUMBER < 0x10100000L
    EVP_cleanup();
    #endif

    return 0;
}

bc1qygk0yjdqx4j2sspswmu4dvc76s6hxwn9z0whlu
nomachine
Full Member
***
Offline Offline

Activity: 812
Merit: 134



View Profile
March 31, 2025, 03:46:00 PM
 #8431

You can use this to both control RAM and thread usage. Count is not working properly.

I'll upload the next version to GitHub. It's too long for posts, especially if someone quotes it. Otherwise, users would have to scroll through the post for half an hour, making it pointless  Wink

BTC: bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
POD5
Member
**
Offline Offline

Activity: 335
Merit: 10

Keep smiling if you're loosing!


View Profile
March 31, 2025, 03:56:26 PM
 #8432

Do you all have telegram?  Grin

bc1qygk0yjdqx4j2sspswmu4dvc76s6hxwn9z0whlu
Denevron
Newbie
*
Offline Offline

Activity: 121
Merit: 0


View Profile
March 31, 2025, 04:57:53 PM
 #8433

Do you all have telegram?  Grin

There is)
nomachine
Full Member
***
Offline Offline

Activity: 812
Merit: 134



View Profile
March 31, 2025, 06:48:01 PM
 #8434

Well, there is no need to improve it forever, because you will simply get tired of doing it  Grin
and whether it is useless and the idea itself, time will tell)

https://github.com/NoMachine1/Mutagen

BTC: bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
Denevron
Newbie
*
Offline Offline

Activity: 121
Merit: 0


View Profile
March 31, 2025, 06:54:23 PM
 #8435

Well, there is no need to improve it forever, because you will simply get tired of doing it  Grin
and whether it is useless and the idea itself, time will tell)

https://github.com/NoMachine1/Mutagen


Lots of improvements)) and I'm trying to make it work with avx2  Grin
AlanJohnson
Member
**
Offline Offline

Activity: 185
Merit: 11


View Profile
March 31, 2025, 07:09:51 PM
 #8436

Well, there is no need to improve it forever, because you will simply get tired of doing it  Grin
and whether it is useless and the idea itself, time will tell)

https://github.com/NoMachine1/Mutagen


Lots of improvements)) and I'm trying to make it work with avx2  Grin

How many times faster it can be than a standard brute force ?  Cause if less than  million you will not solve anything new anyway ...
POD5
Member
**
Offline Offline

Activity: 335
Merit: 10

Keep smiling if you're loosing!


View Profile
March 31, 2025, 07:17:20 PM
 #8437

Well, there is no need to improve it forever, because you will simply get tired of doing it  Grin
and whether it is useless and the idea itself, time will tell)

https://github.com/NoMachine1/Mutagen

=======================================
== Mutagen Puzzle Solver by Denevron ==
=======================================
Searching Puzzle 68 (68-bit)
Base Key: 0000000000...5C1942C1AE
Target HASH160: e0b8a2baee...7451fc8cfc
Predicted Flip Count: 34 bits
Total Combinations: 47478523248093572
Using 8 workers...
Segmentation fault (core dumped)

bc1qygk0yjdqx4j2sspswmu4dvc76s6hxwn9z0whlu
Denevron
Newbie
*
Offline Offline

Activity: 121
Merit: 0


View Profile
March 31, 2025, 07:43:32 PM
 #8438

Well, there is no need to improve it forever, because you will simply get tired of doing it  Grin
and whether it is useless and the idea itself, time will tell)

https://github.com/NoMachine1/Mutagen


Lots of improvements)) and I'm trying to make it work with avx2  Grin

How many times faster it can be than a standard brute force ?  Cause if less than  million you will not solve anything new anyway ...


even if I don't solve it myself, maybe someone will solve it using this method, which will also be nice)
AlanJohnson
Member
**
Offline Offline

Activity: 185
Merit: 11


View Profile
March 31, 2025, 07:51:37 PM
 #8439

Well, there is no need to improve it forever, because you will simply get tired of doing it  Grin
and whether it is useless and the idea itself, time will tell)

https://github.com/NoMachine1/Mutagen


Lots of improvements)) and I'm trying to make it work with avx2  Grin

How many times faster it can be than a standard brute force ?  Cause if less than  million you will not solve anything new anyway ...


even if I don't solve it myself, maybe someone will solve it using this method, which will also be nice)

I could risk a thesis that no new puzzles will be solved with CPUs ... You would need millions of them... They are just not efficient enough to bother anymore.
Denevron
Newbie
*
Offline Offline

Activity: 121
Merit: 0


View Profile
March 31, 2025, 08:09:19 PM
 #8440

Well, there is no need to improve it forever, because you will simply get tired of doing it  Grin
and whether it is useless and the idea itself, time will tell)

https://github.com/NoMachine1/Mutagen


Lots of improvements)) and I'm trying to make it work with avx2  Grin

How many times faster it can be than a standard brute force ?  Cause if less than  million you will not solve anything new anyway ...


even if I don't solve it myself, maybe someone will solve it using this method, which will also be nice)

I could risk a thesis that no new puzzles will be solved with CPUs ... You would need millions of them... They are just not efficient enough to bother anymore.

I agree with you, but why not try?)
Pages: « 1 ... 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 [422] 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 ... 652 »
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!