Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ modules.order
Module.symvers
Mkfile.old
dkms.conf
.specstory/
62 changes: 59 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ default:
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c sha3/keccak.c -o keccak.o
gcc -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c xxhash/xxhash.c -o xxhash.o
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c util.c -o util.o
gcc -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c os_random.c -o os_random.o
gcc -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c win_compat.c -o win_compat.o
gcc -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c win_thread_compat.c -o win_thread_compat.o
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c secp256k1/Int.cpp -o Int.o
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c secp256k1/Point.cpp -o Point.o
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c secp256k1/SECP256K1.cpp -o SECP256K1.o
Expand Down Expand Up @@ -36,9 +39,36 @@ legacy:
g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c gmp256k1/IntMod.cpp -o IntMod.o
g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -flto -c gmp256k1/Random.cpp -o Random.o
g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -flto -c gmp256k1/IntGroup.cpp -o IntGroup.o
g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -o keyhunt keyhunt_legacy.cpp base58.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o GMP256K1.o IntMod.o IntGroup.o Random.o hashing.o sha3.o keccak.o -lm -lpthread -lcrypto -lgmp
gcc -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c os_random.c -o os_random.o
gcc -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c win_compat.c -o win_compat.o
gcc -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c win_thread_compat.c -o win_thread_compat.o
g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -o keyhunt keyhunt_legacy.cpp base58.o bloom.o oldbloom.o xxhash.o util.o os_random.o win_compat.o win_thread_compat.o Int.o Point.o GMP256K1.o IntMod.o IntGroup.o Random.o hashing.o sha3.o keccak.o -lm -lpthread -lcrypto -lgmp
rm -r *.o
bsgsd:

CC ?= gcc
CXX ?= g++
AR ?= ar
CFLAGS ?= -Wall -Wextra
CXXFLAGS ?= -Wall -Wextra -Wno-deprecated-copy
LDFLAGS ?= -lm

# MinGW detection
MACHINE := $(shell $(CXX) -dumpmachine 2>/dev/null)
ifneq (,$(findstring mingw,$(MACHINE)))
IS_MINGW := 1
endif

# MinGW-specific flags (used by target `mingw`)
CFLAGS_MINGW := -m64 -march=x86-64 -mssse3 -Wall -Wextra -Wno-unused-parameter -Ofast -ftree-vectorize
CXXFLAGS_MINGW := -m64 -march=x86-64 -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize
# Link libgcc and libstdc++ statically so exe doesn't require libgcc_s_seh-1.dll or libstdc++-6.dll
# Link libgcc and libstdc++ statically and link winpthread statically to avoid libwinpthread-1.dll
# Use -Wl,-Bstatic/-Bdynamic around -lwinpthread so other system libs remain dynamic
LDFLAGS_MINGW := -static-libgcc -static-libstdc++ -Wl,-Bstatic -lwinpthread -Wl,-Bdynamic -lm -lws2_32 -lbcrypt
# Do not request pthread linkage for MinGW build (avoid libwinpthread dependency)
THREAD_FLAGS_MINGW :=

default:
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate target definition: the default target is defined at line 1 and again here at line 67. Make will only execute the last definition, which means the first definition will be ignored. This appears to be an error in the diff application - the second default: should likely be bsgsd: based on the context.

Suggested change
default:
bsgsd:

Copilot uses AI. Check for mistakes.
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -flto -c oldbloom/bloom.cpp -o oldbloom.o
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -flto -c bloom/bloom.cpp -o bloom.o
gcc -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-unused-parameter -Ofast -ftree-vectorize -c base58/base58.c -o base58.o
Expand All @@ -57,5 +87,31 @@ bsgsd:
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -o hash/sha256.o -ftree-vectorize -flto -c hash/sha256.cpp
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -o hash/ripemd160_sse.o -ftree-vectorize -flto -c hash/ripemd160_sse.cpp
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -o hash/sha256_sse.o -ftree-vectorize -flto -c hash/sha256_sse.cpp
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -o bsgsd bsgsd.cpp base58.o rmd160.o hash/ripemd160.o hash/ripemd160_sse.o hash/sha256.o hash/sha256_sse.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -o keyhunt keyhunt.cpp base58.o rmd160.o hash/ripemd160.o hash/ripemd160_sse.o hash/sha256.o hash/sha256_sse.o bloom.o oldbloom.o xxhash.o util.o os_random.o win_compat.o win_thread_compat.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread
rm -r *.o

# Target for building with MinGW (MSYS2 mingw64)
.PHONY: mingw
mingw:
$(CXX) $(CXXFLAGS_MINGW) -c oldbloom/bloom.cpp -o oldbloom.o
$(CXX) $(CXXFLAGS_MINGW) -c bloom/bloom.cpp -o bloom.o
$(CC) $(CFLAGS_MINGW) -c base58/base58.c -o base58.o
$(CC) $(CFLAGS_MINGW) -c rmd160/rmd160.c -o rmd160.o
$(CXX) $(CXXFLAGS_MINGW) -c sha3/sha3.c -o sha3.o
$(CXX) $(CXXFLAGS_MINGW) -c sha3/keccak.c -o keccak.o
$(CC) $(CFLAGS_MINGW) -c xxhash/xxhash.c -o xxhash.o
$(CXX) $(CXXFLAGS_MINGW) -c util.c -o util.o
$(CC) $(CFLAGS_MINGW) -c os_random.c -o os_random.o
$(CC) $(CFLAGS_MINGW) -c win_compat.c -o win_compat.o
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing win_thread_compat.o compilation: The MinGW target compiles win_compat.c at line 101 but doesn't compile win_thread_compat.c. Since MinGW builds need the thread compatibility layer, this file should be compiled and added to the link line at line 112.

Copilot uses AI. Check for mistakes.
$(CXX) $(CXXFLAGS_MINGW) -c secp256k1/Int.cpp -o Int.o
$(CXX) $(CXXFLAGS_MINGW) -c secp256k1/Point.cpp -o Point.o
$(CXX) $(CXXFLAGS_MINGW) -c secp256k1/SECP256K1.cpp -o SECP256K1.o
$(CXX) $(CXXFLAGS_MINGW) -c secp256k1/IntMod.cpp -o IntMod.o
$(CXX) $(CXXFLAGS_MINGW) -c secp256k1/Random.cpp -o Random.o
$(CXX) $(CXXFLAGS_MINGW) -c secp256k1/IntGroup.cpp -o IntGroup.o
$(CXX) $(CXXFLAGS_MINGW) -o hash/ripemd160.o -c hash/ripemd160.cpp
$(CXX) $(CXXFLAGS_MINGW) -o hash/sha256.o -c hash/sha256.cpp
$(CXX) $(CXXFLAGS_MINGW) -o hash/ripemd160_sse.o -c hash/ripemd160_sse.cpp
$(CXX) $(CXXFLAGS_MINGW) -o hash/sha256_sse.o -c hash/sha256_sse.cpp
$(CXX) $(CXXFLAGS_MINGW) -o keyhunt keyhunt.cpp base58.o rmd160.o hash/ripemd160.o hash/ripemd160_sse.o hash/sha256.o hash/sha256_sse.o bloom.o oldbloom.o xxhash.o util.o os_random.o win_compat.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o $(LDFLAGS_MINGW) $(THREAD_FLAGS_MINGW)
rm -r *.o
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,46 @@ and then execute with `-h` to see the help
./keyhunt -h
```

## Windows build (MinGW)

If you want to build natively on Windows, the recommended approach is to use MSYS2 / MinGW-w64 (use the `MINGW64` shell). Below are the minimal tested steps to produce the `keyhunt.exe` binary.

- Prerequisites (MSYS2 MINGW64):

- Install MSYS2: https://www.msys2.org/
- Open the `MSYS2 MinGW 64-bit` shell (MINGW64).

- Update the system and install required packages:

```bash
pacman -Syu # may ask to close/reopen the shell per instructions
pacman -S --needed base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-pkg-config \
mingw-w64-x86_64-gmp mingw-w64-x86_64-openssl mingw-w64-x86_64-make
```

- Clone and build (from the MINGW64 shell):

```bash
git clone https://github.com/albertobsd/keyhunt.git
cd keyhunt
make mingw
```

The `make mingw` target uses a MinGW-specific `Makefile` and links the necessary Windows libraries (`-lws2_32 -lbcrypt`) while compiling the objects required for Windows.

- Run the test binary (e.g. `test.bat`):

In Explorer double-click `test.bat` or run from the shell:

```bash
./keyhunt.exe -d -m address -f tests/66.txt -b 66 -l compress -R -s 10
```

Notes and troubleshooting:

- If the linker complains about missing `-lbcrypt`, ensure you are using the `MINGW64` shell (the MinGW toolchain provides the proper import libraries). If needed, you can try linking `-ladvapi32` and adjust `os_random.c` to use `CryptGenRandom` as a fallback.
- If the program starts and then immediately exits, run it with `-d` (debug) and without `-q` (quiet), capture output to a log (the provided `test.bat` already does this) and check `run.log` for messages such as `"[E] Error os_getrandom() ?"` which indicate RNG API issues on Windows.

## ¡Beta!

This version is still a **beta** version, there are a lot of things that can be fail or improve.
Expand Down
7 changes: 4 additions & 3 deletions base58/base58.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
* under the terms of the standard MIT license. See COPYING for more details.
*/

#ifndef _WIN64
#include <arpa/inet.h>
#else
/* Use Winsock on Windows (including MinGW); otherwise use POSIX arpa/inet.h */
#if defined(_WIN32)
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif

#include <stdbool.h>
Expand Down
2 changes: 1 addition & 1 deletion bloom/bloom.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#ifndef _BLOOM_H
#define _BLOOM_H

#ifdef _WIN64
#if defined(_WIN64) && !defined(__MINGW32__) && !defined(__MINGW64__)
#include <windows.h>
#endif

Expand Down
41 changes: 24 additions & 17 deletions bsgsd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,18 @@ email: albertobsd@gmail.com

#include <unistd.h>
#include <pthread.h>
#if !defined(__MINGW32__) && !defined(__MINGW64__)
#include <sys/random.h>
#include <linux/random.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> // for inet_addr()
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#include "win_compat.h"
#include "os_random.h"
#include <pthread.h> // for pthread functions

#define PORT 8080
Expand Down Expand Up @@ -66,7 +72,7 @@ struct tothread {
struct bPload {
uint32_t threadid;
uint64_t from;
uint64_t to;
int osr = os_getrandom(&rseedvalue, sizeof(unsigned long));
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line appears to be a misplaced code fragment. It looks like a variable initialization int osr = os_getrandom(&rseedvalue, sizeof(unsigned long)); that should not be inside the struct definition. This will cause a compilation error as struct members cannot have code statements like function calls at the point of declaration.

Suggested change
int osr = os_getrandom(&rseedvalue, sizeof(unsigned long));
int osr;

Copilot uses AI. Check for mistakes.
uint64_t counter;
uint64_t workload;
uint32_t aux;
Expand Down Expand Up @@ -315,7 +321,8 @@ int main(int argc, char **argv) {
pthread_mutex_init(&write_random,NULL);
pthread_mutex_init(&mutex_bsgs_thread,NULL);

srand(time(NULL));
// Initialize sockets for Windows compatibility (no-op on POSIX)
socket_init();

secp = new Secp256K1();
secp->Init();
Expand All @@ -324,9 +331,9 @@ int main(int argc, char **argv) {
BSGS_GROUP_SIZE.SetInt32(CPU_GRP_SIZE);

unsigned long rseedvalue;
int bytes_read = getrandom(&rseedvalue, sizeof(unsigned long), GRND_NONBLOCK);
if(bytes_read > 0) {
rseed(rseedvalue);
int osr = os_getrandom(&rseedvalue, sizeof(unsigned long));
if(osr == 0) {
rseed(rseedvalue);
/*
In any case that seed is for a failsafe RNG, the default source on linux is getrandom function
See https://www.2uo.de/myths-about-urandom/
Expand All @@ -337,9 +344,9 @@ int main(int argc, char **argv) {
what year is??
WTF linux without RNG ?
*/
fprintf(stderr,"[E] Error getrandom() ?\n");
fprintf(stderr,"[E] Error os_getrandom() ?\n");
exit(0);
rseed(clock() + time(NULL) + rand()*rand());
rseed(clock() + time(NULL));
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreachable code: line 348 calls exit(0) but line 349 has rseed(clock() + time(NULL)) after it. This line will never execute because the program exits on line 348. This appears to be leftover code that should have been removed.

Suggested change
rseed(clock() + time(NULL));

Copilot uses AI. Check for mistakes.
}

port = PORT;
Expand Down Expand Up @@ -1361,7 +1368,7 @@ int main(int argc, char **argv) {
fflush(stdout);
}

close(server_fd);
socket_close(server_fd);
}

void pubkeytopubaddress_dst(char *pkey,int length,char *dst) {
Expand Down Expand Up @@ -1944,9 +1951,9 @@ void calcualteindex(int i,Int *key) {
}


void sleep_ms(int milliseconds) { // cross-platform sleep function
#if defined(_WIN64) && !defined(__CYGWIN__)
Sleep(milliseconds);
#if defined(_WIN64) && !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__)
void sleep_ms(int milliseconds) { // cross-platform sleep function
Sleep(milliseconds);
Comment on lines +1954 to +1956
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function declaration formatting issue: the function signature is split across multiple lines with inconsistent placement. The opening brace placement and parameter alignment don't match standard formatting conventions.

Copilot uses AI. Check for mistakes.
#elif _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
Expand Down Expand Up @@ -2352,7 +2359,7 @@ void* client_handler(void* arg) {
// Peek at the incoming data to determine its length
bytes_received = recv(client_fd, buffer, sizeof(buffer) - 1, MSG_PEEK);
if (bytes_received <= 0) {
close(client_fd);
socket_close(client_fd);
pthread_exit(NULL);
}

Expand All @@ -2361,7 +2368,7 @@ void* client_handler(void* arg) {
size_t line_length = newline ? (newline - buffer) + 1 : bytes_received;
bytes_received = recv(client_fd, buffer, line_length, 0);
if (bytes_received <= 0) {
close(client_fd);
socket_close(client_fd);
pthread_exit(NULL);
}

Expand All @@ -2372,15 +2379,15 @@ void* client_handler(void* arg) {
printf("Invalid input format from client, tokens %i : %s\n",t.n, buffer);
freetokenizer(&t);
sendstr(client_fd,"400 Bad Request");
close(client_fd);
socket_close(client_fd);
pthread_exit(NULL);
}

if(!secp->ParsePublicKeyHex(t.tokens[0],OriginalPointsBSGS,OriginalPointsBSGScompressed)) {
printf("Invalid publickey format from client %s\n",t.tokens[0]);
freetokenizer(&t);
sendstr(client_fd,"400 Bad Request");
close(client_fd);
socket_close(client_fd);
pthread_exit(NULL);
}
if(!(isValidHex(t.tokens[1]) && isValidHex(t.tokens[2]))) {
Expand Down Expand Up @@ -2454,7 +2461,7 @@ void* client_handler(void* arg) {
}


close(client_fd);
socket_close(client_fd);
pthread_exit(NULL);
}

Expand Down
41 changes: 4 additions & 37 deletions gmp256k1/Random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,7 @@
#include <gmp.h>


#if defined(_WIN32) || defined(_WIN64)
#include <Windows.h>
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib")
#elif __unix__ || __unix || __APPLE__ || __MACH__ || __CYGWIN__
#include <unistd.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <linux/random.h>
#if defined(GRND_NONBLOCK)
#define USE_GETRANDOM
#endif
#endif
#include "../os_random.h"

#include "Int.h"

Expand Down Expand Up @@ -67,28 +55,7 @@ void Int::Rand(Int *min,Int *max) {
this->Add(min);
}

int random_bytes(unsigned char *buffer,int bytes) {
#if defined(_WIN32) || defined(_WIN64)
if (!BCryptGenRandom(NULL, buffer, length, BCRYPT_USE_SYSTEM_PREFERRED_RNG)) {
fprintf(stderr,"Not BCryptGenRandom available\n");
exit(EXIT_FAILURE);
}
else
return bytes;
#elif __unix__ || __unix || __APPLE__ || __MACH__ || __CYGWIN__
#ifdef USE_GETRANDOM
return syscall(SYS_getrandom, buffer, bytes, GRND_NONBLOCK);
#else
int fd = open("/dev/urandom", O_RDONLY);
if (fd == -1) {
fprintf(stderr,"Not /dev/urandom available\n");
exit(EXIT_FAILURE);
}
ssize_t result = read(fd, buffer, bytes);
close(fd);
return result;
#endif
#else
#error "Unsupported platform"
#endif
int random_bytes(unsigned char *buffer,int bytes) {
if (os_getrandom(buffer, bytes) == 0) return bytes;
return -1;
}
10 changes: 6 additions & 4 deletions hash/ripemd160_sse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
// Internal SSE RIPEMD-160 implementation.
namespace ripemd160sse {

#ifdef WIN64
#if defined(_WIN64) && !defined(__MINGW32__) && !defined(__MINGW64__)
static const __declspec(align(16)) uint32_t _init[] = {
#else
static const uint32_t _init[] __attribute__ ((aligned (16))) = {
Expand All @@ -42,7 +42,7 @@ namespace ripemd160sse {

#define ROL(x,n) _mm_or_si128( _mm_slli_epi32(x, n) , _mm_srli_epi32(x, 32 - n) )

#ifdef WIN64
#if defined(_WIN64) && !defined(__MINGW32__) && !defined(__MINGW64__)

#define not(x) _mm_andnot_si128(x, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))
#define f1(x,y,z) _mm_xor_si128(x, _mm_xor_si128(y, z))
Expand Down Expand Up @@ -297,7 +297,8 @@ namespace ripemd160sse {

} // namespace ripemd160sse

#ifdef WIN64

#if defined(_WIN64) && !defined(__MINGW32__) && !defined(__MINGW64__)

#define DEPACK(d,i) \
((uint32_t *)d)[0] = s[0].m128i_u32[i]; \
Expand Down Expand Up @@ -345,7 +346,8 @@ void ripemd160sse_32(

ripemd160sse::Transform(s, bs);

#ifndef WIN64
/* Declare pointer accessors for GCC/MinGW path (non-MSVC) */
#if !defined(_WIN64) || defined(__MINGW32__) || defined(__MINGW64__)
uint32_t *s0 = (uint32_t *)&s[0];
uint32_t *s1 = (uint32_t *)&s[1];
uint32_t *s2 = (uint32_t *)&s[2];
Expand Down
Loading