Keyhunt: Bitcoin Key Search Tool
Keyhunt: Bitcoin Key Search Tool
Develop by Alberto
email: [email protected]
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <vector>
#include <inttypes.h>
#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"
#ifdef __unix__
#ifdef __CYGWIN__
#else
#include <linux/random.h>
#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
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;
};
std::vector<Point> Gn;
Point _2Gn;
std::vector<Point> GSn;
Point _2GSn;
void menu();
void init_generator();
int THREADOUTPUT = 0;
char *bit_range_str_min;
char *bit_range_str_max;
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;
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;
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<Point> 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;
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;
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;
std::vector<Point> BSGS_AMP2;
std::vector<Point> 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;
srand(time(NULL));
}
}
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(FLAGFILE == 0) {
fileName =(char*) default_fileName;
}
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(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);
}
else { //Default N
BSGS_N.SetInt64((uint64_t)0x100000000000);
}
BSGS_AUX.Set(&BSGS_M);
BSGS_AUX.Mod(&BSGS_GROUP_SIZE);
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);
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);
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);
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;
}
#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));
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;
g = secp->DoubleDirect(g);
GSn[1] = g;
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();
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();
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
}
}
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;
}
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;
}
memset(bPload_threads_available,1,NTHREADS);
do {
for(j = 0; j < NTHREADS && !salir; j++) {
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;
}
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);
}
memset(bPload_threads_available,1,NTHREADS);
do {
for(j = 0; j < NTHREADS && !salir; j++) {
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");
}
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);
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;
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 <NTHREADS && check_flag; j++) {
check_flag &= ends[j];
}
if(check_flag) {
continue_flag = 0;
}
if(OUTPUTSECONDS.IsGreater(&ZERO) ){
MPZAUX.Set(&seconds);
MPZAUX.Mod(&OUTPUTSECONDS);
if(MPZAUX.IsZero()) {
total.SetInt32(0);
for(j = 0; j < NTHREADS; j++) {
pretotal.Set(&debugcount_mpz);
pretotal.Mult(steps[j]);
total.Add(&pretotal);
}
if(FLAGENDOMORPHISM) {
if(FLAGMODE == MODE_XPOINT) {
total.Mult(3);
}
else {
total.Mult(6);
}
}
else {
if(FLAGSEARCH == SEARCH_COMPRESS) {
total.Mult(2);
}
}
#ifdef _WIN64
WaitForSingleObject(bsgs_thread, INFINITE);
#else
pthread_mutex_lock(&bsgs_thread);
#endif
pretotal.Set(&total);
pretotal.Div(&seconds);
str_seconds = seconds.GetBase10();
str_pretotal = pretotal.GetBase10();
str_total = total.GetBase10();
if(pretotal.IsLower(&int_limits[0])) {
if(FLAGMATRIX) {
sprintf(buffer,"[+] Total %s keys in %s
seconds: %s keys/s\n",str_total,str_seconds,str_pretotal);
}
else {
sprintf(buffer,"\r[+] Total %s keys in %s
seconds: %s keys/s\r",str_total,str_seconds,str_pretotal);
}
}
else {
i = 0;
salir = 0;
while( i < 6 && !salir) {
if(pretotal.IsLower(&int_limits[i+1])) {
salir = 1;
}
else {
i++;
}
}
div_pretotal.Set(&pretotal);
div_pretotal.Div(&int_limits[salir ? i : i-1]);
str_divpretotal = div_pretotal.GetBase10();
if(FLAGMATRIX) {
sprintf(buffer,"[+] Total %s keys in %s
seconds: ~%s %s (%s keys/s)\
n",str_total,str_seconds,str_divpretotal,str_limits_prefixs[salir ? i : i-
1],str_pretotal);
}
else {
if(THREADOUTPUT == 1) {
sprintf(buffer,"\r[+] Total %s keys in %s
seconds: ~%s %s (%s keys/s)\
r",str_total,str_seconds,str_divpretotal,str_limits_prefixs[salir ? i : i-
1],str_pretotal);
}
else {
sprintf(buffer,"\r[+] Total %s keys in %s
seconds: ~%s %s (%s keys/s)\
r",str_total,str_seconds,str_divpretotal,str_limits_prefixs[salir ? i : i-
1],str_pretotal);
}
}
free(str_divpretotal);
}
printf("%s",buffer);
fflush(stdout);
THREADOUTPUT = 0;
#ifdef _WIN64
ReleaseMutex(bsgs_thread);
#else
pthread_mutex_unlock(&bsgs_thread);
#endif
free(str_seconds);
free(str_pretotal);
free(str_total);
}
}
}while(continue_flag);
printf("\nEnd\n");
#ifdef _WIN64
CloseHandle(write_keys);
CloseHandle(write_random);
CloseHandle(bsgs_thread);
#endif
}
}
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]);
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]);
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;
}
char publickeyhashrmd160[20];
char publickeyhashrmd160_uncompress[4][20];
char rawvalue[32];
char publickeyhashrmd160_endomorphism[12][4][20];
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);
pts[CPU_GRP_SIZE / 2] = startP;
// P = startP + i*G
dy.ModSub(&Gn[i].y,&pp.y);
_s.ModMulK1(&dy,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&Gn[i].x); // rx = pow2(s) -
p1.x - p2.x;
if(calculate_y) {
pp.y.ModSub(&Gn[i].x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&Gn[i].y); // ry = - p2.y
- s*(ret.x-p2.x);
}
_s.ModMulK1(&dyn,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&Gn[i].x); // rx = pow2(s) -
p1.x - p2.x;
if(calculate_y) {
pn.y.ModSub(&Gn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&Gn[i].y); // ry = - p2.y
- s*(ret.x-p2.x);
}
pts[pp_offset] = pp;
pts[pn_offset] = pn;
if(FLAGENDOMORPHISM) {
/*
Q = (x,y)
For any point Q
Q*lambda = (x*beta mod p ,y)
Q*lambda is a Scalar Multiplication
x*beta is just a Multiplication (Very
fast)
*/
if( calculate_y ) {
endomorphism_beta[pp_offset].y.Set(&pp.y);
endomorphism_beta[pn_offset].y.Set(&pn.y);
endomorphism_beta2[pp_offset].y.Set(&pp.y);
endomorphism_beta2[pn_offset].y.Set(&pn.y);
}
endomorphism_beta[pp_offset].x.ModMulK1(&pp.x,
&beta);
endomorphism_beta[pn_offset].x.ModMulK1(&pn.x,
&beta);
endomorphism_beta2[pp_offset].x.ModMulK1(&pp.x,
&beta2);
endomorphism_beta2[pn_offset].x.ModMulK1(&pn.x,
&beta2);
}
}
/*
Half point for endomorphism because
pts[CPU_GRP_SIZE / 2] was not calcualte in the previous cycle
*/
if(FLAGENDOMORPHISM) {
if( calculate_y ) {
endomorphism_beta[CPU_GRP_SIZE /
2].y.Set(&pts[CPU_GRP_SIZE / 2].y);
endomorphism_beta2[CPU_GRP_SIZE /
2].y.Set(&pts[CPU_GRP_SIZE / 2].y);
}
endomorphism_beta[CPU_GRP_SIZE /
2].x.ModMulK1(&pts[CPU_GRP_SIZE / 2].x, &beta);
endomorphism_beta2[CPU_GRP_SIZE /
2].x.ModMulK1(&pts[CPU_GRP_SIZE / 2].x, &beta2);
}
_s.ModMulK1(&dyn,&dx[i]);
_p.ModSquareK1(&_s);
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&Gn[i].x);
if(calculate_y) {
pn.y.ModSub(&Gn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&Gn[i].y);
}
pts[0] = pn;
/*
First point for endomorphism because pts[0] was not
calcualte previously
*/
if(FLAGENDOMORPHISM) {
if( calculate_y ) {
endomorphism_beta[0].y.Set(&pn.y);
endomorphism_beta2[0].y.Set(&pn.y);
}
endomorphism_beta[0].x.ModMulK1(&pn.x, &beta);
endomorphism_beta2[0].x.ModMulK1(&pn.x, &beta2);
}
if(FLAGSEARCH == SEARCH_COMPRESS ||
FLAGSEARCH == SEARCH_BOTH ){
if(FLAGENDOMORPHISM) {
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]);
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]);
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]);
}
}
}
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) {
keyfound.SetInt32(k);
keyfound.Mult(&stride);
keyfound.Add(&key_mpz);
publickey = secp->ComputePublicKey(&keyfound);
switch(l) {
keyfound.Neg();
keyfound.Add(&secp->order);
break;
keyfound.Neg();
keyfound.Add(&secp->order);
break;
case 2: //Beta point, prefix 02
keyfound.ModMulK1order(&lambda);
keyfound.Neg();
keyfound.Add(&secp->order);
break;
keyfound.ModMulK1order(&lambda);
keyfound.Neg();
keyfound.Add(&secp->order);
break;
keyfound.ModMulK1order(&lambda2);
keyfound.Neg();
keyfound.Add(&secp->order);
break;
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);
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);
}
}
keyfound.SetInt32(k);
keyfound.Mult(&stride);
keyfound.Add(&key_mpz);
keyfound.ModMulK1order(&lambda);
writekey(false,&keyfound);
}
}
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]++;
_s.ModMulK1(&dy,&dx[i + 1]);
_p.ModSquareK1(&_s);
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&_2Gn.x);
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(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);
pts[CPU_GRP_SIZE / 2] = startP;
// P = startP + i*G
dy.ModSub(&Gn[i].y,&pp.y);
_s.ModMulK1(&dy,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&Gn[i].x); // rx = pow2(s) -
p1.x - p2.x;
if(calculate_y) {
pp.y.ModSub(&Gn[i].x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&Gn[i].y); // ry = - p2.y
- s*(ret.x-p2.x);
}
_s.ModMulK1(&dyn,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&Gn[i].x); // rx = pow2(s) -
p1.x - p2.x;
if( calculate_y ) {
pn.y.ModSub(&Gn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&Gn[i].y); // ry = - p2.y
- s*(ret.x-p2.x);
}
pp_offset = CPU_GRP_SIZE / 2 + (i + 1);
pn_offset = CPU_GRP_SIZE / 2 - (i + 1);
pts[pp_offset] = pp;
pts[pn_offset] = pn;
if(FLAGENDOMORPHISM) {
/*
Q = (x,y)
For any point Q
Q*lambda = (x*beta mod p ,y)
Q*lambda is a Scalar Multiplication
x*beta is just a Multiplication (Very
fast)
*/
if( calculate_y ) {
endomorphism_beta[pp_offset].y.Set(&pp.y);
endomorphism_beta[pn_offset].y.Set(&pn.y);
endomorphism_beta2[pp_offset].y.Set(&pp.y);
endomorphism_beta2[pn_offset].y.Set(&pn.y);
}
endomorphism_beta[pp_offset].x.ModMulK1(&pp.x,
&beta);
endomorphism_beta[pn_offset].x.ModMulK1(&pn.x,
&beta);
endomorphism_beta2[pp_offset].x.ModMulK1(&pp.x,
&beta2);
endomorphism_beta2[pn_offset].x.ModMulK1(&pn.x,
&beta2);
}
}
/*
Half point for endomorphism because
pts[CPU_GRP_SIZE / 2] was not calcualte in the previous cycle
*/
if(FLAGENDOMORPHISM) {
if( calculate_y ) {
endomorphism_beta[CPU_GRP_SIZE /
2].y.Set(&pts[CPU_GRP_SIZE / 2].y);
endomorphism_beta2[CPU_GRP_SIZE /
2].y.Set(&pts[CPU_GRP_SIZE / 2].y);
}
endomorphism_beta[CPU_GRP_SIZE /
2].x.ModMulK1(&pts[CPU_GRP_SIZE / 2].x, &beta);
endomorphism_beta2[CPU_GRP_SIZE /
2].x.ModMulK1(&pts[CPU_GRP_SIZE / 2].x, &beta2);
}
_s.ModMulK1(&dyn,&dx[i]);
_p.ModSquareK1(&_s);
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&Gn[i].x);
if(calculate_y ) {
pn.y.ModSub(&Gn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&Gn[i].y);
}
pts[0] = pn;
/*
First point for endomorphism because pts[0] was not
calcualte previously
*/
if(FLAGENDOMORPHISM) {
if( calculate_y ) {
endomorphism_beta[0].y.Set(&pn.y);
endomorphism_beta2[0].y.Set(&pn.y);
}
endomorphism_beta[0].x.ModMulK1(&pn.x, &beta);
endomorphism_beta2[0].x.ModMulK1(&pn.x, &beta2);
}
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(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
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
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);
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);
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);
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);
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]++;
_s.ModMulK1(&dy,&dx[i + 1]);
_p.ModSquareK1(&_s);
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&_2Gn.x);
/* 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;
}
}
// 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];
// Other variables
int hLength = (CPU_GRP_SIZE / 2 - 1);
grp->Set(dx);
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
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; i<hLength; i++) {
pp = startP;
pn = startP;
// P = startP + i*G
dy.ModSub(&GSn[i].y,&pp.y);
_s.ModMulK1(&dy,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pp.y.ModSub(&GSn[i].x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
// P = startP - i*G , if (x,y) = i*G then (x,-
y) = -i*G
dyn.Set(&GSn[i].y);
dyn.ModNeg();
dyn.ModSub(&pn.y);
_s.ModMulK1(&dyn,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]);
_p.ModSquareK1(&_s);
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x);
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y);
#endif
pts[0] = pn;
for(int i = 0; i<CPU_GRP_SIZE && bsgs_found[k]== 0;
i++) {
pts[i].x.Get32Bytes((unsigned
char*)xpoint_raw);
r = bloom_check(&bloom_bP[((unsigned
char)xpoint_raw[0])],xpoint_raw,32);
if(r) {
r = bsgs_secondcheck(&base_key,((j*1024)
+ i),k,&keyfound);
if(r) {
hextemp = keyfound.GetBase16();
printf("[+] Thread Key found
privkey %s \n",hextemp);
point_found = secp-
>ComputePublicKey(&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;
}
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;
Int dy;
Int dyn;
Int _s;
Int _p;
Int km,intaux;
Point pp;
Point pn;
grp->Set(dx);
intaux.Set(&BSGS_M_double);
intaux.Mult(CPU_GRP_SIZE/2);
intaux.Add(&BSGS_M);
do {
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);
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;
pp = startP;
pn = startP;
// P = startP + i*G
dy.ModSub(&GSn[i].y,&pp.y);
_s.ModMulK1(&dy,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pp.y.ModSub(&GSn[i].x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]);
_p.ModSquareK1(&_s);
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x);
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y);
#endif
pts[0] = pn;
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
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;
}
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 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]);
}
char rawvalue[32];
struct bPload *tt;
uint64_t i_counter,j,nbStep,to;
i_counter = tt->from;
km.Add((uint64_t)(CPU_GRP_SIZE / 2));
startP = secp->ComputePublicKey(&km);
grp->Set(dx);
for(uint64_t s=0;s<nbStep;s++) {
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
// 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
// P = startP + i*G
dy.ModSub(&Gn[i].y,&pp.y);
_s.ModMulK1(&dy,&dx[i]); // s = (p2.y-p1.y)*inverse(p2.x-
p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&Gn[i].x); // rx = pow2(s) - p1.x - p2.x;
#if 0
pp.y.ModSub(&Gn[i].x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&Gn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]); // s = (p2.y-p1.y)*inverse(p2.x-
p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&Gn[i].x); // rx = pow2(s) - p1.x - p2.x;
#if 0
pn.y.ModSub(&Gn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&Gn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]);
_p.ModSquareK1(&_s);
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&Gn[i].x);
#if 0
pn.y.ModSub(&Gn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&Gn[i].y);
#endif
pts[0] = pn;
for(j=0;j<CPU_GRP_SIZE;j++) {
pts[j].x.Get32Bytes((unsigned char*)rawvalue);
bloom_bP_index = (uint8_t)rawvalue[0];
/*
if(FLAGDEBUG){
tohex_dst(rawvalue,32,hexraw);
printf("%i : %s : %i\n",i_counter,hexraw,bloom_bP_index);
}
*/
if(i_counter < bsgs_m3) {
if(!FLAGREADEDFILE3) {
memcpy(bPtable[i_counter].value,rawvalue+16,BSGS_XVALUE_RAM);
bPtable[i_counter].index = i_counter;
}
if(!FLAGREADEDFILE4) {
#if defined(_WIN64) && !defined(__CYGWIN__)
WaitForSingleObject(bloom_bPx3rd_mutex[bloom_bP_index], INFINITE);
bloom_add(&bloom_bPx3rd[bloom_bP_index], rawvalue,
BSGS_BUFFERXPOINTLENGTH);
ReleaseMutex(bloom_bPx3rd_mutex[bloom_bP_index]);
#else
pthread_mutex_lock(&bloom_bPx3rd_mutex[bloom_bP_index]);
bloom_add(&bloom_bPx3rd[bloom_bP_index], rawvalue,
BSGS_BUFFERXPOINTLENGTH);
pthread_mutex_unlock(&bloom_bPx3rd_mutex[bloom_bP_index]);
#endif
}
}
if(i_counter < bsgs_m2 && !FLAGREADEDFILE2) {
#if defined(_WIN64) && !defined(__CYGWIN__)
WaitForSingleObject(bloom_bPx2nd_mutex[bloom_bP_index],
INFINITE);
bloom_add(&bloom_bPx2nd[bloom_bP_index], rawvalue,
BSGS_BUFFERXPOINTLENGTH);
ReleaseMutex(bloom_bPx2nd_mutex[bloom_bP_index]);
#else
pthread_mutex_lock(&bloom_bPx2nd_mutex[bloom_bP_index]);
bloom_add(&bloom_bPx2nd[bloom_bP_index], rawvalue,
BSGS_BUFFERXPOINTLENGTH);
pthread_mutex_unlock(&bloom_bPx2nd_mutex[bloom_bP_index]);
#endif
}
if(i_counter < to && !FLAGREADEDFILE1 ) {
#if defined(_WIN64) && !defined(__CYGWIN__)
WaitForSingleObject(bloom_bP_mutex[bloom_bP_index],
INFINITE);
bloom_add(&bloom_bP[bloom_bP_index],
rawvalue ,BSGS_BUFFERXPOINTLENGTH);
ReleaseMutex(bloom_bP_mutex[bloom_bP_index);
#else
pthread_mutex_lock(&bloom_bP_mutex[bloom_bP_index]);
bloom_add(&bloom_bP[bloom_bP_index],
rawvalue ,BSGS_BUFFERXPOINTLENGTH);
pthread_mutex_unlock(&bloom_bP_mutex[bloom_bP_index]);
#endif
}
i_counter++;
}
// 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);
pp.y.ModSub(&_2Gn.x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&_2Gn.y);
startP = pp;
}
delete grp;
#if defined(_WIN64) && !defined(__CYGWIN__)
WaitForSingleObject(bPload_mutex[threadid], INFINITE);
tt->finished = 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;
}
i_counter = tt->from;
km.Add((uint64_t)(CPU_GRP_SIZE / 2));
startP = secp->ComputePublicKey(&km);
grp->Set(dx);
for(uint64_t s=0;s<nbStep;s++) {
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
// 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
// P = startP + i*G
dy.ModSub(&Gn[i].y,&pp.y);
_s.ModMulK1(&dy,&dx[i]); // s = (p2.y-p1.y)*inverse(p2.x-
p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&Gn[i].x); // rx = pow2(s) - p1.x - p2.x;
#if 0
pp.y.ModSub(&Gn[i].x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&Gn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]); // s = (p2.y-p1.y)*inverse(p2.x-
p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&Gn[i].x); // rx = pow2(s) - p1.x - p2.x;
#if 0
pn.y.ModSub(&Gn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&Gn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]);
_p.ModSquareK1(&_s);
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&Gn[i].x);
#if 0
pn.y.ModSub(&Gn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&Gn[i].y);
#endif
pts[0] = pn;
for(j=0;j<CPU_GRP_SIZE;j++) {
pts[j].x.Get32Bytes((unsigned char*)rawvalue);
bloom_bP_index = (uint8_t)rawvalue[0];
if(i_counter < bsgs_m3) {
if(!FLAGREADEDFILE3) {
memcpy(bPtable[i_counter].value,rawvalue+16,BSGS_XVALUE_RAM);
bPtable[i_counter].index = i_counter;
}
if(!FLAGREADEDFILE4) {
#if defined(_WIN64) && !defined(__CYGWIN__)
WaitForSingleObject(bloom_bPx3rd_mutex[bloom_bP_index], INFINITE);
bloom_add(&bloom_bPx3rd[bloom_bP_index], rawvalue,
BSGS_BUFFERXPOINTLENGTH);
ReleaseMutex(bloom_bPx3rd_mutex[bloom_bP_index]);
#else
pthread_mutex_lock(&bloom_bPx3rd_mutex[bloom_bP_index]);
bloom_add(&bloom_bPx3rd[bloom_bP_index], rawvalue,
BSGS_BUFFERXPOINTLENGTH);
pthread_mutex_unlock(&bloom_bPx3rd_mutex[bloom_bP_index]);
#endif
}
}
if(i_counter < bsgs_m2 && !FLAGREADEDFILE2) {
#if defined(_WIN64) && !defined(__CYGWIN__)
WaitForSingleObject(bloom_bPx2nd_mutex[bloom_bP_index], INFINITE);
bloom_add(&bloom_bPx2nd[bloom_bP_index], rawvalue,
BSGS_BUFFERXPOINTLENGTH);
ReleaseMutex(bloom_bPx2nd_mutex[bloom_bP_index]);
#else
pthread_mutex_lock(&bloom_bPx2nd_mutex[bloom_bP_index]);
bloom_add(&bloom_bPx2nd[bloom_bP_index], rawvalue,
BSGS_BUFFERXPOINTLENGTH);
pthread_mutex_unlock(&bloom_bPx2nd_mutex[bloom_bP_index]);
#endif
}
i_counter++;
}
// 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);
pp.y.ModSub(&_2Gn.x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&_2Gn.y);
startP = pp;
}
delete grp;
#if defined(_WIN64) && !defined(__CYGWIN__)
WaitForSingleObject(bPload_mutex[threadid], INFINITE);
tt->finished = 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;
}
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);
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);
int i;
// 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;
pp = startP;
pn = startP;
// P = startP + i*G
dy.ModSub(&GSn[i].y,&pp.y);
_s.ModMulK1(&dy,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pp.y.ModSub(&GSn[i].x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]);
_p.ModSquareK1(&_s);
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x);
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y);
#endif
pts[0] = pn;
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
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;
}
Int dy;
Int dyn;
Int _s;
Int _p;
Int km,intaux;
Point pp;
Point pn;
grp->Set(dx);
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(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);
// 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;
pp = startP;
pn = startP;
// P = startP + i*G
dy.ModSub(&GSn[i].y,&pp.y);
_s.ModMulK1(&dy,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pp.y.ModSub(&GSn[i].x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]); // s = (p2.y-
p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p = pow2(s)
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]);
_p.ModSquareK1(&_s);
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x);
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y);
#endif
pts[0] = pn;
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
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;
}
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);
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);
// 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;
pp = startP;
pn = startP;
// P = startP + i*G
dy.ModSub(&GSn[i].y,&pp.y);
_s.ModMulK1(&dy,&dx[i]); // s =
(p2.y-p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p =
pow2(s)
pp.x.ModNeg();
pp.x.ModAdd(&_p);
pp.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pp.y.ModSub(&GSn[i].x,&pp.x);
pp.y.ModMulK1(&_s);
pp.y.ModSub(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]); // s =
(p2.y-p1.y)*inverse(p2.x-p1.x);
_p.ModSquareK1(&_s); // _p =
pow2(s)
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x); // rx =
pow2(s) - p1.x - p2.x;
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x);
#endif
_s.ModMulK1(&dyn,&dx[i]);
_p.ModSquareK1(&_s);
pn.x.ModNeg();
pn.x.ModAdd(&_p);
pn.x.ModSub(&GSn[i].x);
#if 0
pn.y.ModSub(&GSn[i].x,&pn.x);
pn.y.ModMulK1(&_s);
pn.y.ModAdd(&GSn[i].y);
#endif
pts[0] = pn;
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
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;
}
*/
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
#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 menu() {
printf("\nUsage:\n");
printf("-h show this help\n");
printf("-B Mode BSGS now have some modes <sequential, backward, both,
random, dance>\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. <btc, eth> 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
<compress, uncompress, both> 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);
}
secp->GetHash160(P2PKH,compressed,publickey,(uint8_t*)rmdhash);
hexrmd = tohex(rmdhash,20);
rmd160toaddress_dst(rmdhash,address);
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_limi
t_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_limi
t_values_B" ,__LINE__ -1 );
checkpointer((void
*)vanity_rmd_limit_values_B[vanity_rmd_targets],__FILE__,"realloc","vanity_rmd_limi
t_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);
/*
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;
}
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 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;
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;
}
//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));
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;
}
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;
}
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;
}
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
*/
//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");
}
}
}