/* Develop by Alberto email: albertobsd@gmail.com */ #include #include #include #include #include #include #include #include #include "base58/libbase58.h" #include "rmd160/rmd160.h" #include "oldbloom/oldbloom.h" #include "bloom/bloom.h" #include "sha3/sha3.h" #include "util.h" #include "secp256k1/SECP256k1.h" #include "secp256k1/Point.h" #include "secp256k1/Int.h" #include "secp256k1/IntGroup.h" #include "secp256k1/Random.h" #include "hash/sha256.h" #include "hash/ripemd160.h" #if defined(_WIN64) && !defined(__CYGWIN__) #include "getopt.h" #include #else #include #include #include #endif #ifdef __unix__ #ifdef __CYGWIN__ #else #include #endif #endif #define CRYPTO_NONE 0 #define CRYPTO_BTC 1 #define CRYPTO_ETH 2 #define CRYPTO_ALL 3 #define MODE_XPOINT 0 #define MODE_ADDRESS 1 #define MODE_BSGS 2 #define MODE_RMD160 3 #define MODE_PUB2RMD 4 #define MODE_MINIKEYS 5 #define MODE_VANITY 6 #define SEARCH_UNCOMPRESS 0 #define SEARCH_COMPRESS 1 #define SEARCH_BOTH 2 uint32_t THREADBPWORKLOAD = 1048576; struct checksumsha256 { char data[32]; char backup[32]; }; struct bsgs_xvalue { uint8_t value[6]; uint64_t index; }; struct address_value { uint8_t value[20]; }; struct tothread { int nt; //Number thread char *rs; //range start char *rpt; //rng per thread }; struct bPload { uint32_t threadid; uint64_t from; uint64_t to; uint64_t counter; uint64_t workload; uint32_t aux; uint32_t finished; }; #if defined(_WIN64) && !defined(__CYGWIN__) #define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) PACK(struct publickey { uint8_t parity; union { uint8_t data8[32]; uint32_t data32[8]; uint64_t data64[4]; } X; }); #else struct __attribute__((__packed__)) publickey { uint8_t parity; union { uint8_t data8[32]; uint32_t data32[8]; uint64_t data64[4]; } X; }; #endif const char *Ccoinbuffer_default = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; char *Ccoinbuffer = (char*) Ccoinbuffer_default; char *str_baseminikey = NULL; char *raw_baseminikey = NULL; char *minikeyN = NULL; int minikey_n_limit; const char *version = "0.2.230519 Satoshi Quest"; #define CPU_GRP_SIZE 1024 std::vector Gn; Point _2Gn; std::vector GSn; Point _2GSn; void menu(); void init_generator(); int searchbinary(struct address_value *buffer,char *data,int64_t array_length); void sleep_ms(int milliseconds); void _sort(struct address_value *arr,int64_t N); void _insertionsort(struct address_value *arr, int64_t n); void _introsort(struct address_value *arr,uint32_t depthLimit, int64_t n); void _swap(struct address_value *a,struct address_value *b); int64_t _partition(struct address_value *arr, int64_t n); void _myheapsort(struct address_value *arr, int64_t n); void _heapify(struct address_value *arr, int64_t n, int64_t i); void bsgs_sort(struct bsgs_xvalue *arr,int64_t n); void bsgs_myheapsort(struct bsgs_xvalue *arr, int64_t n); void bsgs_insertionsort(struct bsgs_xvalue *arr, int64_t n); void bsgs_introsort(struct bsgs_xvalue *arr,uint32_t depthLimit, int64_t n); void bsgs_swap(struct bsgs_xvalue *a,struct bsgs_xvalue *b); void bsgs_heapify(struct bsgs_xvalue *arr, int64_t n, int64_t i); int64_t bsgs_partition(struct bsgs_xvalue *arr, int64_t n); int bsgs_searchbinary(struct bsgs_xvalue *arr,char *data,int64_t array_length,uint64_t *r_value); int bsgs_secondcheck(Int *start_range,uint32_t a,uint32_t k_index,Int *privatekey); int bsgs_thirdcheck(Int *start_range,uint32_t a,uint32_t k_index,Int *privatekey); void sha256sse_22(uint8_t *src0, uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *dst0, uint8_t *dst1, uint8_t *dst2, uint8_t *dst3); void sha256sse_23(uint8_t *src0, uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *dst0, uint8_t *dst1, uint8_t *dst2, uint8_t *dst3); bool vanityrmdmatch(unsigned char *rmdhash); void writevanitykey(bool compress,Int *key); int addvanity(char *target); int minimum_same_bytes(unsigned char* A,unsigned char* B, int length); void writekey(bool compressed,Int *key); void writekeyeth(Int *key); void checkpointer(void *ptr,const char *file,const char *function,const char *name,int line); bool isBase58(char c); bool isValidBase58String(char *str); bool readFileAddress(char *fileName); bool readFileVanity(char *fileName); bool forceReadFileAddress(char *fileName); bool forceReadFileAddressEth(char *fileName); bool forceReadFileXPoint(char *fileName); bool processOneVanity(); bool initBloomFilter(struct bloom *bloom_arg,uint64_t items_bloom); void writeFileIfNeeded(const char *fileName); void calcualteindex(int i,Int *key); #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_process_vanity(LPVOID vargp); DWORD WINAPI thread_process_minikeys(LPVOID vargp); DWORD WINAPI thread_process(LPVOID vargp); DWORD WINAPI thread_process_bsgs(LPVOID vargp); DWORD WINAPI thread_process_bsgs_backward(LPVOID vargp); DWORD WINAPI thread_process_bsgs_both(LPVOID vargp); DWORD WINAPI thread_process_bsgs_random(LPVOID vargp); DWORD WINAPI thread_process_bsgs_dance(LPVOID vargp); DWORD WINAPI thread_bPload(LPVOID vargp); DWORD WINAPI thread_bPload_2blooms(LPVOID vargp); #else void *thread_process_vanity(void *vargp); void *thread_process_minikeys(void *vargp); void *thread_process(void *vargp); void *thread_process_bsgs(void *vargp); void *thread_process_bsgs_backward(void *vargp); void *thread_process_bsgs_both(void *vargp); void *thread_process_bsgs_random(void *vargp); void *thread_process_bsgs_dance(void *vargp); void *thread_bPload(void *vargp); void *thread_bPload_2blooms(void *vargp); #endif char *pubkeytopubaddress(char *pkey,int length); void pubkeytopubaddress_dst(char *pkey,int length,char *dst); void rmd160toaddress_dst(char *rmd,char *dst); void set_minikey(char *buffer,char *rawbuffer,int length); bool increment_minikey_index(char *buffer,char *rawbuffer,int index); void increment_minikey_N(char *rawbuffer); void KECCAK_256(uint8_t *source, size_t size,uint8_t *dst); void generate_binaddress_eth(Point &publickey,unsigned char *dst_address); int THREADOUTPUT = 0; char *bit_range_str_min; char *bit_range_str_max; const char *bsgs_modes[5] = {"sequential","backward","both","random","dance"}; const char *modes[7] = {"xpoint","address","bsgs","rmd160","pub2rmd","minikeys","vanity"}; const char *cryptos[3] = {"btc","eth","all"}; const char *publicsearch[3] = {"uncompress","compress","both"}; const char *default_fileName = "addresses.txt"; #if defined(_WIN64) && !defined(__CYGWIN__) HANDLE* tid = NULL; HANDLE write_keys; HANDLE write_random; HANDLE bsgs_thread; HANDLE *bPload_mutex = NULL; #else pthread_t *tid = NULL; pthread_mutex_t write_keys; pthread_mutex_t write_random; pthread_mutex_t bsgs_thread; pthread_mutex_t *bPload_mutex = NULL; #endif uint64_t FINISHED_THREADS_COUNTER = 0; uint64_t FINISHED_THREADS_BP = 0; uint64_t THREADCYCLES = 0; uint64_t THREADCOUNTER = 0; uint64_t FINISHED_ITEMS = 0; uint64_t OLDFINISHED_ITEMS = -1; uint8_t byte_encode_crypto = 0x00; /* Bitcoin */ int vanity_rmd_targets = 0; int vanity_rmd_total = 0; int *vanity_rmd_limits = NULL; uint8_t ***vanity_rmd_limit_values_A = NULL,***vanity_rmd_limit_values_B = NULL; int vanity_rmd_minimun_bytes_check_length = 999999; char **vanity_address_targets = NULL; struct bloom *vanity_bloom = NULL; struct bloom bloom; uint64_t *steps = NULL; unsigned int *ends = NULL; uint64_t N = 0; uint64_t N_SEQUENTIAL_MAX = 0x100000000; uint64_t DEBUGCOUNT = 0x400; uint64_t u64range; Int OUTPUTSECONDS; int FLAGSKIPCHECKSUM = 0; int FLAGENDOMORPHISM = 0; int FLAGBLOOMMULTIPLIER = 1; int FLAGVANITY = 0; int FLAGBASEMINIKEY = 0; int FLAGBSGSMODE = 0; int FLAGDEBUG = 0; int FLAGQUIET = 0; int FLAGMATRIX = 0; int KFACTOR = 1; int MAXLENGTHADDRESS = -1; int NTHREADS = 1; int FLAGSAVEREADFILE = 0; int FLAGREADEDFILE1 = 0; int FLAGREADEDFILE2 = 0; int FLAGREADEDFILE3 = 0; int FLAGREADEDFILE4 = 0; int FLAGUPDATEFILE1 = 0; int FLAGSTRIDE = 0; int FLAGSEARCH = 2; int FLAGBITRANGE = 0; int FLAGRANGE = 0; int FLAGFILE = 0; int FLAGMODE = MODE_ADDRESS; int FLAGCRYPTO = 0; int FLAGRAWDATA = 0; int FLAGRANDOM = 0; int FLAG_N = 0; int FLAGPRECALCUTED_P_FILE = 0; int bitrange; char *str_N; char *range_start; char *range_end; char *str_stride; Int stride; uint64_t BSGS_XVALUE_RAM = 6; uint64_t BSGS_BUFFERXPOINTLENGTH = 32; uint64_t BSGS_BUFFERREGISTERLENGTH = 36; /* BSGS Variables */ int *bsgs_found; std::vector OriginalPointsBSGS; bool *OriginalPointsBSGScompressed; uint64_t bytes; char checksum[32],checksum_backup[32]; char buffer_bloom_file[1024]; struct bsgs_xvalue *bPtable; struct address_value *addressTable; struct oldbloom oldbloom_bP; struct bloom *bloom_bP; struct bloom *bloom_bPx2nd; //2nd Bloom filter check struct bloom *bloom_bPx3rd; //3rd Bloom filter check struct checksumsha256 *bloom_bP_checksums; struct checksumsha256 *bloom_bPx2nd_checksums; struct checksumsha256 *bloom_bPx3rd_checksums; #if defined(_WIN64) && !defined(__CYGWIN__) std::vector bloom_bP_mutex; std::vector bloom_bPx2nd_mutex; std::vector bloom_bPx3rd_mutex; #else pthread_mutex_t *bloom_bP_mutex; pthread_mutex_t *bloom_bPx2nd_mutex; pthread_mutex_t *bloom_bPx3rd_mutex; #endif uint64_t bloom_bP_totalbytes = 0; uint64_t bloom_bP2_totalbytes = 0; uint64_t bloom_bP3_totalbytes = 0; uint64_t bsgs_m = 4194304; uint64_t bsgs_m2; uint64_t bsgs_m3; uint64_t bsgs_aux; uint32_t bsgs_point_number; const char *str_limits_prefixs[7] = {"Mkeys/s","Gkeys/s","Tkeys/s","Pkeys/s","Ekeys/s","Zkeys/s","Ykeys/s"}; const char *str_limits[7] = {"1000000","1000000000","1000000000000","1000000000000000","1000000000000000000","1000000000000000000000","1000000000000000000000000"}; Int int_limits[7]; Int BSGS_GROUP_SIZE; Int BSGS_CURRENT; Int BSGS_R; Int BSGS_AUX; Int BSGS_N; Int BSGS_N_double; Int BSGS_M; //M is squareroot(N) Int BSGS_M_double; Int BSGS_M2; //M2 is M/32 Int BSGS_M2_double; //M2_double is M2 * 2 Int BSGS_M3; //M3 is M2/32 Int BSGS_M3_double; //M3_double is M3 * 2 Int ONE; Int ZERO; Int MPZAUX; Point BSGS_P; //Original P is actually G, but this P value change over time for calculations Point BSGS_MP; //MP values this is m * P Point BSGS_MP2; //MP2 values this is m2 * P Point BSGS_MP3; //MP3 values this is m3 * P Point BSGS_MP_double; //MP2 values this is m2 * P * 2 Point BSGS_MP2_double; //MP2 values this is m2 * P * 2 Point BSGS_MP3_double; //MP3 values this is m3 * P * 2 std::vector BSGS_AMP2; std::vector BSGS_AMP3; Point point_temp,point_temp2; //Temp value for some process Int n_range_start; Int n_range_end; Int n_range_diff; Int n_range_aux; Int lambda,lambda2,beta,beta2; Secp256K1 *secp; int main(int argc, char **argv) { char buffer[2048]; char rawvalue[32]; struct tothread *tt; //tothread Tokenizer t,tokenizerbsgs; //tokenizer char *fileName = NULL; char *hextemp = NULL; char *aux = NULL; char *aux2 = NULL; char *pointx_str = NULL; char *pointy_str = NULL; char *str_seconds = NULL; char *str_total = NULL; char *str_pretotal = NULL; char *str_divpretotal = NULL; char *bf_ptr = NULL; char *bPload_threads_available; FILE *fd,*fd_aux1,*fd_aux2,*fd_aux3; uint64_t i,BASE,PERTHREAD_R,itemsbloom,itemsbloom2,itemsbloom3; uint32_t finished; int readed,continue_flag,check_flag,c,salir,index_value,j; Int total,pretotal,debugcount_mpz,seconds,div_pretotal,int_aux,int_r,int_q,int58; struct bPload *bPload_temp_ptr; size_t rsize; #if defined(_WIN64) && !defined(__CYGWIN__) DWORD s; write_keys = CreateMutex(NULL, FALSE, NULL); write_random = CreateMutex(NULL, FALSE, NULL); bsgs_thread = CreateMutex(NULL, FALSE, NULL); #else pthread_mutex_init(&write_keys,NULL); pthread_mutex_init(&write_random,NULL); pthread_mutex_init(&bsgs_thread,NULL); int s; #endif srand(time(NULL)); secp = new Secp256K1(); secp->Init(); OUTPUTSECONDS.SetInt32(30); ZERO.SetInt32(0); ONE.SetInt32(1); BSGS_GROUP_SIZE.SetInt32(CPU_GRP_SIZE); #if defined(_WIN64) && !defined(__CYGWIN__) //Any windows secure random source goes here rseed(clock() + time(NULL) + rand()); #else unsigned long rseedvalue; int bytes_read = getrandom(&rseedvalue, sizeof(unsigned long), GRND_NONBLOCK); if(bytes_read > 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/ */ } else { /* what year is?? WTF linux without RNG ? */ fprintf(stderr,"[E] Error getrandom() ?\n"); exit(EXIT_FAILURE); rseed(clock() + time(NULL) + rand()*rand()); } #endif printf("[+] Version %s, developed by AlbertoBSD\n",version); while ((c = getopt(argc, argv, "deh6MqRSB:b:c:C:E:f:I:k:l:m:N:n:p:r:s:t:v:G:8:z:")) != -1) { switch(c) { case 'h': menu(); break; case '6': FLAGSKIPCHECKSUM = 1; fprintf(stderr,"[W] Skipping checksums on files\n"); break; case 'B': index_value = indexOf(optarg,bsgs_modes,5); if(index_value >= 0 && index_value <= 4) { FLAGBSGSMODE = index_value; //printf("[+] BSGS mode %s\n",optarg); } else { fprintf(stderr,"[W] Ignoring unknow bsgs mode %s\n",optarg); } break; case 'b': bitrange = strtol(optarg,NULL,10); if(bitrange > 0 && bitrange <=256 ) { MPZAUX.Set(&ONE); MPZAUX.ShiftL(bitrange-1); bit_range_str_min = MPZAUX.GetBase16(); checkpointer((void *)bit_range_str_min,__FILE__,"malloc","bit_range_str_min" ,__LINE__ -1); MPZAUX.Set(&ONE); MPZAUX.ShiftL(bitrange); if(MPZAUX.IsGreater(&secp->order)) { MPZAUX.Set(&secp->order); } bit_range_str_max = MPZAUX.GetBase16(); checkpointer((void *)bit_range_str_max,__FILE__,"malloc","bit_range_str_min" ,__LINE__ -1); FLAGBITRANGE = 1; } else { fprintf(stderr,"[E] invalid bits param: %s.\n",optarg); } break; case 'c': index_value = indexOf(optarg,cryptos,3); switch(index_value) { case 0: //btc FLAGCRYPTO = CRYPTO_BTC; break; case 1: //eth FLAGCRYPTO = CRYPTO_ETH; printf("[+] Setting search for ETH adddress.\n"); break; /* case 2: //all FLAGCRYPTO = CRYPTO_ALL; break; */ default: FLAGCRYPTO = CRYPTO_NONE; fprintf(stderr,"[E] Unknow crypto value %s\n",optarg); exit(EXIT_FAILURE); break; } break; case 'C': if(strlen(optarg) == 22) { FLAGBASEMINIKEY = 1; str_baseminikey = (char*) malloc(23); checkpointer((void *)str_baseminikey,__FILE__,"malloc","str_baseminikey" ,__LINE__ - 1); raw_baseminikey = (char*) malloc(23); checkpointer((void *)raw_baseminikey,__FILE__,"malloc","raw_baseminikey" ,__LINE__ - 1); strncpy(str_baseminikey,optarg,22); for(i = 0; i< 21; i++) { if(strchr(Ccoinbuffer,str_baseminikey[i+1]) != NULL) { raw_baseminikey[i] = (int)(strchr(Ccoinbuffer,str_baseminikey[i+1]) - Ccoinbuffer) % 58; } else { fprintf(stderr,"[E] invalid character in minikey\n"); exit(EXIT_FAILURE); } } } else { fprintf(stderr,"[E] Invalid Minikey length %li : %s\n",strlen(optarg),optarg); exit(EXIT_FAILURE); } break; case 'd': FLAGDEBUG = 1; printf("[+] Flag DEBUG enabled\n"); break; case 'e': FLAGENDOMORPHISM = 1; printf("[+] Endomorphism enabled\n"); lambda.SetBase16("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72"); lambda2.SetBase16("ac9c52b33fa3cf1f5ad9e3fd77ed9ba4a880b9fc8ec739c2e0cfc810b51283ce"); beta.SetBase16("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"); beta2.SetBase16("851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40"); break; case 'f': FLAGFILE = 1; fileName = optarg; break; case 'I': FLAGSTRIDE = 1; str_stride = optarg; break; case 'k': KFACTOR = (int)strtol(optarg,NULL,10); if(KFACTOR <= 0) { KFACTOR = 1; } printf("[+] K factor %i\n",KFACTOR); break; case 'l': switch(indexOf(optarg,publicsearch,3)) { case SEARCH_UNCOMPRESS: FLAGSEARCH = SEARCH_UNCOMPRESS; printf("[+] Search uncompress only\n"); break; case SEARCH_COMPRESS: FLAGSEARCH = SEARCH_COMPRESS; printf("[+] Search compress only\n"); break; case SEARCH_BOTH: FLAGSEARCH = SEARCH_BOTH; printf("[+] Search both compress and uncompress\n"); break; } break; case 'M': FLAGMATRIX = 1; printf("[+] Matrix screen\n"); break; case 'm': switch(indexOf(optarg,modes,7)) { case MODE_XPOINT: //xpoint FLAGMODE = MODE_XPOINT; printf("[+] Mode xpoint\n"); break; case MODE_ADDRESS: //address FLAGMODE = MODE_ADDRESS; printf("[+] Mode address\n"); break; case MODE_BSGS: FLAGMODE = MODE_BSGS; //printf("[+] Mode BSGS\n"); break; case MODE_RMD160: FLAGMODE = MODE_RMD160; FLAGCRYPTO = CRYPTO_BTC; printf("[+] Mode rmd160\n"); break; case MODE_PUB2RMD: FLAGMODE = MODE_PUB2RMD; printf("[+] Mode pub2rmd was removed\n"); exit(0); break; case MODE_MINIKEYS: FLAGMODE = MODE_MINIKEYS; printf("[+] Mode minikeys\n"); break; case MODE_VANITY: FLAGMODE = MODE_VANITY; printf("[+] Mode vanity\n"); if(vanity_bloom == NULL){ vanity_bloom = (struct bloom*) calloc(1,sizeof(struct bloom)); checkpointer((void *)vanity_bloom,__FILE__,"calloc","vanity_bloom" ,__LINE__ -1); } break; default: fprintf(stderr,"[E] Unknow mode value %s\n",optarg); exit(EXIT_FAILURE); break; } break; case 'n': FLAG_N = 1; str_N = optarg; break; case 'q': FLAGQUIET = 1; printf("[+] Quiet thread output\n"); break; case 'R': printf("[+] Random mode\n"); FLAGRANDOM = 1; FLAGBSGSMODE = 3; break; case 'r': if(optarg != NULL) { stringtokenizer(optarg,&t); switch(t.n) { case 1: range_start = nextToken(&t); if(isValidHex(range_start)) { FLAGRANGE = 1; range_end = secp->order.GetBase16(); } else { fprintf(stderr,"[E] Invalid hexstring : %s.\n",range_start); } break; case 2: range_start = nextToken(&t); range_end = nextToken(&t); if(isValidHex(range_start) && isValidHex(range_end)) { FLAGRANGE = 1; } else { if(isValidHex(range_start)) { fprintf(stderr,"[E] Invalid hexstring : %s\n",range_start); } else { fprintf(stderr,"[E] Invalid hexstring : %s\n",range_end); } } break; default: printf("[E] Unknow number of Range Params: %i\n",t.n); break; } } break; case 's': OUTPUTSECONDS.SetBase10(optarg); if(OUTPUTSECONDS.IsLower(&ZERO)) { OUTPUTSECONDS.SetInt32(30); } if(OUTPUTSECONDS.IsZero()) { printf("[+] Turn off stats output\n"); } else { hextemp = OUTPUTSECONDS.GetBase10(); printf("[+] Stats output every %s seconds\n",hextemp); free(hextemp); } break; case 'S': FLAGSAVEREADFILE = 1; break; case 't': NTHREADS = strtol(optarg,NULL,10); if(NTHREADS <= 0) { NTHREADS = 1; } printf((NTHREADS > 1) ? "[+] Threads : %u\n": "[+] Thread : %u\n",NTHREADS); break; case 'v': FLAGVANITY = 1; if(vanity_bloom == NULL){ vanity_bloom = (struct bloom*) calloc(1,sizeof(struct bloom)); checkpointer((void *)vanity_bloom,__FILE__,"calloc","vanity_bloom" ,__LINE__ -1); } if(isValidBase58String(optarg)) { if(addvanity(optarg) > 0) { printf("[+] Added Vanity search : %s\n",optarg); } else { printf("[+] Vanity search \"%s\" was NOT Added\n",optarg); } } else { fprintf(stderr,"[+] The string \"%s\" is not Valid Base58\n",optarg); } break; case '8': if(strlen(optarg) == 58) { Ccoinbuffer = optarg; printf("[+] Base58 for Minikeys %s\n",Ccoinbuffer); } else { fprintf(stderr,"[E] The base58 alphabet must be 58 characters long.\n"); exit(EXIT_FAILURE); } break; case 'z': FLAGBLOOMMULTIPLIER= strtol(optarg,NULL,10); if(FLAGBLOOMMULTIPLIER <= 0) { FLAGBLOOMMULTIPLIER = 1; } printf("[+] Bloom Size Multiplier %i\n",FLAGBLOOMMULTIPLIER); break; default: fprintf(stderr,"[E] Unknow opcion -%c\n",c); exit(EXIT_FAILURE); break; } } if( FLAGBSGSMODE == MODE_BSGS && FLAGENDOMORPHISM) { fprintf(stderr,"[E] Endomorphism doesn't work with BSGS\n"); exit(EXIT_FAILURE); } if( FLAGBSGSMODE == MODE_BSGS && FLAGSTRIDE) { fprintf(stderr,"[E] Stride doesn't work with BSGS\n"); exit(EXIT_FAILURE); } if(FLAGSTRIDE) { if(str_stride[0] == '0' && str_stride[1] == 'x') { stride.SetBase16(str_stride+2); } else{ stride.SetBase10(str_stride); } printf("[+] Stride : %s\n",stride.GetBase10()); } else { FLAGSTRIDE = 1; stride.Set(&ONE); } init_generator(); if(FLAGMODE == MODE_BSGS ) { printf("[+] Mode BSGS %s\n",bsgs_modes[FLAGBSGSMODE]); } if(FLAGFILE == 0) { fileName =(char*) default_fileName; } if(FLAGMODE == MODE_ADDRESS && FLAGCRYPTO == CRYPTO_NONE) { //When none crypto is defined the default search is for Bitcoin FLAGCRYPTO = CRYPTO_BTC; printf("[+] Setting search for btc adddress\n"); } if(FLAGRANGE) { n_range_start.SetBase16(range_start); if(n_range_start.IsZero()) { n_range_start.AddOne(); } n_range_end.SetBase16(range_end); if(n_range_start.IsEqual(&n_range_end) == false ) { if( n_range_start.IsLower(&secp->order) && n_range_end.IsLowerOrEqual(&secp->order) ) { if( n_range_start.IsGreater(&n_range_end)) { fprintf(stderr,"[W] Opps, start range can't be great than end range. Swapping them\n"); n_range_aux.Set(&n_range_start); n_range_start.Set(&n_range_end); n_range_end.Set(&n_range_aux); } n_range_diff.Set(&n_range_end); n_range_diff.Sub(&n_range_start); } else { fprintf(stderr,"[E] Start and End range can't be great than N\nFallback to random mode!\n"); FLAGRANGE = 0; } } else { fprintf(stderr,"[E] Start and End range can't be the same\nFallback to random mode!\n"); FLAGRANGE = 0; } } if(FLAGMODE != MODE_BSGS && FLAGMODE != MODE_MINIKEYS) { BSGS_N.SetInt32(DEBUGCOUNT); if(FLAGRANGE == 0 && FLAGBITRANGE == 0) { n_range_start.SetInt32(1); n_range_end.Set(&secp->order); n_range_diff.Set(&n_range_end); n_range_diff.Sub(&n_range_start); } else { if(FLAGBITRANGE) { n_range_start.SetBase16(bit_range_str_min); n_range_end.SetBase16(bit_range_str_max); n_range_diff.Set(&n_range_end); n_range_diff.Sub(&n_range_start); } else { if(FLAGRANGE == 0) { fprintf(stderr,"[W] WTF!\n"); } } } } N = 0; if(FLAGMODE != MODE_BSGS ) { if(FLAG_N){ if(str_N[0] == '0' && str_N[1] == 'x') { N_SEQUENTIAL_MAX =strtol(str_N,NULL,16); } else { N_SEQUENTIAL_MAX =strtol(str_N,NULL,10); } if(N_SEQUENTIAL_MAX < 1024) { fprintf(stderr,"[I] n value need to be equal or great than 1024, back to defaults\n"); FLAG_N = 0; N_SEQUENTIAL_MAX = 0x100000000; } if(N_SEQUENTIAL_MAX % 1024 != 0) { fprintf(stderr,"[I] n value need to be multiplier of 1024\n"); FLAG_N = 0; N_SEQUENTIAL_MAX = 0x100000000; } } printf("[+] N = %p\n",(void*)N_SEQUENTIAL_MAX); if(FLAGMODE == MODE_MINIKEYS) { BSGS_N.SetInt32(DEBUGCOUNT); if(FLAGBASEMINIKEY) { printf("[+] Base Minikey : %s\n",str_baseminikey); } minikeyN = (char*) malloc(22); checkpointer((void *)minikeyN,__FILE__,"malloc","minikeyN" ,__LINE__ -1); i =0; int58.SetInt32(58); int_aux.SetInt64(N_SEQUENTIAL_MAX); int_aux.Mult(253); /* We get approximately one valid mini key for each 256 candidates mini keys since this is only statistics we multiply N_SEQUENTIAL_MAX by 253 to ensure not missed one one candidate minikey between threads... in this approach we repeat from 1 to 3 candidates in each N_SEQUENTIAL_MAX cycle IF YOU FOUND some other workaround please let me know */ i = 20; salir = 0; do { if(!int_aux.IsZero()) { int_r.Set(&int_aux); int_r.Mod(&int58); int_q.Set(&int_aux); minikeyN[i] = (uint8_t)int_r.GetInt64(); int_q.Sub(&int_r); int_q.Div(&int58); int_aux.Set(&int_q); i--; } else { salir =1; } }while(!salir && i > 0); minikey_n_limit = 21 -i; } else { if(FLAGBITRANGE) { // Bit Range printf("[+] Bit Range %i\n",bitrange); } else { printf("[+] Range \n"); } } if(FLAGMODE != MODE_MINIKEYS) { hextemp = n_range_start.GetBase16(); printf("[+] -- from : 0x%s\n",hextemp); free(hextemp); hextemp = n_range_end.GetBase16(); printf("[+] -- to : 0x%s\n",hextemp); free(hextemp); } switch(FLAGMODE) { case MODE_MINIKEYS: case MODE_RMD160: case MODE_ADDRESS: case MODE_XPOINT: if(!readFileAddress(fileName)) { fprintf(stderr,"[E] Unenexpected error\n"); exit(EXIT_FAILURE); } break; case MODE_VANITY: if(!readFileVanity(fileName)) { fprintf(stderr,"[E] Unenexpected error\n"); exit(EXIT_FAILURE); } break; } if(FLAGMODE != MODE_VANITY && !FLAGREADEDFILE1) { printf("[+] Sorting data ..."); _sort(addressTable,N); printf(" done! %" PRIu64 " values were loaded and sorted\n",N); writeFileIfNeeded(fileName); } } if(FLAGMODE == MODE_BSGS ) { printf("[+] Opening file %s\n",fileName); fd = fopen(fileName,"rb"); if(fd == NULL) { fprintf(stderr,"[E] Can't open file %s\n",fileName); exit(EXIT_FAILURE); } aux = (char*) malloc(1024); checkpointer((void *)aux,__FILE__,"malloc","aux" ,__LINE__ - 1); while(!feof(fd)) { if(fgets(aux,1022,fd) == aux) { trim(aux," \t\n\r"); if(strlen(aux) >= 128) { //Length of a full address in hexadecimal without 04 N++; }else { if(strlen(aux) >= 66) { N++; } } } } if(N == 0) { fprintf(stderr,"[E] There is no valid data in the file\n"); exit(EXIT_FAILURE); } bsgs_found = (int*) calloc(N,sizeof(int)); checkpointer((void *)bsgs_found,__FILE__,"calloc","bsgs_found" ,__LINE__ -1 ); OriginalPointsBSGS.reserve(N); OriginalPointsBSGScompressed = (bool*) malloc(N*sizeof(bool)); checkpointer((void *)OriginalPointsBSGScompressed,__FILE__,"malloc","OriginalPointsBSGScompressed" ,__LINE__ -1 ); pointx_str = (char*) malloc(65); checkpointer((void *)pointx_str,__FILE__,"malloc","pointx_str" ,__LINE__ -1 ); pointy_str = (char*) malloc(65); checkpointer((void *)pointy_str,__FILE__,"malloc","pointy_str" ,__LINE__ -1 ); fseek(fd,0,SEEK_SET); i = 0; while(!feof(fd)) { if(fgets(aux,1022,fd) == aux) { trim(aux," \t\n\r"); if(strlen(aux) >= 66) { stringtokenizer(aux,&tokenizerbsgs); aux2 = nextToken(&tokenizerbsgs); memset(pointx_str,0,65); memset(pointy_str,0,65); switch(strlen(aux2)) { case 66: //Compress if(secp->ParsePublicKeyHex(aux2,OriginalPointsBSGS[i],OriginalPointsBSGScompressed[i])) { i++; } else { N--; } break; case 130: //With the 04 if(secp->ParsePublicKeyHex(aux2,OriginalPointsBSGS[i],OriginalPointsBSGScompressed[i])) { i++; } else { N--; } break; default: printf("Invalid length: %s\n",aux2); N--; break; } freetokenizer(&tokenizerbsgs); } } } fclose(fd); bsgs_point_number = N; if(bsgs_point_number > 0) { printf("[+] Added %u points from file\n",bsgs_point_number); } else { fprintf(stderr,"[E] The file don't have any valid publickeys\n"); exit(EXIT_FAILURE); } BSGS_N.SetInt32(0); BSGS_M.SetInt32(0); BSGS_M.SetInt64(bsgs_m); if(FLAG_N) { //Custom N by the -n param /* Here we need to validate if the given string is a valid hexadecimal number or a base 10 number*/ /* Now the conversion*/ if(str_N[0] == '0' && str_N[1] == 'x' ) { /*We expected a hexadecimal value after 0x -> str_N +2 */ BSGS_N.SetBase16((char*)(str_N+2)); } else { BSGS_N.SetBase10(str_N); } } else { //Default N BSGS_N.SetInt64((uint64_t)0x100000000000); } if(BSGS_N.HasSqrt()) { //If the root is exact BSGS_M.Set(&BSGS_N); BSGS_M.ModSqrt(); } else { fprintf(stderr,"[E] -n param doesn't have exact square root\n"); exit(EXIT_FAILURE); } BSGS_AUX.Set(&BSGS_M); BSGS_AUX.Mod(&BSGS_GROUP_SIZE); if(!BSGS_AUX.IsZero()){ //If M is not divisible by BSGS_GROUP_SIZE (1024) hextemp = BSGS_GROUP_SIZE.GetBase10(); fprintf(stderr,"[E] M value is not divisible by %s\n",hextemp); exit(EXIT_FAILURE); } bsgs_m = BSGS_M.GetInt64(); if(FLAGRANGE || FLAGBITRANGE) { if(FLAGBITRANGE) { // Bit Range n_range_start.SetBase16(bit_range_str_min); n_range_end.SetBase16(bit_range_str_max); n_range_diff.Set(&n_range_end); n_range_diff.Sub(&n_range_start); printf("[+] Bit Range %i\n",bitrange); printf("[+] -- from : 0x%s\n",bit_range_str_min); printf("[+] -- to : 0x%s\n",bit_range_str_max); } else { printf("[+] Range \n"); printf("[+] -- from : 0x%s\n",range_start); printf("[+] -- to : 0x%s\n",range_end); } } else { //Random start n_range_start.SetInt32(1); n_range_end.Set(&secp->order); n_range_diff.Rand(&n_range_start,&n_range_end); n_range_start.Set(&n_range_diff); } BSGS_CURRENT.Set(&n_range_start); if(n_range_diff.IsLower(&BSGS_N) ) { fprintf(stderr,"[E] the given range is small\n"); exit(EXIT_FAILURE); } /* M 2199023255552 109951162777.6 M2 109951162778 5497558138.9 M3 5497558139 */ BSGS_M.Mult((uint64_t)KFACTOR); BSGS_AUX.SetInt32(32); BSGS_R.Set(&BSGS_M); BSGS_R.Mod(&BSGS_AUX); BSGS_M2.Set(&BSGS_M); BSGS_M2.Div(&BSGS_AUX); if(!BSGS_R.IsZero()) { /* If BSGS_M modulo 32 is not 0*/ BSGS_M2.AddOne(); } BSGS_M_double.SetInt32(2); BSGS_M_double.Mult(&BSGS_M); BSGS_M2_double.SetInt32(2); BSGS_M2_double.Mult(&BSGS_M2); BSGS_R.Set(&BSGS_M2); BSGS_R.Mod(&BSGS_AUX); BSGS_M3.Set(&BSGS_M2); BSGS_M3.Div(&BSGS_AUX); if(!BSGS_R.IsZero()) { /* If BSGS_M2 modulo 32 is not 0*/ BSGS_M3.AddOne(); } BSGS_M3_double.SetInt32(2); BSGS_M3_double.Mult(&BSGS_M3); bsgs_m2 = BSGS_M2.GetInt64(); bsgs_m3 = BSGS_M3.GetInt64(); BSGS_AUX.Set(&BSGS_N); BSGS_AUX.Div(&BSGS_M); BSGS_R.Set(&BSGS_N); BSGS_R.Mod(&BSGS_M); if(!BSGS_R.IsZero()) { /* if BSGS_N modulo BSGS_M is not 0*/ BSGS_N.Set(&BSGS_M); BSGS_N.Mult(&BSGS_AUX); } bsgs_m = BSGS_M.GetInt64(); bsgs_aux = BSGS_AUX.GetInt64(); BSGS_N_double.SetInt32(2); BSGS_N_double.Mult(&BSGS_N); hextemp = BSGS_N.GetBase16(); printf("[+] N = 0x%s\n",hextemp); free(hextemp); if(((uint64_t)(bsgs_m/256)) > 10000) { itemsbloom = (uint64_t)(bsgs_m / 256); if(bsgs_m % 256 != 0 ) { itemsbloom++; } } else{ itemsbloom = 1000; } if(((uint64_t)(bsgs_m2/256)) > 1000) { itemsbloom2 = (uint64_t)(bsgs_m2 / 256); if(bsgs_m2 % 256 != 0) { itemsbloom2++; } } else { itemsbloom2 = 1000; } if(((uint64_t)(bsgs_m3/256)) > 1000) { itemsbloom3 = (uint64_t)(bsgs_m3/256); if(bsgs_m3 % 256 != 0 ) { itemsbloom3++; } } else { itemsbloom3 = 1000; } printf("[+] Bloom filter for %" PRIu64 " elements ",bsgs_m); bloom_bP = (struct bloom*)calloc(256,sizeof(struct bloom)); checkpointer((void *)bloom_bP,__FILE__,"calloc","bloom_bP" ,__LINE__ -1 ); bloom_bP_checksums = (struct checksumsha256*)calloc(256,sizeof(struct checksumsha256)); checkpointer((void *)bloom_bP_checksums,__FILE__,"calloc","bloom_bP_checksums" ,__LINE__ -1 ); #if defined(_WIN64) && !defined(__CYGWIN__) bloom_bP_mutex = (HANDLE*) calloc(256,sizeof(HANDLE)); #else bloom_bP_mutex = (pthread_mutex_t*) calloc(256,sizeof(pthread_mutex_t)); #endif checkpointer((void *)bloom_bP_mutex,__FILE__,"calloc","bloom_bP_mutex" ,__LINE__ -1 ); fflush(stdout); bloom_bP_totalbytes = 0; for(i=0; i< 256; i++) { #if defined(_WIN64) && !defined(__CYGWIN__) bloom_bP_mutex[i] = CreateMutex(NULL, FALSE, NULL); #else pthread_mutex_init(&bloom_bP_mutex[i],NULL); #endif if(bloom_init2(&bloom_bP[i],itemsbloom,0.000001) == 1){ fprintf(stderr,"[E] error bloom_init _ [%" PRIu64 "]\n",i); exit(EXIT_FAILURE); } bloom_bP_totalbytes += bloom_bP[i].bytes; //if(FLAGDEBUG) bloom_print(&bloom_bP[i]); } printf(": %.2f MB\n",(float)((float)(uint64_t)bloom_bP_totalbytes/(float)(uint64_t)1048576)); printf("[+] Bloom filter for %" PRIu64 " elements ",bsgs_m2); #if defined(_WIN64) && !defined(__CYGWIN__) bloom_bPx2nd_mutex = (HANDLE*) calloc(256,sizeof(HANDLE)); #else bloom_bPx2nd_mutex = (pthread_mutex_t*) calloc(256,sizeof(pthread_mutex_t)); #endif checkpointer((void *)bloom_bPx2nd_mutex,__FILE__,"calloc","bloom_bPx2nd_mutex" ,__LINE__ -1 ); bloom_bPx2nd = (struct bloom*)calloc(256,sizeof(struct bloom)); checkpointer((void *)bloom_bPx2nd,__FILE__,"calloc","bloom_bPx2nd" ,__LINE__ -1 ); bloom_bPx2nd_checksums = (struct checksumsha256*) calloc(256,sizeof(struct checksumsha256)); checkpointer((void *)bloom_bPx2nd_checksums,__FILE__,"calloc","bloom_bPx2nd_checksums" ,__LINE__ -1 ); bloom_bP2_totalbytes = 0; for(i=0; i< 256; i++) { #if defined(_WIN64) && !defined(__CYGWIN__) bloom_bPx2nd_mutex[i] = CreateMutex(NULL, FALSE, NULL); #else pthread_mutex_init(&bloom_bPx2nd_mutex[i],NULL); #endif if(bloom_init2(&bloom_bPx2nd[i],itemsbloom2,0.000001) == 1){ fprintf(stderr,"[E] error bloom_init _ [%" PRIu64 "]\n",i); exit(EXIT_FAILURE); } bloom_bP2_totalbytes += bloom_bPx2nd[i].bytes; //if(FLAGDEBUG) bloom_print(&bloom_bPx2nd[i]); } printf(": %.2f MB\n",(float)((float)(uint64_t)bloom_bP2_totalbytes/(float)(uint64_t)1048576)); #if defined(_WIN64) && !defined(__CYGWIN__) bloom_bPx3rd_mutex = (HANDLE*) calloc(256,sizeof(HANDLE)); #else bloom_bPx3rd_mutex = (pthread_mutex_t*) calloc(256,sizeof(pthread_mutex_t)); #endif checkpointer((void *)bloom_bPx3rd_mutex,__FILE__,"calloc","bloom_bPx3rd_mutex" ,__LINE__ -1 ); bloom_bPx3rd = (struct bloom*)calloc(256,sizeof(struct bloom)); checkpointer((void *)bloom_bPx3rd,__FILE__,"calloc","bloom_bPx3rd" ,__LINE__ -1 ); bloom_bPx3rd_checksums = (struct checksumsha256*) calloc(256,sizeof(struct checksumsha256)); checkpointer((void *)bloom_bPx3rd_checksums,__FILE__,"calloc","bloom_bPx3rd_checksums" ,__LINE__ -1 ); printf("[+] Bloom filter for %" PRIu64 " elements ",bsgs_m3); bloom_bP3_totalbytes = 0; for(i=0; i< 256; i++) { #if defined(_WIN64) && !defined(__CYGWIN__) bloom_bPx3rd_mutex[i] = CreateMutex(NULL, FALSE, NULL); #else pthread_mutex_init(&bloom_bPx3rd_mutex[i],NULL); #endif if(bloom_init2(&bloom_bPx3rd[i],itemsbloom3,0.000001) == 1){ fprintf(stderr,"[E] error bloom_init [%" PRIu64 "]\n",i); exit(EXIT_FAILURE); } bloom_bP3_totalbytes += bloom_bPx3rd[i].bytes; //if(FLAGDEBUG) bloom_print(&bloom_bPx3rd[i]); } printf(": %.2f MB\n",(float)((float)(uint64_t)bloom_bP3_totalbytes/(float)(uint64_t)1048576)); //if(FLAGDEBUG) printf("[D] bloom_bP3_totalbytes : %" PRIu64 "\n",bloom_bP3_totalbytes); BSGS_MP = secp->ComputePublicKey(&BSGS_M); BSGS_MP_double = secp->ComputePublicKey(&BSGS_M_double); BSGS_MP2 = secp->ComputePublicKey(&BSGS_M2); BSGS_MP2_double = secp->ComputePublicKey(&BSGS_M2_double); BSGS_MP3 = secp->ComputePublicKey(&BSGS_M3); BSGS_MP3_double = secp->ComputePublicKey(&BSGS_M3_double); BSGS_AMP2.reserve(32); BSGS_AMP3.reserve(32); GSn.reserve(CPU_GRP_SIZE/2); i= 0; /* New aMP table just to keep the same code of JLP */ /* Auxiliar Points to speed up calculations for the main bloom filter check */ Point bsP = secp->Negation(BSGS_MP_double); Point g = bsP; GSn[0] = g; g = secp->DoubleDirect(g); GSn[1] = g; for(int i = 2; i < CPU_GRP_SIZE / 2; i++) { g = secp->AddDirect(g,bsP); GSn[i] = g; } /* For next center point */ _2GSn = secp->DoubleDirect(GSn[CPU_GRP_SIZE / 2 - 1]); i = 0; point_temp.Set(BSGS_MP2); BSGS_AMP2[0] = secp->Negation(point_temp); BSGS_AMP2[0].Reduce(); point_temp.Set(BSGS_MP2_double); point_temp = secp->Negation(point_temp); point_temp.Reduce(); for(i = 1; i < 32; i++) { BSGS_AMP2[i] = secp->AddDirect(BSGS_AMP2[i-1],point_temp); BSGS_AMP2[i].Reduce(); } i = 0; point_temp.Set(BSGS_MP3); BSGS_AMP3[0] = secp->Negation(point_temp); BSGS_AMP3[0].Reduce(); point_temp.Set(BSGS_MP3_double); point_temp = secp->Negation(point_temp); point_temp.Reduce(); for(i = 1; i < 32; i++) { BSGS_AMP3[i] = secp->AddDirect(BSGS_AMP3[i-1],point_temp); BSGS_AMP3[i].Reduce(); } bytes = (uint64_t)bsgs_m3 * (uint64_t) sizeof(struct bsgs_xvalue); printf("[+] Allocating %.2f MB for %" PRIu64 " bP Points\n",(double)(bytes/1048576),bsgs_m3); bPtable = (struct bsgs_xvalue*) malloc(bytes); checkpointer((void *)bPtable,__FILE__,"malloc","bPtable" ,__LINE__ -1 ); memset(bPtable,0,bytes); if(FLAGSAVEREADFILE) { /*Reading file for 1st bloom filter */ snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_4_%" PRIu64 ".blm",bsgs_m); fd_aux1 = fopen(buffer_bloom_file,"rb"); if(fd_aux1 != NULL) { printf("[+] Reading bloom filter from file %s ",buffer_bloom_file); fflush(stdout); for(i = 0; i < 256;i++) { bf_ptr = (char*) bloom_bP[i].bf; /*We need to save the current bf pointer*/ readed = fread(&bloom_bP[i],sizeof(struct bloom),1,fd_aux1); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } bloom_bP[i].bf = (uint8_t*)bf_ptr; /* Restoring the bf pointer*/ readed = fread(bloom_bP[i].bf,bloom_bP[i].bytes,1,fd_aux1); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fread(&bloom_bP_checksums[i],sizeof(struct checksumsha256),1,fd_aux1); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } if(FLAGSKIPCHECKSUM == 0) { sha256((uint8_t*)bloom_bP[i].bf,bloom_bP[i].bytes,(uint8_t*)rawvalue); if(memcmp(bloom_bP_checksums[i].data,rawvalue,32) != 0 || memcmp(bloom_bP_checksums[i].backup,rawvalue,32) != 0 ) { /* Verification */ fprintf(stderr,"[E] Error checksum file mismatch! %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } } if(i % 64 == 0 ) { printf("."); fflush(stdout); } } printf(" Done!\n"); fclose(fd_aux1); memset(buffer_bloom_file,0,1024); snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_3_%" PRIu64 ".blm",bsgs_m); fd_aux1 = fopen(buffer_bloom_file,"rb"); if(fd_aux1 != NULL) { printf("[W] Unused file detected %s you can delete it without worry\n",buffer_bloom_file); fclose(fd_aux1); } FLAGREADEDFILE1 = 1; } else { /*Checking for old file keyhunt_bsgs_3_ */ snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_3_%" PRIu64 ".blm",bsgs_m); fd_aux1 = fopen(buffer_bloom_file,"rb"); if(fd_aux1 != NULL) { printf("[+] Reading bloom filter from file %s ",buffer_bloom_file); fflush(stdout); for(i = 0; i < 256;i++) { bf_ptr = (char*) bloom_bP[i].bf; /*We need to save the current bf pointer*/ readed = fread(&oldbloom_bP,sizeof(struct oldbloom),1,fd_aux1); /* if(FLAGDEBUG) { printf("old Bloom filter %i\n",i); oldbloom_print(&oldbloom_bP); } */ if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } memcpy(&bloom_bP[i],&oldbloom_bP,sizeof(struct bloom));//We only need to copy the part data to the new bloom size, not from the old size bloom_bP[i].bf = (uint8_t*)bf_ptr; /* Restoring the bf pointer*/ readed = fread(bloom_bP[i].bf,bloom_bP[i].bytes,1,fd_aux1); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } memcpy(bloom_bP_checksums[i].data,oldbloom_bP.checksum,32); memcpy(bloom_bP_checksums[i].backup,oldbloom_bP.checksum_backup,32); memset(rawvalue,0,32); if(FLAGSKIPCHECKSUM == 0) { sha256((uint8_t*)bloom_bP[i].bf,bloom_bP[i].bytes,(uint8_t*)rawvalue); if(memcmp(bloom_bP_checksums[i].data,rawvalue,32) != 0 || memcmp(bloom_bP_checksums[i].backup,rawvalue,32) != 0 ) { /* Verification */ fprintf(stderr,"[E] Error checksum file mismatch! %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } } if(i % 32 == 0 ) { printf("."); fflush(stdout); } } printf(" Done!\n"); fclose(fd_aux1); FLAGUPDATEFILE1 = 1; /* Flag to migrate the data to the new File keyhunt_bsgs_4_ */ FLAGREADEDFILE1 = 1; } else { FLAGREADEDFILE1 = 0; //Flag to make the new file } } /*Reading file for 2nd bloom filter */ snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_6_%" PRIu64 ".blm",bsgs_m2); fd_aux2 = fopen(buffer_bloom_file,"rb"); if(fd_aux2 != NULL) { printf("[+] Reading bloom filter from file %s ",buffer_bloom_file); fflush(stdout); for(i = 0; i < 256;i++) { bf_ptr = (char*) bloom_bPx2nd[i].bf; /*We need to save the current bf pointer*/ readed = fread(&bloom_bPx2nd[i],sizeof(struct bloom),1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } bloom_bPx2nd[i].bf = (uint8_t*)bf_ptr; /* Restoring the bf pointer*/ readed = fread(bloom_bPx2nd[i].bf,bloom_bPx2nd[i].bytes,1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fread(&bloom_bPx2nd_checksums[i],sizeof(struct checksumsha256),1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } memset(rawvalue,0,32); if(FLAGSKIPCHECKSUM == 0) { sha256((uint8_t*)bloom_bPx2nd[i].bf,bloom_bPx2nd[i].bytes,(uint8_t*)rawvalue); if(memcmp(bloom_bPx2nd_checksums[i].data,rawvalue,32) != 0 || memcmp(bloom_bPx2nd_checksums[i].backup,rawvalue,32) != 0 ) { /* Verification */ fprintf(stderr,"[E] Error checksum file mismatch! %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } } if(i % 64 == 0) { printf("."); fflush(stdout); } } fclose(fd_aux2); printf(" Done!\n"); memset(buffer_bloom_file,0,1024); snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_5_%" PRIu64 ".blm",bsgs_m2); fd_aux2 = fopen(buffer_bloom_file,"rb"); if(fd_aux2 != NULL) { printf("[W] Unused file detected %s you can delete it without worry\n",buffer_bloom_file); fclose(fd_aux2); } memset(buffer_bloom_file,0,1024); snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_1_%" PRIu64 ".blm",bsgs_m2); fd_aux2 = fopen(buffer_bloom_file,"rb"); if(fd_aux2 != NULL) { printf("[W] Unused file detected %s you can delete it without worry\n",buffer_bloom_file); fclose(fd_aux2); } FLAGREADEDFILE2 = 1; } else { FLAGREADEDFILE2 = 0; } /*Reading file for bPtable */ snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_2_%" PRIu64 ".tbl",bsgs_m3); fd_aux3 = fopen(buffer_bloom_file,"rb"); if(fd_aux3 != NULL) { printf("[+] Reading bP Table from file %s .",buffer_bloom_file); fflush(stdout); rsize = fread(bPtable,bytes,1,fd_aux3); if(rsize != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } rsize = fread(checksum,32,1,fd_aux3); if(rsize != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } if(FLAGSKIPCHECKSUM == 0) { sha256((uint8_t*)bPtable,bytes,(uint8_t*)checksum_backup); if(memcmp(checksum,checksum_backup,32) != 0) { fprintf(stderr,"[E] Error checksum file mismatch! %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } } printf("... Done!\n"); fclose(fd_aux3); FLAGREADEDFILE3 = 1; } else { FLAGREADEDFILE3 = 0; } /*Reading file for 3rd bloom filter */ snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_7_%" PRIu64 ".blm",bsgs_m3); fd_aux2 = fopen(buffer_bloom_file,"rb"); if(fd_aux2 != NULL) { printf("[+] Reading bloom filter from file %s ",buffer_bloom_file); fflush(stdout); for(i = 0; i < 256;i++) { bf_ptr = (char*) bloom_bPx3rd[i].bf; /*We need to save the current bf pointer*/ readed = fread(&bloom_bPx3rd[i],sizeof(struct bloom),1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } bloom_bPx3rd[i].bf = (uint8_t*)bf_ptr; /* Restoring the bf pointer*/ readed = fread(bloom_bPx3rd[i].bf,bloom_bPx3rd[i].bytes,1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fread(&bloom_bPx3rd_checksums[i],sizeof(struct checksumsha256),1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } memset(rawvalue,0,32); if(FLAGSKIPCHECKSUM == 0) { sha256((uint8_t*)bloom_bPx3rd[i].bf,bloom_bPx3rd[i].bytes,(uint8_t*)rawvalue); if(memcmp(bloom_bPx3rd_checksums[i].data,rawvalue,32) != 0 || memcmp(bloom_bPx3rd_checksums[i].backup,rawvalue,32) != 0 ) { /* Verification */ fprintf(stderr,"[E] Error checksum file mismatch! %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } } if(i % 64 == 0) { printf("."); fflush(stdout); } } fclose(fd_aux2); printf(" Done!\n"); FLAGREADEDFILE4 = 1; } else { FLAGREADEDFILE4 = 0; } } if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 || !FLAGREADEDFILE3 || !FLAGREADEDFILE4) { if(FLAGREADEDFILE1 == 1) { /* We need just to make File 2 to File 4 this is - Second bloom filter 5% - third bloom fitler 0.25 % - bp Table 0.25 % */ printf("[I] We need to recalculate some files, don't worry this is only 3%% of the previous work\n"); FINISHED_THREADS_COUNTER = 0; FINISHED_THREADS_BP = 0; FINISHED_ITEMS = 0; salir = 0; BASE = 0; THREADCOUNTER = 0; if(THREADBPWORKLOAD >= bsgs_m2) { THREADBPWORKLOAD = bsgs_m2; } THREADCYCLES = bsgs_m2 / THREADBPWORKLOAD; PERTHREAD_R = bsgs_m2 % THREADBPWORKLOAD; if(PERTHREAD_R != 0) { THREADCYCLES++; } printf("\r[+] processing %lu/%lu bP points : %i%%\r",FINISHED_ITEMS,bsgs_m,(int) (((double)FINISHED_ITEMS/(double)bsgs_m)*100)); fflush(stdout); #if defined(_WIN64) && !defined(__CYGWIN__) tid = (HANDLE*)calloc(NTHREADS, sizeof(HANDLE)); checkpointer((void *)tid,__FILE__,"calloc","tid" ,__LINE__ -1 ); bPload_mutex = (HANDLE*) calloc(NTHREADS,sizeof(HANDLE)); #else tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); bPload_mutex = (pthread_mutex_t*) calloc(NTHREADS,sizeof(pthread_mutex_t)); #endif checkpointer((void *)bPload_mutex,__FILE__,"calloc","bPload_mutex" ,__LINE__ -1 ); bPload_temp_ptr = (struct bPload*) calloc(NTHREADS,sizeof(struct bPload)); checkpointer((void *)bPload_temp_ptr,__FILE__,"calloc","bPload_temp_ptr" ,__LINE__ -1 ); bPload_threads_available = (char*) calloc(NTHREADS,sizeof(char)); checkpointer((void *)bPload_threads_available,__FILE__,"calloc","bPload_threads_available" ,__LINE__ -1 ); memset(bPload_threads_available,1,NTHREADS); for(j = 0; j < NTHREADS; j++) { #if defined(_WIN64) && !defined(__CYGWIN__) bPload_mutex[j] = CreateMutex(NULL, FALSE, NULL); #else pthread_mutex_init(&bPload_mutex[j],NULL); #endif } do { for(j = 0; j < NTHREADS && !salir; j++) { if(bPload_threads_available[j] && !salir) { bPload_threads_available[j] = 0; bPload_temp_ptr[j].from = BASE; bPload_temp_ptr[j].threadid = j; bPload_temp_ptr[j].finished = 0; if( THREADCOUNTER < THREADCYCLES-1) { bPload_temp_ptr[j].to = BASE + THREADBPWORKLOAD; bPload_temp_ptr[j].workload = THREADBPWORKLOAD; } else { bPload_temp_ptr[j].to = BASE + THREADBPWORKLOAD + PERTHREAD_R; bPload_temp_ptr[j].workload = THREADBPWORKLOAD + PERTHREAD_R; salir = 1; } #if defined(_WIN64) && !defined(__CYGWIN__) tid[j] = CreateThread(NULL, 0, thread_bPload_2blooms, (void*) &bPload_temp_ptr[j], 0, &s); #else s = pthread_create(&tid[j],NULL,thread_bPload_2blooms,(void*) &bPload_temp_ptr[j]); pthread_detach(tid[j]); #endif BASE+=THREADBPWORKLOAD; THREADCOUNTER++; } } if(OLDFINISHED_ITEMS != FINISHED_ITEMS) { printf("\r[+] processing %lu/%lu bP points : %i%%\r",FINISHED_ITEMS,bsgs_m2,(int) (((double)FINISHED_ITEMS/(double)bsgs_m2)*100)); fflush(stdout); OLDFINISHED_ITEMS = FINISHED_ITEMS; } for(j = 0 ; j < NTHREADS ; j++) { #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(bPload_mutex[j], INFINITE); finished = bPload_temp_ptr[j].finished; ReleaseMutex(bPload_mutex[j]); #else pthread_mutex_lock(&bPload_mutex[j]); finished = bPload_temp_ptr[j].finished; pthread_mutex_unlock(&bPload_mutex[j]); #endif if(finished) { bPload_temp_ptr[j].finished = 0; bPload_threads_available[j] = 1; FINISHED_ITEMS += bPload_temp_ptr[j].workload; FINISHED_THREADS_COUNTER++; } } }while(FINISHED_THREADS_COUNTER < THREADCYCLES); printf("\r[+] processing %lu/%lu bP points : 100%% \n",bsgs_m2,bsgs_m2); free(tid); free(bPload_mutex); free(bPload_temp_ptr); free(bPload_threads_available); } else{ /* We need just to do all the files - first bllom filter 100% - Second bloom filter 5% - third bloom fitler 0.25 % - bp Table 0.25 % */ FINISHED_THREADS_COUNTER = 0; FINISHED_THREADS_BP = 0; FINISHED_ITEMS = 0; salir = 0; BASE = 0; THREADCOUNTER = 0; if(THREADBPWORKLOAD >= bsgs_m) { THREADBPWORKLOAD = bsgs_m; } THREADCYCLES = bsgs_m / THREADBPWORKLOAD; PERTHREAD_R = bsgs_m % THREADBPWORKLOAD; //if(FLAGDEBUG) printf("[D] THREADCYCLES: %lu\n",THREADCYCLES); if(PERTHREAD_R != 0) { THREADCYCLES++; //if(FLAGDEBUG) printf("[D] PERTHREAD_R: %lu\n",PERTHREAD_R); } printf("\r[+] processing %lu/%lu bP points : %i%%\r",FINISHED_ITEMS,bsgs_m,(int) (((double)FINISHED_ITEMS/(double)bsgs_m)*100)); fflush(stdout); #if defined(_WIN64) && !defined(__CYGWIN__) tid = (HANDLE*)calloc(NTHREADS, sizeof(HANDLE)); bPload_mutex = (HANDLE*) calloc(NTHREADS,sizeof(HANDLE)); #else tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); bPload_mutex = (pthread_mutex_t*) calloc(NTHREADS,sizeof(pthread_mutex_t)); #endif checkpointer((void *)tid,__FILE__,"calloc","tid" ,__LINE__ -1 ); checkpointer((void *)bPload_mutex,__FILE__,"calloc","bPload_mutex" ,__LINE__ -1 ); bPload_temp_ptr = (struct bPload*) calloc(NTHREADS,sizeof(struct bPload)); checkpointer((void *)bPload_temp_ptr,__FILE__,"calloc","bPload_temp_ptr" ,__LINE__ -1 ); bPload_threads_available = (char*) calloc(NTHREADS,sizeof(char)); checkpointer((void *)bPload_threads_available,__FILE__,"calloc","bPload_threads_available" ,__LINE__ -1 ); memset(bPload_threads_available,1,NTHREADS); for(j = 0; j < NTHREADS; j++) { #if defined(_WIN64) && !defined(__CYGWIN__) bPload_mutex = CreateMutex(NULL, FALSE, NULL); #else pthread_mutex_init(&bPload_mutex[j],NULL); #endif } do { for(j = 0; j < NTHREADS && !salir; j++) { if(bPload_threads_available[j] && !salir) { bPload_threads_available[j] = 0; bPload_temp_ptr[j].from = BASE; bPload_temp_ptr[j].threadid = j; bPload_temp_ptr[j].finished = 0; if( THREADCOUNTER < THREADCYCLES-1) { bPload_temp_ptr[j].to = BASE + THREADBPWORKLOAD; bPload_temp_ptr[j].workload = THREADBPWORKLOAD; } else { bPload_temp_ptr[j].to = BASE + THREADBPWORKLOAD + PERTHREAD_R; bPload_temp_ptr[j].workload = THREADBPWORKLOAD + PERTHREAD_R; salir = 1; //if(FLAGDEBUG) printf("[D] Salir OK\n"); } //if(FLAGDEBUG) printf("[I] %lu to %lu\n",bPload_temp_ptr[i].from,bPload_temp_ptr[i].to); #if defined(_WIN64) && !defined(__CYGWIN__) tid[j] = CreateThread(NULL, 0, thread_bPload, (void*) &bPload_temp_ptr[j], 0, &s); #else s = pthread_create(&tid[j],NULL,thread_bPload,(void*) &bPload_temp_ptr[j]); pthread_detach(tid[j]); #endif BASE+=THREADBPWORKLOAD; THREADCOUNTER++; } } if(OLDFINISHED_ITEMS != FINISHED_ITEMS) { printf("\r[+] processing %lu/%lu bP points : %i%%\r",FINISHED_ITEMS,bsgs_m,(int) (((double)FINISHED_ITEMS/(double)bsgs_m)*100)); fflush(stdout); OLDFINISHED_ITEMS = FINISHED_ITEMS; } for(j = 0 ; j < NTHREADS ; j++) { #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(bPload_mutex[j], INFINITE); finished = bPload_temp_ptr[j].finished; ReleaseMutex(bPload_mutex[j]); #else pthread_mutex_lock(&bPload_mutex[j]); finished = bPload_temp_ptr[j].finished; pthread_mutex_unlock(&bPload_mutex[j]); #endif if(finished) { bPload_temp_ptr[j].finished = 0; bPload_threads_available[j] = 1; FINISHED_ITEMS += bPload_temp_ptr[j].workload; FINISHED_THREADS_COUNTER++; } } }while(FINISHED_THREADS_COUNTER < THREADCYCLES); printf("\r[+] processing %lu/%lu bP points : 100%% \n",bsgs_m,bsgs_m); free(tid); free(bPload_mutex); free(bPload_temp_ptr); free(bPload_threads_available); } } if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 || !FLAGREADEDFILE4) { printf("[+] Making checkums .. "); fflush(stdout); } if(!FLAGREADEDFILE1) { for(i = 0; i < 256 ; i++) { sha256((uint8_t*)bloom_bP[i].bf, bloom_bP[i].bytes,(uint8_t*) bloom_bP_checksums[i].data); memcpy(bloom_bP_checksums[i].backup,bloom_bP_checksums[i].data,32); } printf("."); } if(!FLAGREADEDFILE2) { for(i = 0; i < 256 ; i++) { sha256((uint8_t*)bloom_bPx2nd[i].bf, bloom_bPx2nd[i].bytes,(uint8_t*) bloom_bPx2nd_checksums[i].data); memcpy(bloom_bPx2nd_checksums[i].backup,bloom_bPx2nd_checksums[i].data,32); } printf("."); } if(!FLAGREADEDFILE4) { for(i = 0; i < 256 ; i++) { sha256((uint8_t*)bloom_bPx3rd[i].bf, bloom_bPx3rd[i].bytes,(uint8_t*) bloom_bPx3rd_checksums[i].data); memcpy(bloom_bPx3rd_checksums[i].backup,bloom_bPx3rd_checksums[i].data,32); } printf("."); } if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 || !FLAGREADEDFILE4) { printf(" done\n"); fflush(stdout); } if(!FLAGREADEDFILE3) { printf("[+] Sorting %lu elements... ",bsgs_m3); fflush(stdout); bsgs_sort(bPtable,bsgs_m3); sha256((uint8_t*)bPtable, bytes,(uint8_t*) checksum); memcpy(checksum_backup,checksum,32); printf("Done!\n"); fflush(stdout); } if(FLAGSAVEREADFILE || FLAGUPDATEFILE1 ) { if(!FLAGREADEDFILE1 || FLAGUPDATEFILE1) { snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_4_%" PRIu64 ".blm",bsgs_m); if(FLAGUPDATEFILE1) { printf("[W] Updating old file into a new one\n"); } /* Writing file for 1st bloom filter */ fd_aux1 = fopen(buffer_bloom_file,"wb"); if(fd_aux1 != NULL) { printf("[+] Writing bloom filter to file %s ",buffer_bloom_file); fflush(stdout); for(i = 0; i < 256;i++) { readed = fwrite(&bloom_bP[i],sizeof(struct bloom),1,fd_aux1); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s please delete it\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fwrite(bloom_bP[i].bf,bloom_bP[i].bytes,1,fd_aux1); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s please delete it\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fwrite(&bloom_bP_checksums[i],sizeof(struct checksumsha256),1,fd_aux1); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s please delete it\n",buffer_bloom_file); exit(EXIT_FAILURE); } if(i % 64 == 0) { printf("."); fflush(stdout); } } printf(" Done!\n"); fclose(fd_aux1); } else { fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } } if(!FLAGREADEDFILE2 ) { snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_6_%" PRIu64 ".blm",bsgs_m2); /* Writing file for 2nd bloom filter */ fd_aux2 = fopen(buffer_bloom_file,"wb"); if(fd_aux2 != NULL) { printf("[+] Writing bloom filter to file %s ",buffer_bloom_file); fflush(stdout); for(i = 0; i < 256;i++) { readed = fwrite(&bloom_bPx2nd[i],sizeof(struct bloom),1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fwrite(bloom_bPx2nd[i].bf,bloom_bPx2nd[i].bytes,1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fwrite(&bloom_bPx2nd_checksums[i],sizeof(struct checksumsha256),1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s please delete it\n",buffer_bloom_file); exit(EXIT_FAILURE); } if(i % 64 == 0) { printf("."); fflush(stdout); } } printf(" Done!\n"); fclose(fd_aux2); } else { fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } } if(!FLAGREADEDFILE3) { /* Writing file for bPtable */ snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_2_%" PRIu64 ".tbl",bsgs_m3); fd_aux3 = fopen(buffer_bloom_file,"wb"); if(fd_aux3 != NULL) { printf("[+] Writing bP Table to file %s .. ",buffer_bloom_file); fflush(stdout); readed = fwrite(bPtable,bytes,1,fd_aux3); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fwrite(checksum,32,1,fd_aux3); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } printf("Done!\n"); fclose(fd_aux3); } else { fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } } if(!FLAGREADEDFILE4) { snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_7_%" PRIu64 ".blm",bsgs_m3); /* Writing file for 3rd bloom filter */ fd_aux2 = fopen(buffer_bloom_file,"wb"); if(fd_aux2 != NULL) { printf("[+] Writing bloom filter to file %s ",buffer_bloom_file); fflush(stdout); for(i = 0; i < 256;i++) { readed = fwrite(&bloom_bPx3rd[i],sizeof(struct bloom),1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fwrite(bloom_bPx3rd[i].bf,bloom_bPx3rd[i].bytes,1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } readed = fwrite(&bloom_bPx3rd_checksums[i],sizeof(struct checksumsha256),1,fd_aux2); if(readed != 1) { fprintf(stderr,"[E] Error writing the file %s please delete it\n",buffer_bloom_file); exit(EXIT_FAILURE); } if(i % 64 == 0) { printf("."); fflush(stdout); } } printf(" Done!\n"); fclose(fd_aux2); } else { fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); exit(EXIT_FAILURE); } } } i = 0; steps = (uint64_t *) calloc(NTHREADS,sizeof(uint64_t)); checkpointer((void *)steps,__FILE__,"calloc","steps" ,__LINE__ -1 ); ends = (unsigned int *) calloc(NTHREADS,sizeof(int)); checkpointer((void *)ends,__FILE__,"calloc","ends" ,__LINE__ -1 ); #if defined(_WIN64) && !defined(__CYGWIN__) tid = (HANDLE*)calloc(NTHREADS, sizeof(HANDLE)); #else tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); #endif checkpointer((void *)tid,__FILE__,"calloc","tid" ,__LINE__ -1 ); for(j= 0;j < NTHREADS; j++) { tt = (tothread*) malloc(sizeof(struct tothread)); checkpointer((void *)tt,__FILE__,"malloc","tt" ,__LINE__ -1 ); tt->nt = j; steps[j] = 0; s = 0; switch(FLAGBSGSMODE) { #if defined(_WIN64) && !defined(__CYGWIN__) case 0: tid[j] = CreateThread(NULL, 0, thread_process_bsgs, (void*)tt, 0, &s); break; case 1: tid[j] = CreateThread(NULL, 0, thread_process_bsgs_backward, (void*)tt, 0, &s); break; case 2: tid[j] = CreateThread(NULL, 0, thread_process_bsgs_both, (void*)tt, 0, &s); break; case 3: tid[j] = CreateThread(NULL, 0, thread_process_bsgs_random, (void*)tt, 0, &s); break; case 4: tid[j] = CreateThread(NULL, 0, thread_process_bsgs_dance, (void*)tt, 0, &s); break; } #else case 0: s = pthread_create(&tid[j],NULL,thread_process_bsgs,(void *)tt); break; case 1: s = pthread_create(&tid[j],NULL,thread_process_bsgs_backward,(void *)tt); break; case 2: s = pthread_create(&tid[j],NULL,thread_process_bsgs_both,(void *)tt); break; case 3: s = pthread_create(&tid[j],NULL,thread_process_bsgs_random,(void *)tt); break; case 4: s = pthread_create(&tid[j],NULL,thread_process_bsgs_dance,(void *)tt); break; #endif } #if defined(_WIN64) && !defined(__CYGWIN__) if (tid[j] == NULL) { #else if(s != 0) { #endif fprintf(stderr,"[E] thread thread_process\n"); exit(EXIT_FAILURE); } } free(aux); } if(FLAGMODE != MODE_BSGS) { steps = (uint64_t *) calloc(NTHREADS,sizeof(uint64_t)); checkpointer((void *)steps,__FILE__,"calloc","steps" ,__LINE__ -1 ); ends = (unsigned int *) calloc(NTHREADS,sizeof(int)); checkpointer((void *)ends,__FILE__,"calloc","ends" ,__LINE__ -1 ); #if defined(_WIN64) && !defined(__CYGWIN__) tid = (HANDLE*)calloc(NTHREADS, sizeof(HANDLE)); #else tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); #endif checkpointer((void *)tid,__FILE__,"calloc","tid" ,__LINE__ -1 ); for(j= 0;j < NTHREADS; j++) { tt = (tothread*) malloc(sizeof(struct tothread)); checkpointer((void *)tt,__FILE__,"malloc","tt" ,__LINE__ -1 ); tt->nt = j; steps[j] = 0; s = 0; switch(FLAGMODE) { #if defined(_WIN64) && !defined(__CYGWIN__) case MODE_ADDRESS: case MODE_XPOINT: case MODE_RMD160: tid[j] = CreateThread(NULL, 0, thread_process, (void*)tt, 0, &s); break; case MODE_MINIKEYS: tid[j] = CreateThread(NULL, 0, thread_process_minikeys, (void*)tt, 0, &s); break; case MODE_VANITY: tid[j] = CreateThread(NULL, 0, thread_process_vanity, (void*)tt, 0, &s); break; #else case MODE_ADDRESS: case MODE_XPOINT: case MODE_RMD160: s = pthread_create(&tid[j],NULL,thread_process,(void *)tt); break; case MODE_MINIKEYS: s = pthread_create(&tid[j],NULL,thread_process_minikeys,(void *)tt); break; case MODE_VANITY: s = pthread_create(&tid[j],NULL,thread_process_vanity,(void *)tt); break; #endif } if(s != 0) { fprintf(stderr,"[E] pthread_create thread_process\n"); exit(EXIT_FAILURE); } } } for(j =0; j < 7; j++) { int_limits[j].SetBase10((char*)str_limits[j]); } continue_flag = 1; total.SetInt32(0); pretotal.SetInt32(0); debugcount_mpz.Set(&BSGS_N); seconds.SetInt32(0); do { sleep_ms(1000); seconds.AddOne(); check_flag = 1; for(j = 0; j = 1) { half = (max - min)/2; rcmp = memcmp(data,buffer[current+half].value,20); if(rcmp == 0) { r = 1; //Found!! } else { if(rcmp < 0) { //data < temp_read max = (max-half); } else { // data > temp_read min = (min+half); } current = min; } } return r; } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_process_minikeys(LPVOID vargp) { #else void *thread_process_minikeys(void *vargp) { #endif FILE *keys; Point publickey[4]; Int key_mpz[4]; struct tothread *tt; uint64_t count; char publickeyhashrmd160_uncompress[4][20]; char public_key_uncompressed_hex[131]; char address[4][40],minikey[4][24],minikeys[8][24],buffer_b58[21],minikey2check[24],rawvalue[4][32]; char *hextemp,*rawbuffer; int r,thread_number,continue_flag = 1,k,j,count_valid; Int counter; tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); rawbuffer = (char*) &counter.bits64; count_valid = 0; for(k = 0; k < 4; k++) { minikey[k][0] = 'S'; minikey[k][22] = '?'; minikey[k][23] = 0x00; } minikey2check[0] = 'S'; minikey2check[22] = '?'; minikey2check[23] = 0x00; do { if(FLAGRANDOM) { counter.Rand(256); for(k = 0; k < 21; k++) { buffer_b58[k] =(uint8_t)((uint8_t) rawbuffer[k] % 58); } } else { if(FLAGBASEMINIKEY) { #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_random, INFINITE); memcpy(buffer_b58,raw_baseminikey,21); increment_minikey_N(raw_baseminikey); ReleaseMutex(write_random); #else pthread_mutex_lock(&write_random); memcpy(buffer_b58,raw_baseminikey,21); increment_minikey_N(raw_baseminikey); pthread_mutex_unlock(&write_random); #endif } else { #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_random, INFINITE); #else pthread_mutex_lock(&write_random); #endif if(raw_baseminikey == NULL){ raw_baseminikey = (char *) malloc(22); checkpointer((void *)raw_baseminikey,__FILE__,"malloc","raw_baseminikey" ,__LINE__ -1 ); counter.Rand(256); for(k = 0; k < 21; k++) { raw_baseminikey[k] =(uint8_t)((uint8_t) rawbuffer[k] % 58); } memcpy(buffer_b58,raw_baseminikey,21); increment_minikey_N(raw_baseminikey); } else { memcpy(buffer_b58,raw_baseminikey,21); increment_minikey_N(raw_baseminikey); } #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_random); #else pthread_mutex_unlock(&write_random); #endif } } set_minikey(minikey2check+1,buffer_b58,21); if(continue_flag) { count = 0; if(FLAGMATRIX) { printf("[+] Base minikey: %s \n",minikey2check); fflush(stdout); } else { if(!FLAGQUIET) { printf("\r[+] Base minikey: %s \r",minikey2check); fflush(stdout); } } do { for(j = 0;j<256; j++) { if(count_valid > 0) { for(k = 0; k < count_valid ; k++) { memcpy(minikeys[k],minikeys[4+k],22); } } do { increment_minikey_index(minikey2check+1,buffer_b58,20); memcpy(minikey[0]+1,minikey2check+1,21); increment_minikey_index(minikey2check+1,buffer_b58,20); memcpy(minikey[1]+1,minikey2check+1,21); increment_minikey_index(minikey2check+1,buffer_b58,20); memcpy(minikey[2]+1,minikey2check+1,21); increment_minikey_index(minikey2check+1,buffer_b58,20); memcpy(minikey[3]+1,minikey2check+1,21); sha256sse_23((uint8_t*)minikey[0],(uint8_t*)minikey[1],(uint8_t*)minikey[2],(uint8_t*)minikey[3],(uint8_t*)rawvalue[0],(uint8_t*)rawvalue[1],(uint8_t*)rawvalue[2],(uint8_t*)rawvalue[3]); for(k = 0; k < 4; k++){ if(rawvalue[k][0] == 0x00) { memcpy(minikeys[count_valid],minikey[k],22); count_valid++; } } }while(count_valid < 4); count_valid-=4; sha256sse_22((uint8_t*)minikeys[0],(uint8_t*)minikeys[1],(uint8_t*)minikeys[2],(uint8_t*)minikeys[3],(uint8_t*)rawvalue[0],(uint8_t*)rawvalue[1],(uint8_t*)rawvalue[2],(uint8_t*)rawvalue[3]); for(k = 0; k < 4; k++) { key_mpz[k].Set32Bytes((uint8_t*)rawvalue[k]); publickey[k] = secp->ComputePublicKey(&key_mpz[k]); } secp->GetHash160(P2PKH,false,publickey[0],publickey[1],publickey[2],publickey[3],(uint8_t*)publickeyhashrmd160_uncompress[0],(uint8_t*)publickeyhashrmd160_uncompress[1],(uint8_t*)publickeyhashrmd160_uncompress[2],(uint8_t*)publickeyhashrmd160_uncompress[3]); for(k = 0; k < 4; k++) { r = bloom_check(&bloom,publickeyhashrmd160_uncompress[k],20); if(r) { r = searchbinary(addressTable,publickeyhashrmd160_uncompress[k],N); if(r) { /* hit */ hextemp = key_mpz[k].GetBase16(); secp->GetPublicKeyHex(false,publickey[k],public_key_uncompressed_hex); #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); rmd160toaddress_dst(publickeyhashrmd160_uncompress[k],address[k]); minikeys[k][22] = '\0'; if(keys != NULL) { fprintf(keys,"Private Key: %s\npubkey: %s\nminikey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,minikeys[k],address[k]); fclose(keys); } printf("\nHIT!! Private Key: %s\npubkey: %s\nminikey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,minikeys[k],address[k]); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif free(hextemp); } } } } steps[thread_number]++; count+=1024; }while(count < N_SEQUENTIAL_MAX && continue_flag); } }while(continue_flag); return NULL; } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_process(LPVOID vargp) { #else void *thread_process(void *vargp) { #endif struct tothread *tt; Point pts[CPU_GRP_SIZE]; Point endomorphism_beta[CPU_GRP_SIZE]; Point endomorphism_beta2[CPU_GRP_SIZE]; Point endomorphism_negeted_point[4]; Int dx[CPU_GRP_SIZE / 2 + 1]; IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); Point startP; Int dy; Int dyn; Int _s; Int _p; Point pp; Point pn; int i,l,pp_offset,pn_offset,hLength = (CPU_GRP_SIZE / 2 - 1); uint64_t j,count; Point R,temporal,publickey; int r,thread_number,continue_flag = 1,k; char *hextemp = NULL; char publickeyhashrmd160[20]; char publickeyhashrmd160_uncompress[4][20]; char rawvalue[32]; char publickeyhashrmd160_endomorphism[12][4][20]; bool calculate_y = FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH || FLAGCRYPTO == CRYPTO_ETH; Int key_mpz,keyfound,temp_stride; tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); grp->Set(dx); do { if(FLAGRANDOM){ key_mpz.Rand(&n_range_start,&n_range_end); } else { if(n_range_start.IsLower(&n_range_end)) { #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_random, INFINITE); key_mpz.Set(&n_range_start); n_range_start.Add(N_SEQUENTIAL_MAX); ReleaseMutex(write_random); #else pthread_mutex_lock(&write_random); key_mpz.Set(&n_range_start); n_range_start.Add(N_SEQUENTIAL_MAX); pthread_mutex_unlock(&write_random); #endif } else { continue_flag = 0; } } if(continue_flag) { count = 0; if(FLAGMATRIX) { hextemp = key_mpz.GetBase16(); printf("Base key: %s thread %i\n",hextemp,thread_number); fflush(stdout); free(hextemp); } else { if(FLAGQUIET == 0){ hextemp = key_mpz.GetBase16(); printf("\rBase key: %s \r",hextemp); fflush(stdout); free(hextemp); THREADOUTPUT = 1; } } do { temp_stride.SetInt32(CPU_GRP_SIZE / 2); temp_stride.Mult(&stride); key_mpz.Add(&temp_stride); startP = secp->ComputePublicKey(&key_mpz); key_mpz.Sub(&temp_stride); for(i = 0; i < hLength; i++) { dx[i].ModSub(&Gn[i].x,&startP.x); } dx[i].ModSub(&Gn[i].x,&startP.x); // For the first point dx[i + 1].ModSub(&_2Gn.x,&startP.x); // For the next center point grp->ModInv(); pts[CPU_GRP_SIZE / 2] = startP; for(i = 0; iGetHash160_fromX(P2PKH,0x02,&pts[(j*4)].x,&pts[(j*4)+1].x,&pts[(j*4)+2].x,&pts[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[0][0],(uint8_t*)publickeyhashrmd160_endomorphism[0][1],(uint8_t*)publickeyhashrmd160_endomorphism[0][2],(uint8_t*)publickeyhashrmd160_endomorphism[0][3]); secp->GetHash160_fromX(P2PKH,0x03,&pts[(j*4)].x,&pts[(j*4)+1].x,&pts[(j*4)+2].x,&pts[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[1][0],(uint8_t*)publickeyhashrmd160_endomorphism[1][1],(uint8_t*)publickeyhashrmd160_endomorphism[1][2],(uint8_t*)publickeyhashrmd160_endomorphism[1][3]); secp->GetHash160_fromX(P2PKH,0x02,&endomorphism_beta[(j*4)].x,&endomorphism_beta[(j*4)+1].x,&endomorphism_beta[(j*4)+2].x,&endomorphism_beta[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[2][0],(uint8_t*)publickeyhashrmd160_endomorphism[2][1],(uint8_t*)publickeyhashrmd160_endomorphism[2][2],(uint8_t*)publickeyhashrmd160_endomorphism[2][3]); secp->GetHash160_fromX(P2PKH,0x03,&endomorphism_beta[(j*4)].x,&endomorphism_beta[(j*4)+1].x,&endomorphism_beta[(j*4)+2].x,&endomorphism_beta[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[3][0],(uint8_t*)publickeyhashrmd160_endomorphism[3][1],(uint8_t*)publickeyhashrmd160_endomorphism[3][2],(uint8_t*)publickeyhashrmd160_endomorphism[3][3]); secp->GetHash160_fromX(P2PKH,0x02,&endomorphism_beta2[(j*4)].x,&endomorphism_beta2[(j*4)+1].x,&endomorphism_beta2[(j*4)+2].x,&endomorphism_beta2[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[4][0],(uint8_t*)publickeyhashrmd160_endomorphism[4][1],(uint8_t*)publickeyhashrmd160_endomorphism[4][2],(uint8_t*)publickeyhashrmd160_endomorphism[4][3]); secp->GetHash160_fromX(P2PKH,0x03,&endomorphism_beta2[(j*4)].x,&endomorphism_beta2[(j*4)+1].x,&endomorphism_beta2[(j*4)+2].x,&endomorphism_beta2[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[5][0],(uint8_t*)publickeyhashrmd160_endomorphism[5][1],(uint8_t*)publickeyhashrmd160_endomorphism[5][2],(uint8_t*)publickeyhashrmd160_endomorphism[5][3]); } else { secp->GetHash160_fromX(P2PKH,0x02,&pts[(j*4)].x,&pts[(j*4)+1].x,&pts[(j*4)+2].x,&pts[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[0][0],(uint8_t*)publickeyhashrmd160_endomorphism[0][1],(uint8_t*)publickeyhashrmd160_endomorphism[0][2],(uint8_t*)publickeyhashrmd160_endomorphism[0][3]); secp->GetHash160_fromX(P2PKH,0x03,&pts[(j*4)].x,&pts[(j*4)+1].x,&pts[(j*4)+2].x,&pts[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[1][0],(uint8_t*)publickeyhashrmd160_endomorphism[1][1],(uint8_t*)publickeyhashrmd160_endomorphism[1][2],(uint8_t*)publickeyhashrmd160_endomorphism[1][3]); } } if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){ if(FLAGENDOMORPHISM) { for(l = 0; l < 4; l++) { endomorphism_negeted_point[l] = secp->Negation(pts[(j*4)+l]); } secp->GetHash160(P2PKH,false, pts[(j*4)], pts[(j*4)+1], pts[(j*4)+2], pts[(j*4)+3],(uint8_t*)publickeyhashrmd160_endomorphism[6][0],(uint8_t*)publickeyhashrmd160_endomorphism[6][1],(uint8_t*)publickeyhashrmd160_endomorphism[6][2],(uint8_t*)publickeyhashrmd160_endomorphism[6][3]); secp->GetHash160(P2PKH,false,endomorphism_negeted_point[0] ,endomorphism_negeted_point[1],endomorphism_negeted_point[2],endomorphism_negeted_point[3],(uint8_t*)publickeyhashrmd160_endomorphism[7][0],(uint8_t*)publickeyhashrmd160_endomorphism[7][1],(uint8_t*)publickeyhashrmd160_endomorphism[7][2],(uint8_t*)publickeyhashrmd160_endomorphism[7][3]); for(l = 0; l < 4; l++) { endomorphism_negeted_point[l] = secp->Negation(endomorphism_beta[(j*4)+l]); } secp->GetHash160(P2PKH,false,endomorphism_beta[(j*4)], endomorphism_beta[(j*4)+1], endomorphism_beta[(j*4)+2], endomorphism_beta[(j*4)+3] ,(uint8_t*)publickeyhashrmd160_endomorphism[8][0],(uint8_t*)publickeyhashrmd160_endomorphism[8][1],(uint8_t*)publickeyhashrmd160_endomorphism[8][2],(uint8_t*)publickeyhashrmd160_endomorphism[8][3]); secp->GetHash160(P2PKH,false,endomorphism_negeted_point[0],endomorphism_negeted_point[1],endomorphism_negeted_point[2],endomorphism_negeted_point[3],(uint8_t*)publickeyhashrmd160_endomorphism[9][0],(uint8_t*)publickeyhashrmd160_endomorphism[9][1],(uint8_t*)publickeyhashrmd160_endomorphism[9][2],(uint8_t*)publickeyhashrmd160_endomorphism[9][3]); for(l = 0; l < 4; l++) { endomorphism_negeted_point[l] = secp->Negation(endomorphism_beta2[(j*4)+l]); } secp->GetHash160(P2PKH,false, endomorphism_beta2[(j*4)], endomorphism_beta2[(j*4)+1] , endomorphism_beta2[(j*4)+2] , endomorphism_beta2[(j*4)+3] ,(uint8_t*)publickeyhashrmd160_endomorphism[10][0],(uint8_t*)publickeyhashrmd160_endomorphism[10][1],(uint8_t*)publickeyhashrmd160_endomorphism[10][2],(uint8_t*)publickeyhashrmd160_endomorphism[10][3]); secp->GetHash160(P2PKH,false, endomorphism_negeted_point[0], endomorphism_negeted_point[1], endomorphism_negeted_point[2],endomorphism_negeted_point[3],(uint8_t*)publickeyhashrmd160_endomorphism[11][0],(uint8_t*)publickeyhashrmd160_endomorphism[11][1],(uint8_t*)publickeyhashrmd160_endomorphism[11][2],(uint8_t*)publickeyhashrmd160_endomorphism[11][3]); } else { secp->GetHash160(P2PKH,false,pts[(j*4)],pts[(j*4)+1],pts[(j*4)+2],pts[(j*4)+3],(uint8_t*)publickeyhashrmd160_uncompress[0],(uint8_t*)publickeyhashrmd160_uncompress[1],(uint8_t*)publickeyhashrmd160_uncompress[2],(uint8_t*)publickeyhashrmd160_uncompress[3]); } } } else if(FLAGCRYPTO == CRYPTO_ETH){ if(FLAGENDOMORPHISM) { for(k = 0; k < 4;k++) { endomorphism_negeted_point[k] = secp->Negation(pts[(j*4)+k]); generate_binaddress_eth(pts[(4*j)+k],(uint8_t*)publickeyhashrmd160_endomorphism[0][k]); generate_binaddress_eth(endomorphism_negeted_point[k],(uint8_t*)publickeyhashrmd160_endomorphism[1][k]); endomorphism_negeted_point[k] = secp->Negation(endomorphism_beta[(j*4)+k]); generate_binaddress_eth(endomorphism_beta[(4*j)+k],(uint8_t*)publickeyhashrmd160_endomorphism[2][k]); generate_binaddress_eth(endomorphism_negeted_point[k],(uint8_t*)publickeyhashrmd160_endomorphism[3][k]); endomorphism_negeted_point[k] = secp->Negation(endomorphism_beta2[(j*4)+k]); generate_binaddress_eth(endomorphism_beta[(4*j)+k],(uint8_t*)publickeyhashrmd160_endomorphism[4][k]); generate_binaddress_eth(endomorphism_negeted_point[k],(uint8_t*)publickeyhashrmd160_endomorphism[5][k]); } } else { for(k = 0; k < 4;k++) { generate_binaddress_eth(pts[(4*j)+k],(uint8_t*)publickeyhashrmd160_uncompress[k]); } } } break; } switch(FLAGMODE) { case MODE_RMD160: case MODE_ADDRESS: if( FLAGCRYPTO == CRYPTO_BTC) { for(k = 0; k < 4;k++) { if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){ if(FLAGENDOMORPHISM) { for(l = 0;l < 6; l++) { r = bloom_check(&bloom,publickeyhashrmd160_endomorphism[l][k],MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,publickeyhashrmd160_endomorphism[l][k],N); if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); publickey = secp->ComputePublicKey(&keyfound); switch(l) { case 0: //Original point, prefix 02 if(publickey.y.IsOdd()) { //if the current publickey is odd that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; case 1: //Original point, prefix 03 if(publickey.y.IsEven()) { //if the current publickey is even that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 03 break; case 2: //Beta point, prefix 02 keyfound.ModMulK1order(&lambda); if(publickey.y.IsOdd()) { //if the current publickey is odd that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; case 3: //Beta point, prefix 03 keyfound.ModMulK1order(&lambda); if(publickey.y.IsEven()) { //if the current publickey is even that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; case 4: //Beta^2 point, prefix 02 keyfound.ModMulK1order(&lambda2); if(publickey.y.IsOdd()) { //if the current publickey is odd that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; case 5: //Beta^2 point, prefix 03 keyfound.ModMulK1order(&lambda2); if(publickey.y.IsEven()) { //if the current publickey is even that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; } writekey(true,&keyfound); } } } } else { for(l = 0;l < 2; l++) { r = bloom_check(&bloom,publickeyhashrmd160_endomorphism[l][k],MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,publickeyhashrmd160_endomorphism[l][k],N); if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); publickey = secp->ComputePublicKey(&keyfound); secp->GetHash160(P2PKH,true,publickey,(uint8_t*)publickeyhashrmd160); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160,20) != 0) { keyfound.Neg(); keyfound.Add(&secp->order); } writekey(true,&keyfound); } } } } } if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH) { if(FLAGENDOMORPHISM) { for(l = 6;l < 12; l++) { //We check the array from 6 to 12(excluded) because we save the uncompressed information there r = bloom_check(&bloom,publickeyhashrmd160_endomorphism[l][k],MAXLENGTHADDRESS); //Check in Bloom filter if(r) { r = searchbinary(addressTable,publickeyhashrmd160_endomorphism[l][k],N); //Check in Array using Binary search if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); switch(l) { case 6: case 7: publickey = secp->ComputePublicKey(&keyfound); secp->GetHash160(P2PKH,false,publickey,(uint8_t*)publickeyhashrmd160_uncompress[0]); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160_uncompress[0],20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); } break; case 8: case 9: keyfound.ModMulK1order(&lambda); publickey = secp->ComputePublicKey(&keyfound); secp->GetHash160(P2PKH,false,publickey,(uint8_t*)publickeyhashrmd160_uncompress[0]); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160_uncompress[0],20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); } break; case 10: case 11: keyfound.ModMulK1order(&lambda2); publickey = secp->ComputePublicKey(&keyfound); secp->GetHash160(P2PKH,false,publickey,(uint8_t*)publickeyhashrmd160_uncompress[0]); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160_uncompress[0],20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); } break; } writekey(false,&keyfound); } } } } else { r = bloom_check(&bloom,publickeyhashrmd160_uncompress[k],MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,publickeyhashrmd160_uncompress[k],N); if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); writekey(false,&keyfound); } } } } } } else if( FLAGCRYPTO == CRYPTO_ETH) { if(FLAGENDOMORPHISM) { for(k = 0; k < 4;k++) { for(l = 0;l < 6; l++) { r = bloom_check(&bloom,publickeyhashrmd160_endomorphism[l][k],MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,publickeyhashrmd160_endomorphism[l][k],N); if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); switch(l) { case 0: case 1: publickey = secp->ComputePublicKey(&keyfound); generate_binaddress_eth(publickey,(uint8_t*)publickeyhashrmd160_uncompress[0]); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160_uncompress[0],20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); } break; case 2: case 3: keyfound.ModMulK1order(&lambda); publickey = secp->ComputePublicKey(&keyfound); generate_binaddress_eth(publickey,(uint8_t*)publickeyhashrmd160_uncompress[0]); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160_uncompress[0],20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); } break; case 4: case 5: keyfound.ModMulK1order(&lambda2); publickey = secp->ComputePublicKey(&keyfound); generate_binaddress_eth(publickey,(uint8_t*)publickeyhashrmd160_uncompress[0]); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160_uncompress[0],20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); } break; } writekeyeth(&keyfound); } } } } } else { for(k = 0; k < 4;k++) { r = bloom_check(&bloom,publickeyhashrmd160_uncompress[k],MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,publickeyhashrmd160_uncompress[k],N); if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); writekeyeth(&keyfound); } } } } } break; case MODE_XPOINT: for(k = 0; k < 4;k++) { if(FLAGENDOMORPHISM) { pts[(4*j)+k].x.Get32Bytes((unsigned char *)rawvalue); r = bloom_check(&bloom,rawvalue,MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,rawvalue,N); if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); writekey(false,&keyfound); } } endomorphism_beta[(j*4)+k].x.Get32Bytes((unsigned char *)rawvalue); r = bloom_check(&bloom,rawvalue,MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,rawvalue,N); if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); keyfound.ModMulK1order(&lambda); writekey(false,&keyfound); } } endomorphism_beta2[(j*4)+k].x.Get32Bytes((unsigned char *)rawvalue); r = bloom_check(&bloom,rawvalue,MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,rawvalue,N); if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); keyfound.ModMulK1order(&lambda2); writekey(false,&keyfound); } } } else { pts[(4*j)+k].x.Get32Bytes((unsigned char *)rawvalue); r = bloom_check(&bloom,rawvalue,MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,rawvalue,N); if(r) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); writekey(false,&keyfound); } } } } break; } count+=4; temp_stride.SetInt32(4); temp_stride.Mult(&stride); key_mpz.Add(&temp_stride); } /* if(FLAGDEBUG) { printf("\n[D] thread_process %i\n",__LINE__ -1 ); fflush(stdout); } */ steps[thread_number]++; // Next start point (startP + GRP_SIZE*G) pp = startP; dy.ModSub(&_2Gn.y,&pp.y); _s.ModMulK1(&dy,&dx[i + 1]); _p.ModSquareK1(&_s); pp.x.ModNeg(); pp.x.ModAdd(&_p); pp.x.ModSub(&_2Gn.x); //The Y value for the next start point always need to be calculated pp.y.ModSub(&_2Gn.x,&pp.x); pp.y.ModMulK1(&_s); pp.y.ModSub(&_2Gn.y); startP = pp; }while(count < N_SEQUENTIAL_MAX && continue_flag); } } while(continue_flag); ends[thread_number] = 1; return NULL; } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_process_vanity(LPVOID vargp) { #else void *thread_process_vanity(void *vargp) { #endif struct tothread *tt; Point pts[CPU_GRP_SIZE]; Point endomorphism_beta[CPU_GRP_SIZE]; Point endomorphism_beta2[CPU_GRP_SIZE]; Point endomorphism_negeted_point[4]; Int dx[CPU_GRP_SIZE / 2 + 1]; IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); Point startP; Int dy; Int dyn; Int _s; Int _p; Point pp; //point positive Point pn; //point negative int l,pp_offset,pn_offset,i,hLength = (CPU_GRP_SIZE / 2 - 1); uint64_t j,count; Point R,temporal,publickey; int thread_number,continue_flag = 1,k; char *hextemp = NULL; char publickeyhashrmd160[20]; char publickeyhashrmd160_uncompress[4][20]; char publickeyhashrmd160_endomorphism[12][4][20]; Int key_mpz,temp_stride,keyfound; tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); grp->Set(dx); //if FLAGENDOMORPHISM == 1 and only compress search is enabled then there is no need to calculate the Y value value bool calculate_y = FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH; /* if(FLAGDEBUG && thread_number == 0) { printf("[D] vanity_rmd_targets = %i fillllll\n",vanity_rmd_targets); printf("[D] vanity_rmd_total = %i\n",vanity_rmd_total); for(i =0; i < vanity_rmd_targets;i++) { printf("[D] vanity_rmd_limits[%li] = %i\n",i,vanity_rmd_limits[i]); } printf("[D] vanity_rmd_minimun_bytes_check_length = %i\n",vanity_rmd_minimun_bytes_check_length); } */ do { if(FLAGRANDOM){ key_mpz.Rand(&n_range_start,&n_range_end); } else { if(n_range_start.IsLower(&n_range_end)) { #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_random, INFINITE); key_mpz.Set(&n_range_start); n_range_start.Add(N_SEQUENTIAL_MAX); ReleaseMutex(write_random); #else pthread_mutex_lock(&write_random); key_mpz.Set(&n_range_start); n_range_start.Add(N_SEQUENTIAL_MAX); pthread_mutex_unlock(&write_random); #endif } else { continue_flag = 0; } } if(continue_flag) { count = 0; if(FLAGMATRIX) { hextemp = key_mpz.GetBase16(); printf("Base key: %s thread %i\n",hextemp,thread_number); fflush(stdout); free(hextemp); } else { if(FLAGQUIET == 0) { hextemp = key_mpz.GetBase16(); printf("\rBase key: %s \r",hextemp); fflush(stdout); free(hextemp); THREADOUTPUT = 1; } } do { temp_stride.SetInt32(CPU_GRP_SIZE / 2); temp_stride.Mult(&stride); key_mpz.Add(&temp_stride); startP = secp->ComputePublicKey(&key_mpz); key_mpz.Sub(&temp_stride); for(i = 0; i < hLength; i++) { dx[i].ModSub(&Gn[i].x,&startP.x); } dx[i].ModSub(&Gn[i].x,&startP.x); // For the first point dx[i + 1].ModSub(&_2Gn.x,&startP.x); // For the next center point grp->ModInv(); pts[CPU_GRP_SIZE / 2] = startP; for(i = 0; iGetHash160_fromX(P2PKH,0x02,&pts[(j*4)].x,&pts[(j*4)+1].x,&pts[(j*4)+2].x,&pts[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[0][0],(uint8_t*)publickeyhashrmd160_endomorphism[0][1],(uint8_t*)publickeyhashrmd160_endomorphism[0][2],(uint8_t*)publickeyhashrmd160_endomorphism[0][3]); secp->GetHash160_fromX(P2PKH,0x03,&pts[(j*4)].x,&pts[(j*4)+1].x,&pts[(j*4)+2].x,&pts[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[1][0],(uint8_t*)publickeyhashrmd160_endomorphism[1][1],(uint8_t*)publickeyhashrmd160_endomorphism[1][2],(uint8_t*)publickeyhashrmd160_endomorphism[1][3]); secp->GetHash160_fromX(P2PKH,0x02,&endomorphism_beta[(j*4)].x,&endomorphism_beta[(j*4)+1].x,&endomorphism_beta[(j*4)+2].x,&endomorphism_beta[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[2][0],(uint8_t*)publickeyhashrmd160_endomorphism[2][1],(uint8_t*)publickeyhashrmd160_endomorphism[2][2],(uint8_t*)publickeyhashrmd160_endomorphism[2][3]); secp->GetHash160_fromX(P2PKH,0x03,&endomorphism_beta[(j*4)].x,&endomorphism_beta[(j*4)+1].x,&endomorphism_beta[(j*4)+2].x,&endomorphism_beta[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[3][0],(uint8_t*)publickeyhashrmd160_endomorphism[3][1],(uint8_t*)publickeyhashrmd160_endomorphism[3][2],(uint8_t*)publickeyhashrmd160_endomorphism[3][3]); secp->GetHash160_fromX(P2PKH,0x02,&endomorphism_beta2[(j*4)].x,&endomorphism_beta2[(j*4)+1].x,&endomorphism_beta2[(j*4)+2].x,&endomorphism_beta2[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[4][0],(uint8_t*)publickeyhashrmd160_endomorphism[4][1],(uint8_t*)publickeyhashrmd160_endomorphism[4][2],(uint8_t*)publickeyhashrmd160_endomorphism[4][3]); secp->GetHash160_fromX(P2PKH,0x03,&endomorphism_beta2[(j*4)].x,&endomorphism_beta2[(j*4)+1].x,&endomorphism_beta2[(j*4)+2].x,&endomorphism_beta2[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[5][0],(uint8_t*)publickeyhashrmd160_endomorphism[5][1],(uint8_t*)publickeyhashrmd160_endomorphism[5][2],(uint8_t*)publickeyhashrmd160_endomorphism[5][3]); } else { secp->GetHash160_fromX(P2PKH,0x02,&pts[(j*4)].x,&pts[(j*4)+1].x,&pts[(j*4)+2].x,&pts[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[0][0],(uint8_t*)publickeyhashrmd160_endomorphism[0][1],(uint8_t*)publickeyhashrmd160_endomorphism[0][2],(uint8_t*)publickeyhashrmd160_endomorphism[0][3]); secp->GetHash160_fromX(P2PKH,0x03,&pts[(j*4)].x,&pts[(j*4)+1].x,&pts[(j*4)+2].x,&pts[(j*4)+3].x,(uint8_t*)publickeyhashrmd160_endomorphism[1][0],(uint8_t*)publickeyhashrmd160_endomorphism[1][1],(uint8_t*)publickeyhashrmd160_endomorphism[1][2],(uint8_t*)publickeyhashrmd160_endomorphism[1][3]); } } if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH) { if(FLAGENDOMORPHISM) { for(l = 0; l < 4; l++) { endomorphism_negeted_point[l] = secp->Negation(pts[(j*4)+l]); } secp->GetHash160(P2PKH,false, pts[(j*4)], pts[(j*4)+1], pts[(j*4)+2], pts[(j*4)+3],(uint8_t*)publickeyhashrmd160_endomorphism[6][0],(uint8_t*)publickeyhashrmd160_endomorphism[6][1],(uint8_t*)publickeyhashrmd160_endomorphism[6][2],(uint8_t*)publickeyhashrmd160_endomorphism[6][3]); secp->GetHash160(P2PKH,false,endomorphism_negeted_point[0] ,endomorphism_negeted_point[1],endomorphism_negeted_point[2],endomorphism_negeted_point[3],(uint8_t*)publickeyhashrmd160_endomorphism[7][0],(uint8_t*)publickeyhashrmd160_endomorphism[7][1],(uint8_t*)publickeyhashrmd160_endomorphism[7][2],(uint8_t*)publickeyhashrmd160_endomorphism[7][3]); for(l = 0; l < 4; l++) { endomorphism_negeted_point[l] = secp->Negation(endomorphism_beta[(j*4)+l]); } secp->GetHash160(P2PKH,false,endomorphism_beta[(j*4)], endomorphism_beta[(j*4)+1], endomorphism_beta[(j*4)+2], endomorphism_beta[(j*4)+3] ,(uint8_t*)publickeyhashrmd160_endomorphism[8][0],(uint8_t*)publickeyhashrmd160_endomorphism[8][1],(uint8_t*)publickeyhashrmd160_endomorphism[8][2],(uint8_t*)publickeyhashrmd160_endomorphism[8][3]); secp->GetHash160(P2PKH,false,endomorphism_negeted_point[0],endomorphism_negeted_point[1],endomorphism_negeted_point[2],endomorphism_negeted_point[3],(uint8_t*)publickeyhashrmd160_endomorphism[9][0],(uint8_t*)publickeyhashrmd160_endomorphism[9][1],(uint8_t*)publickeyhashrmd160_endomorphism[9][2],(uint8_t*)publickeyhashrmd160_endomorphism[9][3]); for(l = 0; l < 4; l++) { endomorphism_negeted_point[l] = secp->Negation(endomorphism_beta2[(j*4)+l]); } secp->GetHash160(P2PKH,false, endomorphism_beta2[(j*4)], endomorphism_beta2[(j*4)+1] , endomorphism_beta2[(j*4)+2] , endomorphism_beta2[(j*4)+3] ,(uint8_t*)publickeyhashrmd160_endomorphism[10][0],(uint8_t*)publickeyhashrmd160_endomorphism[10][1],(uint8_t*)publickeyhashrmd160_endomorphism[10][2],(uint8_t*)publickeyhashrmd160_endomorphism[10][3]); secp->GetHash160(P2PKH,false, endomorphism_negeted_point[0], endomorphism_negeted_point[1], endomorphism_negeted_point[2],endomorphism_negeted_point[3],(uint8_t*)publickeyhashrmd160_endomorphism[11][0],(uint8_t*)publickeyhashrmd160_endomorphism[11][1],(uint8_t*)publickeyhashrmd160_endomorphism[11][2],(uint8_t*)publickeyhashrmd160_endomorphism[11][3]); } else { secp->GetHash160(P2PKH,false,pts[(j*4)],pts[(j*4)+1],pts[(j*4)+2],pts[(j*4)+3],(uint8_t*)publickeyhashrmd160_uncompress[0],(uint8_t*)publickeyhashrmd160_uncompress[1],(uint8_t*)publickeyhashrmd160_uncompress[2],(uint8_t*)publickeyhashrmd160_uncompress[3]); } } for(k = 0; k < 4;k++) { if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH ){ if(FLAGENDOMORPHISM) { for(l = 0;l < 6; l++) { if(vanityrmdmatch((uint8_t*)publickeyhashrmd160_endomorphism[l][k])) { // Here the given publickeyhashrmd160 match againts one of the vanity targets // We need to check which of the cases is it. keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); publickey = secp->ComputePublicKey(&keyfound); switch(l) { case 0: //Original point, prefix 02 if(publickey.y.IsOdd()) { //if the current publickey is odd that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; case 1: //Original point, prefix 03 if(publickey.y.IsEven()) { //if the current publickey is even that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 03 break; case 2: //Beta point, prefix 02 keyfound.ModMulK1order(&lambda); if(publickey.y.IsOdd()) { //if the current publickey is odd that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; case 3: //Beta point, prefix 03 keyfound.ModMulK1order(&lambda); if(publickey.y.IsEven()) { //if the current publickey is even that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; case 4: //Beta^2 point, prefix 02 keyfound.ModMulK1order(&lambda2); if(publickey.y.IsOdd()) { //if the current publickey is odd that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; case 5: //Beta^2 point, prefix 03 keyfound.ModMulK1order(&lambda2); if(publickey.y.IsEven()) { //if the current publickey is even that means, we need to negate the keyfound to get the correct key keyfound.Neg(); keyfound.Add(&secp->order); } // else we dont need to chage the current keyfound because it already have prefix 02 break; } writevanitykey(true,&keyfound); } } } else { for(l = 0;l < 2; l++) { if(vanityrmdmatch((uint8_t*)publickeyhashrmd160_endomorphism[l][k])) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); publickey = secp->ComputePublicKey(&keyfound); secp->GetHash160(P2PKH,true,publickey,(uint8_t*)publickeyhashrmd160); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160,20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); //if(FLAGDEBUG) printf("[D] Key need to be negated\n"); } writevanitykey(true,&keyfound); } } } } if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH) { if(FLAGENDOMORPHISM) { for(l = 6;l < 12; l++) { if(vanityrmdmatch((uint8_t*)publickeyhashrmd160_endomorphism[l][k])) { // Here the given publickeyhashrmd160 match againts one of the vanity targets // We need to check which of the cases is it. //rmd160toaddress_dst(publickeyhashrmd160_endomorphism[l][k],address); keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); switch(l) { case 6: case 7: publickey = secp->ComputePublicKey(&keyfound); secp->GetHash160(P2PKH,false,publickey,(uint8_t*)publickeyhashrmd160_uncompress[0]); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160_uncompress[0],20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); } break; case 8: case 9: keyfound.ModMulK1order(&lambda); publickey = secp->ComputePublicKey(&keyfound); secp->GetHash160(P2PKH,false,publickey,(uint8_t*)publickeyhashrmd160_uncompress[0]); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160_uncompress[0],20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); } break; case 10: case 11: keyfound.ModMulK1order(&lambda2); publickey = secp->ComputePublicKey(&keyfound); secp->GetHash160(P2PKH,false,publickey,(uint8_t*)publickeyhashrmd160_uncompress[0]); if(memcmp(publickeyhashrmd160_endomorphism[l][k],publickeyhashrmd160_uncompress[0],20) != 0){ keyfound.Neg(); keyfound.Add(&secp->order); } break; } writevanitykey(false,&keyfound); } } } else { if(vanityrmdmatch((uint8_t*)publickeyhashrmd160_uncompress[k])) { keyfound.SetInt32(k); keyfound.Mult(&stride); keyfound.Add(&key_mpz); writevanitykey(false,&keyfound); } } } } count+=4; temp_stride.SetInt32(4); temp_stride.Mult(&stride); key_mpz.Add(&temp_stride); } steps[thread_number]++; // Next start point (startP + GRP_SIZE*G) pp = startP; dy.ModSub(&_2Gn.y,&pp.y); _s.ModMulK1(&dy,&dx[i + 1]); _p.ModSquareK1(&_s); pp.x.ModNeg(); pp.x.ModAdd(&_p); pp.x.ModSub(&_2Gn.x); //The Y value for the next start point always need to be calculated pp.y.ModSub(&_2Gn.x,&pp.x); pp.y.ModMulK1(&_s); pp.y.ModSub(&_2Gn.y); startP = pp; }while(count < N_SEQUENTIAL_MAX && continue_flag); } } while(continue_flag); ends[thread_number] = 1; return NULL; } void _swap(struct address_value *a,struct address_value *b) { struct address_value t; t = *a; *a = *b; *b = t; } void _sort(struct address_value *arr,int64_t n) { uint32_t depthLimit = ((uint32_t) ceil(log(n))) * 2; _introsort(arr,depthLimit,n); } void _introsort(struct address_value *arr,uint32_t depthLimit, int64_t n) { int64_t p; if(n > 1) { if(n <= 16) { _insertionsort(arr,n); } else { if(depthLimit == 0) { _myheapsort(arr,n); } else { p = _partition(arr,n); if(p > 0) _introsort(arr , depthLimit-1 , p); if(p < n) _introsort(&arr[p+1],depthLimit-1,n-(p+1)); } } } } void _insertionsort(struct address_value *arr, int64_t n) { int64_t j; int64_t i; struct address_value key; for(i = 1; i < n ; i++ ) { key = arr[i]; j= i-1; while(j >= 0 && memcmp(arr[j].value,key.value,20) > 0) { arr[j+1] = arr[j]; j--; } arr[j+1] = key; } } int64_t _partition(struct address_value *arr, int64_t n) { struct address_value pivot; int64_t r,left,right; r = n/2; pivot = arr[r]; left = 0; right = n-1; do { while(left < right && memcmp(arr[left].value,pivot.value,20) <= 0 ) { left++; } while(right >= left && memcmp(arr[right].value,pivot.value,20) > 0) { right--; } if(left < right) { if(left == r || right == r) { if(left == r) { r = right; } if(right == r) { r = left; } } _swap(&arr[right],&arr[left]); } }while(left < right); if(right != r) { _swap(&arr[right],&arr[r]); } return right; } void _heapify(struct address_value *arr, int64_t n, int64_t i) { int64_t largest = i; int64_t l = 2 * i + 1; int64_t r = 2 * i + 2; if (l < n && memcmp(arr[l].value,arr[largest].value,20) > 0) largest = l; if (r < n && memcmp(arr[r].value,arr[largest].value,20) > 0) largest = r; if (largest != i) { _swap(&arr[i],&arr[largest]); _heapify(arr, n, largest); } } void _myheapsort(struct address_value *arr, int64_t n) { int64_t i; for ( i = (n / 2) - 1; i >= 0; i--) { _heapify(arr, n, i); } for ( i = n - 1; i > 0; i--) { _swap(&arr[0] , &arr[i]); _heapify(arr, i, 0); } } /* OK */ void bsgs_swap(struct bsgs_xvalue *a,struct bsgs_xvalue *b) { struct bsgs_xvalue t; t = *a; *a = *b; *b = t; } /* OK */ void bsgs_sort(struct bsgs_xvalue *arr,int64_t n) { uint32_t depthLimit = ((uint32_t) ceil(log(n))) * 2; bsgs_introsort(arr,depthLimit,n); } /* OK */ void bsgs_introsort(struct bsgs_xvalue *arr,uint32_t depthLimit, int64_t n) { int64_t p; if(n > 1) { if(n <= 16) { bsgs_insertionsort(arr,n); } else { if(depthLimit == 0) { bsgs_myheapsort(arr,n); } else { p = bsgs_partition(arr,n); if(p > 0) bsgs_introsort(arr , depthLimit-1 , p); if(p < n) bsgs_introsort(&arr[p+1],depthLimit-1,n-(p+1)); } } } } /* OK */ void bsgs_insertionsort(struct bsgs_xvalue *arr, int64_t n) { int64_t j; int64_t i; struct bsgs_xvalue key; for(i = 1; i < n ; i++ ) { key = arr[i]; j= i-1; while(j >= 0 && memcmp(arr[j].value,key.value,BSGS_XVALUE_RAM) > 0) { arr[j+1] = arr[j]; j--; } arr[j+1] = key; } } int64_t bsgs_partition(struct bsgs_xvalue *arr, int64_t n) { struct bsgs_xvalue pivot; int64_t r,left,right; r = n/2; pivot = arr[r]; left = 0; right = n-1; do { while(left < right && memcmp(arr[left].value,pivot.value,BSGS_XVALUE_RAM) <= 0 ) { left++; } while(right >= left && memcmp(arr[right].value,pivot.value,BSGS_XVALUE_RAM) > 0) { right--; } if(left < right) { if(left == r || right == r) { if(left == r) { r = right; } if(right == r) { r = left; } } bsgs_swap(&arr[right],&arr[left]); } }while(left < right); if(right != r) { bsgs_swap(&arr[right],&arr[r]); } return right; } void bsgs_heapify(struct bsgs_xvalue *arr, int64_t n, int64_t i) { int64_t largest = i; int64_t l = 2 * i + 1; int64_t r = 2 * i + 2; if (l < n && memcmp(arr[l].value,arr[largest].value,BSGS_XVALUE_RAM) > 0) largest = l; if (r < n && memcmp(arr[r].value,arr[largest].value,BSGS_XVALUE_RAM) > 0) largest = r; if (largest != i) { bsgs_swap(&arr[i],&arr[largest]); bsgs_heapify(arr, n, largest); } } void bsgs_myheapsort(struct bsgs_xvalue *arr, int64_t n) { int64_t i; for ( i = (n / 2) - 1; i >= 0; i--) { bsgs_heapify(arr, n, i); } for ( i = n - 1; i > 0; i--) { bsgs_swap(&arr[0] , &arr[i]); bsgs_heapify(arr, i, 0); } } int bsgs_searchbinary(struct bsgs_xvalue *buffer,char *data,int64_t array_length,uint64_t *r_value) { int64_t min,max,half,current; int r = 0,rcmp; min = 0; current = 0; max = array_length; half = array_length; while(!r && half >= 1) { half = (max - min)/2; rcmp = memcmp(data+16,buffer[current+half].value,BSGS_XVALUE_RAM); if(rcmp == 0) { *r_value = buffer[current+half].index; r = 1; } else { if(rcmp < 0) { max = (max-half); } else { min = (min+half); } current = min; } } return r; } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_process_bsgs(LPVOID vargp) { #else void *thread_process_bsgs(void *vargp) { #endif // File-related variables FILE* filekey; struct tothread* tt; // Character variables char xpoint_raw[32], *aux_c, *hextemp; // Integer variables Int base_key, keyfound; IntGroup* grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); Int dx[CPU_GRP_SIZE / 2 + 1]; Int dy, dyn, _s, _p, km, intaux; // Point variables Point base_point, point_aux, point_found; Point startP; Point pp, pn; Point pts[CPU_GRP_SIZE]; // Unsigned integer variables uint32_t k, l, r, salir, thread_number, cycles; // Other variables int hLength = (CPU_GRP_SIZE / 2 - 1); grp->Set(dx); tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); cycles = bsgs_aux / 1024; if(bsgs_aux % 1024 != 0) { cycles++; } intaux.Set(&BSGS_M_double); intaux.Mult(CPU_GRP_SIZE/2); intaux.Add(&BSGS_M); do { /* We do this in an atomic pthread_mutex operation to not affect others threads so BSGS_CURRENT is never the same between threads */ #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(bsgs_thread, INFINITE); #else pthread_mutex_lock(&bsgs_thread); #endif base_key.Set(&BSGS_CURRENT); /* we need to set our base_key to the current BSGS_CURRENT value*/ BSGS_CURRENT.Add(&BSGS_N_double); /*Then add 2*BSGS_N to BSGS_CURRENT*/ /* BSGS_CURRENT.Add(&BSGS_N); //Then add BSGS_N to BSGS_CURRENT BSGS_CURRENT.Add(&BSGS_N); //Then add BSGS_N to BSGS_CURRENT */ #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(bsgs_thread); #else pthread_mutex_unlock(&bsgs_thread); #endif if(base_key.IsGreaterOrEqual(&n_range_end)) break; if(FLAGMATRIX) { aux_c = base_key.GetBase16(); printf("[+] Thread 0x%s \n",aux_c); fflush(stdout); free(aux_c); } else { if(FLAGQUIET == 0){ aux_c = base_key.GetBase16(); printf("\r[+] Thread 0x%s \r",aux_c); fflush(stdout); free(aux_c); THREADOUTPUT = 1; } } base_point = secp->ComputePublicKey(&base_key); km.Set(&base_key); km.Neg(); km.Add(&secp->order); km.Sub(&intaux); point_aux = secp->ComputePublicKey(&km); for(k = 0; k < bsgs_point_number ; k++) { if(bsgs_found[k] == 0) { startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); uint32_t j = 0; while( j < cycles && bsgs_found[k]== 0 ) { int i; for(i = 0; i < hLength; i++) { dx[i].ModSub(&GSn[i].x,&startP.x); } dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point // Grouped ModInv grp->ModInv(); /* We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse We compute key in the positive and negative way from the center of the group */ // center point pts[CPU_GRP_SIZE / 2] = startP; for(i = 0; iComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); if(filekey != NULL) { fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); fclose(filekey); } free(hextemp); free(aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif bsgs_found[k] = 1; salir = 1; for(l = 0; l < bsgs_point_number && salir; l++) { salir &= bsgs_found[l]; } if(salir) { printf("All points were found\n"); exit(EXIT_FAILURE); } } //End if second check }//End if first check }// For for pts variable // Next start point (startP += (bsSize*GRP_SIZE).G) pp = startP; dy.ModSub(&_2GSn.y,&pp.y); _s.ModMulK1(&dy,&dx[i + 1]); _p.ModSquareK1(&_s); pp.x.ModNeg(); pp.x.ModAdd(&_p); pp.x.ModSub(&_2GSn.x); pp.y.ModSub(&_2GSn.x,&pp.x); pp.y.ModMulK1(&_s); pp.y.ModSub(&_2GSn.y); startP = pp; j++; } // end while }// End if } steps[thread_number]+=2; }while(1); ends[thread_number] = 1; return NULL; } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_process_bsgs_random(LPVOID vargp) { #else void *thread_process_bsgs_random(void *vargp) { #endif FILE *filekey; struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; Int base_key,keyfound,n_range_random; Point base_point,point_aux,point_found; uint32_t l,k,r,salir,thread_number,cycles; IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); Point startP; int hLength = (CPU_GRP_SIZE / 2 - 1); Int dx[CPU_GRP_SIZE / 2 + 1]; Point pts[CPU_GRP_SIZE]; Int dy; Int dyn; Int _s; Int _p; Int km,intaux; Point pp; Point pn; grp->Set(dx); tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); cycles = bsgs_aux / 1024; if(bsgs_aux % 1024 != 0) { cycles++; } intaux.Set(&BSGS_M_double); intaux.Mult(CPU_GRP_SIZE/2); intaux.Add(&BSGS_M); do { /* | Start Range | End Range | None | 1 | EC.N | -b bit | Min bit value | Max bit value | -r A:B | A | B | */ #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(bsgs_thread, INFINITE); #else pthread_mutex_lock(&bsgs_thread); #endif base_key.Rand(&n_range_start,&n_range_end); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(bsgs_thread); #else pthread_mutex_unlock(&bsgs_thread); #endif if(FLAGMATRIX) { aux_c = base_key.GetBase16(); printf("[+] Thread 0x%s \n",aux_c); fflush(stdout); free(aux_c); } else{ if(FLAGQUIET == 0){ aux_c = base_key.GetBase16(); printf("\r[+] Thread 0x%s \r",aux_c); fflush(stdout); free(aux_c); THREADOUTPUT = 1; } } base_point = secp->ComputePublicKey(&base_key); km.Set(&base_key); km.Neg(); km.Add(&secp->order); km.Sub(&intaux); point_aux = secp->ComputePublicKey(&km); /* We need to test individually every point in BSGS_Q */ for(k = 0; k < bsgs_point_number ; k++) { if(bsgs_found[k] == 0) { startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); uint32_t j = 0; while( j < cycles && bsgs_found[k]== 0 ) { int i; for(i = 0; i < hLength; i++) { dx[i].ModSub(&GSn[i].x,&startP.x); } dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point // Grouped ModInv grp->ModInv(); /* We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse We compute key in the positive and negative way from the center of the group */ // center point pts[CPU_GRP_SIZE / 2] = startP; for(i = 0; iComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); if(filekey != NULL) { fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); fclose(filekey); } free(hextemp); free(aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif bsgs_found[k] = 1; salir = 1; for(l = 0; l < bsgs_point_number && salir; l++) { salir &= bsgs_found[l]; } if(salir) { printf("All points were found\n"); exit(EXIT_FAILURE); } } //End if second check }//End if first check }// For for pts variable // Next start point (startP += (bsSize*GRP_SIZE).G) pp = startP; dy.ModSub(&_2GSn.y,&pp.y); _s.ModMulK1(&dy,&dx[i + 1]); _p.ModSquareK1(&_s); pp.x.ModNeg(); pp.x.ModAdd(&_p); pp.x.ModSub(&_2GSn.x); pp.y.ModSub(&_2GSn.x,&pp.x); pp.y.ModMulK1(&_s); pp.y.ModSub(&_2GSn.y); startP = pp; j++; } //End While } //End if } // End for with k bsgs_point_number steps[thread_number]+=2; }while(1); ends[thread_number] = 1; return NULL; } /* The bsgs_secondcheck function is made to perform a second BSGS search in a Range of less size. This funtion is made with the especific purpouse to USE a smaller bPtable in RAM. */ int bsgs_secondcheck(Int *start_range,uint32_t a,uint32_t k_index,Int *privatekey) { int i = 0,found = 0,r = 0; Int base_key; Point base_point,point_aux; Point BSGS_Q, BSGS_S,BSGS_Q_AMP; char xpoint_raw[32]; base_key.Set(&BSGS_M_double); base_key.Mult((uint64_t) a); base_key.Add(start_range); base_point = secp->ComputePublicKey(&base_key); point_aux = secp->Negation(base_point); /* BSGS_S = Q - base_key Q is the target Key base_key is the Start range + a*BSGS_M */ BSGS_S = secp->AddDirect(OriginalPointsBSGS[k_index],point_aux); BSGS_Q.Set(BSGS_S); do { BSGS_Q_AMP = secp->AddDirect(BSGS_Q,BSGS_AMP2[i]); BSGS_S.Set(BSGS_Q_AMP); BSGS_S.x.Get32Bytes((unsigned char *) xpoint_raw); r = bloom_check(&bloom_bPx2nd[(uint8_t) xpoint_raw[0]],xpoint_raw,32); if(r) { found = bsgs_thirdcheck(&base_key,i,k_index,privatekey); } i++; }while(i < 32 && !found); return found; } int bsgs_thirdcheck(Int *start_range,uint32_t a,uint32_t k_index,Int *privatekey) { uint64_t j = 0; int i = 0,found = 0,r = 0; Int base_key,calculatedkey; Point base_point,point_aux; Point BSGS_Q, BSGS_S,BSGS_Q_AMP; char xpoint_raw[32]; base_key.SetInt32(a); base_key.Mult(&BSGS_M2_double); base_key.Add(start_range); base_point = secp->ComputePublicKey(&base_key); point_aux = secp->Negation(base_point); BSGS_S = secp->AddDirect(OriginalPointsBSGS[k_index],point_aux); BSGS_Q.Set(BSGS_S); do { BSGS_Q_AMP = secp->AddDirect(BSGS_Q,BSGS_AMP3[i]); BSGS_S.Set(BSGS_Q_AMP); BSGS_S.x.Get32Bytes((unsigned char *)xpoint_raw); r = bloom_check(&bloom_bPx3rd[(uint8_t)xpoint_raw[0]],xpoint_raw,32); if(r) { r = bsgs_searchbinary(bPtable,xpoint_raw,bsgs_m3,&j); if(r) { calcualteindex(i,&calculatedkey); privatekey->Set(&calculatedkey); privatekey->Add((uint64_t)(j+1)); privatekey->Add(&base_key); point_aux = secp->ComputePublicKey(privatekey); if(point_aux.x.IsEqual(&OriginalPointsBSGS[k_index].x)) { found = 1; } else { calcualteindex(i,&calculatedkey); privatekey->Set(&calculatedkey); privatekey->Sub((uint64_t)(j+1)); privatekey->Add(&base_key); point_aux = secp->ComputePublicKey(privatekey); if(point_aux.x.IsEqual(&OriginalPointsBSGS[k_index].x)) { found = 1; } } } } else { /* For some reason the AddDirect don't return 000000... value when the publickeys are the negated values from each other Why JLP? This is is an special case */ if(BSGS_Q.x.IsEqual(&BSGS_AMP3[i].x)) { calcualteindex(i,&calculatedkey); privatekey->Set(&calculatedkey); privatekey->Add(&base_key); found = 1; } } i++; }while(i < 32 && !found); return found; } void sleep_ms(int milliseconds) { // cross-platform sleep function #if defined(_WIN64) && !defined(__CYGWIN__) Sleep(milliseconds); #elif _POSIX_C_SOURCE >= 199309L struct timespec ts; ts.tv_sec = milliseconds / 1000; ts.tv_nsec = (milliseconds % 1000) * 1000000; nanosleep(&ts, NULL); #else if (milliseconds >= 1000) sleep(milliseconds / 1000); usleep((milliseconds % 1000) * 1000); #endif } void init_generator() { Point G = secp->ComputePublicKey(&stride); Point g; g.Set(G); Gn.reserve(CPU_GRP_SIZE / 2); Gn[0] = g; g = secp->DoubleDirect(g); Gn[1] = g; for(int i = 2; i < CPU_GRP_SIZE / 2; i++) { g = secp->AddDirect(g,G); Gn[i] = g; } _2Gn = secp->DoubleDirect(Gn[CPU_GRP_SIZE / 2 - 1]); } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_bPload(LPVOID vargp) { #else void *thread_bPload(void *vargp) { #endif char rawvalue[32]; struct bPload *tt; uint64_t i_counter,j,nbStep,to; IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); Point startP; Int dx[CPU_GRP_SIZE / 2 + 1]; Point pts[CPU_GRP_SIZE]; Int dy,dyn,_s,_p; Point pp,pn; int i,bloom_bP_index,hLength = (CPU_GRP_SIZE / 2 - 1) ,threadid; tt = (struct bPload *)vargp; Int km((uint64_t)(tt->from + 1)); threadid = tt->threadid; //if(FLAGDEBUG) printf("[D] thread %i from %" PRIu64 " to %" PRIu64 "\n",threadid,tt->from,tt->to); i_counter = tt->from; nbStep = (tt->to - tt->from) / CPU_GRP_SIZE; if( ((tt->to - tt->from) % CPU_GRP_SIZE ) != 0) { nbStep++; } //if(FLAGDEBUG) printf("[D] thread %i nbStep %" PRIu64 "\n",threadid,nbStep); to = tt->to; km.Add((uint64_t)(CPU_GRP_SIZE / 2)); startP = secp->ComputePublicKey(&km); grp->Set(dx); for(uint64_t s=0;sModInv(); // We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse // We compute key in the positive and negative way from the center of the group // center point pts[CPU_GRP_SIZE / 2] = startP; //Center point for(i = 0; ifinished = 1; ReleaseMutex(bPload_mutex[threadid]); #else pthread_mutex_lock(&bPload_mutex[threadid]); tt->finished = 1; pthread_mutex_unlock(&bPload_mutex[threadid]); pthread_exit(NULL); #endif return NULL; } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_bPload_2blooms(LPVOID vargp) { #else void *thread_bPload_2blooms(void *vargp) { #endif char rawvalue[32]; struct bPload *tt; uint64_t i_counter,j,nbStep; //,to; IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); Point startP; Int dx[CPU_GRP_SIZE / 2 + 1]; Point pts[CPU_GRP_SIZE]; Int dy,dyn,_s,_p; Point pp,pn; int i,bloom_bP_index,hLength = (CPU_GRP_SIZE / 2 - 1) ,threadid; tt = (struct bPload *)vargp; Int km((uint64_t)(tt->from +1 )); threadid = tt->threadid; i_counter = tt->from; nbStep = (tt->to - (tt->from)) / CPU_GRP_SIZE; if( ((tt->to - (tt->from)) % CPU_GRP_SIZE ) != 0) { nbStep++; } //if(FLAGDEBUG) printf("[D] thread %i nbStep %" PRIu64 "\n",threadid,nbStep); //to = tt->to; km.Add((uint64_t)(CPU_GRP_SIZE / 2)); startP = secp->ComputePublicKey(&km); grp->Set(dx); for(uint64_t s=0;sModInv(); // We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse // We compute key in the positive and negative way from the center of the group // center point pts[CPU_GRP_SIZE / 2] = startP; //Center point for(i = 0; ifinished = 1; ReleaseMutex(bPload_mutex[threadid]); #else pthread_mutex_lock(&bPload_mutex[threadid]); tt->finished = 1; pthread_mutex_unlock(&bPload_mutex[threadid]); pthread_exit(NULL); #endif return NULL; } /* This function perform the KECCAK Opetation*/ void KECCAK_256(uint8_t *source, size_t size,uint8_t *dst) { SHA3_256_CTX ctx; SHA3_256_Init(&ctx); SHA3_256_Update(&ctx,source,size); KECCAK_256_Final(dst,&ctx); } /* This function takes in two parameters: publickey: a reference to a Point object representing a public key. dst_address: a pointer to an unsigned char array where the generated binary address will be stored. The function is designed to generate a binary address for Ethereum using the given public key. It first extracts the x and y coordinates of the public key as 32-byte arrays, and concatenates them to form a 64-byte array called bin_publickey. Then, it applies the KECCAK-256 hashing algorithm to bin_publickey to generate the binary address, which is stored in dst_address. */ void generate_binaddress_eth(Point &publickey,unsigned char *dst_address) { unsigned char bin_publickey[64]; publickey.x.Get32Bytes(bin_publickey); publickey.y.Get32Bytes(bin_publickey+32); KECCAK_256(bin_publickey, 64, bin_publickey); memcpy(dst_address,bin_publickey+12,20); } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_process_bsgs_dance(LPVOID vargp) { #else void *thread_process_bsgs_dance(void *vargp) { #endif Point pts[CPU_GRP_SIZE]; Int dx[CPU_GRP_SIZE / 2 + 1]; Point pp,pn,startP,base_point,point_aux,point_found; FILE *filekey; struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; Int base_key,keyfound,dy,dyn,_s,_p,km,intaux; IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); uint32_t k,l,r,salir,thread_number,entrar,cycles; int hLength = (CPU_GRP_SIZE / 2 - 1); grp->Set(dx); tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); cycles = bsgs_aux / 1024; if(bsgs_aux % 1024 != 0) { cycles++; } intaux.Set(&BSGS_M_double); intaux.Mult(CPU_GRP_SIZE/2); intaux.Add(&BSGS_M); entrar = 1; /* while base_key is less than n_range_end then: */ do { r = rand() % 3; #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(bsgs_thread, INFINITE); #else pthread_mutex_lock(&bsgs_thread); #endif switch(r) { case 0: //TOP if(n_range_end.IsGreater(&BSGS_CURRENT)) { /* n_range_end.Sub(&BSGS_N); n_range_end.Sub(&BSGS_N); */ n_range_end.Sub(&BSGS_N_double); if(n_range_end.IsLower(&BSGS_CURRENT)) { base_key.Set(&BSGS_CURRENT); } else { base_key.Set(&n_range_end); } } else { entrar = 0; } break; case 1: //BOTTOM if(BSGS_CURRENT.IsLower(&n_range_end)) { base_key.Set(&BSGS_CURRENT); //BSGS_N_double BSGS_CURRENT.Add(&BSGS_N_double); /* BSGS_CURRENT.Add(&BSGS_N); BSGS_CURRENT.Add(&BSGS_N); */ } else { entrar = 0; } break; case 2: //random - middle base_key.Rand(&BSGS_CURRENT,&n_range_end); break; } #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(bsgs_thread); #else pthread_mutex_unlock(&bsgs_thread); #endif if(entrar == 0) break; if(FLAGMATRIX) { aux_c = base_key.GetBase16(); printf("[+] Thread 0x%s \n",aux_c); fflush(stdout); free(aux_c); } else { if(FLAGQUIET == 0){ aux_c = base_key.GetBase16(); printf("\r[+] Thread 0x%s \r",aux_c); fflush(stdout); free(aux_c); THREADOUTPUT = 1; } } base_point = secp->ComputePublicKey(&base_key); km.Set(&base_key); km.Neg(); km.Add(&secp->order); km.Sub(&intaux); point_aux = secp->ComputePublicKey(&km); for(k = 0; k < bsgs_point_number ; k++) { if(bsgs_found[k] == 0) { startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); uint32_t j = 0; while( j < cycles && bsgs_found[k]== 0 ) { int i; for(i = 0; i < hLength; i++) { dx[i].ModSub(&GSn[i].x,&startP.x); } dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point // Grouped ModInv grp->ModInv(); /* We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse We compute key in the positive and negative way from the center of the group */ // center point pts[CPU_GRP_SIZE / 2] = startP; for(i = 0; iComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); if(filekey != NULL) { fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); fclose(filekey); } free(hextemp); free(aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif bsgs_found[k] = 1; salir = 1; for(l = 0; l < bsgs_point_number && salir; l++) { salir &= bsgs_found[l]; } if(salir) { printf("All points were found\n"); exit(EXIT_FAILURE); } } //End if second check }//End if first check }// For for pts variable // Next start point (startP += (bsSize*GRP_SIZE).G) pp = startP; dy.ModSub(&_2GSn.y,&pp.y); _s.ModMulK1(&dy,&dx[i + 1]); _p.ModSquareK1(&_s); pp.x.ModNeg(); pp.x.ModAdd(&_p); pp.x.ModSub(&_2GSn.x); pp.y.ModSub(&_2GSn.x,&pp.x); pp.y.ModMulK1(&_s); pp.y.ModSub(&_2GSn.y); startP = pp; j++; }//while all the aMP points }// End if } steps[thread_number]+=2; }while(1); ends[thread_number] = 1; return NULL; } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_process_bsgs_backward(LPVOID vargp) { #else void *thread_process_bsgs_backward(void *vargp) { #endif FILE *filekey; struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; Int base_key,keyfound; Point base_point,point_aux,point_found; uint32_t k,l,r,salir,thread_number,entrar,cycles; IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); Point startP; int hLength = (CPU_GRP_SIZE / 2 - 1); Int dx[CPU_GRP_SIZE / 2 + 1]; Point pts[CPU_GRP_SIZE]; Int dy; Int dyn; Int _s; Int _p; Int km,intaux; Point pp; Point pn; grp->Set(dx); tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); cycles = bsgs_aux / 1024; if(bsgs_aux % 1024 != 0) { cycles++; } intaux.Set(&BSGS_M_double); intaux.Mult(CPU_GRP_SIZE/2); intaux.Add(&BSGS_M); entrar = 1; /* while base_key is less than n_range_end then: */ do { #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(bsgs_thread, INFINITE); #else pthread_mutex_lock(&bsgs_thread); #endif if(n_range_end.IsGreater(&n_range_start)) { n_range_end.Sub(&BSGS_N_double); if(n_range_end.IsLower(&n_range_start)) { base_key.Set(&n_range_start); } else { base_key.Set(&n_range_end); } } else { entrar = 0; } #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(bsgs_thread); #else pthread_mutex_unlock(&bsgs_thread); #endif if(entrar == 0) break; if(FLAGMATRIX) { aux_c = base_key.GetBase16(); printf("[+] Thread 0x%s \n",aux_c); fflush(stdout); free(aux_c); } else { if(FLAGQUIET == 0){ aux_c = base_key.GetBase16(); printf("\r[+] Thread 0x%s \r",aux_c); fflush(stdout); free(aux_c); THREADOUTPUT = 1; } } base_point = secp->ComputePublicKey(&base_key); km.Set(&base_key); km.Neg(); km.Add(&secp->order); km.Sub(&intaux); point_aux = secp->ComputePublicKey(&km); for(k = 0; k < bsgs_point_number ; k++) { if(bsgs_found[k] == 0) { startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); uint32_t j = 0; while( j < cycles && bsgs_found[k]== 0 ) { int i; for(i = 0; i < hLength; i++) { dx[i].ModSub(&GSn[i].x,&startP.x); } dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point // Grouped ModInv grp->ModInv(); /* We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse We compute key in the positive and negative way from the center of the group */ // center point pts[CPU_GRP_SIZE / 2] = startP; for(i = 0; iComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); if(filekey != NULL) { fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); fclose(filekey); } free(hextemp); free(aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif bsgs_found[k] = 1; salir = 1; for(l = 0; l < bsgs_point_number && salir; l++) { salir &= bsgs_found[l]; } if(salir) { printf("All points were found\n"); exit(EXIT_FAILURE); } } //End if second check }//End if first check }// For for pts variable // Next start point (startP += (bsSize*GRP_SIZE).G) pp = startP; dy.ModSub(&_2GSn.y,&pp.y); _s.ModMulK1(&dy,&dx[i + 1]); _p.ModSquareK1(&_s); pp.x.ModNeg(); pp.x.ModAdd(&_p); pp.x.ModSub(&_2GSn.x); pp.y.ModSub(&_2GSn.x,&pp.x); pp.y.ModMulK1(&_s); pp.y.ModSub(&_2GSn.y); startP = pp; j++; }//while all the aMP points }// End if } steps[thread_number]+=2; }while(1); ends[thread_number] = 1; return NULL; } #if defined(_WIN64) && !defined(__CYGWIN__) DWORD WINAPI thread_process_bsgs_both(LPVOID vargp) { #else void *thread_process_bsgs_both(void *vargp) { #endif FILE *filekey; struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; Int base_key,keyfound; Point base_point,point_aux,point_found; uint32_t k,l,r,salir,thread_number,entrar,cycles; IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); Point startP; int hLength = (CPU_GRP_SIZE / 2 - 1); Int dx[CPU_GRP_SIZE / 2 + 1]; Point pts[CPU_GRP_SIZE]; Int dy; Int dyn; Int _s; Int _p; Int km,intaux; Point pp; Point pn; grp->Set(dx); tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); cycles = bsgs_aux / 1024; if(bsgs_aux % 1024 != 0) { cycles++; } intaux.Set(&BSGS_M_double); intaux.Mult(CPU_GRP_SIZE/2); intaux.Add(&BSGS_M); entrar = 1; /* while BSGS_CURRENT is less than n_range_end */ do { r = rand() % 2; #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(bsgs_thread, INFINITE); #else pthread_mutex_lock(&bsgs_thread); #endif switch(r) { case 0: //TOP if(n_range_end.IsGreater(&BSGS_CURRENT)) { n_range_end.Sub(&BSGS_N_double); /* n_range_end.Sub(&BSGS_N); n_range_end.Sub(&BSGS_N); */ if(n_range_end.IsLower(&BSGS_CURRENT)) { base_key.Set(&BSGS_CURRENT); } else { base_key.Set(&n_range_end); } } else { entrar = 0; } break; case 1: //BOTTOM if(BSGS_CURRENT.IsLower(&n_range_end)) { base_key.Set(&BSGS_CURRENT); //BSGS_N_double BSGS_CURRENT.Add(&BSGS_N_double); /* BSGS_CURRENT.Add(&BSGS_N); BSGS_CURRENT.Add(&BSGS_N); */ } else { entrar = 0; } break; } #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(bsgs_thread); #else pthread_mutex_unlock(&bsgs_thread); #endif if(entrar == 0) break; if(FLAGMATRIX) { aux_c = base_key.GetBase16(); printf("[+] Thread 0x%s \n",aux_c); fflush(stdout); free(aux_c); } else { if(FLAGQUIET == 0){ aux_c = base_key.GetBase16(); printf("\r[+] Thread 0x%s \r",aux_c); fflush(stdout); free(aux_c); THREADOUTPUT = 1; } } base_point = secp->ComputePublicKey(&base_key); km.Set(&base_key); km.Neg(); km.Add(&secp->order); km.Sub(&intaux); point_aux = secp->ComputePublicKey(&km); for(k = 0; k < bsgs_point_number ; k++) { if(bsgs_found[k] == 0) { startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); uint32_t j = 0; while( j < cycles && bsgs_found[k]== 0 ) { int i; for(i = 0; i < hLength; i++) { dx[i].ModSub(&GSn[i].x,&startP.x); } dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point // Grouped ModInv grp->ModInv(); /* We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse We compute key in the positive and negative way from the center of the group */ // center point pts[CPU_GRP_SIZE / 2] = startP; for(i = 0; iComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); if(filekey != NULL) { fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); fclose(filekey); } free(hextemp); free(aux_c); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif bsgs_found[k] = 1; salir = 1; for(l = 0; l < bsgs_point_number && salir; l++) { salir &= bsgs_found[l]; } if(salir) { printf("All points were found\n"); exit(EXIT_FAILURE); } } //End if second check }//End if first check }// For for pts variable // Next start point (startP += (bsSize*GRP_SIZE).G) pp = startP; dy.ModSub(&_2GSn.y,&pp.y); _s.ModMulK1(&dy,&dx[i + 1]); _p.ModSquareK1(&_s); pp.x.ModNeg(); pp.x.ModAdd(&_p); pp.x.ModSub(&_2GSn.x); pp.y.ModSub(&_2GSn.x,&pp.x); pp.y.ModMulK1(&_s); pp.y.ModSub(&_2GSn.y); startP = pp; j++; }//while all the aMP points }// End if } steps[thread_number]+=2; }while(1); ends[thread_number] = 1; return NULL; } /* This function takes in three parameters: buffer: a pointer to a char array where the minikey will be stored. rawbuffer: a pointer to a char array that contains the raw data. length: an integer representing the length of the raw data. The function is designed to convert the raw data using a lookup table (Ccoinbuffer) and store the result in the buffer. */ void set_minikey(char *buffer,char *rawbuffer,int length) { for(int i = 0; i < length; i++) { buffer[i] = Ccoinbuffer[(uint8_t)rawbuffer[i]]; } } /* This function takes in three parameters: buffer: a pointer to a char array where the minikey will be stored. rawbuffer: a pointer to a char array that contains the raw data. index: an integer representing the index of the raw data array to be incremented. The function is designed to increment the value at the specified index in the raw data array, and update the corresponding value in the buffer using a lookup table (Ccoinbuffer). If the value at the specified index exceeds 57, it is reset to 0x00 and the function recursively calls itself to increment the value at the previous index, unless the index is already 0, in which case the function returns false. The function returns true otherwise. */ bool increment_minikey_index(char *buffer,char *rawbuffer,int index) { if(rawbuffer[index] < 57){ rawbuffer[index]++; buffer[index] = Ccoinbuffer[(uint8_t)rawbuffer[index]]; } else { rawbuffer[index] = 0x00; buffer[index] = Ccoinbuffer[0]; if(index>0) { return increment_minikey_index(buffer,rawbuffer,index-1); } else { return false; } } return true; } /* This function takes in a single parameter: rawbuffer: a pointer to a char array that contains the raw data. The function is designed to increment the values in the raw data array using a lookup table (minikeyN), while also handling carry-over to the previous element in the array if necessary. The maximum number of iterations is limited by minikey_n_limit. */ void increment_minikey_N(char *rawbuffer) { int i = 20,j = 0; while( i > 0 && j < minikey_n_limit) { rawbuffer[i] = rawbuffer[i] + minikeyN[i]; if(rawbuffer[i] > 57) { // Handling carry-over if value exceeds 57 rawbuffer[i] = rawbuffer[i] % 58; rawbuffer[i-1]++; } i--; j++; } } #define BUFFMINIKEY(buff,src) \ (buff)[ 0] = (uint32_t)src[ 0] << 24 | (uint32_t)src[ 1] << 16 | (uint32_t)src[ 2] << 8 | (uint32_t)src[ 3]; \ (buff)[ 1] = (uint32_t)src[ 4] << 24 | (uint32_t)src[ 5] << 16 | (uint32_t)src[ 6] << 8 | (uint32_t)src[ 7]; \ (buff)[ 2] = (uint32_t)src[ 8] << 24 | (uint32_t)src[ 9] << 16 | (uint32_t)src[10] << 8 | (uint32_t)src[11]; \ (buff)[ 3] = (uint32_t)src[12] << 24 | (uint32_t)src[13] << 16 | (uint32_t)src[14] << 8 | (uint32_t)src[15]; \ (buff)[ 4] = (uint32_t)src[16] << 24 | (uint32_t)src[17] << 16 | (uint32_t)src[18] << 8 | (uint32_t)src[19]; \ (buff)[ 5] = (uint32_t)src[20] << 24 | (uint32_t)src[21] << 16 | 0x8000; \ (buff)[ 6] = 0; \ (buff)[ 7] = 0; \ (buff)[ 8] = 0; \ (buff)[ 9] = 0; \ (buff)[10] = 0; \ (buff)[11] = 0; \ (buff)[12] = 0; \ (buff)[13] = 0; \ (buff)[14] = 0; \ (buff)[15] = 0xB0; //176 bits => 22 BYTES void sha256sse_22(uint8_t *src0, uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *dst0, uint8_t *dst1, uint8_t *dst2, uint8_t *dst3) { uint32_t b0[16]; uint32_t b1[16]; uint32_t b2[16]; uint32_t b3[16]; BUFFMINIKEY(b0, src0); BUFFMINIKEY(b1, src1); BUFFMINIKEY(b2, src2); BUFFMINIKEY(b3, src3); sha256sse_1B(b0, b1, b2, b3, dst0, dst1, dst2, dst3); } #define BUFFMINIKEYCHECK(buff,src) \ (buff)[ 0] = (uint32_t)src[ 0] << 24 | (uint32_t)src[ 1] << 16 | (uint32_t)src[ 2] << 8 | (uint32_t)src[ 3]; \ (buff)[ 1] = (uint32_t)src[ 4] << 24 | (uint32_t)src[ 5] << 16 | (uint32_t)src[ 6] << 8 | (uint32_t)src[ 7]; \ (buff)[ 2] = (uint32_t)src[ 8] << 24 | (uint32_t)src[ 9] << 16 | (uint32_t)src[10] << 8 | (uint32_t)src[11]; \ (buff)[ 3] = (uint32_t)src[12] << 24 | (uint32_t)src[13] << 16 | (uint32_t)src[14] << 8 | (uint32_t)src[15]; \ (buff)[ 4] = (uint32_t)src[16] << 24 | (uint32_t)src[17] << 16 | (uint32_t)src[18] << 8 | (uint32_t)src[19]; \ (buff)[ 5] = (uint32_t)src[20] << 24 | (uint32_t)src[21] << 16 | (uint32_t)src[22] << 8 | 0x80; \ (buff)[ 6] = 0; \ (buff)[ 7] = 0; \ (buff)[ 8] = 0; \ (buff)[ 9] = 0; \ (buff)[10] = 0; \ (buff)[11] = 0; \ (buff)[12] = 0; \ (buff)[13] = 0; \ (buff)[14] = 0; \ (buff)[15] = 0xB8; //184 bits => 23 BYTES void sha256sse_23(uint8_t *src0, uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *dst0, uint8_t *dst1, uint8_t *dst2, uint8_t *dst3) { uint32_t b0[16]; uint32_t b1[16]; uint32_t b2[16]; uint32_t b3[16]; BUFFMINIKEYCHECK(b0, src0); BUFFMINIKEYCHECK(b1, src1); BUFFMINIKEYCHECK(b2, src2); BUFFMINIKEYCHECK(b3, src3); sha256sse_1B(b0, b1, b2, b3, dst0, dst1, dst2, dst3); } void menu() { printf("\nUsage:\n"); printf("-h show this help\n"); printf("-B Mode BSGS now have some modes \n"); printf("-b bits For some puzzles you only need some numbers of bits in the test keys.\n"); printf("-c crypto Search for specific crypto. valid only w/ -m address\n"); printf("-C mini Set the minikey Base only 22 character minikeys, ex: SRPqx8QiwnW4WNWnTVa2W5\n"); printf("-8 alpha Set the bas58 alphabet for minikeys\n"); printf("-e Enable endomorphism search (Only for address, rmd160 and vanity)\n"); printf("-f file Specify file name with addresses or xpoints or uncompressed public keys\n"); printf("-I stride Stride for xpoint, rmd160 and address, this option don't work with bsgs\n"); printf("-k value Use this only with bsgs mode, k value is factor for M, more speed but more RAM use wisely\n"); printf("-l look What type of address/hash160 are you looking for Only for rmd160 and address\n"); printf("-m mode mode of search for cryptos. (bsgs, xpoint, rmd160, address, vanity) default: address\n"); printf("-M Matrix screen, feel like a h4x0r, but performance will dropped\n"); printf("-n number Check for N sequential numbers before the random chosen, this only works with -R option\n"); printf(" Use -n to set the N for the BSGS process. Bigger N more RAM needed\n"); printf("-q Quiet the thread output\n"); printf("-r SR:EN StarRange:EndRange, the end range can be omitted for search from start range to N-1 ECC value\n"); printf("-R Random, this is the default behavior\n"); printf("-s ns Number of seconds for the stats output, 0 to omit output.\n"); printf("-S S is for SAVING in files BSGS data (Bloom filters and bPtable)\n"); printf("-6 to skip sha256 Checksum on data files"); printf("-t tn Threads number, must be a positive integer\n"); printf("-v value Search for vanity Address, only with -m vanity\n"); printf("-z value Bloom size multiplier, only address,rmd160,vanity, xpoint, value >= 1\n"); printf("\nExample:\n\n"); printf("./keyhunt -m rmd160 -f tests/unsolvedpuzzles.rmd -b 66 -l compress -R -q -t 8\n\n"); printf("This line runs the program with 8 threads from the range 20000000000000000 to 40000000000000000 without stats output\n\n"); printf("Developed by AlbertoBSD\tTips BTC: 1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW\n"); printf("Thanks to Iceland always helping and sharing his ideas.\nTips to Iceland: bc1q39meky2mn5qjq704zz0nnkl0v7kj4uz6r529at\n\n"); exit(EXIT_FAILURE); } bool vanityrmdmatch(unsigned char *rmdhash) { bool r = false; int i,j,cmpA,cmpB,result; result = bloom_check(vanity_bloom,rmdhash,vanity_rmd_minimun_bytes_check_length); switch(result) { case -1: fprintf(stderr,"[E] Bloom is not initialized\n"); exit(EXIT_FAILURE); break; case 1: for(i = 0; i < vanity_rmd_targets && !r;i++) { for(j = 0; j < vanity_rmd_limits[i] && !r; j++) { cmpA = memcmp(vanity_rmd_limit_values_A[i][j],rmdhash,20); cmpB = memcmp(vanity_rmd_limit_values_B[i][j],rmdhash,20); if(cmpA <= 0 && cmpB >= 0) { //if(FLAGDEBUG ) printf("\n\n[D] cmpA = %i, cmpB = %i \n\n",cmpA,cmpB); r = true; } } } break; default: r = false; break; } return r; } void writevanitykey(bool compressed,Int *key) { Point publickey; FILE *keys; char *hextemp,*hexrmd,public_key_hex[131],address[50],rmdhash[20]; hextemp = key->GetBase16(); publickey = secp->ComputePublicKey(key); secp->GetPublicKeyHex(compressed,publickey,public_key_hex); secp->GetHash160(P2PKH,compressed,publickey,(uint8_t*)rmdhash); hexrmd = tohex(rmdhash,20); rmd160toaddress_dst(rmdhash,address); #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif keys = fopen("VANITYKEYFOUND.txt","a+"); if(keys != NULL) { fprintf(keys,"Vanity Private Key: %s\npubkey: %s\nAddress %s\nrmd160 %s\n",hextemp,public_key_hex,address,hexrmd); fclose(keys); } printf("\nVanity Private Key: %s\npubkey: %s\nAddress %s\nrmd160 %s\n",hextemp,public_key_hex,address,hexrmd); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif free(hextemp); free(hexrmd); } int addvanity(char *target) { unsigned char raw_value_A[50],raw_value_B[50]; char target_copy[50]; int stringsize,targetsize,j,r = 0; size_t raw_value_length; int values_A_size = 0,values_B_size = 0,minimun_bytes; raw_value_length = 50; targetsize = strlen(target); stringsize = targetsize; memset(raw_value_A,0,50); memset(target_copy,0,50); if(targetsize >= 30 ) { return 0; } memcpy(target_copy,target,targetsize); j = 0; vanity_address_targets = (char**) realloc(vanity_address_targets,(vanity_rmd_targets+1) * sizeof(char*)); vanity_address_targets[vanity_rmd_targets] = NULL; checkpointer((void *)vanity_address_targets,__FILE__,"realloc","vanity_address_targets" ,__LINE__ -1 ); vanity_rmd_limits = (int*) realloc(vanity_rmd_limits,(vanity_rmd_targets+1) * sizeof(int)); vanity_rmd_limits[vanity_rmd_targets] = 0; checkpointer((void *)vanity_rmd_limits,__FILE__,"realloc","vanity_rmd_limits" ,__LINE__ -1 ); vanity_rmd_limit_values_A = (uint8_t***)realloc(vanity_rmd_limit_values_A,(vanity_rmd_targets+1) * sizeof(unsigned char *)); checkpointer((void *)vanity_rmd_limit_values_A,__FILE__,"realloc","vanity_rmd_limit_values_A" ,__LINE__ -1 ); vanity_rmd_limit_values_A[vanity_rmd_targets] = NULL; vanity_rmd_limit_values_B = (uint8_t***)realloc(vanity_rmd_limit_values_B,(vanity_rmd_targets+1) * sizeof(unsigned char *)); checkpointer((void *)vanity_rmd_limit_values_B,__FILE__,"realloc","vanity_rmd_limit_values_B" ,__LINE__ -1 ); vanity_rmd_limit_values_B[vanity_rmd_targets] = NULL; do { raw_value_length = 50; b58tobin(raw_value_A,&raw_value_length,target_copy,stringsize); if(raw_value_length < 25) { target_copy[stringsize] = '1'; stringsize++; } if(raw_value_length == 25) { b58tobin(raw_value_A,&raw_value_length,target_copy,stringsize); vanity_rmd_limit_values_A[vanity_rmd_targets] = (uint8_t**)realloc(vanity_rmd_limit_values_A[vanity_rmd_targets],(j+1) * sizeof(unsigned char *)); checkpointer((void *)vanity_rmd_limit_values_A[vanity_rmd_targets],__FILE__,"realloc","vanity_rmd_limit_values_A" ,__LINE__ -1 ); vanity_rmd_limit_values_A[vanity_rmd_targets][j] = (uint8_t*)calloc(20,1); checkpointer((void *)vanity_rmd_limit_values_A[vanity_rmd_targets][j],__FILE__,"realloc","vanity_rmd_limit_values_A" ,__LINE__ -1 ); memcpy(vanity_rmd_limit_values_A[vanity_rmd_targets][j] ,raw_value_A +1,20); j++; values_A_size = j; target_copy[stringsize] = '1'; stringsize++; } }while(raw_value_length <= 25); stringsize = targetsize; memset(raw_value_B,0,50); memset(target_copy,0,50); memcpy(target_copy,target,targetsize); j = 0; do { raw_value_length = 50; b58tobin(raw_value_B,&raw_value_length,target_copy,stringsize); if(raw_value_length < 25) { target_copy[stringsize] = 'z'; stringsize++; } if(raw_value_length == 25) { b58tobin(raw_value_B,&raw_value_length,target_copy,stringsize); vanity_rmd_limit_values_B[vanity_rmd_targets] = (uint8_t**)realloc(vanity_rmd_limit_values_B[vanity_rmd_targets],(j+1) * sizeof(unsigned char *)); checkpointer((void *)vanity_rmd_limit_values_B[vanity_rmd_targets],__FILE__,"realloc","vanity_rmd_limit_values_B" ,__LINE__ -1 ); checkpointer((void *)vanity_rmd_limit_values_B[vanity_rmd_targets],__FILE__,"realloc","vanity_rmd_limit_values_B" ,__LINE__ -1 ); vanity_rmd_limit_values_B[vanity_rmd_targets][j] = (uint8_t*)calloc(20,1); checkpointer((void *)vanity_rmd_limit_values_B[vanity_rmd_targets][j],__FILE__,"calloc","vanity_rmd_limit_values_B" ,__LINE__ -1 ); memcpy(vanity_rmd_limit_values_B[vanity_rmd_targets][j],raw_value_B+1,20); j++; values_B_size = j; target_copy[stringsize] = 'z'; stringsize++; } }while(raw_value_length <= 25); if(values_A_size >= 1 && values_B_size >= 1) { if(values_A_size != values_B_size) { if(values_A_size > values_B_size) r = values_B_size; else r = values_A_size; } else { r = values_A_size; } for(j = 0; j < r; j++) { minimun_bytes = minimum_same_bytes(vanity_rmd_limit_values_A[vanity_rmd_targets][j],vanity_rmd_limit_values_B[vanity_rmd_targets][j],20); if(minimun_bytes < vanity_rmd_minimun_bytes_check_length) { vanity_rmd_minimun_bytes_check_length = minimun_bytes; } } vanity_address_targets[vanity_rmd_targets] = (char*) calloc(targetsize+1,sizeof(char)); checkpointer((void *)vanity_address_targets[vanity_rmd_targets],__FILE__,"calloc","vanity_address_targets" ,__LINE__ -1 ); memcpy(vanity_address_targets[vanity_rmd_targets],target,targetsize+1); // +1 to copy the null character vanity_rmd_limits[vanity_rmd_targets] = r; vanity_rmd_total+=r; vanity_rmd_targets++; } else { for(j = 0; j < values_A_size;j++) { free(vanity_rmd_limit_values_A[vanity_rmd_targets][j]); } free(vanity_rmd_limit_values_A[vanity_rmd_targets]); vanity_rmd_limit_values_A[vanity_rmd_targets] = NULL; for(j = 0; j < values_B_size;j++) { free(vanity_rmd_limit_values_B[vanity_rmd_targets][j]); } free(vanity_rmd_limit_values_B[vanity_rmd_targets]); vanity_rmd_limit_values_B[vanity_rmd_targets] = NULL; r = 0; } return r; } /* A and B are binary o string data pointers length the max lenght to check. Caller must by sure that the pointer are valid and have at least length bytes readebles witout causing overflow */ int minimum_same_bytes(unsigned char* A,unsigned char* B, int length) { int minBytes = 0; // Assume initially that all bytes are the same if(A == NULL || B == NULL) { // In case of some NULL pointer return 0; } for (int i = 0; i < length; i++) { if (A[i] != B[i]) { break; // Exit the loop since we found a mismatch } minBytes++; // Update the minimum number of bytes where data is the same } return minBytes; } void checkpointer(void *ptr,const char *file,const char *function,const char *name,int line) { if(ptr == NULL) { fprintf(stderr,"[E] error in file %s, %s pointer %s on line %i\n",file,function,name,line); exit(EXIT_FAILURE); } } void writekey(bool compressed,Int *key) { Point publickey; FILE *keys; char *hextemp,*hexrmd,public_key_hex[132],address[50],rmdhash[20]; memset(address,0,50); memset(public_key_hex,0,132); hextemp = key->GetBase16(); publickey = secp->ComputePublicKey(key); secp->GetPublicKeyHex(compressed,publickey,public_key_hex); secp->GetHash160(P2PKH,compressed,publickey,(uint8_t*)rmdhash); hexrmd = tohex(rmdhash,20); rmd160toaddress_dst(rmdhash,address); #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(keys != NULL) { fprintf(keys,"Private Key: %s\npubkey: %s\nAddress %s\nrmd160 %s\n",hextemp,public_key_hex,address,hexrmd); fclose(keys); } printf("\nHit! Private Key: %s\npubkey: %s\nAddress %s\nrmd160 %s\n",hextemp,public_key_hex,address,hexrmd); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif free(hextemp); free(hexrmd); } void writekeyeth(Int *key) { Point publickey; FILE *keys; char *hextemp,address[43],hash[20]; hextemp = key->GetBase16(); publickey = secp->ComputePublicKey(key); generate_binaddress_eth(publickey,(unsigned char*)hash); address[0] = '0'; address[1] = 'x'; tohex_dst(hash,20,address+2); #if defined(_WIN64) && !defined(__CYGWIN__) WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(keys != NULL) { fprintf(keys,"Private Key: %s\naddress: %s\n",hextemp,address); fclose(keys); } printf("\n Hit!!!! Private Key: %s\naddress: %s\n",hextemp,address); #if defined(_WIN64) && !defined(__CYGWIN__) ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif free(hextemp); } bool isBase58(char c) { // Define the base58 set const char base58Set[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; // Check if the character is in the base58 set return strchr(base58Set, c) != NULL; } bool isValidBase58String(char *str) { int len = strlen(str); bool continuar = true; for (int i = 0; i < len && continuar; i++) { continuar = isBase58(str[i]); } return continuar; } bool processOneVanity() { int i,k; if(vanity_rmd_targets == 0) { fprintf(stderr,"[E] There aren't any vanity targets\n"); return false; } if(!initBloomFilter(vanity_bloom, vanity_rmd_total)) return false; for(i = 0; i < vanity_rmd_targets;i++) { for(k = 0; k < vanity_rmd_limits[i]; k++) { bloom_add(vanity_bloom, vanity_rmd_limit_values_A[i][k] ,vanity_rmd_minimun_bytes_check_length); } } return true; } bool readFileVanity(char *fileName) { FILE *fileDescriptor; int i,k,len; char aux[100],*hextemp; fileDescriptor = fopen(fileName,"r"); if(fileDescriptor == NULL) { if(vanity_rmd_targets == 0) { fprintf(stderr,"[E] There aren't any vanity targets\n"); return false; } } else { while(!feof(fileDescriptor)) { hextemp = fgets(aux,100,fileDescriptor); if(hextemp == aux) { trim(aux," \t\n\r"); len = strlen(aux); if(len > 0 && len < 36){ if(isValidBase58String(aux)) { addvanity(aux); } else { fprintf(stderr,"[E] the string \"%s\" is not valid Base58, omiting it\n",aux); } } } } fclose(fileDescriptor); } N = vanity_rmd_total; if(!initBloomFilter(vanity_bloom,N)) return false; for(i = 0; i < vanity_rmd_targets ; i++) { for(k = 0; k < vanity_rmd_limits[i]; k++) { bloom_add(vanity_bloom, vanity_rmd_limit_values_A[i][k] ,vanity_rmd_minimun_bytes_check_length); } } return true; } bool readFileAddress(char *fileName) { FILE *fileDescriptor; char fileBloomName[30]; /* Actually it is Bloom and Table but just to keep the variable name short*/ uint8_t checksum[32],hexPrefix[9]; char dataChecksum[32],bloomChecksum[32]; size_t bytesRead; uint64_t dataSize; /* if the FLAGSAVEREADFILE is Set to 1 we need to the checksum and check if we have that information already saved */ if(FLAGSAVEREADFILE) { /* if the flag is set to REAd and SAVE the file firs we need to check it the file exist*/ if(!sha256_file((const char*)fileName,checksum)){ fprintf(stderr,"[E] sha256_file error line %i\n",__LINE__ - 1); return false; } tohex_dst((char*)checksum,4,(char*)hexPrefix); // we save the prefix (last fourt bytes) hexadecimal value snprintf(fileBloomName,30,"data_%s.dat",hexPrefix); fileDescriptor = fopen(fileBloomName,"rb"); if(fileDescriptor != NULL) { printf("[+] Reading file %s\n",fileBloomName); //read bloom checksum (expected value to be checked) //read bloom filter structure //read bloom filter data //calculate checksum of the current readed data //Compare checksums //read data checksum (expected value to be checked) //read data size //read data //compare the expected datachecksum againts the current data checksum //compare the expected bloom checksum againts the current bloom checksum //read bloom checksum (expected value to be checked) bytesRead = fread(bloomChecksum,1,32,fileDescriptor); if(bytesRead != 32) { fprintf(stderr,"[E] Errore reading file, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } //read bloom filter structure bytesRead = fread(&bloom,1,sizeof(struct bloom),fileDescriptor); if(bytesRead != sizeof(struct bloom)) { fprintf(stderr,"[E] Error reading file, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } printf("[+] Bloom filter for %" PRIu64 " elements.\n",bloom.entries); bloom.bf = (uint8_t*) malloc(bloom.bytes); if(bloom.bf == NULL) { fprintf(stderr,"[E] Error allocating memory, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } //read bloom filter data bytesRead = fread(bloom.bf,1,bloom.bytes,fileDescriptor); if(bytesRead != bloom.bytes) { fprintf(stderr,"[E] Error reading file, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } if(FLAGSKIPCHECKSUM == 0){ //calculate checksum of the current readed data sha256((uint8_t*)bloom.bf,bloom.bytes,(uint8_t*)checksum); //Compare checksums /* if(FLAGDEBUG) { hextemp = tohex((char*)checksum,32); printf("[D] Current Bloom checksum %s\n",hextemp); free(hextemp); } */ if(memcmp(checksum,bloomChecksum,32) != 0) { fprintf(stderr,"[E] Error checksum mismatch, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } } /* if(FLAGDEBUG) { hextemp = tohex((char*)bloom.bf,32); printf("[D] first 32 bytes of the bloom : %s\n",hextemp); bloom_print(&bloom); printf("[D] bloom.bf points to %p\n",bloom.bf); } */ bytesRead = fread(dataChecksum,1,32,fileDescriptor); if(bytesRead != 32) { fprintf(stderr,"[E] Errore reading file, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } bytesRead = fread(&dataSize,1,sizeof(uint64_t),fileDescriptor); if(bytesRead != sizeof(uint64_t)) { fprintf(stderr,"[E] Errore reading file, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } N = dataSize / sizeof(struct address_value); printf("[+] Allocating memory for %" PRIu64 " elements: %.2f MB\n",N,(double)(((double) sizeof(struct address_value)*N)/(double)1048576)); addressTable = (struct address_value*) malloc(dataSize); if(addressTable == NULL) { fprintf(stderr,"[E] Error allocating memory, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } bytesRead = fread(addressTable,1,dataSize,fileDescriptor); if(bytesRead != dataSize) { fprintf(stderr,"[E] Error reading file, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } if(FLAGSKIPCHECKSUM == 0) { sha256((uint8_t*)addressTable,dataSize,(uint8_t*)checksum); if(memcmp(checksum,dataChecksum,32) != 0) { fprintf(stderr,"[E] Error checksum mismatch, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); return false; } } //printf("[D] bloom.bf points to %p\n",bloom.bf); FLAGREADEDFILE1 = 1; /* We mark the file as readed*/ fclose(fileDescriptor); MAXLENGTHADDRESS = sizeof(struct address_value); } } if(FLAGVANITY) { processOneVanity(); } if(!FLAGREADEDFILE1) { /* if the data_ file doesn't exist we need read it first: */ switch(FLAGMODE) { case MODE_ADDRESS: if(FLAGCRYPTO == CRYPTO_BTC) { return forceReadFileAddress(fileName); } if(FLAGCRYPTO == CRYPTO_ETH) { return forceReadFileAddressEth(fileName); } break; case MODE_MINIKEYS: case MODE_RMD160: return forceReadFileAddress(fileName); break; case MODE_XPOINT: return forceReadFileXPoint(fileName); break; default: return false; break; } } return true; } bool forceReadFileAddress(char *fileName) { /* Here we read the original file as usual */ FILE *fileDescriptor; bool validAddress; uint64_t numberItems,i; size_t r,raw_value_length; uint8_t rawvalue[50]; char aux[100],*hextemp; fileDescriptor = fopen(fileName,"r"); if(fileDescriptor == NULL) { fprintf(stderr,"[E] Error opening the file %s, line %i\n",fileName,__LINE__ - 2); return false; } /*Count lines in the file*/ numberItems = 0; while(!feof(fileDescriptor)) { hextemp = fgets(aux,100,fileDescriptor); trim(aux," \t\n\r"); if(hextemp == aux) { r = strlen(aux); if(r > 20) { numberItems++; } } } fseek(fileDescriptor,0,SEEK_SET); MAXLENGTHADDRESS = 20; /*20 bytes beacuase we only need the data in binary*/ printf("[+] Allocating memory for %" PRIu64 " elements: %.2f MB\n",numberItems,(double)(((double) sizeof(struct address_value)*numberItems)/(double)1048576)); addressTable = (struct address_value*) malloc(sizeof(struct address_value)*numberItems); checkpointer((void *)addressTable,__FILE__,"malloc","addressTable" ,__LINE__ -1 ); if(!initBloomFilter(&bloom,numberItems)) return false; i = 0; while(i < numberItems) { validAddress = false; memset(aux,0,100); memset(addressTable[i].value,0,sizeof(struct address_value)); hextemp = fgets(aux,100,fileDescriptor); trim(aux," \t\n\r"); r = strlen(aux); if(r > 0 && r <= 40) { if(r<40 && isValidBase58String(aux)) { //Address raw_value_length = 25; b58tobin(rawvalue,&raw_value_length,aux,r); if(raw_value_length == 25) { //hextemp = tohex((char*)rawvalue+1,20); bloom_add(&bloom, rawvalue+1 ,sizeof(struct address_value)); memcpy(addressTable[i].value,rawvalue+1,sizeof(struct address_value)); i++; validAddress = true; } } if(r == 40 && isValidHex(aux)) { //RMD hexs2bin(aux,rawvalue); bloom_add(&bloom, rawvalue ,sizeof(struct address_value)); memcpy(addressTable[i].value,rawvalue,sizeof(struct address_value)); i++; validAddress = true; } } if(!validAddress) { fprintf(stderr,"[I] Ommiting invalid line %s\n",aux); numberItems--; } } N = numberItems; return true; } bool forceReadFileAddressEth(char *fileName) { /* Here we read the original file as usual */ FILE *fileDescriptor; bool validAddress; uint64_t numberItems,i; size_t r; uint8_t rawvalue[50]; char aux[100],*hextemp; fileDescriptor = fopen(fileName,"r"); if(fileDescriptor == NULL) { fprintf(stderr,"[E] Error opening the file %s, line %i\n",fileName,__LINE__ - 2); return false; } /*Count lines in the file*/ numberItems = 0; while(!feof(fileDescriptor)) { hextemp = fgets(aux,100,fileDescriptor); trim(aux," \t\n\r"); if(hextemp == aux) { r = strlen(aux); if(r >= 40) { numberItems++; } } } fseek(fileDescriptor,0,SEEK_SET); MAXLENGTHADDRESS = 20; /*20 bytes beacuase we only need the data in binary*/ N = numberItems; printf("[+] Allocating memory for %" PRIu64 " elements: %.2f MB\n",numberItems,(double)(((double) sizeof(struct address_value)*numberItems)/(double)1048576)); addressTable = (struct address_value*) malloc(sizeof(struct address_value)*numberItems); checkpointer((void *)addressTable,__FILE__,"malloc","addressTable" ,__LINE__ -1 ); if(!initBloomFilter(&bloom,N)) return false; i = 0; while(i < numberItems) { validAddress = false; memset(aux,0,100); memset(addressTable[i].value,0,sizeof(struct address_value)); hextemp = fgets(aux,100,fileDescriptor); trim(aux," \t\n\r"); r = strlen(aux); if(r >= 40 && r <= 42){ switch(r) { case 40: if(isValidHex(aux)){ hexs2bin(aux,rawvalue); bloom_add(&bloom, rawvalue ,sizeof(struct address_value)); memcpy(addressTable[i].value,rawvalue,sizeof(struct address_value)); i++; validAddress = true; } break; case 42: if(isValidHex(aux+2)){ hexs2bin(aux+2,rawvalue); bloom_add(&bloom, rawvalue ,sizeof(struct address_value)); memcpy(addressTable[i].value,rawvalue,sizeof(struct address_value)); i++; validAddress = true; } break; } } if(!validAddress) { fprintf(stderr,"[I] Ommiting invalid line %s\n",aux); numberItems--; } } fclose(fileDescriptor); return true; } bool forceReadFileXPoint(char *fileName) { /* Here we read the original file as usual */ FILE *fileDescriptor; uint64_t numberItems,i; size_t r,lenaux; uint8_t rawvalue[100]; char aux[1000],*hextemp; Tokenizer tokenizer_xpoint; //tokenizer fileDescriptor = fopen(fileName,"r"); if(fileDescriptor == NULL) { fprintf(stderr,"[E] Error opening the file %s, line %i\n",fileName,__LINE__ - 2); return false; } /*Count lines in the file*/ numberItems = 0; while(!feof(fileDescriptor)) { hextemp = fgets(aux,1000,fileDescriptor); trim(aux," \t\n\r"); if(hextemp == aux) { r = strlen(aux); if(r >= 40) { numberItems++; } } } fseek(fileDescriptor,0,SEEK_SET); MAXLENGTHADDRESS = 20; /*20 bytes beacuase we only need the data in binary*/ printf("[+] Allocating memory for %" PRIu64 " elements: %.2f MB\n",numberItems,(double)(((double) sizeof(struct address_value)*numberItems)/(double)1048576)); addressTable = (struct address_value*) malloc(sizeof(struct address_value)*numberItems); checkpointer((void *)addressTable,__FILE__,"malloc","addressTable" ,__LINE__ - 1); N = numberItems; if(!initBloomFilter(&bloom,N)) return false; i= 0; while(i < N) { memset(aux,0,1000); hextemp = fgets(aux,1000,fileDescriptor); memset((void *)&addressTable[i],0,sizeof(struct address_value)); if(hextemp == aux) { trim(aux," \t\n\r"); stringtokenizer(aux,&tokenizer_xpoint); hextemp = nextToken(&tokenizer_xpoint); lenaux = strlen(hextemp); if(isValidHex(hextemp)) { switch(lenaux) { case 64: /*X value*/ r = hexs2bin(aux,(uint8_t*) rawvalue); if(r) { memcpy(addressTable[i].value,rawvalue,20); bloom_add(&bloom,rawvalue,MAXLENGTHADDRESS); } else { fprintf(stderr,"[E] error hexs2bin\n"); } break; case 66: /*Compress publickey*/ r = hexs2bin(aux+2, (uint8_t*)rawvalue); if(r) { memcpy(addressTable[i].value,rawvalue,20); bloom_add(&bloom,rawvalue,MAXLENGTHADDRESS); } else { fprintf(stderr,"[E] error hexs2bin\n"); } break; case 130: /* Uncompress publickey length*/ r = hexs2bin(aux, (uint8_t*) rawvalue); if(r) { memcpy(addressTable[i].value,rawvalue+2,20); bloom_add(&bloom,rawvalue,MAXLENGTHADDRESS); } else { fprintf(stderr,"[E] error hexs2bin\n"); } break; default: fprintf(stderr,"[E] Omiting line unknow length size %li: %s\n",lenaux,aux); break; } } else { fprintf(stderr,"[E] Ignoring invalid hexvalue %s\n",aux); } freetokenizer(&tokenizer_xpoint); } else { fprintf(stderr,"[E] Omiting line : %s\n",aux); N--; } i++; } fclose(fileDescriptor); return true; } /* I write this as a function because i have the same segment of code in 3 different functions */ bool initBloomFilter(struct bloom *bloom_arg,uint64_t items_bloom) { bool r = true; printf("[+] Bloom filter for %" PRIu64 " elements.\n",items_bloom); if(items_bloom <= 10000) { if(bloom_init2(bloom_arg,10000,0.000001) == 1){ fprintf(stderr,"[E] error bloom_init for 10000 elements.\n"); r = false; } } else { if(bloom_init2(bloom_arg,FLAGBLOOMMULTIPLIER*items_bloom,0.000001) == 1){ fprintf(stderr,"[E] error bloom_init for %" PRIu64 " elements.\n",items_bloom); r = false; } } printf("[+] Loading data to the bloomfilter total: %.2f MB\n",(double)(((double) bloom_arg->bytes)/(double)1048576)); return r; } void writeFileIfNeeded(const char *fileName) { //printf("[D] FLAGSAVEREADFILE %i, FLAGREADEDFILE1 %i\n",FLAGSAVEREADFILE,FLAGREADEDFILE1); if(FLAGSAVEREADFILE && !FLAGREADEDFILE1) { FILE *fileDescriptor; char fileBloomName[30]; uint8_t checksum[32],hexPrefix[9]; char dataChecksum[32],bloomChecksum[32]; size_t bytesWrite; uint64_t dataSize; if(!sha256_file((const char*)fileName,checksum)){ fprintf(stderr,"[E] sha256_file error line %i\n",__LINE__ - 1); exit(EXIT_FAILURE); } tohex_dst((char*)checksum,4,(char*)hexPrefix); // we save the prefix (last fourt bytes) hexadecimal value snprintf(fileBloomName,30,"data_%s.dat",hexPrefix); fileDescriptor = fopen(fileBloomName,"wb"); dataSize = N * (sizeof(struct address_value)); printf("[D] size data %li\n",dataSize); if(fileDescriptor != NULL) { printf("[+] Writing file %s ",fileBloomName); //calculate bloom checksum //write bloom checksum (expected value to be checked) //write bloom filter structure //write bloom filter data //calculate dataChecksum //write data checksum (expected value to be checked) //write data size //write data sha256((uint8_t*)bloom.bf,bloom.bytes,(uint8_t*)bloomChecksum); printf("."); bytesWrite = fwrite(bloomChecksum,1,32,fileDescriptor); if(bytesWrite != 32) { fprintf(stderr,"[E] Errore writing file, code line %i\n",__LINE__ - 2); exit(EXIT_FAILURE); } printf("."); bytesWrite = fwrite(&bloom,1,sizeof(struct bloom),fileDescriptor); if(bytesWrite != sizeof(struct bloom)) { fprintf(stderr,"[E] Error writing file, code line %i\n",__LINE__ - 2); exit(EXIT_FAILURE); } printf("."); bytesWrite = fwrite(bloom.bf,1,bloom.bytes,fileDescriptor); if(bytesWrite != bloom.bytes) { fprintf(stderr,"[E] Error writing file, code line %i\n",__LINE__ - 2); fclose(fileDescriptor); exit(EXIT_FAILURE); } printf("."); /* if(FLAGDEBUG) { hextemp = tohex((char*)bloom.bf,32); printf("\n[D] first 32 bytes bloom : %s\n",hextemp); bloom_print(&bloom); free(hextemp); } */ sha256((uint8_t*)addressTable,dataSize,(uint8_t*)dataChecksum); printf("."); bytesWrite = fwrite(dataChecksum,1,32,fileDescriptor); if(bytesWrite != 32) { fprintf(stderr,"[E] Errore writing file, code line %i\n",__LINE__ - 2); exit(EXIT_FAILURE); } printf("."); bytesWrite = fwrite(&dataSize,1,sizeof(uint64_t),fileDescriptor); if(bytesWrite != sizeof(uint64_t)) { fprintf(stderr,"[E] Errore writing file, code line %i\n",__LINE__ - 2); exit(EXIT_FAILURE); } printf("."); bytesWrite = fwrite(addressTable,1,dataSize,fileDescriptor); if(bytesWrite != dataSize) { fprintf(stderr,"[E] Error writing file, code line %i\n",__LINE__ - 2); exit(EXIT_FAILURE); } printf("."); FLAGREADEDFILE1 = 1; fclose(fileDescriptor); printf("\n"); } } } void calcualteindex(int i,Int *key) { if(i == 0) { key->Set(&BSGS_M3); } else { key->SetInt32(i); key->Mult(&BSGS_M3_double); key->Add(&BSGS_M3); } }