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 }