Bitcoin Forum
June 13, 2025, 10:03:04 PM *
News: Latest Bitcoin Core release: 29.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 ... 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 [525] 526 527 528 529 530 531 532 »
  Print  
Author Topic: Bitcoin puzzle transaction ~32 BTC prize to who solves it  (Read 307893 times)
nomachine
Full Member
***
Offline Offline

Activity: 686
Merit: 104


View Profile
June 04, 2025, 09:40:14 AM
Last edit: June 04, 2025, 10:51:08 AM by nomachine
Merited by AlexanderCurl (33), mcdouglasx (1)
 #10481

Who wrote this code?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Share your donation address I can see light at the end of a tunnel.

I wrote it. It's based on the lightweight database for publickeys from @Mcdouglas-X3. The difference is that my script empties RAM and stores the DB in parts compressed on disk. You need a huge amount of storage. And of course the public key.

Here is C++ version

Code:
#include <iostream>
#include <atomic>
#include <memory>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
#include <unordered_map>
#include <cmath>
#include <gmpxx.h>
#include <chrono>
#include <cassert>
#include <cstdio>
#include <sys/stat.h>
#include <xxhash.h>
#include <omp.h>
#include <unistd.h>
#include <iomanip>

using namespace std;

// Constants and typedefs
typedef array<mpz_class, 2> Point;

const mpz_class modulo("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
const mpz_class order("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
const mpz_class Gx("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
const mpz_class Gy("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", 16);
const Point PG = {Gx, Gy};
const Point Z = {0, 0};

// Global variables
int puzzle = 40;
string puzzle_pubkey = "03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4";
int threads = 0;
bool verbose = false;
const size_t MAX_TABLE_SIZE = 200 * 1024 * 1024; // 200MB per part

// Function declarations
void print_help();
bool validate_pubkey(const string& pubkey);
Point parse_pubkey(const string& pubkey);
inline Point add(const Point& P, const Point& Q, const mpz_class& p = modulo);
inline Point mul(const mpz_class& k, const Point& P = PG, const mpz_class& p = modulo);
inline Point point_subtraction(const Point& P, const Point& Q);
inline mpz_class X2Y(const mpz_class& X, int y_parity, const mpz_class& p = modulo);
inline string point_to_cpub(const Point& point);
inline string hash_cpub(const string& cpub);
void save_baby_table_part(const unordered_map<string, int>& baby_table, int part_num);
void save_baby_table(const unordered_map<string, int>& baby_table);
unordered_map<string, int> load_baby_table_part(const string& filename);
unordered_map<string, int> load_baby_table();
void delete_existing_table();
unordered_map<string, int> generate_baby_table_parallel(const mpz_class& m);

void print_help() {
    cout << "BSGS (Baby-Step Giant-Step) Elliptic Curve Cryptography Tool\n\n";
    cout << "Usage: ./bsgs [options]\n\n";
    cout << "Options:\n";
    cout << "  -p <number>     Puzzle number (default: 40)\n";
    cout << "  -k <pubkey>     Compressed public key in hex format\n";
    cout << "  -t <threads>    Number of CPU cores to use (default: all available)\n";
    cout << "  -v              Verbose output\n";
    cout << "  -h              Show this help message\n\n";
    cout << "Example:\n";
    cout << "  ./bsgs -p 40 -k 03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4 -t 8\n";
}

bool validate_pubkey(const string& pubkey) {
    if (pubkey.length() != 66) {
        cerr << "[error] Public key must be 66 characters long (including 02/03 prefix)\n";
        return false;
    }
    
    if (pubkey[0] != '0' || (pubkey[1] != '2' && pubkey[1] != '3')) {
        cerr << "[error] Public key must start with 02 or 03\n";
        return false;
    }
    
    for (size_t i = 2; i < pubkey.length(); i++) {
        if (!isxdigit(pubkey[i])) {
            cerr << "[error] Public key contains invalid hex characters\n";
            return false;
        }
    }
    
    return true;
}

Point parse_pubkey(const string& pubkey) {
    string prefix = pubkey.substr(0, 2);
    mpz_class X(pubkey.substr(2), 16);
    int y_parity = stoi(prefix) - 2;
    mpz_class Y = X2Y(X, y_parity);
    
    if (Y == 0) {
        cerr << "[error] Invalid compressed public key!\n";
        exit(1);
    }
    
    return {X, Y};
}

inline Point add(const Point& P, const Point& Q, const mpz_class& p) {
    if (P == Z) return Q;
    if (Q == Z) return P;
    const mpz_class& P0 = P[0];
    const mpz_class& P1 = P[1];
    const mpz_class& Q0 = Q[0];
    const mpz_class& Q1 = Q[1];
    mpz_class lmbda, num, denom, inv;
    if (P != Q) {
        num = Q1 - P1;
        denom = Q0 - P0;
    } else {
        if (P1 == 0) return Z;
        num = 3 * P0 * P0;
        denom = 2 * P1;
    }
    mpz_invert(inv.get_mpz_t(), denom.get_mpz_t(), p.get_mpz_t());
    lmbda = (num * inv) % p;
    mpz_class x = (lmbda * lmbda - P0 - Q0) % p;
    if (x < 0) x += p;
    mpz_class y = (lmbda * (P0 - x) - P1) % p;
    if (y < 0) y += p;
    return {x, y};
}

inline Point mul(const mpz_class& k, const Point& P, const mpz_class& p) {
    Point R0 = Z, R1 = P;
    unsigned long bit_length = mpz_sizeinbase(k.get_mpz_t(), 2);
    for (unsigned long i = bit_length - 1; i < bit_length; --i) {
        if (mpz_tstbit(k.get_mpz_t(), i)) {
            R0 = add(R0, R1, p);
            R1 = add(R1, R1, p);
        } else {
            R1 = add(R0, R1, p);
            R0 = add(R0, R0, p);
        }
    }
    return R0;
}

inline Point point_subtraction(const Point& P, const Point& Q) {
    Point Q_neg = {Q[0], (-Q[1]) % modulo};
    return add(P, Q_neg);
}

inline mpz_class X2Y(const mpz_class& X, int y_parity, const mpz_class& p) {
    mpz_class X_cubed = (X * X * X) % p;
    mpz_class tmp = (X_cubed + mpz_class(7)) % p;
    mpz_class Y;
    mpz_class exp = (p + mpz_class(1)) / mpz_class(4);
    mpz_powm(Y.get_mpz_t(), tmp.get_mpz_t(), exp.get_mpz_t(), p.get_mpz_t());
    if ((Y % 2) != y_parity) {
        Y = p - Y;
    }
    return Y;
}

inline string point_to_cpub(const Point& point) {
    mpz_class x = point[0], y = point[1];
    int y_parity = y.get_ui() & 1;
    string prefix = y_parity == 0 ? "02" : "03";
    char buffer[65];
    mpz_get_str(buffer, 16, x.get_mpz_t());
    return prefix + string(buffer);
}

inline string hash_cpub(const string& cpub) {
    XXH64_hash_t hash = XXH64(cpub.c_str(), cpub.size(), 0);
    char buffer[17];
    snprintf(buffer, sizeof(buffer), "%016lx", hash);
    return string(buffer, 8);
}

void save_baby_table_part(const unordered_map<string, int>& baby_table, int part_num) {
    string filename = "baby_table_part_" + to_string(part_num);
    ofstream outfile(filename, ios::binary);
    if (!outfile) {
        cerr << "[error] Failed to open file for writing: " << filename << endl;
        return;
    }
    
    for (const auto& entry : baby_table) {
        outfile.write(entry.first.c_str(), 8);
        int index = entry.second;
        outfile.write(reinterpret_cast<const char*>(&index), sizeof(index));
    }
    
    if (verbose) {
        cout << "[+] Saved baby table part " << part_num << " with " << baby_table.size() << " entries" << endl;
    }
    
    string command = "pigz -9 -b 128 -f " + filename;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe) {
        cerr << "[error] Failed to compress file: " << filename << endl;
        return;
    }
    pclose(pipe);
}

void save_baby_table(const unordered_map<string, int>& baby_table) {
    size_t current_size = 0;
    int part_num = 1;
    unordered_map<string, int> current_part;
    
    for (const auto& entry : baby_table) {
        size_t entry_size = entry.first.size() + sizeof(int);
        if (current_size + entry_size > MAX_TABLE_SIZE && !current_part.empty()) {
            save_baby_table_part(current_part, part_num++);
            current_part.clear();
            current_size = 0;
        }
        current_part.insert(entry);
        current_size += entry_size;
    }
    
    if (!current_part.empty()) {
        save_baby_table_part(current_part, part_num);
    }
}

unordered_map<string, int> load_baby_table_part(const string& filename) {
    string command = "pigz -d -c " + filename;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe) {
        cerr << "[error] Failed to decompress file: " << filename << endl;
        return {};
    }
    
    unordered_map<string, int> baby_table_part;
    char key_buffer[9];
    int index;
    
    while (fread(key_buffer, 8, 1, pipe) == 1) {
        key_buffer[8] = '\0';
        fread(&index, sizeof(index), 1, pipe);
        baby_table_part[key_buffer] = index;
    }
    
    pclose(pipe);
    return baby_table_part;
}

unordered_map<string, int> load_baby_table() {
    unordered_map<string, int> baby_table;
    int part_num = 1;
    
    while (true) {
        string filename = "baby_table_part_" + to_string(part_num) + ".gz";
        ifstream test(filename);
        if (!test.good()) {
            if (part_num == 1) {
                cerr << "[error] No baby table parts found!" << endl;
                return {};
            }
            break;
        }
        test.close();
        
        string command = "pigz -d -c " + filename;
        FILE* pipe = popen(command.c_str(), "r");
        if (!pipe) {
            cerr << "[error] Failed to decompress file: " << filename << endl;
            return {};
        }
        
        char key[9] = {0};
        int index;
        size_t entries = 0;
        
        while (fread(key, 8, 1, pipe) == 1) {
            if (fread(&index, sizeof(int), 1, pipe) != 1) break;
            key[8] = '\0';
            baby_table[key] = index;
            entries++;
        }
        
        pclose(pipe);
        if (verbose) {
            cout << "[+] Loaded part " << part_num << " with " << entries << " entries" << endl;
        }
        part_num++;
    }
    
    cout << "[+] Loaded baby table with " << baby_table.size() << " total entries" << endl;
    return baby_table;
}

void delete_existing_table() {
    int part_num = 1;
    while (true) {
        string filename = "baby_table_part_" + to_string(part_num);
        string compressed_filename = filename + ".gz";
        
        struct stat buffer;
        bool found = false;
        
        if (stat(filename.c_str(), &buffer) == 0) {
            if (remove(filename.c_str()) != 0) {
                cerr << "[error] Failed to delete file: " << filename << endl;
            } else {
                found = true;
            }
        }
        
        if (stat(compressed_filename.c_str(), &buffer) == 0) {
            if (remove(compressed_filename.c_str()) != 0) {
                cerr << "[error] Failed to delete file: " << compressed_filename << endl;
            } else {
                found = true;
            }
        }
        
        if (!found) {
            if (part_num == 1 && verbose) {
                cout << "[+] No existing table parts found to delete" << endl;
            }
            break;
        }
        
        part_num++;
    }
}

unordered_map<string, int> generate_baby_table_parallel(const mpz_class& m) {
    const int num_threads = threads > 0 ? threads : omp_get_max_threads();
    const unsigned long total_entries = m.get_ui();
    const size_t max_part_size = MAX_TABLE_SIZE * 0.99; // 99% threshold
    std::atomic<int> parts_created(0);
    std::atomic<size_t> current_part_size(0);
    std::atomic<size_t> total_entries_written(0);
    
    system("rm -f baby_table_part_* baby_table_part_*.gz 2>/dev/null");
  
    cout << "[+] Generating " << total_entries << " baby steps" << endl;

    #pragma omp parallel num_threads(num_threads)
    {
        vector<pair<string, int>> local_buffer;
        local_buffer.reserve(100000);

        #pragma omp for schedule(dynamic, 100000)
        for (unsigned long i = 0; i < total_entries; ++i) {
            Point P = mul(i);
            string cpub_hash = hash_cpub(point_to_cpub(P));
            local_buffer.emplace_back(cpub_hash, i);

            if (local_buffer.size() >= 100000) {
                #pragma omp critical
                {
                    int current_part = parts_created + 1;
                    string filename = "baby_table_part_" + to_string(current_part);
                    ofstream outfile(filename, ios::binary | ios::app);
                    if (outfile) {
                        for (const auto& entry : local_buffer) {
                            outfile.write(entry.first.c_str(), 8);
                            outfile.write(reinterpret_cast<const char*>(&entry.second), sizeof(int));
                            total_entries_written++;
                            current_part_size += 12;
                            
                            if (current_part_size >= max_part_size) {
                                outfile.close();
                                string cmd = "pigz -9 -b 128 -f " + filename;
                                system(cmd.c_str());
                                parts_created++;
                                current_part_size = 0;
                            }
                        }
                    }
                    local_buffer.clear();
                }
            }
        }

        #pragma omp critical
        {
            if (!local_buffer.empty()) {
                int current_part = parts_created + 1;
                string filename = "baby_table_part_" + to_string(current_part);
                ofstream outfile(filename, ios::binary | ios::app);
                if (outfile) {
                    for (const auto& entry : local_buffer) {
                        outfile.write(entry.first.c_str(), 8);
                        outfile.write(reinterpret_cast<const char*>(&entry.second), sizeof(int));
                        total_entries_written++;
                    }
                    outfile.close();
                    string cmd = "pigz -9 -b 128 -f " + filename;
                    system(cmd.c_str());
                    parts_created++;
                }
            }
        }
    }

    cout << "[+] Generated " << parts_created << " compressed parts ("
         << total_entries_written << " total entries) " << endl;

    return {};
}

int main(int argc, char* argv[]) {
    // Parse command line arguments
    int opt;
    while ((opt = getopt(argc, argv, "p:k:t:vh")) != -1) {
        switch (opt) {
            case 'p':
                puzzle = atoi(optarg);
                if (puzzle < 1 || puzzle > 256) {
                    cerr << "[error] Invalid puzzle number (must be between 1-256)\n";
                    print_help();
                    return 1;
                }
                break;
            case 'k':
                puzzle_pubkey = optarg;
                if (!validate_pubkey(puzzle_pubkey)) {
                    print_help();
                    return 1;
                }
                break;
            case 't':
                threads = atoi(optarg);
                if (threads < 1) {
                    cerr << "[error] Thread count must be at least 1\n";
                    print_help();
                    return 1;
                }
                break;
            case 'v':
                verbose = true;
                break;
            case 'h':
            default:
                print_help();
                return 0;
        }
    }

    // Initialize OpenMP threads
    if (threads > 0) {
        omp_set_num_threads(threads);
    }
    int actual_threads = omp_get_max_threads();

    // Print configuration
    time_t currentTime = time(nullptr);
    cout << "\n\033[01;33m[+]\033[32m BSGS Started: \033[01;33m" << ctime(&currentTime);
    cout << "\033[0m[+] Puzzle: " << puzzle << endl;
    cout << "[+] Public Key: " << puzzle_pubkey << endl;
    cout << "[+] Using " << actual_threads << " CPU cores" << endl;

    // Initialize range and point
    mpz_class start_range = mpz_class(1) << (puzzle - 1);
    mpz_class end_range = (mpz_class(1) << puzzle) - 1;
    Point P = parse_pubkey(puzzle_pubkey);

    // Calculate m and generate baby table
    mpz_class m = sqrt(end_range - start_range);
    m = m * 4;
    Point m_P = mul(m);

    if (verbose) {
        cout << "[+] Range: 2^" << (puzzle-1) << " to 2^" << puzzle << "-1" << endl;
        cout << "[+] Baby-step count (m): " << m << endl;
    }

    delete_existing_table();

    cout << "[+] Generating baby table..." << endl;
    auto baby_table = generate_baby_table_parallel(m);

    cout << "[+] Loading baby table..." << endl;
    baby_table = load_baby_table();
    if (baby_table.empty()) {
        cerr << "[error] Failed to load baby table\n";
        return 1;
    }

    cout << "[+] Starting BSGS search..." << endl;
    Point S = point_subtraction(P, mul(start_range));
    mpz_class step = 0;
    bool found = false;
    mpz_class found_key;
    
    auto st = chrono::high_resolution_clock::now();
    
    #pragma omp parallel
    {
        Point local_S = S;
        mpz_class local_step = step;
        
        #pragma omp for schedule(dynamic)
        for (int i = 0; i < actual_threads; ++i) {
            while (local_step < (end_range - start_range)) {
                #pragma omp flush(found)
                if (found) break;
                
                string cpub = point_to_cpub(local_S);
                string cpub_hash = hash_cpub(cpub);
                auto it = baby_table.find(cpub_hash);
                if (it != baby_table.end()) {
                    int b = it->second;
                    mpz_class k = start_range + local_step + b;
                    if (point_to_cpub(mul(k)) == puzzle_pubkey) {
                        #pragma omp critical
                        {
                            if (!found) {
                                found = true;
                                found_key = k;
                                auto et = chrono::high_resolution_clock::now();
                                chrono::duration<double> elapsed = et - st;
                                
                                cout << "\n\033[01;32m[+] Solution found!\033[0m" << endl;
                                cout << "[+] Private key: " << k << endl;
                                cout << "[+] Hex: 0x" << hex << k << dec << endl;
                                cout << "[+] Time elapsed: " << elapsed.count() << " seconds\n";
                            }
                        }
                        #pragma omp flush(found)
                        break;
                    }
                }
                local_S = point_subtraction(local_S, m_P);
                local_step += m;
            }
        }
    }

    if (!found) {
        auto et = chrono::high_resolution_clock::now();
        chrono::duration<double> elapsed = et - st;
        cout << "\n\033[01;31m[!] Key not found in the specified range\033[0m" << endl;
        cout << "[+] Time elapsed: " << elapsed.count() << " seconds\n";
    }

    return 0;
}

Makefile
Code:
# Detect OS
UNAME_S := $(shell uname -s)

# Enable static linking by default (change to 'no' to use dynamic linking)
STATIC_LINKING = yes

# Compiler settings based on OS
ifeq ($(UNAME_S),Linux)
# Linux settings

# Compiler
CXX = g++

# Compiler flags
CXXFLAGS = -m64 -std=c++17 -march=native -mtune=native -Ofast -mssse3 -Wall -Wextra \
           -funroll-loops -ftree-vectorize -fstrict-aliasing -fno-semantic-interposition \
           -fvect-cost-model=unlimited -fno-trapping-math -fipa-ra -flto -fopenmp \
           -mavx2 -mbmi2 -madx
LDFLAGS = -lgmp -lgmpxx -lxxhash

# Source files
SRCS = bsgs.cpp

# Object files
OBJS = $(SRCS:.cpp=.o)

# Target executable
TARGET = bsgs

# Default target
all: $(TARGET)

# Link the object files to create the executable
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS)
rm -f $(OBJS) && chmod +x $(TARGET)

# Compile each source file into an object file
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@

# Clean up build files
clean:
@echo "Cleaning..."
rm -f $(OBJS) $(TARGET)

.PHONY: all clean

else
# Windows settings (MinGW-w64)

# Compiler
CXX = g++

# Check if compiler is found
CHECK_COMPILER := $(shell which $(CXX) 2>/dev/null)

# Add MSYS path if the compiler is not found
ifeq ($(CHECK_COMPILER),)
  $(info Compiler not found. Adding MSYS path to the environment...)
  SHELL := cmd
  PATH := C:\msys64\mingw64\bin;$(PATH)
endif

# Compiler flags
CXXFLAGS = -m64 -std=c++17 -march=native -mtune=native -Ofast -mssse3 -Wall -Wextra \
           -funroll-loops -ftree-vectorize -fstrict-aliasing -fno-semantic-interposition \
           -fvect-cost-model=unlimited -fno-trapping-math -fipa-ra -flto -fopenmp \
           -mavx2 -mbmi2 -madx
LDFLAGS = -lgmp -lgmpxx -lxxhash

# Add -static flag if STATIC_LINKING is enabled
ifeq ($(STATIC_LINKING),yes)
    LDFLAGS += -static
else
    $(info Dynamic linking will be used. Ensure required DLLs are distributed)
endif

# Source files
SRCS = bsgs.cpp

# Object files
OBJS = $(SRCS:.cpp=.o)

# Target executable
TARGET = bsgs.exe

# Default target
all: $(TARGET)

# Link the object files to create the executable
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS)
del /q $(OBJS) 2>nul

# Compile each source file into an object file
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@

# Clean up build files
clean:
@echo Cleaning...
del /q $(OBJS) $(TARGET) 2>nul

.PHONY: all clean
endif

dependencies:

Quote
sudo apt install libgmp-dev libomp-dev xxhash pigz


Quote
  • BSGS Started: Wed Jun  4 01:56:48 2025
  • Puzzle: 40
  • Public Key: 03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4
  • Using 12 CPU cores
  • Generating baby table...
  • Generating 2965820 baby steps
  • Generated 1 compressed parts (2965820 total entries)
  • Loading baby table...
  • Loaded baby table with 2964816 total entries
  • Starting BSGS search...
  • Solution found!
  • Private key: 1003651412950
  • Hex: 0xe9ae4933d6
  • Time elapsed: 0.612888 seconds
# ./bsgs -p 50  -k 03f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6 -t 12

Quote
  • BSGS Started: Wed Jun  4 02:20:52 2025
  • Puzzle: 50
  • Public Key: 03f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6
  • Using 12 CPU cores
  • Generating baby table...
  • Generating 94906264 baby steps
  • Generated 6 compressed parts (94906264 total entries)
  • Loading baby table...
  • Loaded baby table with 93398236 total entries
  • Starting BSGS search...
  • Solution found!
  • Private key: 611140496167764
  • Hex: 0x22bd43c2e9354
  • Time elapsed: 4.83157 seconds
P.S. This can be easily modified to use a Bloom Filter. And probably the GPU version. Use it for whatever you want.

BTC: bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
kTimesG
Full Member
***
Offline Offline

Activity: 504
Merit: 129


View Profile
June 04, 2025, 10:55:40 AM
Last edit: June 04, 2025, 11:10:48 AM by kTimesG
Merited by Frequence (1)
 #10482

The most amusing stuff using mutex locks and creating bloomfilters with the same inputs two times in row.
Code:
alexander@alexander-home:~/Documents/Test_Dir/Point_Search_GMP$ diff bloom1B.bf bloom1.bf
Binary files bloom1B.bf and bloom1.bf differ

What did you expect? I looked at your update, and you are simply creating multiple mutexes, one for each thread that runs process_chunk. And locking the entire loop. Basically protecting nothing.

That's not mutexes are for. You only need a single mutex, and you only need to lock the "bf.insert" call, not the entire loop (or else the entire loops will be exclusive).

I'd personally move the mutex to the bloom filter code, and further block only the actual code that accesses data which can potentially be shared (for example, the hashing part probably doesn't need exclusive access).

But I'm glad that at least you got to a case where you can clearly see that the output is wrong, when synchronization is missing. So which one of those 2 outputs is the right one? You'll never know, since they were basically in a race condition, running both in parallel under different mutexes (so, identical as not having a mutex at all).

If you wanna go fancy you can implement a multi-mutex scheme, one for each some memory area size, and only lock the specific mutex for the area the bloom filter writes. This may increase throughput, or it may not, the right balance needs to be found by trial and error. But this is not a programming thread, after all. Smiley

LE: another option is to compute the points in parallel, and queue them in a producer-consumer fashion. And consuming the queue in a single thread, that only does the BF insertions. This simply moves the sync on the queue itself, of course, if you don't want to mess with the bloom class.

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

Activity: 33
Merit: 171


View Profile WWW
June 04, 2025, 12:55:38 PM
Last edit: June 04, 2025, 02:08:19 PM by AlexanderCurl
 #10483

The most amusing stuff using mutex locks and creating bloomfilters with the same inputs two times in row.
Code:
alexander@alexander-home:~/Documents/Test_Dir/Point_Search_GMP$ diff bloom1B.bf bloom1.bf
Binary files bloom1B.bf and bloom1.bf differ

What did you expect? I looked at your update, and you are simply creating multiple mutexes, one for each thread that runs process_chunk. And locking the entire loop. Basically protecting nothing.

That's not mutexes are for. You only need a single mutex, and you only need to lock the "bf.insert" call, not the entire loop (or else the entire loops will be exclusive).

I'd personally move the mutex to the bloom filter code, and further block only the actual code that accesses data which can potentially be shared (for example, the hashing part probably doesn't need exclusive access).

But I'm glad that at least you got to a case where you can clearly see that the output is wrong, when synchronization is missing. So which one of those 2 outputs is the right one? You'll never know, since they were basically in a race condition, running both in parallel under different mutexes (so, identical as not having a mutex at all).

If you wanna go fancy you can implement a multi-mutex scheme, one for each some memory area size, and only lock the specific mutex for the area the bloom filter writes. This may increase throughput, or it may not, the right balance needs to be found by trial and error. But this is not a programming thread, after all. Smiley

LE: another option is to compute the points in parallel, and queue them in a producer-consumer fashion. And consuming the queue in a single thread, that only does the BF insertions. This simply moves the sync on the queue itself, of course, if you don't want to mess with the bloom class.

Code:
for (int i = 0; i < POINTS_BATCH_SIZE; i++) { // inserting all batch points into the bloomfilter
                    BloomP.x = pointBatchX[i];
                    BloomP.y = pointBatchY[i];
                    std::lock_guard<std::mutex> lock(mtx);
                    bf.insert(secp256k1->GetPublicKeyHex(BloomP));
                }
Exactly. Locking the bf like this leads to nothing. The same. May be no diff. Might be multiple.
But the running instance yields the right result even so no matter what. Has no impact after all. 69 bits. Tested.

The thing was only not putting the mutex for each bloom in relative to them global scope. Updated accordingly.
alexander@alexander-home:~/Documents/Test_Dir/Point_Search_GMP$ diff bloom1.bf bloom1B.bf
alexander@alexander-home:~/Documents/Test_Dir/Point_Search_GMP$ diff bloom2.bf bloom2B.bf

Locking the batch compared to locking just bf.insert is faster time-wise.


vneos
Jr. Member
*
Offline Offline

Activity: 35
Merit: 12


View Profile
June 04, 2025, 01:26:59 PM
 #10484

Does anyone know who the author of the puzzle is?JPL?…

Adam Back


I think it's satoshi himself. The way @satoshi and @saatoshi_rising break up their sentences is the same.

Looking at their posts, they both like to leave two spaces after a period.

@saatoshi_rising: "I am the creator" is also quite thought-provoking. Does it refer to the creator of the puzzle, or the creator of bitcoin? Roll Eyes

Of course, this is just my guess.
axwfae
Newbie
*
Offline Offline

Activity: 1
Merit: 0


View Profile
June 04, 2025, 02:28:49 PM
 #10485

Who wrote this code?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Share your donation address I can see light at the end of a tunnel.

I wrote it. It's based on the lightweight database for publickeys from @Mcdouglas-X3. The difference is that my script empties RAM and stores the DB in parts compressed on disk. You need a huge amount of storage. And of course the public key.

Here is C++ version

Code:
#include <iostream>
#include <atomic>
#include <memory>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
#include <unordered_map>
#include <cmath>
#include <gmpxx.h>
#include <chrono>
#include <cassert>
#include <cstdio>
#include <sys/stat.h>
#include <xxhash.h>
#include <omp.h>
#include <unistd.h>
#include <iomanip>

using namespace std;

// Constants and typedefs
typedef array<mpz_class, 2> Point;

const mpz_class modulo("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
const mpz_class order("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
const mpz_class Gx("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
const mpz_class Gy("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", 16);
const Point PG = {Gx, Gy};
const Point Z = {0, 0};

// Global variables
int puzzle = 40;
string puzzle_pubkey = "03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4";
int threads = 0;
bool verbose = false;
const size_t MAX_TABLE_SIZE = 200 * 1024 * 1024; // 200MB per part

// Function declarations
void print_help();
bool validate_pubkey(const string& pubkey);
Point parse_pubkey(const string& pubkey);
inline Point add(const Point& P, const Point& Q, const mpz_class& p = modulo);
inline Point mul(const mpz_class& k, const Point& P = PG, const mpz_class& p = modulo);
inline Point point_subtraction(const Point& P, const Point& Q);
inline mpz_class X2Y(const mpz_class& X, int y_parity, const mpz_class& p = modulo);
inline string point_to_cpub(const Point& point);
inline string hash_cpub(const string& cpub);
void save_baby_table_part(const unordered_map<string, int>& baby_table, int part_num);
void save_baby_table(const unordered_map<string, int>& baby_table);
unordered_map<string, int> load_baby_table_part(const string& filename);
unordered_map<string, int> load_baby_table();
void delete_existing_table();
unordered_map<string, int> generate_baby_table_parallel(const mpz_class& m);

void print_help() {
    cout << "BSGS (Baby-Step Giant-Step) Elliptic Curve Cryptography Tool\n\n";
    cout << "Usage: ./bsgs [options]\n\n";
    cout << "Options:\n";
    cout << "  -p <number>     Puzzle number (default: 40)\n";
    cout << "  -k <pubkey>     Compressed public key in hex format\n";
    cout << "  -t <threads>    Number of CPU cores to use (default: all available)\n";
    cout << "  -v              Verbose output\n";
    cout << "  -h              Show this help message\n\n";
    cout << "Example:\n";
    cout << "  ./bsgs -p 40 -k 03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4 -t 8\n";
}

bool validate_pubkey(const string& pubkey) {
    if (pubkey.length() != 66) {
        cerr << "[error] Public key must be 66 characters long (including 02/03 prefix)\n";
        return false;
    }
   
    if (pubkey[0] != '0' || (pubkey[1] != '2' && pubkey[1] != '3')) {
        cerr << "[error] Public key must start with 02 or 03\n";
        return false;
    }
   
    for (size_t i = 2; i < pubkey.length(); i++) {
        if (!isxdigit(pubkey[i])) {
            cerr << "[error] Public key contains invalid hex characters\n";
            return false;
        }
    }
   
    return true;
}

Point parse_pubkey(const string& pubkey) {
    string prefix = pubkey.substr(0, 2);
    mpz_class X(pubkey.substr(2), 16);
    int y_parity = stoi(prefix) - 2;
    mpz_class Y = X2Y(X, y_parity);
   
    if (Y == 0) {
        cerr << "[error] Invalid compressed public key!\n";
        exit(1);
    }
   
    return {X, Y};
}

inline Point add(const Point& P, const Point& Q, const mpz_class& p) {
    if (P == Z) return Q;
    if (Q == Z) return P;
    const mpz_class& P0 = P[0];
    const mpz_class& P1 = P[1];
    const mpz_class& Q0 = Q[0];
    const mpz_class& Q1 = Q[1];
    mpz_class lmbda, num, denom, inv;
    if (P != Q) {
        num = Q1 - P1;
        denom = Q0 - P0;
    } else {
        if (P1 == 0) return Z;
        num = 3 * P0 * P0;
        denom = 2 * P1;
    }
    mpz_invert(inv.get_mpz_t(), denom.get_mpz_t(), p.get_mpz_t());
    lmbda = (num * inv) % p;
    mpz_class x = (lmbda * lmbda - P0 - Q0) % p;
    if (x < 0) x += p;
    mpz_class y = (lmbda * (P0 - x) - P1) % p;
    if (y < 0) y += p;
    return {x, y};
}

inline Point mul(const mpz_class& k, const Point& P, const mpz_class& p) {
    Point R0 = Z, R1 = P;
    unsigned long bit_length = mpz_sizeinbase(k.get_mpz_t(), 2);
    for (unsigned long i = bit_length - 1; i < bit_length; --i) {
        if (mpz_tstbit(k.get_mpz_t(), i)) {
            R0 = add(R0, R1, p);
            R1 = add(R1, R1, p);
        } else {
            R1 = add(R0, R1, p);
            R0 = add(R0, R0, p);
        }
    }
    return R0;
}

inline Point point_subtraction(const Point& P, const Point& Q) {
    Point Q_neg = {Q[0], (-Q[1]) % modulo};
    return add(P, Q_neg);
}

inline mpz_class X2Y(const mpz_class& X, int y_parity, const mpz_class& p) {
    mpz_class X_cubed = (X * X * X) % p;
    mpz_class tmp = (X_cubed + mpz_class(7)) % p;
    mpz_class Y;
    mpz_class exp = (p + mpz_class(1)) / mpz_class(4);
    mpz_powm(Y.get_mpz_t(), tmp.get_mpz_t(), exp.get_mpz_t(), p.get_mpz_t());
    if ((Y % 2) != y_parity) {
        Y = p - Y;
    }
    return Y;
}

inline string point_to_cpub(const Point& point) {
    mpz_class x = point[0], y = point[1];
    int y_parity = y.get_ui() & 1;
    string prefix = y_parity == 0 ? "02" : "03";
    char buffer[65];
    mpz_get_str(buffer, 16, x.get_mpz_t());
    return prefix + string(buffer);
}

inline string hash_cpub(const string& cpub) {
    XXH64_hash_t hash = XXH64(cpub.c_str(), cpub.size(), 0);
    char buffer[17];
    snprintf(buffer, sizeof(buffer), "%016lx", hash);
    return string(buffer, 8);
}

void save_baby_table_part(const unordered_map<string, int>& baby_table, int part_num) {
    string filename = "baby_table_part_" + to_string(part_num);
    ofstream outfile(filename, ios::binary);
    if (!outfile) {
        cerr << "[error] Failed to open file for writing: " << filename << endl;
        return;
    }
   
    for (const auto& entry : baby_table) {
        outfile.write(entry.first.c_str(), 8);
        int index = entry.second;
        outfile.write(reinterpret_cast<const char*>(&index), sizeof(index));
    }
   
    if (verbose) {
        cout << "[+] Saved baby table part " << part_num << " with " << baby_table.size() << " entries" << endl;
    }
   
    string command = "pigz -9 -b 128 -f " + filename;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe) {
        cerr << "[error] Failed to compress file: " << filename << endl;
        return;
    }
    pclose(pipe);
}

void save_baby_table(const unordered_map<string, int>& baby_table) {
    size_t current_size = 0;
    int part_num = 1;
    unordered_map<string, int> current_part;
   
    for (const auto& entry : baby_table) {
        size_t entry_size = entry.first.size() + sizeof(int);
        if (current_size + entry_size > MAX_TABLE_SIZE && !current_part.empty()) {
            save_baby_table_part(current_part, part_num++);
            current_part.clear();
            current_size = 0;
        }
        current_part.insert(entry);
        current_size += entry_size;
    }
   
    if (!current_part.empty()) {
        save_baby_table_part(current_part, part_num);
    }
}

unordered_map<string, int> load_baby_table_part(const string& filename) {
    string command = "pigz -d -c " + filename;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe) {
        cerr << "[error] Failed to decompress file: " << filename << endl;
        return {};
    }
   
    unordered_map<string, int> baby_table_part;
    char key_buffer[9];
    int index;
   
    while (fread(key_buffer, 8, 1, pipe) == 1) {
        key_buffer[8] = '\0';
        fread(&index, sizeof(index), 1, pipe);
        baby_table_part[key_buffer] = index;
    }
   
    pclose(pipe);
    return baby_table_part;
}

unordered_map<string, int> load_baby_table() {
    unordered_map<string, int> baby_table;
    int part_num = 1;
   
    while (true) {
        string filename = "baby_table_part_" + to_string(part_num) + ".gz";
        ifstream test(filename);
        if (!test.good()) {
            if (part_num == 1) {
                cerr << "[error] No baby table parts found!" << endl;
                return {};
            }
            break;
        }
        test.close();
       
        string command = "pigz -d -c " + filename;
        FILE* pipe = popen(command.c_str(), "r");
        if (!pipe) {
            cerr << "[error] Failed to decompress file: " << filename << endl;
            return {};
        }
       
        char key[9] = {0};
        int index;
        size_t entries = 0;
       
        while (fread(key, 8, 1, pipe) == 1) {
            if (fread(&index, sizeof(int), 1, pipe) != 1) break;
            key[8] = '\0';
            baby_table[key] = index;
            entries++;
        }
       
        pclose(pipe);
        if (verbose) {
            cout << "[+] Loaded part " << part_num << " with " << entries << " entries" << endl;
        }
        part_num++;
    }
   
    cout << "[+] Loaded baby table with " << baby_table.size() << " total entries" << endl;
    return baby_table;
}

void delete_existing_table() {
    int part_num = 1;
    while (true) {
        string filename = "baby_table_part_" + to_string(part_num);
        string compressed_filename = filename + ".gz";
       
        struct stat buffer;
        bool found = false;
       
        if (stat(filename.c_str(), &buffer) == 0) {
            if (remove(filename.c_str()) != 0) {
                cerr << "[error] Failed to delete file: " << filename << endl;
            } else {
                found = true;
            }
        }
       
        if (stat(compressed_filename.c_str(), &buffer) == 0) {
            if (remove(compressed_filename.c_str()) != 0) {
                cerr << "[error] Failed to delete file: " << compressed_filename << endl;
            } else {
                found = true;
            }
        }
       
        if (!found) {
            if (part_num == 1 && verbose) {
                cout << "[+] No existing table parts found to delete" << endl;
            }
            break;
        }
       
        part_num++;
    }
}

unordered_map<string, int> generate_baby_table_parallel(const mpz_class& m) {
    const int num_threads = threads > 0 ? threads : omp_get_max_threads();
    const unsigned long total_entries = m.get_ui();
    const size_t max_part_size = MAX_TABLE_SIZE * 0.99; // 99% threshold
    std::atomic<int> parts_created(0);
    std::atomic<size_t> current_part_size(0);
    std::atomic<size_t> total_entries_written(0);
   
    system("rm -f baby_table_part_* baby_table_part_*.gz 2>/dev/null");
 
    cout << "[+] Generating " << total_entries << " baby steps" << endl;

    #pragma omp parallel num_threads(num_threads)
    {
        vector<pair<string, int>> local_buffer;
        local_buffer.reserve(100000);

        #pragma omp for schedule(dynamic, 100000)
        for (unsigned long i = 0; i < total_entries; ++i) {
            Point P = mul(i);
            string cpub_hash = hash_cpub(point_to_cpub(P));
            local_buffer.emplace_back(cpub_hash, i);

            if (local_buffer.size() >= 100000) {
                #pragma omp critical
                {
                    int current_part = parts_created + 1;
                    string filename = "baby_table_part_" + to_string(current_part);
                    ofstream outfile(filename, ios::binary | ios::app);
                    if (outfile) {
                        for (const auto& entry : local_buffer) {
                            outfile.write(entry.first.c_str(), 8);
                            outfile.write(reinterpret_cast<const char*>(&entry.second), sizeof(int));
                            total_entries_written++;
                            current_part_size += 12;
                           
                            if (current_part_size >= max_part_size) {
                                outfile.close();
                                string cmd = "pigz -9 -b 128 -f " + filename;
                                system(cmd.c_str());
                                parts_created++;
                                current_part_size = 0;
                            }
                        }
                    }
                    local_buffer.clear();
                }
            }
        }

        #pragma omp critical
        {
            if (!local_buffer.empty()) {
                int current_part = parts_created + 1;
                string filename = "baby_table_part_" + to_string(current_part);
                ofstream outfile(filename, ios::binary | ios::app);
                if (outfile) {
                    for (const auto& entry : local_buffer) {
                        outfile.write(entry.first.c_str(), 8);
                        outfile.write(reinterpret_cast<const char*>(&entry.second), sizeof(int));
                        total_entries_written++;
                    }
                    outfile.close();
                    string cmd = "pigz -9 -b 128 -f " + filename;
                    system(cmd.c_str());
                    parts_created++;
                }
            }
        }
    }

    cout << "[+] Generated " << parts_created << " compressed parts ("
         << total_entries_written << " total entries) " << endl;

    return {};
}

int main(int argc, char* argv[]) {
    // Parse command line arguments
    int opt;
    while ((opt = getopt(argc, argv, "p:k:t:vh")) != -1) {
        switch (opt) {
            case 'p':
                puzzle = atoi(optarg);
                if (puzzle < 1 || puzzle > 256) {
                    cerr << "[error] Invalid puzzle number (must be between 1-256)\n";
                    print_help();
                    return 1;
                }
                break;
            case 'k':
                puzzle_pubkey = optarg;
                if (!validate_pubkey(puzzle_pubkey)) {
                    print_help();
                    return 1;
                }
                break;
            case 't':
                threads = atoi(optarg);
                if (threads < 1) {
                    cerr << "[error] Thread count must be at least 1\n";
                    print_help();
                    return 1;
                }
                break;
            case 'v':
                verbose = true;
                break;
            case 'h':
            default:
                print_help();
                return 0;
        }
    }

    // Initialize OpenMP threads
    if (threads > 0) {
        omp_set_num_threads(threads);
    }
    int actual_threads = omp_get_max_threads();

    // Print configuration
    time_t currentTime = time(nullptr);
    cout << "\n\033[01;33m[+]\033[32m BSGS Started: \033[01;33m" << ctime(&currentTime);
    cout << "\033[0m[+] Puzzle: " << puzzle << endl;
    cout << "[+] Public Key: " << puzzle_pubkey << endl;
    cout << "[+] Using " << actual_threads << " CPU cores" << endl;

    // Initialize range and point
    mpz_class start_range = mpz_class(1) << (puzzle - 1);
    mpz_class end_range = (mpz_class(1) << puzzle) - 1;
    Point P = parse_pubkey(puzzle_pubkey);

    // Calculate m and generate baby table
    mpz_class m = sqrt(end_range - start_range);
    m = m * 4;
    Point m_P = mul(m);

    if (verbose) {
        cout << "[+] Range: 2^" << (puzzle-1) << " to 2^" << puzzle << "-1" << endl;
        cout << "[+] Baby-step count (m): " << m << endl;
    }

    delete_existing_table();

    cout << "[+] Generating baby table..." << endl;
    auto baby_table = generate_baby_table_parallel(m);

    cout << "[+] Loading baby table..." << endl;
    baby_table = load_baby_table();
    if (baby_table.empty()) {
        cerr << "[error] Failed to load baby table\n";
        return 1;
    }

    cout << "[+] Starting BSGS search..." << endl;
    Point S = point_subtraction(P, mul(start_range));
    mpz_class step = 0;
    bool found = false;
    mpz_class found_key;
   
    auto st = chrono::high_resolution_clock::now();
   
    #pragma omp parallel
    {
        Point local_S = S;
        mpz_class local_step = step;
       
        #pragma omp for schedule(dynamic)
        for (int i = 0; i < actual_threads; ++i) {
            while (local_step < (end_range - start_range)) {
                #pragma omp flush(found)
                if (found) break;
               
                string cpub = point_to_cpub(local_S);
                string cpub_hash = hash_cpub(cpub);
                auto it = baby_table.find(cpub_hash);
                if (it != baby_table.end()) {
                    int b = it->second;
                    mpz_class k = start_range + local_step + b;
                    if (point_to_cpub(mul(k)) == puzzle_pubkey) {
                        #pragma omp critical
                        {
                            if (!found) {
                                found = true;
                                found_key = k;
                                auto et = chrono::high_resolution_clock::now();
                                chrono::duration<double> elapsed = et - st;
                               
                                cout << "\n\033[01;32m[+] Solution found!\033[0m" << endl;
                                cout << "[+] Private key: " << k << endl;
                                cout << "[+] Hex: 0x" << hex << k << dec << endl;
                                cout << "[+] Time elapsed: " << elapsed.count() << " seconds\n";
                            }
                        }
                        #pragma omp flush(found)
                        break;
                    }
                }
                local_S = point_subtraction(local_S, m_P);
                local_step += m;
            }
        }
    }

    if (!found) {
        auto et = chrono::high_resolution_clock::now();
        chrono::duration<double> elapsed = et - st;
        cout << "\n\033[01;31m[!] Key not found in the specified range\033[0m" << endl;
        cout << "[+] Time elapsed: " << elapsed.count() << " seconds\n";
    }

    return 0;
}

Makefile
Code:
# Detect OS
UNAME_S := $(shell uname -s)

# Enable static linking by default (change to 'no' to use dynamic linking)
STATIC_LINKING = yes

# Compiler settings based on OS
ifeq ($(UNAME_S),Linux)
# Linux settings

# Compiler
CXX = g++

# Compiler flags
CXXFLAGS = -m64 -std=c++17 -march=native -mtune=native -Ofast -mssse3 -Wall -Wextra \
           -funroll-loops -ftree-vectorize -fstrict-aliasing -fno-semantic-interposition \
           -fvect-cost-model=unlimited -fno-trapping-math -fipa-ra -flto -fopenmp \
           -mavx2 -mbmi2 -madx
LDFLAGS = -lgmp -lgmpxx -lxxhash

# Source files
SRCS = bsgs.cpp

# Object files
OBJS = $(SRCS:.cpp=.o)

# Target executable
TARGET = bsgs

# Default target
all: $(TARGET)

# Link the object files to create the executable
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS)
rm -f $(OBJS) && chmod +x $(TARGET)

# Compile each source file into an object file
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@

# Clean up build files
clean:
@echo "Cleaning..."
rm -f $(OBJS) $(TARGET)

.PHONY: all clean

else
# Windows settings (MinGW-w64)

# Compiler
CXX = g++

# Check if compiler is found
CHECK_COMPILER := $(shell which $(CXX) 2>/dev/null)

# Add MSYS path if the compiler is not found
ifeq ($(CHECK_COMPILER),)
  $(info Compiler not found. Adding MSYS path to the environment...)
  SHELL := cmd
  PATH := C:\msys64\mingw64\bin;$(PATH)
endif

# Compiler flags
CXXFLAGS = -m64 -std=c++17 -march=native -mtune=native -Ofast -mssse3 -Wall -Wextra \
           -funroll-loops -ftree-vectorize -fstrict-aliasing -fno-semantic-interposition \
           -fvect-cost-model=unlimited -fno-trapping-math -fipa-ra -flto -fopenmp \
           -mavx2 -mbmi2 -madx
LDFLAGS = -lgmp -lgmpxx -lxxhash

# Add -static flag if STATIC_LINKING is enabled
ifeq ($(STATIC_LINKING),yes)
    LDFLAGS += -static
else
    $(info Dynamic linking will be used. Ensure required DLLs are distributed)
endif

# Source files
SRCS = bsgs.cpp

# Object files
OBJS = $(SRCS:.cpp=.o)

# Target executable
TARGET = bsgs.exe

# Default target
all: $(TARGET)

# Link the object files to create the executable
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS)
del /q $(OBJS) 2>nul

# Compile each source file into an object file
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@

# Clean up build files
clean:
@echo Cleaning...
del /q $(OBJS) $(TARGET) 2>nul

.PHONY: all clean
endif

dependencies:

Quote
sudo apt install libgmp-dev libomp-dev xxhash pigz


Quote
  • BSGS Started: Wed Jun  4 01:56:48 2025
  • Puzzle: 40
  • Public Key: 03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4
  • Using 12 CPU cores
  • Generating baby table...
  • Generating 2965820 baby steps
  • Generated 1 compressed parts (2965820 total entries)
  • Loading baby table...
  • Loaded baby table with 2964816 total entries
  • Starting BSGS search...
  • Solution found!
  • Private key: 1003651412950
  • Hex: 0xe9ae4933d6
  • Time elapsed: 0.612888 seconds
# ./bsgs -p 50  -k 03f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6 -t 12

Quote
  • BSGS Started: Wed Jun  4 02:20:52 2025
  • Puzzle: 50
  • Public Key: 03f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6
  • Using 12 CPU cores
  • Generating baby table...
  • Generating 94906264 baby steps
  • Generated 6 compressed parts (94906264 total entries)
  • Loading baby table...
  • Loaded baby table with 93398236 total entries
  • Starting BSGS search...
  • Solution found!
  • Private key: 611140496167764
  • Hex: 0x22bd43c2e9354
  • Time elapsed: 4.83157 seconds
P.S. This can be easily modified to use a Bloom Filter. And probably the GPU version. Use it for whatever you want.


make  fail  , 

1. sudo apt install libxxhash-dev
2. bsgs.cpp   add  " #include <array>"

I'm very sorry, my English is not good, I can only explain it this way
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 336
Merit: 8


View Profile
June 04, 2025, 04:31:03 PM
 #10486



make  fail  , 

1. sudo apt install libxxhash-dev
2. bsgs.cpp   add  " #include <array>"

I'm very sorry, my English is not good, I can only explain it this way

Yep. On Windows it must be like this. But he doesn't have Windows to see.  Tongue
nomachine
Full Member
***
Offline Offline

Activity: 686
Merit: 104


View Profile
June 04, 2025, 04:57:45 PM
 #10487


I think it's satoshi himself. The way @satoshi and @saatoshi_rising break up their sentences is the same.

Looking at their posts, they both like to leave two spaces after a period.

@saatoshi_rising: "I am the creator" is also quite thought-provoking. Does it refer to the creator of the puzzle, or the creator of bitcoin? Roll Eyes

Of course, this is just my guess.

Satoshi rarely used phrases like "by way of excuse"  or "what is especially embarrassing."  or "I will make up for two years of stupidity". There is no cryptographic signature or undeniable link to Satoshi unless proven otherwise. Probably not Satoshi. But who knows? He could be anyone (a pseudonym) here… or no one at all.  Grin

BTC: bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
kTimesG
Full Member
***
Offline Offline

Activity: 504
Merit: 129


View Profile
June 04, 2025, 06:27:15 PM
Merited by AlexanderCurl (33)
 #10488

Locking the batch compared to locking just bf.insert is faster time-wise.

This probably depends on the batch size. Since the atomic lock is basically just a clock cycle, this might indicate that multiple cores are often accessing overlapping RAM areas, forcing I/O between CPU caches and main memory.

I think a synchronized queue fits better, and it fills the compute pipeline. Add the hashed pubKeys to the queue (and signal addition), consume them from an auxiliary thread (using signaled events). This ensures no false sharing of L1 cache occurs, and no threads get blocked (unless the queue itself goes OOM). Cheesy

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

Activity: 686
Merit: 104


View Profile
June 04, 2025, 07:00:02 PM
 #10489


This probably depends on the batch size. Since the atomic lock is basically just a clock cycle, this might indicate that multiple cores are often accessing overlapping RAM areas, forcing I/O between CPU caches and main memory.



I also have a problem with my implementation.

The current implementation loads the entire baby table into memory before starting the search phase. For large puzzles (like puzzle 70), this becomes impractical.

For puzzle 70, the baby table would contain approximately 2^35 entries (34 billion+). With each entry being ~12 bytes (8-byte hash + 4-byte index), this would require ~512GB of RAM. Instead of loading the entire table at once: Process each compressed partition one at a time.

For each DB part: Decompress it to memory...Search against the current DB part....Discard it before loading the next DB part

Code:
// Modified search function
void partitioned_search(const Point& S, const mpz_class& start_range,
                       const mpz_class& end_range, const Point& m_P,
                       const string& puzzle_pubkey) {
    bool found = false;
    mpz_class found_key;
    int part_num = 1;
    auto st = chrono::high_resolution_clock::now();

    while (!found) {
        string filename = "baby_table_part_" + to_string(part_num) + ".gz";
        ifstream test(filename);
        if (!test.good()) {
            if (part_num == 1) {
                cerr << "[error] No baby table parts found!" << endl;
                return;
            }
            break; // No more parts
        }
        test.close();

        // Load just this part
        auto baby_table_part = load_baby_table_part(filename);
        if (baby_table_part.empty()) {
            part_num++;
            continue;
        }

        if (verbose) {
            cout << "[+] Searching part " << part_num << " with "
                 << baby_table_part.size() << " entries" << endl;
        }

        #pragma omp parallel
        {
            Point local_S = S;
            mpz_class local_step = 0;
           
            #pragma omp for schedule(dynamic)
            for (int i = 0; i < omp_get_num_threads(); ++i) {
                while (local_step < (end_range - start_range)) {
                    if (found) break;
                   
                    string cpub = point_to_cpub(local_S);
                    string cpub_hash = hash_cpub(cpub);
                    auto it = baby_table_part.find(cpub_hash);
                    if (it != baby_table_part.end()) {
                        int b = it->second;
                        mpz_class k = start_range + local_step + b;
                        if (point_to_cpub(mul(k)) == puzzle_pubkey) {
                            #pragma omp critical
                            {
                                if (!found) {
                                    found = true;
                                    found_key = k;
                                    auto et = chrono::high_resolution_clock::now();
                                    chrono::duration<double> elapsed = et - st;
                                   
                                    cout << "\n\033[01;32m[+] Solution found!\033[0m" << endl;
                                    cout << "[+] Private key: " << k << endl;
                                    cout << "[+] Hex: 0x" << hex << k << dec << endl;
                                    cout << "[+] Time elapsed: " << elapsed.count() << " seconds\n";
                                }
                            }
                            break;
                        }
                    }
                    local_S = point_subtraction(local_S, m_P);
                    local_step += m;
                }
            }
        }
        part_num++;
    }

    if (!found) {
        auto et = chrono::high_resolution_clock::now();
        chrono::duration<double> elapsed = et - st;
        cout << "\n\033[01;31m[!] Key not found in the specified range\033[0m" << endl;
        cout << "[+] Time elapsed: " << elapsed.count() << " seconds\n";
    }
}

BTC: bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
AlexanderCurl
Jr. Member
*
Offline Offline

Activity: 33
Merit: 171


View Profile WWW
June 04, 2025, 07:00:23 PM
 #10490

Locking the batch compared to locking just bf.insert is faster time-wise.

This probably depends on the batch size. Since the atomic lock is basically just a clock cycle, this might indicate that multiple cores are often accessing overlapping RAM areas, forcing I/O between CPU caches and main memory.

I think a synchronized queue fits better, and it fills the compute pipeline. Add the hashed pubKeys to the queue (and signal addition), consume them from an auxiliary thread (using signaled events). This ensures no false sharing of L1 cache occurs, and no threads get blocked (unless the queue itself goes OOM). Cheesy

Thanks a lot for explanations. Will definitely see to it. But I do not feel like improving Point_Search further. At least not now.
I have recently came to a new idea. Will devote my spare time to put it to code.
FrozenThroneGuy
Jr. Member
*
Offline Offline

Activity: 44
Merit: 20


View Profile
June 04, 2025, 07:02:53 PM
Last edit: June 04, 2025, 08:05:38 PM by FrozenThroneGuy
 #10491

3 seconds on PYTHON! PK found.

Code:
import math, time, sys, os
from gmpy2 import mpz, powmod, invert, jacobi
import xxhash  
from sortedcontainers import SortedDict

# Clear screen and initialize
os.system("cls||clear")
t = time.ctime()
sys.stdout.write(f"\033[?25l\033[01;33m[+] BSGS: {t}\n")
sys.stdout.flush()

# Elliptic Curve Parameters (secp256k1)
modulo = mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
order = mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
Gx = mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
Gy = mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
PG = (Gx, Gy)

# Point Addition on Elliptic Curve
def add(P, Q):
    if P == (0, 0):
        return Q
    if Q == (0, 0):
        return P
    Px, Py = P
    Qx, Qy = Q
    if Px == Qx:
        if Py == Qy:
            inv_2Py = invert((Py << 1) % modulo, modulo)
            m = (3 * Px * Px * inv_2Py) % modulo
        else:
            return (0, 0)
    else:
        inv_diff_x = invert(Qx - Px, modulo)
        m = ((Qy - Py) * inv_diff_x) % modulo
    x = (m * m - Px - Qx) % modulo
    y = (m * (Px - x) - Py) % modulo
    return (x, y)

# Scalar Multiplication on Elliptic Curve
def mul(k, P=PG):
    R0, R1 = (0, 0), P
    for i in reversed(range(k.bit_length())):
        if (k >> i) & 1:
            R0, R1 = add(R0, R1), add(R1, R1)
        else:
            R1, R0 = add(R0, R1), add(R0, R0)
    return R0

# Point Subtraction
def point_subtraction(P, Q):
    Q_neg = (Q[0], (-Q[1]) % modulo)
    return add(P, Q_neg)

# Compute Y from X using curve equation
def X2Y(X, y_parity, p=modulo):
    X3_7 = (pow(X, 3, p) + 7) % p
    if jacobi(X3_7, p) != 1:
        return None
    Y = powmod(X3_7, (p + 1) >> 2, p)
    return Y if (Y & 1) == y_parity else (p - Y)

# Convert point to compressed public key
def point_to_cpub(point):
    x, y = point
    y_parity = y & 1
    prefix = '02' if y_parity == 0 else '03'
    compressed_pubkey = prefix + format(x, '064x')
    return compressed_pubkey

# Hash a compressed public key using xxhash and store only the first 8 characters
def hash_cpub(cpub):
    return xxhash.xxh64(cpub.encode()).hexdigest()[:8]

# Main Script
if __name__ == "__main__":
    # Puzzle Parameters
    puzzle = 40
    start_range, end_range = 2**(puzzle-1), (2**puzzle) - 1
    puzzle_pubkey = '03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4'

    # Parse Public Key
    if len(puzzle_pubkey) != 66:
        print("[error] Public key length invalid!")
        sys.exit(1)
    prefix = puzzle_pubkey[:2]
    X = mpz(int(puzzle_pubkey[2:], 16))
    y_parity = int(prefix) - 2
    Y = X2Y(X, y_parity)
    if Y is None:
        print("[error] Invalid compressed public key!")
        sys.exit(1)
    P = (X, Y)  # Uncompressed public key

    # Precompute m and mP for BSGS
    m = int(math.floor(math.sqrt(end_range - start_range)))
    m_P = mul(m)

    # Create Baby Table with SortedDict
    print('[+] Creating babyTable...')
    baby_table = SortedDict()  
    Ps = (0, 0)  # Start with the point at infinity
    for i in range(m + 1):
        cpub = point_to_cpub(Ps)
        cpub_hash = hash_cpub(cpub)  # Use xxhash and store only 8 characters
        baby_table[cpub_hash] = i  # Store the hash as the key and index as the value
        Ps = add(Ps, PG)  # Incrementally add PG

    # BSGS Search
    print('[+] BSGS Search in progress')
    S = point_subtraction(P, mul(start_range))
    step = 0
    st = time.time()
    while step < (end_range - start_range):
        cpub = point_to_cpub(S)
        cpub_hash = hash_cpub(cpub)  # Hash the current compressed public key
        # Check if the hash exists in the baby_table
        if cpub_hash in baby_table:
            b = baby_table[cpub_hash]
            k = start_range + step + b
            if point_to_cpub(mul(k)) == puzzle_pubkey:
                print(f'[+] m={m} step={step} b={b}')
                print(f'[+] Key found: {k}')
                print("[+] Time Spent : {0:.2f} seconds".format(time.time() - st))
                sys.exit()
        S = point_subtraction(S, m_P)
        step += m

    print('[+] Key not found')
    print("[+] Time Spent : {0:.2f} seconds".format(time.time() - st))


puzzle 40
  • BSGS: Thu Feb 20 21:49:30 2025
  • Creating babyTable...
  • BSGS Search in progress
  • m=741455 step=453895024440 b=574622
  • Key found: 1003651412950
  • Time Spent : 2.90 seconds


puzzle 50
  • BSGS: Thu Feb 20 22:13:12 2025
  • Creating babyTable...
  • BSGS Search in progress
  • m=23726566 step=48190529944714 b=12801738
  • Key found: 611140496167764
  • Time Spent : 12.71 seconds

This is the result... on a single core Grin

P.S. For puzzles above 50, you'll need a Bloom Filter



Who wrote this code?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Share your donation address I can see light at the end of a tunnel.

Yes, I agree that NoMachine is great for coding, but did you know it only works if you have a public key!!? That’s clearly tied to the current puzzles.

Also, there's a better option from RC that uses GPU.

Regards.


Puzzle 40 and 50
Code:
root@DESKTOP-BD9V01U:/mnt/e/Kang# ./Mark1 --range 562949953421311:1125899906842623  --pubkey 03f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6 --dp_point 1000000 --dp_bits 8

=========== Phase-0: RAM summary ===========
DP table : 52.1Mb  ( 1000000 / 1333334 slots, load 75.00% )
Bloom    : 1.91Mb
--------------------------------------------
Total    : 54.0Mb

========== Phase-1: Building traps ============
Unique traps: 1000000/1000000 (done)

=========== Phase-2: Kangaroos =============
Speed: 2.52 MH/s | Hops: 12582912 | Time: 0:0:5

============= Phase-3: Result ==============
Private key : 0x00000000000000000000000000000000000000000000000000022BD43C2E9354
Found by thread: 3
Total time: 00:00:00.217

Private key saved to FOUND.txt
root@DESKTOP-BD9V01U:/mnt/e/Kang# ./Mark1 --range 549755813887:1199511627775  --pubkey 03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4 --dp_point 10000 --dp_bits 8

=========== Phase-0: RAM summary ===========
DP table : 534Kb  ( 10000 / 13334 slots, load 75.00% )
Bloom    : 19.5Kb
--------------------------------------------
Total    : 553Kb

========== Phase-1: Building traps ============
Unique traps: 10000/10000 (done)

=========== Phase-2: Kangaroos =============
Speed: 0.00 H/s | Hops: 0 | Time: 0:0:5

============= Phase-3: Result ==============
Private key : 0x000000000000000000000000000000000000000000000000000000E9AE4933D6
Found by thread: 4
Total time: 00:00:00.037

Private key saved to FOUND.txt
Play with kangs...

Puzzle 55
Code:
root@DESKTOP-BD9V01U:/mnt/e/Triarch/Kang# ./Mark1 --range 18014398509481983:36028797018963967  --pubkey 0385a30d8413af4f8f9e6312400f2d194fe14f02e719b24c3f83bf1fd233a8f963 --dp_bits 12 --dp_point 1000000

=========== Phase-0: RAM summary ===========
DP table : 52.1Mb  ( 1000000 / 1333334 slots, load 75.00% )
Bloom    : 1.91Mb
--------------------------------------------
Total    : 54.0Mb

========== Phase-1: Building traps =========
Unique traps: 1000000/1000000 (done)

=========== Phase-2: Kangaroos =============
Speed: 15.94 MH/s | Hops: 79691776 | Time: 0:0:5

============= Phase-3: Result ==============
Private key : 0x000000000000000000000000000000000000000000000000006ABE1F9B67E114
Found by thread: 10
Total time: 00:00:01.251
Private key saved to FOUND.txt

Puzzle 60
Code:
root@DESKTOP-BD9V01U:/mnt/e/Triarch/Kang# ./Mark1 --range 576460752303423487:1152921504606846975  --pubkey 0348e843dc5b1bd246e6309b4924b81543d02b16c8083df973a89ce2c7eb89a10d --dp_bits 10 --dp_point 10000000

=========== Phase-0: RAM summary ===========
DP table : 521Mb  ( 10000000 / 13333334 slots, load 75.00% )
Bloom    : 19.1Mb
--------------------------------------------
Total    : 540Mb

========== Phase-1: Building traps =========
Unique traps: 10000000/10000000 (done)

=========== Phase-2: Kangaroos =============
Speed: 44.30 MH/s | Hops: 548667392 | Time: 0:0:10

============= Phase-3: Result ==============
Private key : 0x0000000000000000000000000000000000000000000000000FC07A1825367BBE
Found by thread: 2
Total time: 00:00:08.347
Private key saved to FOUND.txt

Puzzle 70
Code:
root@DESKTOP-BD9V01U:/mnt/e/Triarch/Kang# ./Mark1 --range 590295810358705651711:1180591620717411303423  --pubkey 0290e6900a58d33393bc1097b5aed31f2e4e7cbd3e5466af958665bc0121248483 --dp_point 100000000 --dp_bits 10

=========== Phase-0: RAM summary ===========
DP table : 5.09Gb  ( 100000000 / 133333334 slots, load 75.00% )
Bloom    : 191Mb
--------------------------------------------
Total    : 5.28Gb

========== Phase-1: Building traps =========
Unique traps: 100000000/100000000 (done)

=========== Phase-2: Kangaroos =============
Speed: 20.45 MH/s | Hops: 14508097536 | Time: 0:3:45

============= Phase-3: Result ==============
Private key : 0x0000000000000000000000000000000000000000000000349B84B6431A6C4EF1
Found by thread: 1
Total time: 00:03:41.587
Private key saved to FOUND.txt

And this is not so powerful CPU Ryzen 7 5800H
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 336
Merit: 8


View Profile
June 04, 2025, 07:44:14 PM
 #10492

~~ snippet ~~


I wonder how many million years it takes you to solve puzzle 135?   Tongue
FrozenThroneGuy
Jr. Member
*
Offline Offline

Activity: 44
Merit: 20


View Profile
June 04, 2025, 07:52:27 PM
 #10493

~~ snippet ~~


I wonder how many million years it takes you to solve puzzle 135?   Tongue
On 1 cpu with my algo 2.288 years. 1 gpu like rtx4060 - 288 years, 10 gpu - 28 years. 10 rtx4090 - 6 may be 7 years.
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 336
Merit: 8


View Profile
June 04, 2025, 07:55:27 PM
 #10494

Everyone give up, don't be cheated of life, because time is life.

You repeat the same sentence like a parrot.  Roll Eyes
IlhamCung23
Newbie
*
Offline Offline

Activity: 8
Merit: 0


View Profile
June 04, 2025, 09:44:25 PM
 #10495

candidate for 71 puzzle prefix 6 digits Huh

Code:
 118393
119305
119315
119324
119334
119344
119354
119363
119373
119383
119392
120305
120314
120324
120334
120343
120353
120363
120373
120382
120392
121304
121314
121324
121333
121343
121353
121362
121372
121382
121391
122207
122216
122226
122236
122245
122255
122265
122275
122284
122294
123206
123216
123226
123235
123245
123255
123264
123274
123284
123294
124206
124215
124225
124235
124245
124254
124264
124274
124283
124293
125108
125118
125128
125137
125147
125157
125166
125176
125186
125196
126108
126117
126127
126137
126147
126156
126166
126176
126185
126195
127107
127117
127127
127136
127146
127156
127166
127175
127185
127195
128000
128010
128020
128029
128039
128049
128058
128068
128078
128087
128097
129000
129009
129019
129029
129039
129048
129058
129068
129077
129087
129097
130009
130019
130028
130038
130048
130057
130067
130077
130087
130096
131008
131018
131028
131038
131047
131057
131067
131076
131086
131096
131901
131911
131921
131930
131940
131950
131960
131969
131979
131989
131998
132901
132911
132920
132930
132940
132949
132959
132969
132978
132988
132998
133900
133910
133920
133930
133939
133949
133959
133968
133978
133988
133997
134803
134813
134822
134832
134842
134851
134861
134871
134881
134890
135802
135812
135822
135832
135841
135851
135861
135870
135880
135890
135899
136802
136812
136821
136831
136841
136851
136860
136870
136880
136889
136899
137802
137811
137821
137831
137840
137850
137860
137869
137879
137889
137899
138704
138714
138723
138733
138743
138753
138762
138772
138782
138791
139704
139713
139723
139733
139742
139752
139762
139772
139781
139791
140703
140713
140723
140732
140742
140752
140761
140771
140781
140790
141606
141615
141625
141635
141644
141654
141664
141674
141683
141693
142605
142615
142625
142634
142644
142654
142663
142673
142683
142693
143605
143614
143624
143634
143644
143653
143663
143673
143682
143692
144507
144517
144527
144536
144546
144556
144565
144575
144585
144595
145507
145517
145526
145536
145546
145555
145565
145575
145584
145594
146506
146516
146526
146535
146545
146555
146565
146574
146584
146594
147506
147516
147525
147535
147545
147554
147564
147574
147584
147593
148408
148418
148428
148438
148447
148457
148467
148476
148486
148496
149408
149418
149427
149437
149447
149456
149466
149476
149486
149495
150408
150417
150427
150437
150446
150456
150466
150475
150485
150495
151300
151310
151320
151329
151339
151349
151359
151368
151378
151388
151397
152300
152310
152319
152329
152339
152348
152358
152368
152378
152387
152397
153309
153319
153329
153338
153348
153358
153367
153377
153387
153396
154202
154212
154221
154231
154241
154250
154260
154270
154280
154289
154299
155201
155211
155221
155231
155240
155250
155260
155269
155279
155289
155299
156201
156211
156220
156230
156240
156250
156259
156269
156279
156288
156298
157201
157210
157220
157230
157239
157249
157259
157269
157278
157288
157298
158103
158113
158123
158132
158142
158152
158161
158171
158181
158190
159103
159112
159122
159132
159141
159151
159161
159171
159180
159190
160102
160112
160122
160131
160141
160151
160160
160170
160180
160190
160199
161005
161014
161024
161034
161044
161053
161063
161073
161082
161092
162004
162014
162024
162033
162043
162053
162062
162072
162082
162092
163004
163014
163023
163033
163043
163052
163062
163072
163081
163091
164003
164013
164023
164032
164042
164052
164062
164071
164081
164091
164906
164916
164925
164935
164945
164954
164964
164974
164983
164993
165905
165915
165925
165935
165944
165954
165964
165973
165983
165993
166905
166915
166924
166934
166944
166953
166963
166973
166983
166992
167807
167817
167827
167837
167846
167856
167866
167875
167885
167895
168807
168817
168826
168836
168846
168856
168865
168875
168885
168894
169807
169816
169826
169836
169845
169855
169865
169874
169884
169894
170709
170719
170728
170738
170748
170758
170767
170777
170787
170796
171709
171718
171728
171738
171747
171757
171767
171777
171786
171796
172708
172718
172728
172737
172747
172757
172766
172776
172786
172796
173708
173717
173727
173737
173747
173756
173766
173776
173785
173795
174601
174610
174620
174630
174639
174649
174659
174668
174678
174688
174698
175600
175610
175619
175629
175639
175649
175658
175668
175678
175687
175697
176600
176609
176619
176629
176638
176648
176658
176668
176677
176687
176697
177502
177512
177522
177531
177541
177551
177560
177570
177580
177589
177599
178502
178511
178521
178531
178540
178550
178560
178570
178579
178589
178599
179501
179511
179521
179530
179540
179550
179559
179569
179579
179589
179598
180501
180510
180520
180530
180540
180549
180559
180569
180578
180588
180598
181403
181413
181423
181432
181442
181452
181462
181471
181481
181491
182403
182413
182422
182432
182442
182451
182461
182471
182480
182490
183402
183412
183422
183431
183441
183451
183461
183470
183480
183490
183499
184305
184315
184324
184334
184344
184353
184363
184373
184383
184392
185304
185314
185324
185334
185343
185353
185363
185372
185382
185392
186304
186314
186323
186333
186343
186353
186362
186372
186382
186391
187206
187216
187226
187236
187245
187255
187265
187274
187284
187294
188206
188216
188225
188235
188245
188255
188264
188274
188284
188293
189206
189215
189225
189235
189244
189254
189264
189274
189283
189293
190205
190215
190225
190234
190244
190254
190263
190273
190283
190292
191108
191117
191127
191137
191146
191156
191166
191176
191185
191195
192107
192117
192127
192136
192146
192156
192165
192175
192185
192195
193107
193116
193126
193136
193146
193155
193165
193175
193184
193194
194000
194009
194019
194029
194038
194048
194058
194067
194077
194087
194097
195009
195019
195028
195038
195048
195057
195067
195077
195086
195096
196008
196018
196028
196037
196047
196057
196067
196076
196086
196096
196901
196911
196921
196930
196940
196950
196959
196969
196979
196989
196998
197901
197910
197920
197930
197940
197949
197959
197969
197978
197988
197998
198900
198910
198920
198929
198939
198949
198958
198968
198978
198988
198997
199900
199910
199919
199929
199939
199948
199958
199968
199977
199987
199997
200802
200812
200822
200831
200841
200851
200861
200870
200880
200890
200899
201802
201812
201821
201831
201841
201850
201860
201870
201880
201889
201899
202801
202811
202821
202831
202840
202850
202860
202869
202879
202889
202898
203704
203714
203723
203733
203743
203752
203762
203772
203782
203791
204703
204713
204723
204733
204742
204752
204762
204771
204781
204791
205703
205713
205722
205732
205742
205752
205761
205771
205781
205790
206703
206712
206722
206732
206741
206751
206761
206771
206780
206790
207605
207615
207624
207634
207644
207654
207663
207673
207683
207692
208605
208614
208624
208634
208643
208653
208663
208673
208682
208692
209604
209614
209624
209633
209643
209653
209662
209672
209682
209692
210507
210516
210526
210536
210546
210555
210565
210575
210584
210594
211506
211516
211526
211535
211545
211555
211564
211574
211584
211594
212506
212515
212525
212535
212545
212554
212564
212574
212583
212593
213408
213418
213428
213437
213447
213457
213467
213476
213486
213496
214408
214418
214427
214437
214447
214456
214466
214476
214485
214495
215407
215417
215427
215437
215446
215456
215466
215475
215485
215495
216407
216417
216426
216436
216446
216455
216465
216475
216485
216494
217300
217309
217319
217329
217339
217348
217358
217368
217377
217387
217397
218309
218319
218328
218338
218348
218358
218367
218377
218387
218396
219309
219318
219328
219338
219347
219357
219367
219376
219386
219396
220201
220211
220221
220230
220240
220250
220260
220269
220279
220289
220298
221201
221211
221220
221230
221240
221249
221259
221269
221279
221288
221298
222200
222210
222220
222230
222239
222249
222259
222268
222278
222288
222297
223200
223210
223219
223229
223239
223249
223258
223268
223278
223287
223297
224103
224112
224122
224132
224141
224151
224161
224170
224180
224190
225102
225112
225121
225131
225141
225151
225160
225170
225180
225189
225199
226102
226111
226121
226131
226140
226150
226160
226170
226179
226189
226199
227004
227014
227024
227033
227043
227053
227062
227072
227082
227091
228004
228013
228023
228033
228042
228052
228062
228072
228081
228091
229003
229013
229023
229032
229042
229052
229061
229071
229081
229091
229906
229915
229925
229935
229945
229954
229964
229974
229983
229993
230905
230915
230925
230934
230944
230954
230963
230973
230983
230993
231905
231915
231924
231934
231944
231953
231963
231973
231982
231992
232904
232914
232924
232933
232943
232953
232963
232972
232982
232992
233807
233817
233826
233836
233846
233855
233865
233875
233885
233894
234806
234816
234826
234836
234845
234855
234865
234874
234884
234894
235806
235816
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 336
Merit: 8


View Profile
June 04, 2025, 10:05:33 PM
 #10496

~~ snippet ~~

What method did you use to get these numbers? Tongue
nomachine
Full Member
***
Offline Offline

Activity: 686
Merit: 104


View Profile
June 05, 2025, 09:17:54 AM
 #10497

I wonder how many million years it takes you to solve puzzle 135?   Tongue

Scripts based on public keys and x and y coordinates are completely useless here because there are no public keys until puzzle #135. There are only two logical options: either invent a new algorithm that will compute HASH160 1000 times faster, or go for 2000 GPUs. I don’t know which method is worse. In any case, this is a dead end. All we can do is showcase useless scripts. Which is exactly what we’re already doing.  Grin

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

Activity: 336
Merit: 8


View Profile
June 05, 2025, 09:32:48 AM
 #10498

invent a new algorithm that will compute HASH160 1000 times faster

How ?  Tongue
nomachine
Full Member
***
Offline Offline

Activity: 686
Merit: 104


View Profile
June 05, 2025, 09:40:47 AM
 #10499

invent a new algorithm that will compute HASH160 1000 times faster

How ?  Tongue

I wanna know how too, bro.  Grin

BTC: bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
bibilgin
Newbie
*
Offline Offline

Activity: 236
Merit: 0


View Profile
June 05, 2025, 12:02:25 PM
 #10500

Does anyone know who the author of the puzzle is?JPL?…

I know who the creator is.
- He cannot be contacted digitally in any way. (But he can reach you.)
- Someone who likes to travel in the mountains, go camping, etc.
- One of the first people to introduce Bitcoin in the EUROPE region and in his own country during the early days of Bitcoin.
- A person who has some interesting comments about the creator of Bitcoin (SATOSHI) and gives clues about who the Satoshi group is.
- The head of the Fund donations who helps people in some regions with the help of 6 associations.
- Finally, a person who has more than 28500 BTC detected in the total of his accounts.
- Just the Last Hint - A citizen of a country you cannot guess (Europe)

...
Pages: « 1 ... 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 [525] 526 527 528 529 530 531 532 »
  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!