/ src / bitmsghash / bitmsghash.cpp
bitmsghash.cpp
  1  // bitmessage cracker, build with g++ or MSVS to a shared library, use included python code for usage under bitmessage
  2  #ifdef _WIN32
  3  #include "winsock.h"
  4  #include "windows.h"
  5  #define uint64_t unsigned __int64
  6  #else
  7  #include <arpa/inet.h>
  8  #include <pthread.h>
  9  #include <stdint.h>
 10  #endif
 11  #include <string.h>
 12  #include <stdio.h>
 13  #include <stdlib.h>
 14  #if defined(__APPLE__) || defined(__FreeBSD__) || defined (__DragonFly__) || defined (__OpenBSD__) || defined (__NetBSD__)
 15  #include <sys/types.h>
 16  #include <sys/sysctl.h>
 17  #endif
 18  
 19  #include "openssl/sha.h"
 20  
 21  #define HASH_SIZE 64
 22  #define BUFLEN 16384
 23  
 24  #if defined(__GNUC__)
 25    #define EXPORT __attribute__ ((__visibility__("default")))
 26  #elif defined(_WIN32)
 27    #define EXPORT __declspec(dllexport)
 28  #endif
 29  
 30  #ifndef __APPLE__
 31  #define ntohll(x) ( ( (uint64_t)(ntohl( (unsigned int)((x << 32) >> 32) )) << 32) | ntohl( ((unsigned int)(x >> 32)) ) )
 32  #endif
 33  
 34  unsigned long long max_val;
 35  unsigned char *initialHash;
 36  unsigned long long successval = 0;
 37  unsigned int numthreads = 0;
 38  
 39  #ifdef _WIN32
 40  DWORD WINAPI threadfunc(LPVOID param) {
 41  #else
 42  void * threadfunc(void* param) {
 43  #endif
 44  	unsigned int incamt = *((unsigned int*)param);
 45  	SHA512_CTX sha;
 46  	unsigned char buf[HASH_SIZE + sizeof(uint64_t)] = { 0 };
 47  	unsigned char output[HASH_SIZE] = { 0 };
 48  
 49  	memcpy(buf + sizeof(uint64_t), initialHash, HASH_SIZE);
 50  
 51  	unsigned long long tmpnonce = incamt;
 52  	unsigned long long * nonce = (unsigned long long *)buf;
 53  	unsigned long long * hash = (unsigned long long *)output;
 54  	while (successval == 0) {
 55  		tmpnonce += numthreads;
 56  
 57  		(*nonce) = ntohll(tmpnonce); /* increment nonce */
 58  		SHA512_Init(&sha);
 59  		SHA512_Update(&sha, buf, HASH_SIZE + sizeof(uint64_t));
 60  		SHA512_Final(output, &sha);
 61  		SHA512_Init(&sha);
 62  		SHA512_Update(&sha, output, HASH_SIZE);
 63  		SHA512_Final(output, &sha);
 64  
 65  		if (ntohll(*hash) < max_val) {
 66  			successval = tmpnonce;
 67  		}
 68  	}
 69  #ifdef _WIN32
 70  	return 0;
 71  #else
 72  	return NULL;
 73  #endif
 74  }
 75  
 76  void getnumthreads()
 77  {
 78  #ifdef _WIN32
 79  	DWORD_PTR dwProcessAffinity, dwSystemAffinity;
 80  #elif __linux__
 81  	cpu_set_t dwProcessAffinity;
 82  #elif __OpenBSD__
 83  	int mib[2], core_count = 0;
 84  	int dwProcessAffinity = 0;
 85  	size_t len2;
 86  #else
 87  	int dwProcessAffinity = 0;
 88  	int32_t core_count = 0;
 89  #endif
 90  	size_t len = sizeof(dwProcessAffinity);
 91  	if (numthreads > 0)
 92  		return;
 93  #ifdef _WIN32
 94  	GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinity, &dwSystemAffinity);
 95  #elif __linux__
 96  	sched_getaffinity(0, len, &dwProcessAffinity);
 97  #elif __OpenBSD__
 98  	len2 = sizeof(core_count);
 99  	mib[0] = CTL_HW;
100  	mib[1] = HW_NCPU;
101  	if (sysctl(mib, 2, &core_count, &len2, 0, 0) == 0)
102  		numthreads = core_count;
103  #else
104  	if (sysctlbyname("hw.logicalcpu", &core_count, &len, 0, 0) == 0)
105  		numthreads = core_count;
106  	else if (sysctlbyname("hw.ncpu", &core_count, &len, 0, 0) == 0)
107  		numthreads = core_count;
108  #endif
109  	for (unsigned int i = 0; i < len * 8; i++)
110  #if defined(_WIN32)
111  #if defined(_MSC_VER)
112  		if (dwProcessAffinity & (1i64 << i))
113  #else // CYGWIN/MINGW
114  		if (dwProcessAffinity & (1ULL << i))
115  #endif
116  #elif defined __linux__
117  		if (CPU_ISSET(i, &dwProcessAffinity))
118  #else
119  		if (dwProcessAffinity & (1 << i))
120  #endif
121  			numthreads++;
122  	if (numthreads == 0) // something failed
123  		numthreads = 1;
124  	printf("Number of threads: %i\n", (int)numthreads);
125  }
126  
127  extern "C" EXPORT unsigned long long BitmessagePOW(unsigned char * starthash, unsigned long long target)
128  {
129  	successval = 0;
130  	max_val = target;
131  	getnumthreads();
132  	initialHash = (unsigned char *)starthash;
133  #   ifdef _WIN32
134  	HANDLE* threads = (HANDLE*)calloc(sizeof(HANDLE), numthreads);
135  #   else
136  	pthread_t* threads = (pthread_t*)calloc(sizeof(pthread_t), numthreads);
137  	struct sched_param schparam;
138  	schparam.sched_priority = 0;
139  #   endif
140  	unsigned int *threaddata = (unsigned int *)calloc(sizeof(unsigned int), numthreads);
141  	for (unsigned int i = 0; i < numthreads; i++) {
142  		threaddata[i] = i;
143  #   ifdef _WIN32
144  		threads[i] = CreateThread(NULL, 0, threadfunc, (LPVOID)&threaddata[i], 0, NULL);
145  		SetThreadPriority(threads[i], THREAD_PRIORITY_IDLE);
146  #   else
147  		pthread_create(&threads[i], NULL, threadfunc, (void*)&threaddata[i]);
148  #   ifdef __linux__
149  		pthread_setschedparam(threads[i], SCHED_IDLE, &schparam);
150  #   else
151  		pthread_setschedparam(threads[i], SCHED_RR, &schparam);
152  #   endif
153  #   endif
154  	}
155  #   ifdef _WIN32
156  	WaitForMultipleObjects(numthreads, threads, TRUE, INFINITE);
157  #   else
158  	for (unsigned int i = 0; i < numthreads; i++) {
159  		pthread_join(threads[i], NULL);
160  	}
161  #   endif
162  	free(threads);
163  	free(threaddata);
164  	return successval;
165  }