0% found this document useful (0 votes)
4 views5 pages

TOP2

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views5 pages

TOP2

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

#include <iostream>

#include <string>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/obj_mac.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <openssl/bn.h>
#include <iomanip>
#include <sstream>
#include <vector>
#include <chrono>
#include <fstream>
#include <thread>

using namespace std;

// Funkcija za heširanje SHA256 koristeći OpenSSL 3.0 API


string sha256(const string& input) {
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int length = 0;

EVP_MD_CTX* mdctx = EVP_MD_CTX_new();


if (mdctx == nullptr) {
cerr << "Error creating context\n";
return "";
}

if (EVP_DigestInit_ex(mdctx, EVP_sha256(), nullptr) != 1) {


cerr << "Error initializing digest\n";
EVP_MD_CTX_free(mdctx);
return "";
}

if (EVP_DigestUpdate(mdctx, input.c_str(), input.length()) != 1) {


cerr << "Error updating digest\n";
EVP_MD_CTX_free(mdctx);
return "";
}

if (EVP_DigestFinal_ex(mdctx, hash, &length) != 1) {


cerr << "Error finalizing digest\n";
EVP_MD_CTX_free(mdctx);
return "";
}

EVP_MD_CTX_free(mdctx);

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

// Funkcija za heširanje RIPEMD160


string ripemd160(const string& input) {
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int hash_len = 0;
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
if (mdctx == nullptr) {
cerr << "Error creating EVP_MD_CTX" << endl;
return "";
}

if (EVP_DigestInit_ex(mdctx, EVP_ripemd160(), nullptr) != 1) {


cerr << "Error initializing RIPEMD160" << endl;
EVP_MD_CTX_free(mdctx);
return "";
}

if (EVP_DigestUpdate(mdctx, input.c_str(), input.length()) != 1) {


cerr << "Error updating RIPEMD160 hash" << endl;
EVP_MD_CTX_free(mdctx);
return "";
}

if (EVP_DigestFinal_ex(mdctx, hash, &hash_len) != 1) {


cerr << "Error finalizing RIPEMD160 hash" << endl;
EVP_MD_CTX_free(mdctx);
return "";
}

EVP_MD_CTX_free(mdctx);

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

// Funkcija za generisanje javnog ključa iz privatnog ključa koristeći secp256k1


string private_to_public(const string& private_key_hex) {
BIGNUM* private_key_bn = BN_new();
BN_hex2bn(&private_key_bn, private_key_hex.c_str());

EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp256k1);


EC_POINT* public_key_point = EC_POINT_new(group);

if (EC_POINT_mul(group, public_key_point, private_key_bn, nullptr, nullptr,


nullptr) != 1) {
cerr << "Error generating public key from private key" << endl;
return "";
}

unsigned char public_key[65];


int public_key_len = EC_POINT_point2oct(group, public_key_point,
POINT_CONVERSION_COMPRESSED, public_key, sizeof(public_key), nullptr);

if (public_key_len < 0) {
cerr << "Error converting public key to octet form" << endl;
return "";
}

stringstream ss;
for (int i = 0; i < public_key_len; i++) {
ss << hex << setw(2) << setfill('0') << (int)public_key[i];
}

BN_free(private_key_bn);
EC_GROUP_free(group);
EC_POINT_free(public_key_point);

return ss.str();
}

// Funkcija za Base58 enkodiranje (Base58Check)


string base58_encode(const string& input) {
const string base58_chars =
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjklmnpqrstuvwxyz";
string result = "";
BIGNUM* bn = BN_new();
BN_CTX* ctx = BN_CTX_new(); // Kreiranje BN_CTX objekta
BN_hex2bn(&bn, input.c_str());

while (BN_cmp(bn, BN_value_one()) > 0) {


BIGNUM* div = BN_new();
BIGNUM* rem = BN_new();

BIGNUM* divisor = BN_new();


BN_set_word(divisor, 58); // Postavljanje 58 kao delitelja
BN_div(div, rem, bn, divisor, ctx); // Korišćenje BN_CTX objekta u
funkciji BN_div

result = base58_chars[BN_get_word(rem)] + result;

BN_copy(bn, div);
BN_free(div);
BN_free(rem);
BN_free(divisor); // Oslobađanje memorije za divisor
}

BN_free(bn);
BN_CTX_free(ctx); // Oslobađanje BN_CTX objekta
return result;
}

// Funkcija za generisanje Bitcoin adrese iz javnog ključa


string pubkey_to_address(const string& pubkey) {
string sha256_hash = sha256(pubkey);
string ripemd160_hash = ripemd160(sha256_hash);

string address = "00" + ripemd160_hash;

string sha256_1 = sha256(address);


string sha256_2 = sha256(sha256_1);
string checksum = sha256_2.substr(0, 8);

address += checksum;

string encoded_address = base58_encode(address);


return encoded_address;
}

void find_address_with_prefix(const string& start_private_key, const string&


target_prefix, uint64_t start_value, uint64_t end_value) {
string base_key = start_private_key.substr(0, start_private_key.length() - 8);
auto start_time = chrono::steady_clock::now();

ofstream found_file("found.txt", ios::app);

if (!found_file) {
cerr << "Error opening found.txt" << endl;
return;
}

for (uint64_t i = start_value; i < end_value; i++) {


string hex_suffix = to_string(i);
string private_key = base_key + hex_suffix;

string pubkey = private_to_public(private_key);


string address = pubkey_to_address(pubkey);

if (address.rfind(target_prefix, 0) == 0) {
auto end_time = chrono::steady_clock::now();
chrono::duration<double> elapsed = end_time - start_time;
cout << "\nFound address: " << address << endl;
cout << "Private Key: " << private_key << endl;
cout << "Public Key: " << pubkey << endl; // Ispis javnog ključa
cout << "Search time: " << elapsed.count() << " seconds\n";

found_file << "Found address: " << address << endl;


found_file << "Private Key: " << private_key << endl;
found_file << "Public Key: " << pubkey << endl; // Čuvanje javnog
ključa u fajl
found_file << "Search time: " << elapsed.count() << " seconds" << endl
<< endl;
}

if (i % 10000 == 0) {
auto end_time = chrono::steady_clock::now();
chrono::duration<double> elapsed = end_time - start_time;
double speed = (i / elapsed.count());
cout << "Thread progress: Checked " << i << " keys | Speed: " << speed
<< " keys/sec | Time elapsed: " << elapsed.count() << " seconds\n";
}
}

found_file.close();
}

void search_with_threads(const string& start_private_key, const string&


target_prefix, int num_threads) {
uint64_t start_value = 0;
uint64_t end_value = 16ULL * 16ULL * 16ULL * 16ULL * 16ULL * 16ULL * 16ULL *
16ULL;
uint64_t range_size = (end_value - start_value) / num_threads;

vector<thread> threads;

for (int i = 0; i < num_threads; i++) {


uint64_t thread_start = start_value + i * range_size;
uint64_t thread_end = start_value + (i + 1) * range_size;
threads.push_back(thread(find_address_with_prefix, start_private_key,
target_prefix, thread_start, thread_end));
}

for (auto& t : threads) {


t.join();
}
}

int main() {
string start_private_key =
"00000000000000000000000000000000000000000000007545bf10859946eca";
string target_prefix = "1B"; // Prefiks koji tražimo
int num_threads = 12; // Broj niti koje želimo da koristimo

search_with_threads(start_private_key, target_prefix, num_threads);

return 0;
}

You might also like