Ottimizza bruteforce con partizionamento keyspace
This commit is contained in:
@@ -52,6 +52,8 @@ static int num_threads = 0; // Numero effettivo di thread da usare
|
|||||||
struct ThreadData {
|
struct ThreadData {
|
||||||
int thread_id;
|
int thread_id;
|
||||||
uint64_t seed;
|
uint64_t seed;
|
||||||
|
uint8_t range_start[32]; // Inizio range dello spazio delle chiavi
|
||||||
|
uint8_t range_end[32]; // Fine range dello spazio delle chiavi
|
||||||
};
|
};
|
||||||
|
|
||||||
// Rileva numero di thread/core disponibili
|
// Rileva numero di thread/core disponibili
|
||||||
@@ -62,6 +64,29 @@ int get_num_threads() {
|
|||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Partiziona lo spazio delle chiavi tra i thread
|
||||||
|
void partition_keyspace(int thread_id, int total_threads, uint8_t* range_start, uint8_t* range_end) {
|
||||||
|
// Azzera entrambi gli array
|
||||||
|
memset(range_start, 0, 32);
|
||||||
|
memset(range_end, 0xFF, 32);
|
||||||
|
|
||||||
|
// Partiziona usando i primi 8 bytes (64 bit)
|
||||||
|
// Questo dà 2^64 / total_threads chiavi per thread
|
||||||
|
uint64_t partition_size = UINT64_MAX / total_threads;
|
||||||
|
uint64_t start = partition_size * thread_id;
|
||||||
|
uint64_t end = (thread_id == total_threads - 1) ? UINT64_MAX : (partition_size * (thread_id + 1) - 1);
|
||||||
|
|
||||||
|
// Converti in big-endian per i primi 8 bytes
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
range_start[i] = (uint8_t)(start >> (56 - i * 8));
|
||||||
|
range_end[i] = (uint8_t)(end >> (56 - i * 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
// I restanti 24 bytes rimangono:
|
||||||
|
// range_start[8..31] = 0x00 (minimo)
|
||||||
|
// range_end[8..31] = 0xFF (massimo)
|
||||||
|
}
|
||||||
|
|
||||||
// Signal handler per chiusura pulita
|
// Signal handler per chiusura pulita
|
||||||
void sigint_handler(int sig) {
|
void sigint_handler(int sig) {
|
||||||
(void)sig;
|
(void)sig;
|
||||||
@@ -135,30 +160,36 @@ int load_target_keys(const char* filename) {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Genera una chiave privata casuale
|
// Genera una chiave privata casuale nel range assegnato al thread
|
||||||
void generate_random_privkey(uint8_t* privkey, uint64_t* seed) {
|
void generate_random_privkey_in_range(uint8_t* privkey, uint64_t* seed,
|
||||||
// Usa un PRNG veloce (xorshift64)
|
const uint8_t* range_start, const uint8_t* range_end) {
|
||||||
*seed ^= *seed << 13;
|
// Usa xorshift64 per generare 32 bytes casuali
|
||||||
*seed ^= *seed >> 7;
|
for (int i = 0; i < 32; i++) {
|
||||||
*seed ^= *seed << 17;
|
|
||||||
|
|
||||||
// Riempi i 32 bytes della privkey
|
|
||||||
uint64_t* key64 = (uint64_t*)privkey;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
*seed ^= *seed << 13;
|
*seed ^= *seed << 13;
|
||||||
*seed ^= *seed >> 7;
|
*seed ^= *seed >> 7;
|
||||||
*seed ^= *seed << 17;
|
*seed ^= *seed << 17;
|
||||||
key64[i] = *seed;
|
privkey[i] = (uint8_t)(*seed & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assicurati che la chiave sia valida (< ordine della curva)
|
// Applica il range: mappa la chiave casuale nel range [range_start, range_end]
|
||||||
// In pratica, quasi tutti i 256 bit casuali sono validi
|
// Usa i primi byte del range per definire il prefisso
|
||||||
|
// I byte successivi sono completamente casuali all'interno del range
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
// Copia i primi 8 bytes dal range_start per partizionare lo spazio
|
||||||
|
privkey[i] = range_start[i];
|
||||||
|
}
|
||||||
|
// I restanti 24 bytes (192 bit) sono completamente casuali
|
||||||
|
// Questo dà ad ogni thread uno spazio di 2^192 chiavi (ancora astronomico)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incrementa la chiave privata
|
// Genera chiave completamente casuale (usata come fallback)
|
||||||
void increment_privkey(uint8_t* privkey) {
|
void generate_random_privkey(uint8_t* privkey, uint64_t* seed) {
|
||||||
for (int i = 31; i >= 0; i--) {
|
// Usa un PRNG veloce (xorshift64)
|
||||||
if (++privkey[i] != 0) break;
|
for (int i = 0; i < 32; i++) {
|
||||||
|
*seed ^= *seed << 13;
|
||||||
|
*seed ^= *seed >> 7;
|
||||||
|
*seed ^= *seed << 17;
|
||||||
|
privkey[i] = (uint8_t)(*seed & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,8 +294,8 @@ void* worker_thread(void* arg) {
|
|||||||
while (keep_running) {
|
while (keep_running) {
|
||||||
// Genera batch di chiavi
|
// Genera batch di chiavi
|
||||||
for (int batch = 0; batch < BATCH_SIZE && keep_running; batch++) {
|
for (int batch = 0; batch < BATCH_SIZE && keep_running; batch++) {
|
||||||
// Genera chiave privata casuale
|
// Genera chiave privata casuale nel range assegnato
|
||||||
generate_random_privkey(privkey, &seed);
|
generate_random_privkey_in_range(privkey, &seed, data->range_start, data->range_end);
|
||||||
|
|
||||||
// Genera chiave pubblica non compressa usando secp256k1
|
// Genera chiave pubblica non compressa usando secp256k1
|
||||||
if (secp256k1_ec_pubkey_create(ctx, &pubkey_obj, privkey)) {
|
if (secp256k1_ec_pubkey_create(ctx, &pubkey_obj, privkey)) {
|
||||||
@@ -280,8 +311,8 @@ void* worker_thread(void* arg) {
|
|||||||
|
|
||||||
local_attempts++;
|
local_attempts++;
|
||||||
|
|
||||||
// Incrementa la chiave privata per il prossimo tentativo
|
// NOTA: Rimosso increment_privkey() - ogni chiave è completamente casuale
|
||||||
increment_privkey(privkey);
|
// Questo elimina la sovrapposizione tra thread
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aggiorna contatore globale
|
// Aggiorna contatore globale
|
||||||
@@ -340,22 +371,45 @@ int main(int argc, char** argv) {
|
|||||||
// Rileva numero di thread disponibili
|
// Rileva numero di thread disponibili
|
||||||
num_threads = get_num_threads();
|
num_threads = get_num_threads();
|
||||||
printf("[+] CPU rilevata: %d thread disponibili\n", num_threads);
|
printf("[+] CPU rilevata: %d thread disponibili\n", num_threads);
|
||||||
|
printf("[+] Partizionamento spazio chiavi in %d regioni\n", num_threads);
|
||||||
|
|
||||||
// Inizializza timestamp
|
// Inizializza timestamp e seed base robusto
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
// Crea threads
|
// Crea threads
|
||||||
pthread_t threads[MAX_THREADS];
|
pthread_t threads[MAX_THREADS];
|
||||||
ThreadData thread_data[MAX_THREADS];
|
ThreadData thread_data[MAX_THREADS];
|
||||||
|
|
||||||
printf("[+] Avvio %d thread worker...\n\n", num_threads);
|
printf("[+] Avvio %d thread worker...\n", num_threads);
|
||||||
|
|
||||||
for (int i = 0; i < num_threads; i++) {
|
for (int i = 0; i < num_threads; i++) {
|
||||||
thread_data[i].thread_id = i;
|
thread_data[i].thread_id = i;
|
||||||
thread_data[i].seed = (uint64_t)time(NULL) + i * 12345;
|
|
||||||
|
// Seed molto distanziati: combina timestamp, thread_id e random
|
||||||
|
// Questo garantisce seed completamente diversi anche se lanciato rapidamente
|
||||||
|
uint64_t base_seed = (uint64_t)time(NULL);
|
||||||
|
uint64_t thread_offset = ((uint64_t)i << 48); // Usa i bit alti
|
||||||
|
uint64_t random_part = ((uint64_t)rand() << 32) | rand();
|
||||||
|
thread_data[i].seed = base_seed ^ thread_offset ^ random_part;
|
||||||
|
|
||||||
|
// Partiziona lo spazio delle chiavi
|
||||||
|
partition_keyspace(i, num_threads, thread_data[i].range_start, thread_data[i].range_end);
|
||||||
|
|
||||||
|
// Mostra info del range (primi 4 bytes per brevità)
|
||||||
|
printf(" Thread %d: range 0x%02x%02x%02x%02x... - 0x%02x%02x%02x%02x... (seed: %016lx)\n",
|
||||||
|
i,
|
||||||
|
thread_data[i].range_start[0], thread_data[i].range_start[1],
|
||||||
|
thread_data[i].range_start[2], thread_data[i].range_start[3],
|
||||||
|
thread_data[i].range_end[0], thread_data[i].range_end[1],
|
||||||
|
thread_data[i].range_end[2], thread_data[i].range_end[3],
|
||||||
|
thread_data[i].seed);
|
||||||
|
|
||||||
pthread_create(&threads[i], NULL, worker_thread, &thread_data[i]);
|
pthread_create(&threads[i], NULL, worker_thread, &thread_data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
// Loop principale - mostra progresso
|
// Loop principale - mostra progresso
|
||||||
while (keep_running) {
|
while (keep_running) {
|
||||||
sleep(10);
|
sleep(10);
|
||||||
|
|||||||
Reference in New Issue
Block a user