diff --git a/.gitignore b/.gitignore index 946406b..2542c25 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ bPfile hexcharstoraw *.bin keyhunt +bsgsd KEYFOUNDKEYFOUND.txt VANITYKEYFOUND.txt *.dat diff --git a/BSGSD.md b/BSGSD.md new file mode 100644 index 0000000..b8ac8d7 --- /dev/null +++ b/BSGSD.md @@ -0,0 +1,103 @@ +# BSGSD + +`BSGS` method but as local `server`, final `D` stand for daemon. + +### Compilation +Same as keyhunt we need to do +```make bsgsd``` + +### Parameters + + - `-6` To skip file checksum + - `-t number` Threads Number + - `-k factor` Same K factor dor keyhunt + - `-n number` Length of the Range to scan each cycle, same as keyhunt + +bsgsd use the same keyhunt files `.blm` and `.tbl` + +### Server +This program is an small and custom server without any protocol. +By default the server only listen on `localhost` port `8080` +``` +localhost:8080 +``` +Tha main advantage of this server is that BSGS blooms and table are always on RAM +Clients need to send a single line and wait for reply + +Format of the client request: +``` + : +``` +example puzzle 63 + +``` +0365ec2994b8cc0a20d40dd69edfe55ca32a54bcbbaa6b0ddcff36049301a54579 4000000000000000:8000000000000000 +``` +The search is done Sequentialy Client need to knows more o less the time expect time to solve. + +The server only reply one single line. Client must read that line and proceed according its content, possible replies: + + - `404 Not Found` if the key wasn't in the given range + - `400 Bad Request`if there is some error on client request + - `value` hexadecimal value with the Private KEY in case of be found + +The server will close the Conection inmediatly after send that line, also in case some other error the server will close the Conection without send any error message. Client need to hadle the Conection status by his own. + +### Example + +Run the server in one terminal: +``` +./bsgsd -k 4096 -t 8 -6 +[+] Version 0.2.230519 Satoshi Quest, developed by AlbertoBSD +[+] K factor 4096 +[+] Threads : 8 +[W] Skipping checksums on files +[+] Mode BSGS secuential +[+] N = 0x100000000000 +[+] Bloom filter for 17179869184 elements : 58890.60 MB +[+] Bloom filter for 536870912 elements : 1840.33 MB +[+] Bloom filter for 16777216 elements : 57.51 MB +[+] Allocating 256.00 MB for 16777216 bP Points +[+] Reading bloom filter from file keyhunt_bsgs_4_17179869184.blm .... Done! +[+] Reading bloom filter from file keyhunt_bsgs_6_536870912.blm .... Done! +[+] Reading bP Table from file keyhunt_bsgs_2_16777216.tbl .... Done! +[+] Reading bloom filter from file keyhunt_bsgs_7_16777216.blm .... Done! +[+] Listening in 127.0.0.1:8080 +``` +Once that you see `[+] Listening in 127.0.0.1:8080` the server is ready to process client requests + +Now we can connect it in annother terminal with `netcat` as client, this server is `64 GB` ram, expected time for puzzle 63 `~8` Seconds + +command: +``` +time echo "0365ec2994b8cc0a20d40dd69edfe55ca32a54bcbbaa6b0ddcff36049301a54579 4000000000000000:8000000000000000" | nc -v localhost 8080 +``` +``` +time echo "0365ec2994b8cc0a20d40dd69edfe55ca32a54bcbbaa6b0ddcff36049301a54579 4000000000000000:8000000000000000" | nc -v localhost 8080 +localhost.localdomain [127.0.0.1] 8080 (http-alt) open +7cce5efdaccf6808 +real 0m7.551s +user 0m0.002s +sys 0m0.001s +``` +If you notice the answer from the server is `7cce5efdaccf6808` + +**Other example `404 Not Found`:** + +``` +time echo "0233709eb11e0d4439a729f21c2c443dedb727528229713f0065721ba8fa46f00e 4000000000000000:8000000000000000" | nc -v localhost 8080 +localhost.localdomain [127.0.0.1] 8080 (http-alt) open +404 Not Found +real 0m7.948s +user 0m0.003s +sys 0m0.000s +``` + +### One client at the time +To maximize the Speed of BSGS this server only attends one client at the time. +I know what are you thinking, but if you are doing 10 ranges of 63 bits, you can send only one range and the time and the program only will take 80 seconds (Based on the speed of the previous example). + +But if i do the program multi-client, and you send the 10 ranges at the same time in 10 different connections, the whole process will also take 80 seconds... so is only question of how your client send the data and manage the ranges.. + +### Client +**There is public NO client**, i think that this is fair, I already write a lot of code for free, if this server fits your needs write your on client on python or any other langue that you like. diff --git a/Makefile b/Makefile index cd71142..b5524e4 100644 --- a/Makefile +++ b/Makefile @@ -22,19 +22,40 @@ default: clean: rm keyhunt legacy: - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -flto -c oldbloom/bloom.cpp -o oldbloom.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -flto -c bloom/bloom.cpp -o bloom.o - gcc -march=native -mtune=native -Wno-unused-result -Ofast -g -ftree-vectorize -c base58/base58.c -o base58.o - gcc -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -c xxhash/xxhash.c -o xxhash.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -c util.c -o util.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -c sha3/sha3.c -o sha3.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -c sha3/keccak.c -o keccak.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -c hashing.c -o hashing.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -c gmp256k1/Int.cpp -o Int.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -c gmp256k1/Point.cpp -o Point.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -c gmp256k1/GMP256K1.cpp -o GMP256K1.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -c gmp256k1/IntMod.cpp -o IntMod.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -flto -c gmp256k1/Random.cpp -o Random.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -flto -c gmp256k1/IntGroup.cpp -o IntGroup.o - g++ -march=native -mtune=native -Wall -Wextra -Ofast -g -ftree-vectorize -o keyhunt keyhunt_legacy.cpp base58.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o GMP256K1.o IntMod.o IntGroup.o Random.o hashing.o sha3.o keccak.o -lm -lpthread -lcrypto -lgmp + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -flto -c oldbloom/bloom.cpp -o oldbloom.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -flto -c bloom/bloom.cpp -o bloom.o + gcc -march=native -mtune=native -Wno-unused-result -Ofast -ftree-vectorize -c base58/base58.c -o base58.o + gcc -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c xxhash/xxhash.c -o xxhash.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c util.c -o util.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c sha3/sha3.c -o sha3.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c sha3/keccak.c -o keccak.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c hashing.c -o hashing.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c gmp256k1/Int.cpp -o Int.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c gmp256k1/Point.cpp -o Point.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c gmp256k1/GMP256K1.cpp -o GMP256K1.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -c gmp256k1/IntMod.cpp -o IntMod.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -flto -c gmp256k1/Random.cpp -o Random.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -flto -c gmp256k1/IntGroup.cpp -o IntGroup.o + g++ -march=native -mtune=native -Wall -Wextra -Ofast -ftree-vectorize -o keyhunt keyhunt_legacy.cpp base58.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o GMP256K1.o IntMod.o IntGroup.o Random.o hashing.o sha3.o keccak.o -lm -lpthread -lcrypto -lgmp + rm -r *.o +bsgsd: + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -flto -c oldbloom/bloom.cpp -o oldbloom.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -flto -c bloom/bloom.cpp -o bloom.o + gcc -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-unused-parameter -Ofast -ftree-vectorize -c base58/base58.c -o base58.o + gcc -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c rmd160/rmd160.c -o rmd160.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c sha3/sha3.c -o sha3.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c sha3/keccak.c -o keccak.o + gcc -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c xxhash/xxhash.c -o xxhash.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c util.c -o util.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c secp256k1/Int.cpp -o Int.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c secp256k1/Point.cpp -o Point.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c secp256k1/SECP256K1.cpp -o SECP256K1.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -c secp256k1/IntMod.cpp -o IntMod.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -flto -c secp256k1/Random.cpp -o Random.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -flto -c secp256k1/IntGroup.cpp -o IntGroup.o + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -o hash/ripemd160.o -ftree-vectorize -flto -c hash/ripemd160.cpp + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -o hash/sha256.o -ftree-vectorize -flto -c hash/sha256.cpp + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -o hash/ripemd160_sse.o -ftree-vectorize -flto -c hash/ripemd160_sse.cpp + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -o hash/sha256_sse.o -ftree-vectorize -flto -c hash/sha256_sse.cpp + g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Wno-deprecated-copy -Ofast -ftree-vectorize -o bsgsd bsgsd.cpp base58.o rmd160.o hash/ripemd160.o hash/ripemd160_sse.o hash/sha256.o hash/sha256_sse.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread rm -r *.o diff --git a/bsgsd.cpp b/bsgsd.cpp new file mode 100644 index 0000000..0e1405e --- /dev/null +++ b/bsgsd.cpp @@ -0,0 +1,2642 @@ +/* +Develop by Alberto +email: albertobsd@gmail.com +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "base58/libbase58.h" +#include "rmd160/rmd160.h" +#include "oldbloom/oldbloom.h" +#include "bloom/bloom.h" +#include "sha3/sha3.h" +#include "util.h" + +#include "secp256k1/SECP256k1.h" +#include "secp256k1/Point.h" +#include "secp256k1/Int.h" +#include "secp256k1/IntGroup.h" +#include "secp256k1/Random.h" + +#include "hash/sha256.h" +#include "hash/ripemd160.h" + +#include +#include +#include +#include + +#include +#include +#include // for inet_addr() +#include // for pthread functions + +#define PORT 8080 +#define BUFFER_SIZE 1024 + + + +#define MODE_BSGS 2 + + +uint32_t THREADBPWORKLOAD = 1048576; + +struct checksumsha256 { + char data[32]; + char backup[32]; +}; + +struct bsgs_xvalue { + uint8_t value[6]; + uint64_t index; +}; + +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; +}; + + + +const char *version = "0.2.230519 Satoshi Quest"; + +#define CPU_GRP_SIZE 1024 + +std::vector Gn; +Point _2Gn; + +std::vector GSn; +Point _2GSn; + + +void menu(); +void init_generator(); + +int sendstr(int client_fd,const char *str); + +void sleep_ms(int milliseconds); + +void bsgs_sort(struct bsgs_xvalue *arr,int64_t n); +void bsgs_myheapsort(struct bsgs_xvalue *arr, int64_t n); +void bsgs_insertionsort(struct bsgs_xvalue *arr, int64_t n); +void bsgs_introsort(struct bsgs_xvalue *arr,uint32_t depthLimit, int64_t n); +void bsgs_swap(struct bsgs_xvalue *a,struct bsgs_xvalue *b); +void bsgs_heapify(struct bsgs_xvalue *arr, int64_t n, int64_t i); +int64_t bsgs_partition(struct bsgs_xvalue *arr, int64_t n); + +int bsgs_searchbinary(struct bsgs_xvalue *arr,char *data,int64_t array_length,uint64_t *r_value); +int bsgs_secondcheck(Int *start_range,uint32_t a,Int *privatekey); +int bsgs_thirdcheck(Int *start_range,uint32_t a,Int *privatekey); + + +void writekey(bool compressed,Int *key); +void checkpointer(void *ptr,const char *file,const char *function,const char *name,int line); + +void* client_handler(void* arg); + + +void calcualteindex(int i,Int *key); + +void *thread_process_bsgs(void *vargp); +void *thread_bPload(void *vargp); +void *thread_bPload_2blooms(void *vargp); + +char *publickeytohashrmd160(char *pkey,int length); +void publickeytohashrmd160_dst(char *pkey,int length,char *dst); +char *pubkeytopubaddress(char *pkey,int length); +void pubkeytopubaddress_dst(char *pkey,int length,char *dst); +void rmd160toaddress_dst(char *rmd,char *dst); + + + +int THREADOUTPUT = 0; +char *bit_range_str_min; +char *bit_range_str_max; + +const char *bsgs_modes[5] = {"secuential","backward","both","random","dance"}; + +pthread_t *tid = NULL; +pthread_mutex_t write_keys; +pthread_mutex_t write_random; +pthread_mutex_t mutex_bsgs_thread; +pthread_mutex_t *bPload_mutex; + +uint64_t FINISHED_THREADS_COUNTER = 0; +uint64_t FINISHED_THREADS_BP = 0; +uint64_t THREADCYCLES = 0; +uint64_t THREADCOUNTER = 0; +uint64_t FINISHED_ITEMS = 0; +uint64_t OLDFINISHED_ITEMS = -1; + +uint8_t byte_encode_crypto = 0x00; /* Bitcoin */ + + + +struct bloom bloom; + +uint64_t N = 0; + +uint64_t N_SECUENTIAL_MAX = 0x100000000; +uint64_t DEBUGCOUNT = 0x400; +uint64_t u64range; + + +Int BSGSkeyfound; + +int FLAGSKIPCHECKSUM = 0; +int FLAGBSGSMODE = 0; +int FLAGDEBUG = 0; +int KFACTOR = 1; +int MAXLENGTHADDRESS = 20; +int NTHREADS = 1; + +int FLAGSAVEREADFILE = 1; +int FLAGREADEDFILE1 = 0; +int FLAGREADEDFILE2 = 0; +int FLAGREADEDFILE3 = 0; +int FLAGREADEDFILE4 = 0; +int FLAGUPDATEFILE1 = 0; + + +int FLAGBITRANGE = 0; +int FLAGRANGE = 0; +int FLAGMODE = MODE_BSGS; +int FLAG_N = 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; +Point OriginalPointsBSGS; +bool OriginalPointsBSGScompressed; + +uint64_t bytes; +char checksum[32],checksum_backup[32]; +char buffer_bloom_file[1024]; +struct bsgs_xvalue *bPtable; + +struct oldbloom oldbloom_bP; + +struct bloom *bloom_bP; +struct bloom *bloom_bPx2nd; //2nd Bloom filter check +struct bloom *bloom_bPx3rd; //3rd Bloom filter check + +struct checksumsha256 *bloom_bP_checksums; +struct checksumsha256 *bloom_bPx2nd_checksums; +struct checksumsha256 *bloom_bPx3rd_checksums; + +pthread_mutex_t *bloom_bP_mutex; +pthread_mutex_t *bloom_bPx2nd_mutex; +pthread_mutex_t *bloom_bPx3rd_mutex; + + + + +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; +unsigned long int bsgs_aux; +//int32_t bsgs_point_number; + +const char *str_limits_prefixs[7] = {"Mkeys/s","Gkeys/s","Tkeys/s","Pkeys/s","Ekeys/s","Zkeys/s","Ykeys/s"}; +const char *str_limits[7] = {"1000000","1000000000","1000000000000","1000000000000000","1000000000000000000","1000000000000000000000","1000000000000000000000000"}; +Int int_limits[7]; + + + + +Int BSGS_GROUP_SIZE; +Int BSGS_CURRENT; +Int BSGS_R; +Int BSGS_AUX; +Int BSGS_N; +Int BSGS_M; //M is squareroot(N) +Int BSGS_M_double; +Int BSGS_M2; //M2 is M/32 +Int BSGS_M2_double; //M2_double is M2 * 2 + +Int BSGS_M3; //M3 is M2/32 +Int BSGS_M3_double; //M3_double is M3 * 2 + + +Int ONE; +Int ZERO; +Int MPZAUX; + +Point BSGS_P; //Original P is actually G, but this P value change over time for calculations +Point BSGS_MP; //MP values this is m * P +Point BSGS_MP2; //MP2 values this is m2 * P +Point BSGS_MP3; //MP3 values this is m3 * P + + +Point BSGS_MP_double; //MP2 values this is m2 * P * 2 +Point BSGS_MP2_double; //MP2 values this is m2 * P * 2 +Point BSGS_MP3_double; //MP3 values this is m3 * P * 2 + + +std::vector BSGS_AMP2; +std::vector BSGS_AMP3; + +Point point_temp,point_temp2; //Temp value for some process + +Int n_range_start; +Int n_range_end; +Int n_range_diff; +Int n_range_aux; + + +Secp256K1 *secp; + +int main(int argc, char **argv) { + // File pointers + FILE *fd_aux1, *fd_aux2, *fd_aux3; + + // Strings + char *hextemp = NULL; + char *bf_ptr = NULL; + char *bPload_threads_available; + + // Buffers + char rawvalue[32]; + + // 64-bit integers + uint64_t BASE, PERTHREAD_R, itemsbloom, itemsbloom2, itemsbloom3; + + // 32-bit integers + uint32_t finished; + int readed, c, salir,i,s; + + // Custom integers + Int total, pretotal, debugcount_mpz, seconds, div_pretotal, int_aux, int_r, int_q, int58; + + // Pointers + struct bPload *bPload_temp_ptr; + + // Sizes + size_t rsize; + + + pthread_mutex_init(&write_keys,NULL); + pthread_mutex_init(&write_random,NULL); + pthread_mutex_init(&mutex_bsgs_thread,NULL); + + srand(time(NULL)); + + secp = new Secp256K1(); + secp->Init(); + ZERO.SetInt32(0); + ONE.SetInt32(1); + BSGS_GROUP_SIZE.SetInt32(CPU_GRP_SIZE); + + unsigned long rseedvalue; + int bytes_read = getrandom(&rseedvalue, sizeof(unsigned long), GRND_NONBLOCK); + if(bytes_read > 0) { + rseed(rseedvalue); + /* + In any case that seed is for a failsafe RNG, the default source on linux is getrandom function + See https://www.2uo.de/myths-about-urandom/ + */ + } + else { + /* + what year is?? + WTF linux without RNG ? + */ + fprintf(stderr,"[E] Error getrandom() ?\n"); + exit(0); + rseed(clock() + time(NULL) + rand()*rand()); + } + + + + printf("[+] Version %s, developed by AlbertoBSD\n",version); + + while ((c = getopt(argc, argv, "6hk:n:t:")) != -1) { + switch(c) { + case '6': + FLAGSKIPCHECKSUM = 1; + fprintf(stderr,"[W] Skipping checksums on files\n"); + break; + case 'h': + // Show help menu + menu(); + break; + case 'k': + // Set KFACTOR + KFACTOR = (int)strtol(optarg,NULL,10); + if(KFACTOR <= 0) { + KFACTOR = 1; + } + printf("[+] K factor %i\n",KFACTOR); + break; + case 'n': + // Set FLAG_N and str_N + FLAG_N = 1; + str_N = optarg; + break; + case 't': + // Set number of threads (NTHREADS) + NTHREADS = strtol(optarg,NULL,10); + if(NTHREADS <= 0) { + NTHREADS = 1; + } + printf((NTHREADS > 1) ? "[+] Threads : %u\n": "[+] Thread : %u\n",NTHREADS); + break; + default: + // Handle unknown options + fprintf(stderr,"[E] Unknow opcion -%c\n",c); + exit(0); + break; + } + } + + + + + stride.Set(&ONE); + init_generator(); + + if(FLAGMODE == MODE_BSGS ) { + printf("[+] Mode BSGS %s\n",bsgs_modes[FLAGBSGSMODE]); + } + + + if(FLAGMODE == MODE_BSGS ) { + + BSGS_N.SetInt32(0); + BSGS_M.SetInt32(0); + + + BSGS_M.SetInt64(bsgs_m); + + + if(FLAG_N) { //Custom N by the -n param + + /* Here we need to validate if the given string is a valid hexadecimal number or a base 10 number*/ + + /* Now the conversion*/ + if(str_N[0] == '0' && (str_N[1] == 'x' || str_N[1] == 'X')) { /*We expected a hexadecimal value after 0x -> str_N +2 */ + BSGS_N.SetBase16((char*)(str_N+2)); + } + else { + BSGS_N.SetBase10(str_N); + } + + } + else { //Default N + BSGS_N.SetInt64((uint64_t)0x100000000000); + } + + if(BSGS_N.HasSqrt()) { //If the root is exact + BSGS_M.Set(&BSGS_N); + BSGS_M.ModSqrt(); + } + else { + fprintf(stderr,"[E] -n param doesn't have exact square root\n"); + exit(0); + } + + BSGS_AUX.Set(&BSGS_M); + BSGS_AUX.Mod(&BSGS_GROUP_SIZE); + + if(!BSGS_AUX.IsZero()){ //If M is not divisible by BSGS_GROUP_SIZE (1024) + hextemp = BSGS_GROUP_SIZE.GetBase10(); + fprintf(stderr,"[E] M value is not divisible by %s\n",hextemp); + exit(0); + } + + /* + M 2199023255552 + 109951162777.6 + M2 109951162778 + 5497558138.9 + M3 5497558139 + */ + + BSGS_M.Mult((uint64_t)KFACTOR); + BSGS_AUX.SetInt32(32); + BSGS_R.Set(&BSGS_M); + BSGS_R.Mod(&BSGS_AUX); + BSGS_M2.Set(&BSGS_M); + BSGS_M2.Div(&BSGS_AUX); + + if(!BSGS_R.IsZero()) { /* If BSGS_M modulo 32 is not 0*/ + BSGS_M2.AddOne(); + } + + BSGS_M_double.SetInt32(2); + BSGS_M_double.Mult(&BSGS_M); + + + BSGS_M2_double.SetInt32(2); + BSGS_M2_double.Mult(&BSGS_M2); + + BSGS_R.Set(&BSGS_M2); + BSGS_R.Mod(&BSGS_AUX); + + + + BSGS_M3.Set(&BSGS_M2); + BSGS_M3.Div(&BSGS_AUX); + + if(!BSGS_R.IsZero()) { /* If BSGS_M2 modulo 32 is not 0*/ + BSGS_M3.AddOne(); + } + + BSGS_M3_double.SetInt32(2); + BSGS_M3_double.Mult(&BSGS_M3); + + bsgs_m2 = BSGS_M2.GetInt64(); + bsgs_m3 = BSGS_M3.GetInt64(); + + BSGS_AUX.Set(&BSGS_N); + BSGS_AUX.Div(&BSGS_M); + + BSGS_R.Set(&BSGS_N); + BSGS_R.Mod(&BSGS_M); + + if(!BSGS_R.IsZero()) { /* if BSGS_N modulo BSGS_M is not 0*/ + BSGS_N.Set(&BSGS_M); + BSGS_N.Mult(&BSGS_AUX); + } + + bsgs_m = BSGS_M.GetInt64(); + bsgs_aux = BSGS_AUX.GetInt64(); + + + hextemp = BSGS_N.GetBase16(); + printf("[+] N = 0x%s\n",hextemp); + bsgs_m = BSGS_M.GetInt64(); + free(hextemp); + + + + if(((uint64_t)(bsgs_m/256)) > 10000) { + itemsbloom = (uint64_t)(bsgs_m / 256); + if(bsgs_m % 256 != 0 ) { + itemsbloom++; + } + } + else{ + itemsbloom = 1000; + } + + if(((uint64_t)(bsgs_m2/256)) > 1000) { + itemsbloom2 = (uint64_t)(bsgs_m2 / 256); + if(bsgs_m2 % 256 != 0) { + itemsbloom2++; + } + } + else { + itemsbloom2 = 1000; + } + + if(((uint64_t)(bsgs_m3/256)) > 1000) { + itemsbloom3 = (uint64_t)(bsgs_m3/256); + if(bsgs_m3 % 256 != 0 ) { + itemsbloom3++; + } + } + else { + itemsbloom3 = 1000; + } + + printf("[+] Bloom filter for %" PRIu64 " elements ",bsgs_m); + bloom_bP = (struct bloom*)calloc(256,sizeof(struct bloom)); + checkpointer((void *)bloom_bP,__FILE__,"calloc","bloom_bP" ,__LINE__ -1 ); + bloom_bP_checksums = (struct checksumsha256*)calloc(256,sizeof(struct checksumsha256)); + checkpointer((void *)bloom_bP_checksums,__FILE__,"calloc","bloom_bP_checksums" ,__LINE__ -1 ); + + bloom_bP_mutex = (pthread_mutex_t*) calloc(256,sizeof(pthread_mutex_t)); + checkpointer((void *)bloom_bP_mutex,__FILE__,"calloc","bloom_bP_mutex" ,__LINE__ -1 ); + + + fflush(stdout); + bloom_bP_totalbytes = 0; + for(i=0; i< 256; i++) { + pthread_mutex_init(&bloom_bP_mutex[i],NULL); + if(bloom_init2(&bloom_bP[i],itemsbloom,0.000001) == 1){ + fprintf(stderr,"[E] error bloom_init _ %i\n",i); + exit(0); + } + bloom_bP_totalbytes += bloom_bP[i].bytes; + } + printf(": %.2f MB\n",(float)((float)(uint64_t)bloom_bP_totalbytes/(float)(uint64_t)1048576)); + + + printf("[+] Bloom filter for %" PRIu64 " elements ",bsgs_m2); + + bloom_bPx2nd_mutex = (pthread_mutex_t*) calloc(256,sizeof(pthread_mutex_t)); + checkpointer((void *)bloom_bPx2nd_mutex,__FILE__,"calloc","bloom_bPx2nd_mutex" ,__LINE__ -1 ); + bloom_bPx2nd = (struct bloom*)calloc(256,sizeof(struct bloom)); + checkpointer((void *)bloom_bPx2nd,__FILE__,"calloc","bloom_bPx2nd" ,__LINE__ -1 ); + bloom_bPx2nd_checksums = (struct checksumsha256*) calloc(256,sizeof(struct checksumsha256)); + checkpointer((void *)bloom_bPx2nd_checksums,__FILE__,"calloc","bloom_bPx2nd_checksums" ,__LINE__ -1 ); + bloom_bP2_totalbytes = 0; + for(i=0; i< 256; i++) { + pthread_mutex_init(&bloom_bPx2nd_mutex[i],NULL); + if(bloom_init2(&bloom_bPx2nd[i],itemsbloom2,0.000001) == 1){ + fprintf(stderr,"[E] error bloom_init _ %i\n",i); + exit(0); + } + bloom_bP2_totalbytes += bloom_bPx2nd[i].bytes; + } + printf(": %.2f MB\n",(float)((float)(uint64_t)bloom_bP2_totalbytes/(float)(uint64_t)1048576)); + + + bloom_bPx3rd_mutex = (pthread_mutex_t*) calloc(256,sizeof(pthread_mutex_t)); + checkpointer((void *)bloom_bPx3rd_mutex,__FILE__,"calloc","bloom_bPx3rd_mutex" ,__LINE__ -1 ); + bloom_bPx3rd = (struct bloom*)calloc(256,sizeof(struct bloom)); + checkpointer((void *)bloom_bPx3rd,__FILE__,"calloc","bloom_bPx3rd" ,__LINE__ -1 ); + bloom_bPx3rd_checksums = (struct checksumsha256*) calloc(256,sizeof(struct checksumsha256)); + checkpointer((void *)bloom_bPx3rd_checksums,__FILE__,"calloc","bloom_bPx3rd_checksums" ,__LINE__ -1 ); + + printf("[+] Bloom filter for %" PRIu64 " elements ",bsgs_m3); + bloom_bP3_totalbytes = 0; + for(i=0; i< 256; i++) { + pthread_mutex_init(&bloom_bPx3rd_mutex[i],NULL); + if(bloom_init2(&bloom_bPx3rd[i],itemsbloom3,0.000001) == 1){ + fprintf(stderr,"[E] error bloom_init %i\n",i); + exit(0); + } + bloom_bP3_totalbytes += bloom_bPx3rd[i].bytes; + } + printf(": %.2f MB\n",(float)((float)(uint64_t)bloom_bP3_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; + + + /* New aMP table just to keep the same code of JLP */ + /* Auxiliar Points to speed up calculations for the main bloom filter check */ + + Point bsP = secp->Negation(BSGS_MP_double); + Point g = bsP; + GSn[0] = g; + + + g = secp->DoubleDirect(g); + GSn[1] = g; + + + for(int i = 2; i < CPU_GRP_SIZE / 2; i++) { + g = secp->AddDirect(g,bsP); + GSn[i] = g; + } + + /* For next center point */ + _2GSn = secp->DoubleDirect(GSn[CPU_GRP_SIZE / 2 - 1]); + + + i = 0; + point_temp.Set(BSGS_MP2); + BSGS_AMP2[0] = secp->Negation(point_temp); + BSGS_AMP2[0].Reduce(); + point_temp.Set(BSGS_MP2_double); + point_temp = secp->Negation(point_temp); + + + for(i = 1; i < 32; i++) { + BSGS_AMP2[i] = secp->AddDirect(BSGS_AMP2[i-1],point_temp); + BSGS_AMP2[i].Reduce(); + } + + i = 0; + point_temp.Set(BSGS_MP3); + BSGS_AMP3[0] = secp->Negation(point_temp); + BSGS_AMP3[0].Reduce(); + point_temp.Set(BSGS_MP3_double); + point_temp = secp->Negation(point_temp); + + for(i = 1; i < 32; i++) { + BSGS_AMP3[i] = secp->AddDirect(BSGS_AMP3[i-1],point_temp); + BSGS_AMP3[i].Reduce(); + } + + bytes = (uint64_t)bsgs_m3 * (uint64_t) sizeof(struct bsgs_xvalue); + printf("[+] Allocating %.2f MB for %" PRIu64 " bP Points\n",(double)(bytes/1048576),bsgs_m3); + + bPtable = (struct bsgs_xvalue*) malloc(bytes); + checkpointer((void *)bPtable,__FILE__,"malloc","bPtable" ,__LINE__ -1 ); + memset(bPtable,0,bytes); + + if(FLAGSAVEREADFILE) { + /*Reading file for 1st bloom filter */ + + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_4_%" PRIu64 ".blm",bsgs_m); + fd_aux1 = fopen(buffer_bloom_file,"rb"); + if(fd_aux1 != NULL) { + printf("[+] Reading bloom filter from file %s ",buffer_bloom_file); + fflush(stdout); + for(i = 0; i < 256;i++) { + bf_ptr = (char*) bloom_bP[i].bf; /*We need to save the current bf pointer*/ + readed = fread(&bloom_bP[i],sizeof(struct bloom),1,fd_aux1); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + 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(0); + } + 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(0); + } + 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(0); + } + } + 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(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + 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(0); + } + 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(0); + } + } + if(i % 32 == 0 ) { + printf("."); + fflush(stdout); + } + } + printf(" Done!\n"); + fclose(fd_aux1); + FLAGUPDATEFILE1 = 1; /* Flag to migrate the data to the new File keyhunt_bsgs_4_ */ + FLAGREADEDFILE1 = 1; + + } + else { + FLAGREADEDFILE1 = 0; + //Flag to make the new file + } + } + + /*Reading file for 2nd bloom filter */ + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_6_%" PRIu64 ".blm",bsgs_m2); + fd_aux2 = fopen(buffer_bloom_file,"rb"); + if(fd_aux2 != NULL) { + printf("[+] Reading bloom filter from file %s ",buffer_bloom_file); + fflush(stdout); + for(i = 0; i < 256;i++) { + bf_ptr = (char*) bloom_bPx2nd[i].bf; /*We need to save the current bf pointer*/ + readed = fread(&bloom_bPx2nd[i],sizeof(struct bloom),1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + bloom_bPx2nd[i].bf = (uint8_t*)bf_ptr; /* Restoring the bf pointer*/ + readed = fread(bloom_bPx2nd[i].bf,bloom_bPx2nd[i].bytes,1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + readed = fread(&bloom_bPx2nd_checksums[i],sizeof(struct checksumsha256),1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + memset(rawvalue,0,32); + if(FLAGSKIPCHECKSUM == 0) { + sha256((uint8_t*)bloom_bPx2nd[i].bf,bloom_bPx2nd[i].bytes,(uint8_t*)rawvalue); + if(memcmp(bloom_bPx2nd_checksums[i].data,rawvalue,32) != 0 || memcmp(bloom_bPx2nd_checksums[i].backup,rawvalue,32) != 0 ) { /* Verification */ + fprintf(stderr,"[E] Error checksum file mismatch! %s\n",buffer_bloom_file); + exit(0); + } + } + if(i % 64 == 0) { + printf("."); + fflush(stdout); + } + } + fclose(fd_aux2); + printf(" Done!\n"); + memset(buffer_bloom_file,0,1024); + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_5_%" PRIu64 ".blm",bsgs_m2); + fd_aux2 = fopen(buffer_bloom_file,"rb"); + if(fd_aux2 != NULL) { + printf("[W] Unused file detected %s you can delete it without worry\n",buffer_bloom_file); + fclose(fd_aux2); + } + memset(buffer_bloom_file,0,1024); + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_1_%" PRIu64 ".blm",bsgs_m2); + fd_aux2 = fopen(buffer_bloom_file,"rb"); + if(fd_aux2 != NULL) { + printf("[W] Unused file detected %s you can delete it without worry\n",buffer_bloom_file); + fclose(fd_aux2); + } + FLAGREADEDFILE2 = 1; + } + else { + FLAGREADEDFILE2 = 0; + } + + /*Reading file for bPtable */ + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_2_%" PRIu64 ".tbl",bsgs_m3); + fd_aux3 = fopen(buffer_bloom_file,"rb"); + if(fd_aux3 != NULL) { + printf("[+] Reading bP Table from file %s .",buffer_bloom_file); + fflush(stdout); + rsize = fread(bPtable,bytes,1,fd_aux3); + if(rsize != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + rsize = fread(checksum,32,1,fd_aux3); + if(FLAGSKIPCHECKSUM == 0) { + sha256((uint8_t*)bPtable,bytes,(uint8_t*)checksum_backup); + if(memcmp(checksum,checksum_backup,32) != 0) { + fprintf(stderr,"[E] Error checksum file mismatch! %s\n",buffer_bloom_file); + exit(0); + } + } + printf("... Done!\n"); + fclose(fd_aux3); + FLAGREADEDFILE3 = 1; + } + else { + FLAGREADEDFILE3 = 0; + } + + /*Reading file for 3rd bloom filter */ + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_7_%" PRIu64 ".blm",bsgs_m3); + fd_aux2 = fopen(buffer_bloom_file,"rb"); + if(fd_aux2 != NULL) { + printf("[+] Reading bloom filter from file %s ",buffer_bloom_file); + fflush(stdout); + for(i = 0; i < 256;i++) { + bf_ptr = (char*) bloom_bPx3rd[i].bf; /*We need to save the current bf pointer*/ + readed = fread(&bloom_bPx3rd[i],sizeof(struct bloom),1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + bloom_bPx3rd[i].bf = (uint8_t*)bf_ptr; /* Restoring the bf pointer*/ + readed = fread(bloom_bPx3rd[i].bf,bloom_bPx3rd[i].bytes,1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + readed = fread(&bloom_bPx3rd_checksums[i],sizeof(struct checksumsha256),1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + memset(rawvalue,0,32); + if(FLAGSKIPCHECKSUM == 0) { + sha256((uint8_t*)bloom_bPx3rd[i].bf,bloom_bPx3rd[i].bytes,(uint8_t*)rawvalue); + if(memcmp(bloom_bPx3rd_checksums[i].data,rawvalue,32) != 0 || memcmp(bloom_bPx3rd_checksums[i].backup,rawvalue,32) != 0 ) { /* Verification */ + fprintf(stderr,"[E] Error checksum file mismatch! %s\n",buffer_bloom_file); + exit(0); + } + } + if(i % 64 == 0) { + printf("."); + fflush(stdout); + } + } + fclose(fd_aux2); + printf(" Done!\n"); + FLAGREADEDFILE4 = 1; + } + else { + FLAGREADEDFILE4 = 0; + } + + } + + if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 || !FLAGREADEDFILE3 || !FLAGREADEDFILE4) { + if(FLAGREADEDFILE1 == 1) { + /* + We need just to make File 2 to File 4 this is + - Second bloom filter 5% + - third bloom fitler 0.25 % + - bp Table 0.25 % + */ + printf("[I] We need to recalculate some files, don't worry this is only 3%% of the previous work\n"); + FINISHED_THREADS_COUNTER = 0; + FINISHED_THREADS_BP = 0; + FINISHED_ITEMS = 0; + salir = 0; + BASE = 0; + THREADCOUNTER = 0; + if(THREADBPWORKLOAD >= bsgs_m2) { + THREADBPWORKLOAD = bsgs_m2; + } + THREADCYCLES = bsgs_m2 / THREADBPWORKLOAD; + PERTHREAD_R = bsgs_m2 % THREADBPWORKLOAD; + if(PERTHREAD_R != 0) { + THREADCYCLES++; + } + + printf("\r[+] processing %lu/%lu bP points : %i%%\r",FINISHED_ITEMS,bsgs_m,(int) (((double)FINISHED_ITEMS/(double)bsgs_m)*100)); + fflush(stdout); + + tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); + bPload_mutex = (pthread_mutex_t*) calloc(NTHREADS,sizeof(pthread_mutex_t)); + checkpointer((void *)bPload_mutex,__FILE__,"calloc","bPload_mutex" ,__LINE__ -1 ); + bPload_temp_ptr = (struct bPload*) calloc(NTHREADS,sizeof(struct bPload)); + checkpointer((void *)bPload_temp_ptr,__FILE__,"calloc","bPload_temp_ptr" ,__LINE__ -1 ); + bPload_threads_available = (char*) calloc(NTHREADS,sizeof(char)); + checkpointer((void *)bPload_threads_available,__FILE__,"calloc","bPload_threads_available" ,__LINE__ -1 ); + + memset(bPload_threads_available,1,NTHREADS); + + for(i = 0; i < NTHREADS; i++) { + pthread_mutex_init(&bPload_mutex[i],NULL); + } + + do { + for(i = 0; i < NTHREADS && !salir; i++) { + + if(bPload_threads_available[i] && !salir) { + bPload_threads_available[i] = 0; + bPload_temp_ptr[i].from = BASE; + bPload_temp_ptr[i].threadid = i; + bPload_temp_ptr[i].finished = 0; + if( THREADCOUNTER < THREADCYCLES-1) { + bPload_temp_ptr[i].to = BASE + THREADBPWORKLOAD; + bPload_temp_ptr[i].workload = THREADBPWORKLOAD; + } + else { + bPload_temp_ptr[i].to = BASE + THREADBPWORKLOAD + PERTHREAD_R; + bPload_temp_ptr[i].workload = THREADBPWORKLOAD + PERTHREAD_R; + salir = 1; + } + s = pthread_create(&tid[i],NULL,thread_bPload_2blooms,(void*) &bPload_temp_ptr[i]); + if(s != 0){ + printf("Thread creation failed. Error code: %d\n", s); + exit(EXIT_FAILURE); + } + pthread_detach(tid[i]); + BASE+=THREADBPWORKLOAD; + THREADCOUNTER++; + } + } + + if(OLDFINISHED_ITEMS != FINISHED_ITEMS) { + printf("\r[+] processing %lu/%lu bP points : %i%%\r",FINISHED_ITEMS,bsgs_m2,(int) (((double)FINISHED_ITEMS/(double)bsgs_m2)*100)); + fflush(stdout); + OLDFINISHED_ITEMS = FINISHED_ITEMS; + } + + for(i = 0 ; i < NTHREADS ; i++) { + + pthread_mutex_lock(&bPload_mutex[i]); + finished = bPload_temp_ptr[i].finished; + pthread_mutex_unlock(&bPload_mutex[i]); + if(finished) { + bPload_temp_ptr[i].finished = 0; + bPload_threads_available[i] = 1; + FINISHED_ITEMS += bPload_temp_ptr[i].workload; + FINISHED_THREADS_COUNTER++; + } + } + + }while(FINISHED_THREADS_COUNTER < THREADCYCLES); + printf("\r[+] processing %lu/%lu bP points : 100%% \n",bsgs_m2,bsgs_m2); + + free(tid); + free(bPload_mutex); + free(bPload_temp_ptr); + free(bPload_threads_available); + } + else{ + /* We need just to do all the files + - first bllom filter 100% + - Second bloom filter 5% + - third bloom fitler 0.25 % + - bp Table 0.25 % + */ + FINISHED_THREADS_COUNTER = 0; + FINISHED_THREADS_BP = 0; + FINISHED_ITEMS = 0; + salir = 0; + BASE = 0; + THREADCOUNTER = 0; + if(THREADBPWORKLOAD >= bsgs_m) { + THREADBPWORKLOAD = bsgs_m; + } + THREADCYCLES = bsgs_m / THREADBPWORKLOAD; + PERTHREAD_R = bsgs_m % THREADBPWORKLOAD; + if(PERTHREAD_R != 0) { + THREADCYCLES++; + } + + printf("\r[+] processing %lu/%lu bP points : %i%%\r",FINISHED_ITEMS,bsgs_m,(int) (((double)FINISHED_ITEMS/(double)bsgs_m)*100)); + fflush(stdout); + + tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); + bPload_mutex = (pthread_mutex_t*) calloc(NTHREADS,sizeof(pthread_mutex_t)); + checkpointer((void *)tid,__FILE__,"calloc","tid" ,__LINE__ -1 ); + checkpointer((void *)bPload_mutex,__FILE__,"calloc","bPload_mutex" ,__LINE__ -1 ); + + bPload_temp_ptr = (struct bPload*) calloc(NTHREADS,sizeof(struct bPload)); + checkpointer((void *)bPload_temp_ptr,__FILE__,"calloc","bPload_temp_ptr" ,__LINE__ -1 ); + bPload_threads_available = (char*) calloc(NTHREADS,sizeof(char)); + checkpointer((void *)bPload_threads_available,__FILE__,"calloc","bPload_threads_available" ,__LINE__ -1 ); + + + memset(bPload_threads_available,1,NTHREADS); + + for(i = 0; i < NTHREADS; i++) { + pthread_mutex_init(&bPload_mutex[i],NULL); + } + + do { + for(i = 0; i < NTHREADS && !salir; i++) { + + if(bPload_threads_available[i] && !salir) { + bPload_threads_available[i] = 0; + bPload_temp_ptr[i].from = BASE; + bPload_temp_ptr[i].threadid = i; + bPload_temp_ptr[i].finished = 0; + if( THREADCOUNTER < THREADCYCLES-1) { + bPload_temp_ptr[i].to = BASE + THREADBPWORKLOAD; + bPload_temp_ptr[i].workload = THREADBPWORKLOAD; + } + else { + bPload_temp_ptr[i].to = BASE + THREADBPWORKLOAD + PERTHREAD_R; + bPload_temp_ptr[i].workload = THREADBPWORKLOAD + PERTHREAD_R; + salir = 1; + } + + s = pthread_create(&tid[i],NULL,thread_bPload,(void*) &bPload_temp_ptr[i]); + if(s != 0){ + printf("Thread creation failed. Error code: %d\n", s); + exit(EXIT_FAILURE); + } + pthread_detach(tid[i]); + BASE+=THREADBPWORKLOAD; + THREADCOUNTER++; + } + } + if(OLDFINISHED_ITEMS != FINISHED_ITEMS) { + printf("\r[+] processing %lu/%lu bP points : %i%%\r",FINISHED_ITEMS,bsgs_m,(int) (((double)FINISHED_ITEMS/(double)bsgs_m)*100)); + fflush(stdout); + OLDFINISHED_ITEMS = FINISHED_ITEMS; + } + + for(i = 0 ; i < NTHREADS ; i++) { + + pthread_mutex_lock(&bPload_mutex[i]); + finished = bPload_temp_ptr[i].finished; + pthread_mutex_unlock(&bPload_mutex[i]); + if(finished) { + bPload_temp_ptr[i].finished = 0; + bPload_threads_available[i] = 1; + FINISHED_ITEMS += bPload_temp_ptr[i].workload; + FINISHED_THREADS_COUNTER++; + } + } + + }while(FINISHED_THREADS_COUNTER < THREADCYCLES); + printf("\r[+] processing %lu/%lu bP points : 100%% \n",bsgs_m,bsgs_m); + + free(tid); + free(bPload_mutex); + free(bPload_temp_ptr); + free(bPload_threads_available); + } + } + + if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 || !FLAGREADEDFILE4) { + printf("[+] Making checkums .. "); + fflush(stdout); + } + if(!FLAGREADEDFILE1) { + for(i = 0; i < 256 ; i++) { + sha256((uint8_t*)bloom_bP[i].bf, bloom_bP[i].bytes,(uint8_t*) bloom_bP_checksums[i].data); + memcpy(bloom_bP_checksums[i].backup,bloom_bP_checksums[i].data,32); + } + printf("."); + } + if(!FLAGREADEDFILE2) { + for(i = 0; i < 256 ; i++) { + sha256((uint8_t*)bloom_bPx2nd[i].bf, bloom_bPx2nd[i].bytes,(uint8_t*) bloom_bPx2nd_checksums[i].data); + memcpy(bloom_bPx2nd_checksums[i].backup,bloom_bPx2nd_checksums[i].data,32); + } + printf("."); + } + if(!FLAGREADEDFILE4) { + for(i = 0; i < 256 ; i++) { + sha256((uint8_t*)bloom_bPx3rd[i].bf, bloom_bPx3rd[i].bytes,(uint8_t*) bloom_bPx3rd_checksums[i].data); + memcpy(bloom_bPx3rd_checksums[i].backup,bloom_bPx3rd_checksums[i].data,32); + } + printf("."); + } + if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 || !FLAGREADEDFILE4) { + printf(" done\n"); + fflush(stdout); + } + if(!FLAGREADEDFILE3) { + printf("[+] Sorting %lu elements... ",bsgs_m3); + fflush(stdout); + bsgs_sort(bPtable,bsgs_m3); + sha256((uint8_t*)bPtable, bytes,(uint8_t*) checksum); + memcpy(checksum_backup,checksum,32); + printf("Done!\n"); + fflush(stdout); + } + if(FLAGSAVEREADFILE || FLAGUPDATEFILE1 ) { + if(!FLAGREADEDFILE1 || FLAGUPDATEFILE1) { + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_4_%" PRIu64 ".blm",bsgs_m); + + if(FLAGUPDATEFILE1) { + printf("[W] Updating old file into a new one\n"); + } + + /* Writing file for 1st bloom filter */ + + fd_aux1 = fopen(buffer_bloom_file,"wb"); + if(fd_aux1 != NULL) { + printf("[+] Writing bloom filter to file %s ",buffer_bloom_file); + fflush(stdout); + for(i = 0; i < 256;i++) { + readed = fwrite(&bloom_bP[i],sizeof(struct bloom),1,fd_aux1); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s please delete it\n",buffer_bloom_file); + exit(0); + } + 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(0); + } + 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(0); + } + 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(0); + } + } + if(!FLAGREADEDFILE2 ) { + + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_6_%" PRIu64 ".blm",bsgs_m2); + + /* Writing file for 2nd bloom filter */ + fd_aux2 = fopen(buffer_bloom_file,"wb"); + if(fd_aux2 != NULL) { + printf("[+] Writing bloom filter to file %s ",buffer_bloom_file); + fflush(stdout); + for(i = 0; i < 256;i++) { + readed = fwrite(&bloom_bPx2nd[i],sizeof(struct bloom),1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); + exit(0); + } + readed = fwrite(bloom_bPx2nd[i].bf,bloom_bPx2nd[i].bytes,1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); + exit(0); + } + readed = fwrite(&bloom_bPx2nd_checksums[i],sizeof(struct checksumsha256),1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s please delete it\n",buffer_bloom_file); + exit(0); + } + 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(0); + } + } + + 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(0); + } + readed = fwrite(checksum,32,1,fd_aux3); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); + exit(0); + } + printf("Done!\n"); + fclose(fd_aux3); + } + else { + fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); + exit(0); + } + } + 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(0); + } + 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(0); + } + 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(0); + } + 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(0); + } + } + } + } + /* + Here we already finish the BSGS setup + - Baby table and bloom filters are alrady setup + + */ + + + int server_fd, client_fd; + struct sockaddr_in address; + int addrlen = sizeof(address); + + // Creating socket file descriptor + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { + perror("socket failed"); + exit(EXIT_FAILURE); + } + + // Setting socket options + int opt = 1; + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { + perror("setsockopt failed"); + exit(EXIT_FAILURE); + } + + // Setting address parameters + address.sin_family = AF_INET; + address.sin_addr.s_addr = inet_addr("127.0.0.1"); + address.sin_port = htons(PORT); + // Binding socket to address + if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { + perror("bind failed"); + exit(EXIT_FAILURE); + } + printf("[+] Listening in 127.0.0.1:8080\n"); + // Listening for incoming connections + if (listen(server_fd, 3) < 0) { + perror("listen failed"); + exit(EXIT_FAILURE); + } + + pthread_t tid; + while(1) { + // Accepting incoming connection + if ((client_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { + perror("accept failed"); + exit(EXIT_FAILURE); + } + + // Creating new thread to handle client + if (pthread_create(&tid, NULL, client_handler, &client_fd) != 0) { + perror("pthread_create failed"); + printf("Failed to attend to one client\n"); + } + else{ + // Detaching thread to prevent memory leak + pthread_detach(tid); + } + } + + close(server_fd); + + + +/* + steps = (uint64_t *) calloc(NTHREADS,sizeof(uint64_t)); + checkpointer((void *)steps,__FILE__,"calloc","steps" ,__LINE__ -1 ); + ends = (unsigned int *) calloc(NTHREADS,sizeof(int)); + checkpointer((void *)ends,__FILE__,"calloc","ends" ,__LINE__ -1 ); + tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); + checkpointer((void *)tid,__FILE__,"calloc","tid" ,__LINE__ -1 ); + + for(i= 0;i < NTHREADS; i++) { + tt = (tothread*) malloc(sizeof(struct tothread)); + checkpointer((void *)tt,__FILE__,"malloc","tt" ,__LINE__ -1 ); + tt->nt = i; + + switch(FLAGBSGSMODE) { + case 0: + s = pthread_create(&tid[i],NULL,thread_process_bsgs,(void *)tt); + break; + + } + + if(s != 0) { + + fprintf(stderr,"[E] thread thread_process\n"); + exit(EXIT_FAILURE); + } + } + free(aux); + +*/ + +} + +void pubkeytopubaddress_dst(char *pkey,int length,char *dst) { + char digest[60]; + size_t pubaddress_size = 40; + sha256((uint8_t*)pkey, length,(uint8_t*) digest); + RMD160Data((const unsigned char*)digest,32, digest+1); + digest[0] = 0; + sha256((uint8_t*)digest, 21,(uint8_t*) digest+21); + sha256((uint8_t*)digest+21, 32,(uint8_t*) digest+21); + if(!b58enc(dst,&pubaddress_size,digest,25)){ + fprintf(stderr,"error b58enc\n"); + } +} + +void rmd160toaddress_dst(char *rmd,char *dst){ + char digest[60]; + size_t pubaddress_size = 40; + digest[0] = byte_encode_crypto; + memcpy(digest+1,rmd,20); + sha256((uint8_t*)digest, 21,(uint8_t*) digest+21); + sha256((uint8_t*)digest+21, 32,(uint8_t*) digest+21); + if(!b58enc(dst,&pubaddress_size,digest,25)){ + fprintf(stderr,"error b58enc\n"); + } +} + + +char *pubkeytopubaddress(char *pkey,int length) { + char *pubaddress = (char*) calloc(MAXLENGTHADDRESS+10,1); + char *digest = (char*) calloc(60,1); + size_t pubaddress_size = MAXLENGTHADDRESS+10; + checkpointer((void *)pubaddress,__FILE__,"malloc","pubaddress" ,__LINE__ -1 ); + checkpointer((void *)digest,__FILE__,"malloc","digest" ,__LINE__ -1 ); + //digest [000...0] + sha256((uint8_t*)pkey, length,(uint8_t*) digest); + //digest [SHA256 32 bytes+000....0] + RMD160Data((const unsigned char*)digest,32, digest+1); + //digest [? +RMD160 20 bytes+????000....0] + digest[0] = 0; + //digest [0 +RMD160 20 bytes+????000....0] + sha256((uint8_t*)digest, 21,(uint8_t*) digest+21); + //digest [0 +RMD160 20 bytes+SHA256 32 bytes+....0] + sha256((uint8_t*)digest+21, 32,(uint8_t*) digest+21); + //digest [0 +RMD160 20 bytes+SHA256 32 bytes+....0] + if(!b58enc(pubaddress,&pubaddress_size,digest,25)){ + fprintf(stderr,"error b58enc\n"); + } + free(digest); + return pubaddress; // pubaddress need to be free by te caller funtion +} + +void publickeytohashrmd160_dst(char *pkey,int length,char *dst) { + char digest[32]; + //digest [000...0] + sha256((uint8_t*)pkey, length,(uint8_t*) digest); + //digest [SHA256 32 bytes] + RMD160Data((const unsigned char*)digest,32, dst); + //hash160 [RMD160 20 bytes] +} + +char *publickeytohashrmd160(char *pkey,int length) { + char *hash160 = (char*) malloc(20); + char *digest = (char*) malloc(32); + checkpointer((void *)hash160,__FILE__,"malloc","hash160" ,__LINE__ -1 ); + checkpointer((void *)digest,__FILE__,"malloc","digest" ,__LINE__ -1 ); + //digest [000...0] + sha256((uint8_t*)pkey, length,(uint8_t*) digest); + //digest [SHA256 32 bytes] + RMD160Data((const unsigned char*)digest,32, hash160); + //hash160 [RMD160 20 bytes] + free(digest); + return hash160; // hash160 need to be free by te caller funtion +} + + +/* OK */ +void bsgs_swap(struct bsgs_xvalue *a,struct bsgs_xvalue *b) { + struct bsgs_xvalue t; + t = *a; + *a = *b; + *b = t; +} + +/* OK */ +void bsgs_sort(struct bsgs_xvalue *arr,int64_t n) { + uint32_t depthLimit = ((uint32_t) ceil(log(n))) * 2; + bsgs_introsort(arr,depthLimit,n); +} + +/* OK */ +void bsgs_introsort(struct bsgs_xvalue *arr,uint32_t depthLimit, int64_t n) { + int64_t p; + if(n > 1) { + if(n <= 16) { + bsgs_insertionsort(arr,n); + } + else { + if(depthLimit == 0) { + bsgs_myheapsort(arr,n); + } + else { + p = bsgs_partition(arr,n); + if(p > 0) bsgs_introsort(arr , depthLimit-1 , p); + if(p < n) bsgs_introsort(&arr[p+1],depthLimit-1,n-(p+1)); + } + } + } +} + +/* OK */ +void bsgs_insertionsort(struct bsgs_xvalue *arr, int64_t n) { + int64_t j; + int64_t i; + struct bsgs_xvalue key; + for(i = 1; i < n ; i++ ) { + key = arr[i]; + j= i-1; + while(j >= 0 && memcmp(arr[j].value,key.value,BSGS_XVALUE_RAM) > 0) { + arr[j+1] = arr[j]; + j--; + } + arr[j+1] = key; + } +} + +int64_t bsgs_partition(struct bsgs_xvalue *arr, int64_t n) { + struct bsgs_xvalue pivot; + int64_t r,left,right; + r = n/2; + pivot = arr[r]; + left = 0; + right = n-1; + do { + while(left < right && memcmp(arr[left].value,pivot.value,BSGS_XVALUE_RAM) <= 0 ) { + left++; + } + while(right >= left && memcmp(arr[right].value,pivot.value,BSGS_XVALUE_RAM) > 0) { + right--; + } + if(left < right) { + if(left == r || right == r) { + if(left == r) { + r = right; + } + if(right == r) { + r = left; + } + } + bsgs_swap(&arr[right],&arr[left]); + } + }while(left < right); + if(right != r) { + bsgs_swap(&arr[right],&arr[r]); + } + return right; +} + +void bsgs_heapify(struct bsgs_xvalue *arr, int64_t n, int64_t i) { + int64_t largest = i; + int64_t l = 2 * i + 1; + int64_t r = 2 * i + 2; + if (l < n && memcmp(arr[l].value,arr[largest].value,BSGS_XVALUE_RAM) > 0) + largest = l; + if (r < n && memcmp(arr[r].value,arr[largest].value,BSGS_XVALUE_RAM) > 0) + largest = r; + if (largest != i) { + bsgs_swap(&arr[i],&arr[largest]); + bsgs_heapify(arr, n, largest); + } +} + +void bsgs_myheapsort(struct bsgs_xvalue *arr, int64_t n) { + int64_t i; + for ( i = (n / 2) - 1; i >= 0; i--) { + bsgs_heapify(arr, n, i); + } + for ( i = n - 1; i > 0; i--) { + bsgs_swap(&arr[0] , &arr[i]); + bsgs_heapify(arr, i, 0); + } +} + +int bsgs_searchbinary(struct bsgs_xvalue *buffer,char *data,int64_t array_length,uint64_t *r_value) { + int64_t min,max,half,current; + int r = 0,rcmp; + min = 0; + current = 0; + max = array_length; + half = array_length; + while(!r && half >= 1) { + half = (max - min)/2; + rcmp = memcmp(data+16,buffer[current+half].value,BSGS_XVALUE_RAM); + if(rcmp == 0) { + *r_value = buffer[current+half].index; + r = 1; + } + else { + if(rcmp < 0) { + max = (max-half); + } + else { + min = (min+half); + } + current = min; + } + } + return r; +} + +void *thread_process_bsgs(void *vargp) { + + FILE *filekey; + char xpoint_raw[32],*aux_c,*hextemp; + Int base_key,keyfound; + Point base_point,point_aux,point_found; + uint32_t r, cycles; + IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); + Point startP; + + int hLength = (CPU_GRP_SIZE / 2 - 1); + + Int dx[CPU_GRP_SIZE / 2 + 1]; + Point pts[CPU_GRP_SIZE]; + + Int dy; + Int dyn; + Int _s; + Int _p; + Int km,intaux; + Point pp; + Point pn; + grp->Set(dx); + + + + cycles = bsgs_aux / 1024; + if(bsgs_aux % 1024 != 0) { + cycles++; + } + + + intaux.Set(&BSGS_M_double); + intaux.Mult(CPU_GRP_SIZE/2); + intaux.Add(&BSGS_M); + + /* + intaux hold the Current middle range value (Current) + (BSGS_M*2) * (CPU_GRP_SIZE/2) + BSGS_M + or + (BSGS_M * 512) + BSGS_M + */ + /* + while base_key is less than n_range_end then: + */ + do { + + /* + We do this in an atomic pthread_mutex operation to not affect others threads + so BSGS_CURRENT is never the same between threads + */ + pthread_mutex_lock(&mutex_bsgs_thread); + + base_key.Set(&BSGS_CURRENT); /* we need to set our base_key to the current BSGS_CURRENT value*/ + BSGS_CURRENT.Add(&BSGS_N); /*Then add BSGS_N to BSGS_CURRENT*/ + BSGS_CURRENT.Add(&BSGS_N); /*Then add BSGS_N to BSGS_CURRENT*/ + + pthread_mutex_unlock(&mutex_bsgs_thread); + + if(base_key.IsGreaterOrEqual(&n_range_end)) + break; + + + //base point is the point of the current start range (Base_key) + base_point = secp->ComputePublicKey(&base_key); + + km.Set(&base_key); + km.Neg(); + + km.Add(&secp->order); + km.Sub(&intaux); + + //point_aux =-( basekey + ((BSGS_M*2) * 512) + BSGS_M) + point_aux = secp->ComputePublicKey(&km); + + + + if(base_point.equals(OriginalPointsBSGS)) { + hextemp = base_key.GetBase16(); + printf("[+] Thread Key found privkey %s \n",hextemp); + aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed,base_point); + printf("[+] Publickey %s\n",aux_c); + + pthread_mutex_lock(&write_keys); + + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + BSGSkeyfound.Set(&base_key); + pthread_mutex_unlock(&write_keys); + + free(hextemp); + free(aux_c); + + bsgs_found = 1; + } + else { + + startP = secp->AddDirect(OriginalPointsBSGS,point_aux); + + uint32_t j = 0; + while( j < cycles && bsgs_found == 0 ) { + + int i; + + for(i = 0; i < hLength; i++) { + dx[i].ModSub(&GSn[i].x,&startP.x); + } + dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point + dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point + + // Grouped ModInv + grp->ModInv(); + + /* + We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse + We compute key in the positive and negative way from the center of the group + */ + + // center point + pts[CPU_GRP_SIZE / 2] = startP; + + for(i = 0; iComputePublicKey(&keyfound); + aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed,point_found); + printf("[+] Publickey %s\n",aux_c); + pthread_mutex_lock(&write_keys); + + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + BSGSkeyfound.Set(&keyfound); + pthread_mutex_unlock(&write_keys); + free(hextemp); + free(aux_c); + bsgs_found = 1; + + } //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); + + + /* For this BSGS we only need to calculate the Y value of the next start point */ + + 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 else + }while(base_key.IsLower(&n_range_end) && bsgs_found == 0); + pthread_exit(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,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,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,privatekey); + } + i++; + }while(i < 32 && !found); + return found; +} + +int bsgs_thirdcheck(Int *start_range,uint32_t a,Int *privatekey) { + uint64_t j = 0; + int i = 0,found = 0,r = 0; + Int base_key,calculatedkey; + Point base_point,point_aux; + Point BSGS_Q, BSGS_S,BSGS_Q_AMP; + char xpoint_raw[32]; + + base_key.SetInt32(a); + base_key.Mult(&BSGS_M2_double); + base_key.Add(start_range); + + base_point = secp->ComputePublicKey(&base_key); + point_aux = secp->Negation(base_point); + + BSGS_S = secp->AddDirect(OriginalPointsBSGS,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.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.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 calcualteindex(int i,Int *key) { + if(i == 0) { + key->Set(&BSGS_M3); + } + else { + key->SetInt32(i); + key->Mult(&BSGS_M3_double); + key->Add(&BSGS_M3); + } +} + + +void sleep_ms(int milliseconds) { // cross-platform sleep function +#if defined(_WIN64) && !defined(__CYGWIN__) + Sleep(milliseconds); +#elif _POSIX_C_SOURCE >= 199309L + struct timespec ts; + ts.tv_sec = milliseconds / 1000; + ts.tv_nsec = (milliseconds % 1000) * 1000000; + nanosleep(&ts, NULL); +#else + if (milliseconds >= 1000) + sleep(milliseconds / 1000); + usleep((milliseconds % 1000) * 1000); +#endif +} + + +void *thread_bPload(void *vargp) { + + char rawvalue[32]; + struct bPload *tt; + uint64_t i_counter,j,nbStep,to; + + IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); + Point startP; + Int dx[CPU_GRP_SIZE / 2 + 1]; + Point pts[CPU_GRP_SIZE]; + Int dy,dyn,_s,_p; + Point pp,pn; + + int i,bloom_bP_index,hLength = (CPU_GRP_SIZE / 2 - 1) ,threadid; + tt = (struct bPload *)vargp; + Int km((uint64_t)(tt->from + 1)); + threadid = tt->threadid; + + + i_counter = tt->from; + + nbStep = (tt->to - tt->from) / CPU_GRP_SIZE; + + if( ((tt->to - tt->from) % CPU_GRP_SIZE ) != 0) { + nbStep++; + } + to = tt->to; + + km.Add((uint64_t)(CPU_GRP_SIZE / 2)); + startP = secp->ComputePublicKey(&km); + grp->Set(dx); + for(uint64_t s=0;sModInv(); + + // We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse + // We compute key in the positive and negative way from the center of the group + // center point + + pts[CPU_GRP_SIZE / 2] = startP; //Center point + + for(i = 0; ifinished = 1; + pthread_mutex_unlock(&bPload_mutex[threadid]); + pthread_exit(NULL); + return NULL; +} + +void *thread_bPload_2blooms(void *vargp) { + char rawvalue[32]; + struct bPload *tt; + uint64_t i_counter,j,nbStep; + IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); + Point startP; + Int dx[CPU_GRP_SIZE / 2 + 1]; + Point pts[CPU_GRP_SIZE]; + Int dy,dyn,_s,_p; + Point pp,pn; + int i,bloom_bP_index,hLength = (CPU_GRP_SIZE / 2 - 1) ,threadid; + tt = (struct bPload *)vargp; + Int km((uint64_t)(tt->from +1 )); + threadid = tt->threadid; + + i_counter = tt->from; + + nbStep = (tt->to - (tt->from)) / CPU_GRP_SIZE; + + if( ((tt->to - (tt->from)) % CPU_GRP_SIZE ) != 0) { + nbStep++; + } + + km.Add((uint64_t)(CPU_GRP_SIZE / 2)); + startP = secp->ComputePublicKey(&km); + grp->Set(dx); + for(uint64_t s=0;sModInv(); + + // We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse + // We compute key in the positive and negative way from the center of the group + // center point + + pts[CPU_GRP_SIZE / 2] = startP; //Center point + + for(i = 0; ifinished = 1; + pthread_mutex_unlock(&bPload_mutex[threadid]); + pthread_exit(NULL); + return NULL; +} + + +/* This function takes in two parameters: + +publickey: a reference to a Point object representing a public key. +dst_address: a pointer to an unsigned char array where the generated binary address will be stored. +The function is designed to generate a binary address for Ethereum using the given public key. +It first extracts the x and y coordinates of the public key as 32-byte arrays, and concatenates them +to form a 64-byte array called bin_publickey. Then, it applies the KECCAK-256 hashing algorithm to +bin_publickey to generate the binary address, which is stored in dst_address. */ + + +void menu() { + printf("\nUsage:\n"); + printf("-h show this help\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("-n number Check for N sequential numbers before the random chosen, this only works with -R option\n"); + printf("-t tn Threads number, must be a positive integer\n"); + printf("\nExample:\n\n"); + printf("./bsgs -k 512 \n\n"); + exit(EXIT_FAILURE); +} + + +void checkpointer(void *ptr,const char *file,const char *function,const char *name,int line) { + if(ptr == NULL) { + fprintf(stderr,"[E] error in file %s, %s pointer %s on line %i\n",file,function,name,line); + exit(EXIT_FAILURE); + } +} + +void writekey(bool compressed,Int *key) { + Point publickey; + FILE *keys; + char *hextemp,*hexrmd,public_key_hex[132],address[50],rmdhash[20]; + memset(address,0,50); + memset(public_key_hex,0,132); + hextemp = key->GetBase16(); + publickey = secp->ComputePublicKey(key); + secp->GetPublicKeyHex(compressed,publickey,public_key_hex); + secp->GetHash160(P2PKH,compressed,publickey,(uint8_t*)rmdhash); + hexrmd = tohex(rmdhash,20); + rmd160toaddress_dst(rmdhash,address); + + pthread_mutex_lock(&write_keys); + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); + if(keys != NULL) { + fprintf(keys,"Private Key: %s\npubkey: %s\nAddress %s\nrmd160 %s\n",hextemp,public_key_hex,address,hexrmd); + fclose(keys); + } + printf("\nHit! Private Key: %s\npubkey: %s\nAddress %s\nrmd160 %s\n",hextemp,public_key_hex,address,hexrmd); + + pthread_mutex_unlock(&write_keys); + free(hextemp); + free(hexrmd); +} + + +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]); +} + + + + /* + We need to define the range in some other part + */ + + /* + if(FLAGRANGE) { + + n_range_start.SetBase16(range_start); + if(n_range_start.IsZero()) { + n_range_start.AddOne(); + } + n_range_end.SetBase16(range_end); + if(n_range_start.IsEqual(&n_range_end) == false ) { + if( n_range_start.IsLower(&secp->order) && n_range_end.IsLowerOrEqual(&secp->order) ) { + if( n_range_start.IsGreater(&n_range_end)) { + fprintf(stderr,"[W] Opps, start range can't be great than end range. Swapping them\n"); + n_range_aux.Set(&n_range_start); + n_range_start.Set(&n_range_end); + n_range_end.Set(&n_range_aux); + } + n_range_diff.Set(&n_range_end); + n_range_diff.Sub(&n_range_start); + } + else { + fprintf(stderr,"[E] Start and End range can't be great than N\nFallback to random mode!\n"); + FLAGRANGE = 0; + } + } + else { + fprintf(stderr,"[E] Start and End range can't be the same\nFallback to random mode!\n"); + FLAGRANGE = 0; + } + } + */ + + + + /* + For thhe BSGS Server version we only work with one publickey at the time + + */ + + + /* + 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); + } + */ + + + +/* + 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); + } +*/ + + +void* client_handler(void* arg) { + int client_fd = *(int*)arg; + char buffer[1024]; + char *hextemp; + int bytes_received; + Tokenizer t; + t.tokens = NULL; + + // Peek at the incoming data to determine its length + bytes_received = recv(client_fd, buffer, sizeof(buffer) - 1, MSG_PEEK); + if (bytes_received <= 0) { + close(client_fd); + pthread_exit(NULL); + } + + + char* newline = (char*) memchr(buffer, '\n', bytes_received); + size_t line_length = newline ? (newline - buffer) + 1 : bytes_received; + bytes_received = recv(client_fd, buffer, line_length, 0); + if (bytes_received <= 0) { + close(client_fd); + pthread_exit(NULL); + } + + // Process the received bytes here + buffer[bytes_received] = '\0'; + stringtokenizer(buffer, &t); + if (t.n != 3) { + printf("Invalid input format from client, tokens %i : %s\n",t.n, buffer); + freetokenizer(&t); + sendstr(client_fd,"400 Bad Request"); + close(client_fd); + pthread_exit(NULL); + } + + if(!secp->ParsePublicKeyHex(t.tokens[0],OriginalPointsBSGS,OriginalPointsBSGScompressed)) { + printf("Invalid publickey format from client %s\n",t.tokens[0]); + freetokenizer(&t); + sendstr(client_fd,"400 Bad Request"); + close(client_fd); + pthread_exit(NULL); + } + if(!(isValidHex(t.tokens[1]) && isValidHex(t.tokens[1]))) { + printf("Invalid hexadecimal format from client %s:%s\n",t.tokens[1],t.tokens[2]); + freetokenizer(&t); + sendstr(client_fd,"400 Bad Request"); + close(client_fd); + pthread_exit(NULL); + } + + n_range_start.SetBase16(t.tokens[1]); + n_range_end.SetBase16(t.tokens[2]); + + freetokenizer(&t); + + BSGS_CURRENT.Set(&n_range_start); + + bool *threads_created; + pthread_t *threads; + int *thread_args; + + threads_created = (bool*) calloc(NTHREADS,sizeof(bool)); + threads = (pthread_t*) calloc(NTHREADS,sizeof(pthread_t)); + thread_args = (int*) calloc(NTHREADS,sizeof(int)); + checkpointer(threads_created,__FILE__,"calloc","threads_created",__LINE__); + checkpointer(threads,__FILE__,"calloc","threads",__LINE__); + checkpointer(thread_args,__FILE__,"calloc","thread_args",__LINE__); + + + + int i, rc; + + // Create threads + for (i = 0; i < NTHREADS; i++) { + thread_args[i] = i; + threads_created[i] = true; + rc = pthread_create(&threads[i], NULL, thread_process_bsgs, &thread_args[i]); + if (rc != 0) { + printf("Failed to create thread %d\n", i); + threads_created[i] = false; + } + + } + + // Wait for threads to finish + for (i = 0; i < NTHREADS; i++) { + if(threads_created[i]){ + rc = pthread_join(threads[i], NULL); + if (rc != 0) { + printf("Failed to join thread %d\n", i); + } + } + } + + free(threads_created); + free(threads); + free(thread_args); + int message_len; + if(bsgs_found) { + hextemp = BSGSkeyfound.GetBase16(); + message_len = snprintf(buffer, sizeof(buffer), "%s",hextemp); + free(hextemp); + } + else { + message_len = snprintf(buffer, sizeof(buffer), "404 Not Found"); + } + bsgs_found = 0; + int bytes_sent = send(client_fd, buffer, message_len, 0); + if (bytes_sent == -1) { + printf("Failed to send message to client\n"); + } + + + close(client_fd); + pthread_exit(NULL); +} + +int sendstr(int client_fd,const char *str) { + int len = strlen(str); + int bytes = send(client_fd, str, len, 0); + if (bytes == -1) { + printf("Failed to send message to client\n"); + } + return bytes; +} \ No newline at end of file diff --git a/gmp256k1/Int.cpp b/gmp256k1/Int.cpp index 1f7928a..01a023d 100644 --- a/gmp256k1/Int.cpp +++ b/gmp256k1/Int.cpp @@ -62,7 +62,6 @@ Int::Int(const Int &value) { } - void Int::Add(const uint64_t u64) { mpz_t value; char my_str_value[U64STRINGSIZE]; // 30 digits + null terminator @@ -81,8 +80,7 @@ void Int::Add(const Int *a) { } void Int::Add(const Int *a,const Int *b) { - mpz_add(num,num,a->num); - mpz_add(num,num,b->num); + mpz_add(num,a->num,b->num); } void Int::Sub(const uint32_t u32) { @@ -103,8 +101,7 @@ void Int::Sub(Int *a) { } void Int::Sub(Int *a, Int *b) { - mpz_sub(num,num,a->num); - mpz_sub(num,num,b->num); + mpz_sub(num,a->num,b->num); } void Int::Mult(Int *a) { @@ -204,10 +201,6 @@ bool Int::IsOdd() { } int Int::GetSize() { - /* - gmp_printf("GetSize of %Zi\n",num); - fflush(stdout); - */ int r = mpz_sizeinbase(num,2); if(r % 8 == 0) return (int)(r/8); @@ -236,6 +229,14 @@ int Int::GetBit(uint32_t n) { return mpz_tstbit(num,n); } +void Int::SetBit(uint32_t n) { + mpz_setbit(num,n); +} + +void Int::ClearBit(uint32_t n) { + mpz_clrbit(num,n); +} + void Int::Get32Bytes(unsigned char *buff) { size_t count, size = this->GetSize(); @@ -255,24 +256,6 @@ unsigned char Int::GetByte(int n) { return buffer[n]; } -/* -void mpz_get_byte(mpz_t num, unsigned char* bytes, size_t index) { - size_t num_bytes = (mpz_sizeinbase(num, 2) + 7) / 8; // Calculate the total number of bytes - if (index < num_bytes) { - mpz_export(bytes, NULL, 1, sizeof(unsigned char), 0, 0, num); // Export the mpz_t variable to bytes - } else { - // Handle invalid index - printf("Error: Index out of range.\n"); - } -} -*/ - -/* -unsigned char Int::GetByte(unsigned char *buff) { - -} -*/ - char* Int::GetBase2() { return mpz_get_str(NULL,2,num); } diff --git a/gmp256k1/Int.h b/gmp256k1/Int.h index 4f60b44..75a4fc0 100644 --- a/gmp256k1/Int.h +++ b/gmp256k1/Int.h @@ -102,6 +102,10 @@ class Int { char* GetBase2(); char* GetBase10(); char* GetBase16(); + + + void SetBit(uint32_t n); + void ClearBit(uint32_t n); /* char* GetBaseN(int n,const char *charset); char* GetBlockStr(); @@ -141,6 +145,7 @@ class Int { void ModMulK1(Int *a, Int *b); void ModMulK1(Int *a); void ModMulK1order(Int *a); + void ModInvorder(); // this <- this^-1 (mod O) void ModSquareK1(Int *a); void ModAddK1order(Int *a,Int *b); diff --git a/gmp256k1/IntMod.cpp b/gmp256k1/IntMod.cpp index 3bb581f..265f5cd 100644 --- a/gmp256k1/IntMod.cpp +++ b/gmp256k1/IntMod.cpp @@ -99,7 +99,7 @@ void Int::ModDouble() { mpz_add(num,num,num); mpz_init_set(p,num); mpz_sub(p,p,_P.num); - if(mpz_cmp(p,0) > 0) { + if(mpz_cmp_ui(p,0) > 0) { mpz_set(num,p); } mpz_clear(p); @@ -142,3 +142,7 @@ void Int::ModAddK1order(Int *a, Int *b) { if (mpz_cmp_ui(num,0) < 0 ) mpz_add(num,num,_O->num); } + +void Int::ModInvorder() { + mpz_invert(num,num,_O->num); +} diff --git a/gmp256k1/Point.cpp b/gmp256k1/Point.cpp index ac0d79b..3c3fe27 100644 --- a/gmp256k1/Point.cpp +++ b/gmp256k1/Point.cpp @@ -19,31 +19,13 @@ #include Point::Point() { - mpz_set_ui(x.num,0); - mpz_set_ui(y.num,0); - mpz_set_ui(z.num,0); - } Point::Point(const Point &p) { - - //char *ptrs[3]; + mpz_set(x.num,p.x.num); mpz_set(y.num,p.y.num); mpz_set(z.num,p.z.num); - /* - ptrs[0] = x.GetBase16(); - ptrs[1] = y.GetBase16(); - ptrs[2] = z.GetBase16(); - printf("Point\n"); - printf("X: %s\n",ptrs[0]); - printf("Y: %s\n",ptrs[1]); - printf("Z: %s\n",ptrs[2]); - printf("End Point\n"); - for(int i = 0; i<3; i++) { - free(ptrs[i]); - } - */ } Point::Point(Int *cx,Int *cy,Int *cz) { @@ -52,13 +34,6 @@ Point::Point(Int *cx,Int *cy,Int *cz) { mpz_set(z.num,cz->num); } -/* -Point::Point(Int *cx, Int *cz) { - x.Set(cx); - z.Set(cz); -} -*/ - void Point::Clear() { mpz_set_ui(x.num,0); mpz_set_ui(y.num,0); @@ -103,7 +78,6 @@ Point& Point::operator=(const Point& other) { if (this == &other) { return *this; } - //char *ptrs[3]; // Assign the values from 'other' to the current object mpz_set(x.num,other.x.num); mpz_set(y.num,other.y.num); @@ -113,6 +87,7 @@ Point& Point::operator=(const Point& other) { return *this; } +/* void Point::print(const char *str) { char *ptrs[3]; ptrs[0] = x.GetBase16(); @@ -126,4 +101,5 @@ void Point::print(const char *str) { for(int i = 0; i<3; i++) { free(ptrs[i]); } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/util.c b/util.c index b2f4b54..0c46cd4 100644 --- a/util.c +++ b/util.c @@ -79,7 +79,7 @@ void stringtokenizer(char *data,Tokenizer *t) { exit(0); } t->tokens[t->n - 1] = token; - token = strtok(NULL," \t"); + token = strtok(NULL," \t:"); } }