...
it would be awesome if there's a CUDA version for it.
I can give you this same script that works in C++ but you have to do the GPU part yourself.CUDA programming can be complex, and proper error handling and synchronization are crucial. Also, not all parts of your program may benefit from GPU acceleration, so it's essential to profile and optimize as needed.
puzzle66.cpp
#include <iostream>
#include <vector>
#include <iomanip>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/obj_mac.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <ctime>
#include <sstream>
#include <fstream>
// Function to convert a byte vector to a hexadecimal string
std::string bytesToHex(const std::vector<unsigned char>& bytes) {
std::stringstream ss;
for (unsigned char byte : bytes) {
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte);
}
return ss.str();
}
// Function to calculate the RIPEMD160 hash of a byte vector
std::vector<unsigned char> calculateRIPEMD160(const std::vector<unsigned char>& data) {
std::vector<unsigned char> hash(RIPEMD160_DIGEST_LENGTH);
RIPEMD160(data.data(), data.size(), hash.data());
return hash;
}
int main() {
// Initialize the OpenSSL library
if (OpenSSL_add_all_algorithms() != 1) {
std::cerr << "OpenSSL initialization failed." << std::endl;
return 1;
}
// Set the target Hash160 value (replace with your target hash)
std::string target_hash160_hex = "20d45a6a762535700ce9e0b216e31994335db8a5";
int puzzle = 66; // The puzzle number (Bits)
// Clear the console
std::system("clear");
std::cout << "\r\033[01;33m[+] Bytea HASH160 Search by NoMachine" << "\n";
time_t currentTime = std::time(nullptr);
std::cout << "\r\033[01;33m[+] " << std::ctime(¤tTime) << "\r";
std::cout << "\r\033[01;33m[+] Puzzle: " << puzzle << "\033[0m" << std::endl;
std::cout.flush();
// Calculate the maximum bytes value based on the puzzle
BIGNUM* limit_int = BN_new();
BN_set_word(limit_int, 1);
BN_lshift(limit_int, limit_int, puzzle);
BN_sub_word(limit_int, 1);
int max_bytes = (BN_num_bits(limit_int) + 7) / 8;
// Create an EC_KEY object
EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
// Calculate the SHA-256 hash of the public key
unsigned char sha256_result[SHA256_DIGEST_LENGTH];
// Calculate the RIPEMD160 hash of the SHA-256 hash
std::vector<unsigned char> ripemd160_result(RIPEMD160_DIGEST_LENGTH);
while (true) {
// Create a 32-byte private key with 32 zeros followed by random bytes
std::vector<unsigned char> private_key_bytes(32, 0);
// Generate random bytes for the remaining part of the private key
std::vector<unsigned char> random_bytes(max_bytes);
if (RAND_bytes(random_bytes.data(), random_bytes.size()) != 1) {
std::cerr << "Error generating random bytes." << std::endl;
BN_free(limit_int);
EC_KEY_free(ec_key);
return 1;
}
// Append the random bytes to the private key
std::copy(random_bytes.begin(), random_bytes.end(), private_key_bytes.begin() + 32 - max_bytes);
// Create a BIGNUM from the private key bytes
BIGNUM* bn_private_key = BN_bin2bn(private_key_bytes.data(), private_key_bytes.size(), NULL);
// Set the private key in the EC_KEY object
EC_KEY_set_private_key(ec_key, bn_private_key);
// Compute the public key from the private key
EC_POINT* public_key_point = EC_POINT_new(EC_KEY_get0_group(ec_key));
EC_POINT_mul(EC_KEY_get0_group(ec_key), public_key_point, bn_private_key, NULL, NULL, NULL);
// Convert the public key point to binary representation (compressed)
size_t public_key_length = EC_POINT_point2oct(EC_KEY_get0_group(ec_key), public_key_point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL);
std::vector<unsigned char> public_key_bytes(public_key_length);
EC_POINT_point2oct(EC_KEY_get0_group(ec_key), public_key_point, POINT_CONVERSION_COMPRESSED, public_key_bytes.data(), public_key_length, NULL);
// Check if the public key starts with "02" (compressed format)
if (public_key_bytes[0] == 0x02) {
SHA256(public_key_bytes.data(), public_key_bytes.size(), sha256_result);
ripemd160_result = calculateRIPEMD160(std::vector<unsigned char>(sha256_result, sha256_result + SHA256_DIGEST_LENGTH));
// Convert the calculated RIPEMD160 hash to a hexadecimal string
std::string calculated_hash160_hex = bytesToHex(ripemd160_result);
// Display the generated public key hash (Hash160) and private key
std::string message = "\r\033[01;33m[+] Public Key Hash (Hash 160): " + calculated_hash160_hex;
std::cout << message << "\e[?25l";
std::cout.flush();
// Check if the generated public key hash matches the target
if (calculated_hash160_hex == target_hash160_hex) {
// Get the current time
std::time_t currentTime;
std::time(¤tTime);
std::tm tmStruct = *std::localtime(¤tTime);
// Format the current time into a human-readable string
std::stringstream timeStringStream;
timeStringStream << std::put_time(&tmStruct, "%Y-%m-%d %H:%M:%S");
std::string formattedTime = timeStringStream.str();
std::cout << "\n\033[32m[+] PUZZLE SOLVED: " << formattedTime << "\033[0m" << std::endl;
std::cout << "\r\033[32m[+] Target Public Key Hash (Hash160) found! Private Key: " << bytesToHex(private_key_bytes) << std::endl;
// Append the private key information to a file if it matches
std::ofstream file("KEYFOUNDKEYFOUND.txt", std::ios::app);
if (file.is_open()) {
file << "\nPUZZLE SOLVED " << formattedTime;
file << "\nPrivate Key (hex): " << bytesToHex(private_key_bytes);
file << "\n--------------------------------------------------------------------------------------------------------------------------------------------";
file.close();
}
break;
}
}
}
// Free the EC_KEY and BIGNUM objects
BN_free(limit_int);
EC_KEY_free(ec_key);
return 0;
}
Scripts check if the public key starts with "02" (compressed format) and you can change to "03".
Makefile
# Makefile
# Source files
SRC = puzzle66.cpp
# Compiler and flags
CXX = g++
CXXFLAGS = -m64 -march=native -mtune=native -mfpmath=sse -Wall -msse2 -msse3 -msse4 -msse4.1 -msse4.2 -msse4a -mavx -pthread -O3 -I.
# OpenSSL libraries
LIBS = -lssl -lcrypto
# Output executable
TARGET = puzzle66
# Default target
all: $(TARGET)
# Rule for compiling the source code
$(TARGET): $(SRC)
$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
# Clean target to remove generated files
clean:
rm -f $(TARGET)
.PHONY: all clean
I am running this on an AMD Ryzen 9 7950X.
It has compiler flags for AMD which accelerate mathematical crypto functions. A similar file must be created for CUDA.
Good luck....