Aggiungi versione GPU (CUDA) del bruteforce

Porta la stessa strategia algoritmica della versione CPU (batch EC in
coordinate Jacobiane con Z1=1 + un'unica inversione di campo per batch
via trucco di Montgomery) su GPU NVIDIA, dove però GMP non è
disponibile: l'aritmetica a 256 bit mod il primo di secp256k1 è scritta
a mano (limb a 64 bit + __int128, riduzione veloce sfruttando
2^256 ≡ 2^32+977 mod p), e ogni thread CUDA agisce come una lane di
ricerca indipendente con la propria chiave privata iniziale casuale —
esattamente come un thread CPU, ma migliaia in parallelo invece di una
manciata.

La moltiplicazione scalare su device è un semplice double-and-add
(nessun wNAF/tabelle precalcolate come in libsecp256k1 lato host), il
principale margine di ottimizzazione futura. Il matching usa un Bloom
filter + ricerca binaria su un array di target ordinato, entrambi
caricati una volta sola in memoria device.

Aggiunge i target `make gpu` / `make gpu-info` al Makefile (NVCC_ARCH
configurabile, default sm_61/Pascal) e documenta in README che su WSL2
il driver NVIDIA arriva dall'host Windows: dentro WSL serve installare
solo il CUDA Toolkit, mai un driver.

Verificato: aritmetica di campo, moltiplicazione scalare e batch add
confrontati bit-per-bit con secp256k1_ec_pubkey_create (nessuna
discrepanza su ~30 valori di test); run end-to-end con privkey nota
trova la chiave corretta; nessun falso positivo su chiavi pubbliche
valide casuali. Su una Quadro P4000 (Pascal): ~15M keys/sec, contro
~3.5-4M keys/sec della CPU con 11 thread nello stesso ambiente.
This commit is contained in:
2026-07-03 15:58:26 +02:00
parent adb608df38
commit ac68b6aa88
5 changed files with 820 additions and 8 deletions
+47 -3
View File
@@ -27,6 +27,14 @@ SOURCE = p2pk_bruteforce.cpp
INCLUDE_PATH = -I/usr/local/include -I/usr/include
LIB_PATH = -L/usr/local/lib -L/usr/lib
# Versione GPU (CUDA)
NVCC = nvcc
# Architettura GPU target: sm_61 = Pascal (es. Quadro/GTX 10xx). Sovrascrivi con
# `make gpu NVCC_ARCH=sm_75` (Turing), sm_86 (Ampere), sm_89 (Ada) etc. secondo la tua GPU.
NVCC_ARCH = sm_61
GPU_TARGET = p2pk_bruteforce_gpu
GPU_SOURCE = p2pk_bruteforce_gpu.cu
# ============================================================================
# TARGET PRINCIPALI
# ============================================================================
@@ -140,7 +148,7 @@ valgrind: debug
# Pulizia
clean:
@echo "[+] Pulizia file compilati..."
rm -f $(TARGET) $(TARGET)_debug $(TARGET)_pgo
rm -f $(TARGET) $(TARGET)_debug $(TARGET)_pgo $(GPU_TARGET)
rm -f *.o *.gcda *.gcno *.s
rm -f progress.csv
@echo "[+] Pulizia completata!"
@@ -170,6 +178,35 @@ build-secp256k1:
@echo "[+] Compilazione libsecp256k1 ottimizzata..."
@./build_secp256k1.sh
# ============================================================================
# VERSIONE GPU (CUDA)
# ============================================================================
# Richiede: NVIDIA CUDA Toolkit (nvcc) + driver NVIDIA funzionante (verifica
# con `nvidia-smi`). Su WSL2 il driver è quello del sistema Windows host: non
# va installato dentro WSL, basta il CUDA Toolkit (`nvcc --version` per controllare).
gpu: $(GPU_SOURCE)
@echo "========================================="
@echo " Bitcoin P2PK Bruteforce GPU - Compilazione"
@echo "========================================="
@which $(NVCC) > /dev/null || (echo "[ERROR] nvcc non trovato. Installa il CUDA Toolkit."; exit 1)
$(NVCC) -O3 -arch=$(NVCC_ARCH) -std=c++17 -diag-suppress 1650 \
$(INCLUDE_PATH) $(LIB_PATH) \
-o $(GPU_TARGET) $(GPU_SOURCE) -lsecp256k1
@echo "[+] Compilazione completata!"
@echo "[+] Eseguibile: ./$(GPU_TARGET)"
@echo ""
@echo "OTTIMIZZAZIONI ATTIVE:"
@echo " ✓ Batch EC point addition in coordinate Jacobiane (stesso algoritmo della CPU)"
@echo " ✓ Batch modular inversion (Montgomery) per thread"
@echo " ✓ Migliaia di thread paralleli invece di N core CPU"
@echo "========================================="
gpu-info:
@nvidia-smi --query-gpu=name,driver_version,memory.total,compute_cap --format=csv 2>&1 || \
echo "[!] nvidia-smi non disponibile: driver NVIDIA non rilevato"
@which $(NVCC) > /dev/null && $(NVCC) --version || echo "[!] nvcc non trovato: CUDA Toolkit non installato"
# ============================================================================
# HELP
# ============================================================================
@@ -191,15 +228,22 @@ help:
@echo " make clean-all - Pulizia completa"
@echo " make install-deps - Installa dipendenze"
@echo " make build-secp256k1 - Compila libsecp256k1 locale"
@echo " make gpu - Compila la versione GPU (richiede CUDA Toolkit)"
@echo " make gpu-info - Controlla driver NVIDIA e CUDA Toolkit disponibili"
@echo ""
@echo "Uso consigliato:"
@echo " 1. make # Compila"
@echo " 2. ./$(TARGET) # Esegui bruteforce"
@echo ""
@echo "Per massime performance:"
@echo "Per massime performance su CPU:"
@echo " make pgo # Compila con PGO (+10-20% speed)"
@echo ""
@echo "Per usare la GPU (molto più veloce, se disponibile):"
@echo " make gpu-info # Verifica driver/CUDA Toolkit"
@echo " make gpu # Compila"
@echo " ./$(GPU_TARGET) # Esegui"
@echo ""
@echo "==================================================="
.PHONY: all build pgo pgo-generate pgo-run pgo-use debug asm bench \
valgrind clean clean-all install-deps build-secp256k1 help
valgrind clean clean-all install-deps build-secp256k1 gpu gpu-info help