diff --git a/.gitignore b/.gitignore index 6429592..f410ae8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ hexcharstoraw *.bin keyhunt KEYFOUNDKEYFOUND.txt +*.tbl +*.blm # Prerequisites *.d diff --git a/CHANGELOG.md b/CHANGELOG.md index ca6cd80..deb60af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# Version 0.2.211018 Chocolate ¡Beta! +- Solved some bugs: https://github.com/albertobsd/keyhunt/issues/122 https://github.com/albertobsd/keyhunt/issues/111 +- Files are going to be updated automatillyca +-- from keyhunt_bsgs_3_*.blm to keyhunt_bsgs_4*.blm +-- from keyhunt_bsgs_1_*.blm to keyhunt_bsgs_5*.blm +-- the program will notify you when time to delete the old files + # Version 0.2.211012 Chocolate ¡Beta! - Fixed the slow bP table generation. -- This fix make obsolete the files keyhunt_bsgs_0_*.blm diff --git a/Makefile b/Makefile index e0cecb8..e57c21d 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ default: - gcc -O3 -c bloom/bloom.c -o bloom.o + g++ -O3 -c oldbloom/bloom.cpp -o oldbloom.o + g++ -O3 -c bloom/bloom.cpp -o bloom.o g++ -O3 -c sha256/sha256.c -o sha256.o gcc -O3 -c base58/base58.c -o base58.o gcc -O3 -c rmd160/rmd160.c -o rmd160.o @@ -13,9 +14,7 @@ default: g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntMod.cpp -o IntMod.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Random.cpp -o Random.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntGroup.cpp -o IntGroup.o - g++ -o keyhunt keyhunt.c base58.o rmd160.o sha256.o bloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread + g++ -o keyhunt keyhunt.cpp base58.o rmd160.o sha256.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 clean: rm keyhunt - rm bPfile - diff --git a/README.md b/README.md index b844597..4a94bdd 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,11 @@ Work for btc in this moment, only legacy Addresses that start with '1' Ethereum addresses is a work in develop + +## For regulars users + +Please read the CHANGELOG.md to see the new changes + # Download To clone the repository: @@ -772,7 +777,7 @@ OK at this point maybe you want to use ALL your RAM memory to solve the puzzle 1 I already tested it with some **18 GB ** used with `-k 1024` and I get **~46 Petakeys/s per thread.** -with 6 threads +with **6** threads `./keyhunt -m bsgs -f tests/120.txt -b 120 -R -k 1024 -q -t 6` @@ -947,35 +952,35 @@ To get optimal performance the k values need to be base 2^x values, this is 1,2, ### Valid n and k values ``` -+---------------------------+-------------+---------------------------+ -| bits | n in hexadecimal | k max value | Amount of RAM with k = 1 | -| +-------------------------+-------------+---------------------------+ -| 20 | 0x100000 | 1 (default) | | -| 22 | 0x400000 | 2 | | -| 24 | 0x1000000 | 4 | | -| 26 | 0x4000000 | 8 | | -| 28 | 0x10000000 | 16 | | -| 30 | 0x40000000 | 32 | | -| 32 | 0x100000000 | 64 | | -| 34 | 0x400000000 | 128 | | -| 36 | 0x1000000000 | 256 | | -| 38 | 0x4000000000 | 512 | | -| 40 | 0x10000000000 | 1024 | | -| 42 | 0x40000000000 | 2048 | | -| 44 | 0x100000000000 | 4096 | ~17 MB | -| 46 | 0x400000000000 | 8192 | ~34 MB | -| 48 | 0x1000000000000 | 16384 | | -| 50 | 0x4000000000000 | 32768 | | -| 52 | 0x10000000000000 | 65536 | | -| 54 | 0x40000000000000 | 131072 | | -| 56 | 0x100000000000000 | 262144 | | -| 58 | 0x400000000000000 | 524288 | | -| 60 | 0x1000000000000000 | 1048576 | ~4.5 GB | -| 62 | 0x4000000000000000 | 2097152 | ~9 GB | ++---------------------------+-------------+---------------------------+ +| bits | n in hexadecimal | k max value | Amount of RAM with k = 1 | ++---------------------------+-------------+---------------------------+ +| 20 | 0x100000 | 1 (default) | | +| 22 | 0x400000 | 2 | | +| 24 | 0x1000000 | 4 | | +| 26 | 0x4000000 | 8 | | +| 28 | 0x10000000 | 16 | | +| 30 | 0x40000000 | 32 | | +| 32 | 0x100000000 | 64 | | +| 34 | 0x400000000 | 128 | | +| 36 | 0x1000000000 | 256 | | +| 38 | 0x4000000000 | 512 | | +| 40 | 0x10000000000 | 1024 | | +| 42 | 0x40000000000 | 2048 | | +| 44 | 0x100000000000 | 4096 | ~17 MB | +| 46 | 0x400000000000 | 8192 | ~34 MB | +| 48 | 0x1000000000000 | 16384 | | +| 50 | 0x4000000000000 | 32768 | | +| 52 | 0x10000000000000 | 65536 | | +| 54 | 0x40000000000000 | 131072 | | +| 56 | 0x100000000000000 | 262144 | | +| 58 | 0x400000000000000 | 524288 | | +| 60 | 0x1000000000000000 | 1048576 | ~4.5 GB | +| 62 | 0x4000000000000000 | 2097152 | ~9 GB | +---------------------------+-------------+---------------------------+ ``` - -*if you exceed the Max value of K the program can have a unknow behavior, the program can have a suboptimal performance, or in the wrong cases you can missing some hits and have an incorrect SPEED.* + +**if you exceed the Max value of K the program can have a unknow behavior, the program can have a suboptimal performance, or in the wrong cases you can missing some hits and have an incorrect SPEED.** Of course you can use a bigger number N like 2^64 or 2^70 if you have enough memory for it. @@ -1035,7 +1040,7 @@ Please note that number of threads was setting to 6 but only 4 threads were used The next command also solve the Puzzle 63 with more threads ``` -time ./keyhunt -m bsgs -t 6 -f tests/63.pub -n 0x400000000000000 -M -s 0 -S -k 16 -b 63 -B both +time ./keyhunt -m bsgs -t 6 -f tests/63.pub -n 0x400000000000000 -M -s 0 -S -k 8 -b 63 ``` ``` @@ -1057,16 +1062,21 @@ Please check the video that i made to answer that https://youtu.be/MVby8mYNxbI - Is available for Windows? R: It can be compiled with mingw, also it can be executed in the Ubuntu shell for windows 10 + Updated: -Yes, thanks to @WanderingPhilosopher +Yes thanks to @kanhavishva +Available in: https://github.com/kanhavishva/keyhunt + +Also, thanks to @WanderingPhilosopher Available in: https://github.com/WanderingPhilosopher/keyhunt Also thanks to @XopMC Available in: https://github.com/XopMC/keyhunt-win + - Why i need the bPfile.bin ? R: Usually you don't need it, but if you are going to run and stop the program several times is faster load the data from a file. -NOTE: *bPfile.bin will discontinued in some future version, the current versios have the `-S` to SAVE the FILES or READ from IT if they already exist* +**NOTE: bPfile.bin will discontinued in some future version, the current versios have the `-S` to SAVE the FILES or READ from IT if they already exist** - The bPfile gives me extra speed? R: No, is just to help to speed up a little the load process and no more, but the final speed of keys per second is going to be the same without this file. @@ -1075,13 +1085,14 @@ R: No, is just to help to speed up a little the load process and no more, but th ## Dependencies - pthread -Tested under Debian, Termux, Ubuntu Shell for windows 10 +Tested under Debian, Ubuntu Shell for windows 10 ## Thanks This program was possible thanks to - IceLand - kanhavishva +- JLP for part of his code - All the group of CryptoHunters that made this program possible - All the users that tested it, report bugs, requested improvements and shared his knowledge. diff --git a/bloom/bloom.c b/bloom/bloom.cpp similarity index 62% rename from bloom/bloom.c rename to bloom/bloom.cpp index 1a5f9b4..81a4ed5 100644 --- a/bloom/bloom.c +++ b/bloom/bloom.cpp @@ -1,393 +1,299 @@ -/* - * Copyright (c) 2012-2019, Jyri J. Virkki - * All rights reserved. - * - * This file is under BSD license. See LICENSE file. - */ - -/* - * Refer to bloom.h for documentation on the public interfaces. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bloom.h" -#include "../xxhash/xxhash.h" - -#define MAKESTRING(n) STRING(n) -#define STRING(n) #n -#define BLOOM_MAGIC "libbloom2" -#define BLOOM_VERSION_MAJOR 2 -#define BLOOM_VERSION_MINOR 200 - -inline static int test_bit_set_bit(struct bloom * bloom, uint64_t bit, int set_bit) -{ - uint64_t byte = bit >> 3; - uint8_t c; - uint8_t mask = 1 << (bit % 8); - pthread_mutex_lock(&bloom->mutex); - c = bloom->bf[byte]; // expensive memory access - pthread_mutex_unlock(&bloom->mutex); - if (c & mask) { - return 1; - } else { - if (set_bit) { - pthread_mutex_lock(&bloom->mutex); - bloom->bf[byte] = c | mask; - pthread_mutex_unlock(&bloom->mutex); - } - return 0; - } -} - - -static int bloom_check_add(struct bloom * bloom, const void * buffer, int len, int add) -{ - if (bloom->ready == 0) { - printf("bloom at %p not initialized!\n", (void *)bloom); - return -1; - } - uint8_t hits = 0; - uint64_t a = XXH64(buffer, len, 0x59f2815b16f81798); - uint64_t b = XXH64(buffer, len, a); - uint64_t x; - uint8_t i; - int r; - for (i = 0; i < bloom->hashes; i++) { - x = (a + b*i) % bloom->bits; - r = test_bit_set_bit(bloom, x, add); - - if (r) { - hits++; - } else if (!add) { - // Don't care about the presence of all the bits. Just our own. - return 0; - } - } - if (hits == bloom->hashes) { - return 1; // 1 == element already in (or collision) - } - return 0; -} - - -// DEPRECATED - Please migrate to bloom_init2. -int bloom_init(struct bloom * bloom, uint64_t entries, long double error) -{ - return bloom_init2(bloom, entries, error); -} - - -int bloom_init2(struct bloom * bloom, uint64_t entries, long double error) -{ - memset(bloom, 0, sizeof(struct bloom)); - if (entries < 1000 || error <= 0 || error >= 1) { - return 1; - } - - bloom->entries = entries; - bloom->error = error; - - long double num = -log(bloom->error); - long double denom = 0.480453013918201; // ln(2)^2 - bloom->bpe = (num / denom); - - long double dentries = (long double)entries; - long double allbits = dentries * bloom->bpe; - bloom->bits = (uint64_t)allbits; - - bloom->bytes = (uint64_t) bloom->bits / 8; - if (bloom->bits % 8) { - bloom->bytes +=1; - } - - bloom->hashes = (uint8_t)ceil(0.693147180559945 * bloom->bpe); // ln(2) - - bloom->bf = (uint8_t *)calloc(bloom->bytes, sizeof(uint8_t)); - if (bloom->bf == NULL) { // LCOV_EXCL_START - return 1; - } // LCOV_EXCL_STOP - - bloom->ready = 1; - bloom->major = BLOOM_VERSION_MAJOR; - bloom->minor = BLOOM_VERSION_MINOR; - return 0; -} - -int bloom_dummy(struct bloom * bloom, uint64_t entries, long double error) -{ - memset(bloom, 0, sizeof(struct bloom)); - if (entries < 1000 || error <= 0 || error >= 1) { - return 1; - } - - bloom->entries = entries; - bloom->error = error; - - long double num = -log(bloom->error); - long double denom = 0.480453013918201; // ln(2)^2 - bloom->bpe = (num / denom); - - long double dentries = (long double)entries; - long double allbits = dentries * bloom->bpe; - bloom->bits = (uint64_t)allbits; - - bloom->bytes = (uint64_t) bloom->bits / 8; - if (bloom->bits % 8) { - bloom->bytes +=1; - } - - bloom->hashes = (uint8_t)ceil(0.693147180559945 * bloom->bpe); // ln(2) - /* - bloom->bf = (uint8_t *)calloc(bloom->bytes, sizeof(uint8_t)); - if (bloom->bf == NULL) { // LCOV_EXCL_START - return 1; - } // LCOV_EXCL_STOP - - bloom->ready = 1; - bloom->major = BLOOM_VERSION_MAJOR; - bloom->minor = BLOOM_VERSION_MINOR; - */ - return 0; -} - -int bloom_check(struct bloom * bloom, const void * buffer, int len) -{ - return bloom_check_add(bloom, buffer, len, 0); -} - - -int bloom_add(struct bloom * bloom, const void * buffer, int len) -{ - int r; - r =bloom_check_add(bloom, buffer, len, 1); - return r; -} - - -void bloom_print(struct bloom * bloom) -{ - printf("bloom at %p\n", (void *)bloom); - if (!bloom->ready) { printf(" *** NOT READY ***\n"); } - printf(" ->version = %d.%d\n", bloom->major, bloom->minor); - printf(" ->entries = %"PRIu64"\n", bloom->entries); - printf(" ->error = %Lf\n", bloom->error); - printf(" ->bits = %"PRIu64"\n", bloom->bits); - printf(" ->bits per elem = %f\n", bloom->bpe); - printf(" ->bytes = %"PRIu64"\n", bloom->bytes); - unsigned int KB = bloom->bytes / 1024; - unsigned int MB = KB / 1024; - printf(" (%u KB, %u MB)\n", KB, MB); - printf(" ->hash functions = %d\n", bloom->hashes); -} - - -void bloom_free(struct bloom * bloom) -{ - if (bloom->ready) { - free(bloom->bf); - } - bloom->ready = 0; -} - - -int bloom_reset(struct bloom * bloom) -{ - if (!bloom->ready) return 1; - memset(bloom->bf, 0, bloom->bytes); - return 0; -} - -int bloom_loadcustom(struct bloom * bloom, char * filename) { - if (filename == NULL || filename[0] == 0) { - return 1; - } - FILE *fd_str,*fd_dat; - char filename_str[70],filename_dat[70]; - memset(filename_str,0,70); - memset(filename_dat,0,70); - snprintf(filename_str,68,"%s.blm",filename); - snprintf(filename_dat,68,"%s.dat",filename); - fd_str = fopen(filename_str,"rb"); - fd_dat = fopen(filename_dat,"rb"); - if (fd_str == NULL || fd_dat == NULL) { - return 1; - } - if(fread(bloom,1,sizeof(struct bloom),fd_str) != sizeof(struct bloom) ) { - fclose(fd_str); - fclose(fd_dat); - return 1; - } - bloom->bf = malloc(bloom->bytes); - if(bloom->bf == NULL) { - memset(bloom, 0, sizeof(struct bloom)); - return 1; - } - if(fread(bloom->bf,1, bloom->bytes,fd_dat) !=bloom->bytes) { - free(bloom->bf); - memset(bloom, 0, sizeof(struct bloom)); - fclose(fd_str); - fclose(fd_dat); - return 1; - } - fclose(fd_str); - fclose(fd_dat); - return 0; -} - -int bloom_savecustom(struct bloom * bloom, char * filename) { - if (filename == NULL || filename[0] == 0) { - return 1; - } - FILE *fd_str,*fd_dat; - char filename_str[70],filename_dat[70]; - memset(filename_str,0,70); - memset(filename_dat,0,70); - snprintf(filename_str,68,"%s.blm",filename); - snprintf(filename_dat,68,"%s.dat",filename); - fd_str = fopen(filename_str,"wb"); - fd_dat = fopen(filename_dat,"wb"); - if (fd_str == NULL || fd_dat == NULL) { - return 1; - } - - if(fwrite(bloom,1,sizeof(struct bloom),fd_str) != sizeof(struct bloom) ) { - fclose(fd_str); - fclose(fd_dat); - fprintf(stderr,"fwrite bloom\n"); - exit(0); - return 1; - } - if(fwrite(bloom->bf,1, bloom->bytes,fd_dat) !=bloom->bytes) { - fclose(fd_str); - fclose(fd_dat); - fprintf(stderr,"fwrite bloom->bf\n"); - exit(0); - return 1; - } - fclose(fd_str); - fclose(fd_dat); - return 0; -} - - -int bloom_save(struct bloom * bloom, char * filename) -{ - if (filename == NULL || filename[0] == 0) { - return 1; - } - - int fd = open(filename, O_WRONLY | O_CREAT, 0644); - if (fd < 0) { - return 1; - } - - ssize_t out = write(fd, BLOOM_MAGIC, strlen(BLOOM_MAGIC)); - if (out != strlen(BLOOM_MAGIC)) { goto save_error; } // LCOV_EXCL_LINE - - uint16_t size = sizeof(struct bloom); - out = write(fd, &size, sizeof(uint16_t)); - if (out != sizeof(uint16_t)) { goto save_error; } // LCOV_EXCL_LINE - - out = write(fd, bloom, sizeof(struct bloom)); - if (out != sizeof(struct bloom)) { goto save_error; } // LCOV_EXCL_LINE - - out = write(fd, bloom->bf, bloom->bytes); - if (out != bloom->bytes) { goto save_error; } // LCOV_EXCL_LINE - - close(fd); - return 0; - // LCOV_EXCL_START - save_error: - close(fd); - return 1; - // LCOV_EXCL_STOP -} - - -int bloom_load(struct bloom * bloom, char * filename) -{ - int rv = 0; - - if (filename == NULL || filename[0] == 0) { return 1; } - if (bloom == NULL) { return 2; } - - memset(bloom, 0, sizeof(struct bloom)); - - int fd = open(filename, O_RDONLY); - if (fd < 0) { return 3; } - - char line[30]; - memset(line, 0, 30); - ssize_t in = read(fd, line, strlen(BLOOM_MAGIC)); - - if (in != strlen(BLOOM_MAGIC)) { - rv = 4; - goto load_error; - } - - if (strncmp(line, BLOOM_MAGIC, strlen(BLOOM_MAGIC))) { - rv = 5; - goto load_error; - } - - uint16_t size; - in = read(fd, &size, sizeof(uint16_t)); - if (in != sizeof(uint16_t)) { - rv = 6; - goto load_error; - } - - if (size != sizeof(struct bloom)) { - rv = 7; - goto load_error; - } - - in = read(fd, bloom, sizeof(struct bloom)); - if (in != sizeof(struct bloom)) { - rv = 8; - goto load_error; - } - - bloom->bf = NULL; - if (bloom->major != BLOOM_VERSION_MAJOR) { - rv = 9; - goto load_error; - } - - bloom->bf = (unsigned char *)malloc(bloom->bytes); - if (bloom->bf == NULL) { rv = 10; goto load_error; } // LCOV_EXCL_LINE - - in = read(fd, bloom->bf, bloom->bytes); - if (in != bloom->bytes) { - rv = 11; - free(bloom->bf); - bloom->bf = NULL; - goto load_error; - } - - close(fd); - return rv; - - load_error: - close(fd); - bloom->ready = 0; - return rv; -} - - -const char * bloom_version() -{ - return MAKESTRING(BLOOM_VERSION); -} +/* + * Copyright (c) 2012-2019, Jyri J. Virkki + * All rights reserved. + * + * This file is under BSD license. See LICENSE file. + */ + +/* + * Refer to bloom.h for documentation on the public interfaces. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bloom.h" +#include "../xxhash/xxhash.h" + +#define MAKESTRING(n) STRING(n) +#define STRING(n) #n +#define BLOOM_MAGIC "libbloom2" +#define BLOOM_VERSION_MAJOR 2 +#define BLOOM_VERSION_MINOR 201 + +inline static int test_bit_set_bit(uint8_t *bf, uint64_t bit, int set_bit) +{ + uint64_t byte = bit >> 3; + uint8_t c = bf[byte]; // expensive memory access + uint8_t mask = 1 << (bit % 8); + if (c & mask) { + return 1; + } else { + if (set_bit) { + bf[byte] = c | mask; + } + return 0; + } +} + +inline static int test_bit(uint8_t *bf, uint64_t bit) +{ + uint64_t byte = bit >> 3; + uint8_t c = bf[byte]; // expensive memory access + uint8_t mask = 1 << (bit % 8); + if (c & mask) { + return 1; + } else { + return 0; + } +} + +static int bloom_check_add(struct bloom * bloom, const void * buffer, int len, int add) +{ + if (bloom->ready == 0) { + printf("bloom at %p not initialized!\n", (void *)bloom); + return -1; + } + uint8_t hits = 0; + uint64_t a = XXH64(buffer, len, 0x59f2815b16f81798); + uint64_t b = XXH64(buffer, len, a); + uint64_t x; + uint8_t i; + for (i = 0; i < bloom->hashes; i++) { + x = (a + b*i) % bloom->bits; + if (test_bit_set_bit(bloom->bf, x, add)) { + hits++; + } else if (!add) { + // Don't care about the presence of all the bits. Just our own. + return 0; + } + } + if (hits == bloom->hashes) { + return 1; // 1 == element already in (or collision) + } + return 0; +} + +// DEPRECATED - Please migrate to bloom_init2. +int bloom_init(struct bloom * bloom, uint64_t entries, long double error) +{ + return bloom_init2(bloom, entries, error); +} + +int bloom_init2(struct bloom * bloom, uint64_t entries, long double error) +{ + memset(bloom, 0, sizeof(struct bloom)); + if (entries < 1000 || error <= 0 || error >= 1) { + return 1; + } + bloom->entries = entries; + bloom->error = error; + + long double num = -log(bloom->error); + long double denom = 0.480453013918201; // ln(2)^2 + bloom->bpe = (num / denom); + + long double dentries = (long double)entries; + long double allbits = dentries * bloom->bpe; + bloom->bits = (uint64_t)allbits; + + bloom->bytes = (uint64_t) bloom->bits / 8; + if (bloom->bits % 8) { + bloom->bytes +=1; + } + + bloom->hashes = (uint8_t)ceil(0.693147180559945 * bloom->bpe); // ln(2) + + bloom->bf = (uint8_t *)calloc(bloom->bytes, sizeof(uint8_t)); + if (bloom->bf == NULL) { // LCOV_EXCL_START + return 1; + } // LCOV_EXCL_STOP + + bloom->ready = 1; + bloom->major = BLOOM_VERSION_MAJOR; + bloom->minor = BLOOM_VERSION_MINOR; + return 0; +} + +int bloom_check(struct bloom * bloom, const void * buffer, int len) +{ + if (bloom->ready == 0) { + printf("bloom at %p not initialized!\n", (void *)bloom); + return -1; + } + uint8_t hits = 0; + uint64_t a = XXH64(buffer, len, 0x59f2815b16f81798); + uint64_t b = XXH64(buffer, len, a); + uint64_t x; + uint8_t i; + int r; + for (i = 0; i < bloom->hashes; i++) { + x = (a + b*i) % bloom->bits; + if (test_bit(bloom->bf, x)) { + hits++; + } else { + return 0; + } + } + if (hits == bloom->hashes) { + return 1; // 1 == element already in (or collision) + } + return 0; +} + + +int bloom_add(struct bloom * bloom, const void * buffer, int len) +{ + return bloom_check_add(bloom, buffer, len, 1); +} + +void bloom_print(struct bloom * bloom) +{ + printf("bloom at %p\n", (void *)bloom); + if (!bloom->ready) { printf(" *** NOT READY ***\n"); } + printf(" ->version = %d.%d\n", bloom->major, bloom->minor); + printf(" ->entries = %" PRIu64 "\n", bloom->entries); + printf(" ->error = %Lf\n", bloom->error); + printf(" ->bits = %" PRIu64 "\n", bloom->bits); + printf(" ->bits per elem = %f\n", bloom->bpe); + printf(" ->bytes = %" PRIu64 "\n", bloom->bytes); + unsigned int KB = bloom->bytes / 1024; + unsigned int MB = KB / 1024; + printf(" (%u KB, %u MB)\n", KB, MB); + printf(" ->hash functions = %d\n", bloom->hashes); +} + +void bloom_free(struct bloom * bloom) +{ + if (bloom->ready) { + free(bloom->bf); + } + bloom->ready = 0; +} + +int bloom_reset(struct bloom * bloom) +{ + if (!bloom->ready) return 1; + memset(bloom->bf, 0, bloom->bytes); + return 0; +} +/* +int bloom_save(struct bloom * bloom, char * filename) +{ + if (filename == NULL || filename[0] == 0) { + return 1; + } + + int fd = open(filename, O_WRONLY | O_CREAT, 0644); + if (fd < 0) { + return 1; + } + + ssize_t out = write(fd, BLOOM_MAGIC, strlen(BLOOM_MAGIC)); + if (out != strlen(BLOOM_MAGIC)) { goto save_error; } // LCOV_EXCL_LINE + + uint16_t size = sizeof(struct bloom); + out = write(fd, &size, sizeof(uint16_t)); + if (out != sizeof(uint16_t)) { goto save_error; } // LCOV_EXCL_LINE + + out = write(fd, bloom, sizeof(struct bloom)); + if (out != sizeof(struct bloom)) { goto save_error; } // LCOV_EXCL_LINE + + out = write(fd, bloom->bf, bloom->bytes); + if (out != bloom->bytes) { goto save_error; } // LCOV_EXCL_LINE + + close(fd); + return 0; + // LCOV_EXCL_START + save_error: + close(fd); + return 1; + // LCOV_EXCL_STOP +} + + +int bloom_load(struct bloom * bloom, char * filename) +{ + int rv = 0; + + if (filename == NULL || filename[0] == 0) { return 1; } + if (bloom == NULL) { return 2; } + + memset(bloom, 0, sizeof(struct bloom)); + + int fd = open(filename, O_RDONLY); + if (fd < 0) { return 3; } + + char line[30]; + memset(line, 0, 30); + ssize_t in = read(fd, line, strlen(BLOOM_MAGIC)); + + if (in != strlen(BLOOM_MAGIC)) { + rv = 4; + goto load_error; + } + + if (strncmp(line, BLOOM_MAGIC, strlen(BLOOM_MAGIC))) { + rv = 5; + goto load_error; + } + + uint16_t size; + in = read(fd, &size, sizeof(uint16_t)); + if (in != sizeof(uint16_t)) { + rv = 6; + goto load_error; + } + + if (size != sizeof(struct bloom)) { + rv = 7; + goto load_error; + } + + in = read(fd, bloom, sizeof(struct bloom)); + if (in != sizeof(struct bloom)) { + rv = 8; + goto load_error; + } + + bloom->bf = NULL; + if (bloom->major != BLOOM_VERSION_MAJOR) { + rv = 9; + goto load_error; + } + + bloom->bf = (unsigned char *)malloc(bloom->bytes); + if (bloom->bf == NULL) { rv = 10; goto load_error; } // LCOV_EXCL_LINE + + in = read(fd, bloom->bf, bloom->bytes); + if (in != bloom->bytes) { + rv = 11; + free(bloom->bf); + bloom->bf = NULL; + goto load_error; + } + + close(fd); + return rv; + + load_error: + close(fd); + bloom->ready = 0; + return rv; +} +*/ + +const char * bloom_version() +{ + return MAKESTRING(BLOOM_VERSION); +} diff --git a/bloom/bloom.h b/bloom/bloom.h index d395be6..562348a 100644 --- a/bloom/bloom.h +++ b/bloom/bloom.h @@ -8,6 +8,10 @@ #ifndef _BLOOM_H #define _BLOOM_H +#ifdef _WIN64 +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -37,18 +41,16 @@ struct bloom uint8_t major; uint8_t minor; double bpe; - uint8_t checksum[32]; - uint8_t checksum_backup[32]; uint8_t *bf; - pthread_mutex_t mutex; }; /* Customs */ -int bloom_dummy(struct bloom * bloom, uint64_t entries, long double error); +/* int bloom_loadcustom(struct bloom * bloom, char * filename); int bloom_savecustom(struct bloom * bloom, char * filename); +*/ /** *************************************************************************** @@ -184,7 +186,7 @@ int bloom_reset(struct bloom * bloom); * 1 - on failure * */ -int bloom_save(struct bloom * bloom, char * filename); +//int bloom_save(struct bloom * bloom, char * filename); /** *************************************************************************** @@ -202,7 +204,7 @@ int bloom_save(struct bloom * bloom, char * filename); * > 0 - on failure * */ -int bloom_load(struct bloom * bloom, char * filename); +//int bloom_load(struct bloom * bloom, char * filename); /** *************************************************************************** @@ -217,4 +219,4 @@ const char * bloom_version(); } #endif -#endif +#endif \ No newline at end of file diff --git a/keyhunt.c b/keyhunt.cpp similarity index 78% rename from keyhunt.c rename to keyhunt.cpp index fa4e8cf..2614490 100644 --- a/keyhunt.c +++ b/keyhunt.cpp @@ -8,8 +8,6 @@ email: alberto.bsd@gmail.com #include #include #include -#include -#include #include #include #include @@ -17,8 +15,10 @@ email: alberto.bsd@gmail.com #include "base58/libbase58.h" #include "rmd160/rmd160.h" #include "sha256/sha256.h" +#include "oldbloom/oldbloom.h" #include "bloom/bloom.h" #include "sha3/sha3.h" +#include "util.h" #include "secp256k1/SECP256k1.h" #include "secp256k1/Point.h" @@ -26,9 +26,14 @@ email: alberto.bsd@gmail.com #include "secp256k1/IntGroup.h" #include "secp256k1/Random.h" -#include "util.h" -#ifdef WIN32 - #include + + +#ifdef _WIN64 +#include "getopt.h" +#include +#else +#include +#include #endif #define CRYPTO_NONE 0 @@ -47,6 +52,13 @@ email: alberto.bsd@gmail.com #define SEARCH_COMPRESS 1 #define SEARCH_BOTH 2 +#define THREADBPWORKLOAD 1048576 +#define FLIPBITLIMIT 10000000 + +struct checksumsha256 { + char data[32]; + char backup[32]; +}; struct bsgs_xvalue { uint8_t value[6]; @@ -68,8 +80,21 @@ struct bPload { uint64_t from; uint64_t to; uint64_t counter; + uint32_t aux; }; +#ifdef _WIN64 +#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) +PACK(struct publickey +{ + uint8_t parity; + union { + uint8_t data8[32]; + uint32_t data32[8]; + uint64_t data64[4]; + } X; +}); +#else struct __attribute__((__packed__)) publickey { uint8_t parity; union { @@ -78,8 +103,10 @@ struct __attribute__((__packed__)) publickey { uint64_t data64[4]; } X; }; +#endif -const char *version = "0.2.211012 Chocolate ¡Beta!"; + +const char *version = "0.2.211018 Chocolate ¡Beta!"; #define CPU_GRP_SIZE 1024 @@ -113,6 +140,17 @@ int64_t bsgs_partition(struct bsgs_xvalue *arr, int64_t n); int bsgs_searchbinary(struct bsgs_xvalue *arr,char *data,int64_t _N,uint64_t *r_value); int bsgs_secondcheck(Int *start_range,uint32_t a,uint32_t k_index,Int *privatekey); +#ifdef _WIN64 +DWORD WINAPI thread_process(LPVOID vargp); +DWORD WINAPI thread_process_bsgs(LPVOID vargp); +DWORD WINAPI thread_process_bsgs_backward(LPVOID vargp); +DWORD WINAPI thread_process_bsgs_both(LPVOID vargp); +DWORD WINAPI thread_process_bsgs_random(LPVOID vargp); +DWORD WINAPI thread_process_bsgs_dance(LPVOID vargp); +DWORD WINAPI thread_bPload(LPVOID vargp); +DWORD WINAPI thread_bPloadFile(LPVOID vargp); +DWORD WINAPI thread_pub2rmd(LPVOID vargp); +#else void *thread_process(void *vargp); void *thread_process_bsgs(void *vargp); void *thread_process_bsgs_backward(void *vargp); @@ -122,6 +160,8 @@ void *thread_process_bsgs_dance(void *vargp); void *thread_bPload(void *vargp); void *thread_bPloadFile(void *vargp); void *thread_pub2rmd(void *vargp); +#endif + char *publickeytohashrmd160(char *pkey,int length); char *pubkeytopubaddress(char *pkey,int length); @@ -129,7 +169,7 @@ char *pubkeytopubaddress(char *pkey,int length); void KECCAK_256(uint8_t *source, size_t size,uint8_t *dst); void generate_binaddress_eth(Point *publickey,unsigned char *dst_address); -void memorycheck(); +void memorycheck_bsgs(); int THREADOUTPUT = 0; char *bit_range_str_min; @@ -141,15 +181,32 @@ const char *cryptos[3] = {"btc","eth","all"}; const char *publicsearch[3] = {"uncompress","compress","both"}; const char *default_filename = "addresses.txt"; +#ifdef _WIN64 +HANDLE* tid = NULL; +HANDLE write_keys; +HANDLE write_random; +HANDLE bsgs_thread; +HANDLE bPload_mutex; +#else pthread_t *tid = NULL; pthread_mutex_t write_keys; pthread_mutex_t write_random; - pthread_mutex_t bsgs_thread; +pthread_mutex_t bPload_mutex; +#endif -struct bloom bloom; + +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 AVAILABLE_THREADS; +struct bloom bloom; + uint64_t *steps = NULL; unsigned int *ends = NULL; uint64_t N = 0; @@ -159,8 +216,6 @@ uint64_t N_SECUENTIAL_MAX = 0xffffffff; uint64_t DEBUGCOUNT = 0x100000; - - Int OUTPUTSECONDS; @@ -176,6 +231,10 @@ int FLAGSAVEREADFILE = 0; int FLAGREADEDFILE1 = 0; int FLAGREADEDFILE2 = 0; int FLAGREADEDFILE3 = 0; + +int FLAGUPDATEFILE1 = 0; +int FLAGUPDATEFILE2 = 0; + int FLAGSEARCH = 2; int FLAGBITRANGE = 0; int FLAGRANGE = 0; @@ -213,8 +272,25 @@ char checksum[32],checksum_backup[32]; char buffer_bloom_file[1024]; struct bsgs_xvalue *bPtable; struct address_value *addressTable; -struct bloom bloom_bP[256]; + +struct oldbloom oldbloom_bP; +struct bloom *bloom_bP; +struct checksumsha256 *bloom_bP_checksums; + +#ifdef _WIN64 +std::vector bloom_bP_mutex; +HANDLE bloom_bPx2nd_mutex; +#else +pthread_mutex_t *bloom_bP_mutex; +pthread_mutex_t bloom_bPx2nd_mutex; +#endif + + + + struct bloom bloom_bPx2nd; //Second Bloom filter check +struct checksumsha256 bloom_bPx2nd_checksum; + uint64_t bloom_bP_totalbytes = 0; char *precalculated_p_filename; uint64_t bsgs_m = 4194304; @@ -262,12 +338,35 @@ int main(int argc, char **argv) { char rawvalue[32]; struct tothread *tt; //tothread Tokenizer t,tokenizerbsgs,tokenizer_xpoint; //tokenizer - char *filename,*precalculated_mp_filename,*hextemp,*aux,*aux2,*pointx_str,*pointy_str,*str_seconds,*str_total,*str_pretotal,*str_divpretotal,*bf_ptr; + char *filename = NULL; + char *precalculated_mp_filename = NULL; + char *hextemp = NULL; + char *aux = NULL; + char *aux2 = NULL; + char *pointx_str = NULL; + char *pointy_str = NULL; + char *str_seconds = NULL; + char *str_total = NULL; + char *str_pretotal = NULL; + char *str_divpretotal = NULL; + char *bf_ptr = NULL; + FILE *fd,*fd_aux1,*fd_aux2,*fd_aux3; uint64_t j,total_precalculated,i,PERTHREAD,BASE,PERTHREAD_R,itemsbloom,itemsbloom2; - int readed,s,continue_flag,check_flag,r,lenaux,lendiff,c,salir,index_value; + int readed,continue_flag,check_flag,r,lenaux,lendiff,c,salir,index_value; Int total,pretotal,debugcount_mpz,seconds,div_pretotal; - struct bPload *temp; + struct bPload *bPload_temp_ptr; + +#ifdef _WIN64 + DWORD s; + write_keys = CreateMutex(NULL, FALSE, NULL); + write_random = CreateMutex(NULL, FALSE, NULL); + bsgs_thread = CreateMutex(NULL, FALSE, NULL); +#else + int s; +#endif + + srand (time(NULL)); secp = new Secp256K1(); @@ -277,8 +376,13 @@ int main(int argc, char **argv) { ONE.SetInt32(1); BSGS_GROUP_SIZE.SetInt32(CPU_GRP_SIZE); rseed(clock() + time(NULL)); - + +#ifdef _WIN64 + printf("[+] Version %s, developed by AlbertoBSD(Win64 build by KV)\n", version); +#else printf("[+] Version %s, developed by AlbertoBSD\n",version); +#endif + while ((c = getopt(argc, argv, "dehMqRwzSB:b:c:E:f:k:l:m:n:p:r:s:t:v:V:G:")) != -1) { switch(c) { @@ -370,6 +474,7 @@ int main(int argc, char **argv) { break; case 'd': FLAGDEBUG = 1; + printf("[+] Flag DEBUG enabled\n"); break; case 'e': @@ -696,9 +801,6 @@ int main(int argc, char **argv) { N_SECUENTIAL_MAX = 0xFFFFFFFF; } } - - - aux =(char*) malloc(1000); if(aux == NULL) { @@ -1097,9 +1199,6 @@ int main(int argc, char **argv) { bsgs_m = BSGS_M.GetInt64(); - - - if(FLAGRANGE || FLAGBITRANGE) { if(FLAGBITRANGE) { // Bit Range n_range_start.SetBase16(bit_range_str_min); @@ -1165,6 +1264,14 @@ int main(int argc, char **argv) { itemsbloom2 = bsgs_m2 > 1000 ? bsgs_m2 : 10000; printf("[+] Bloom filter for %" PRIu64 " elements ",bsgs_m); + bloom_bP = (struct bloom*)calloc(256,sizeof(struct bloom)); + bloom_bP_checksums = (struct checksumsha256*)calloc(256,sizeof(struct checksumsha256)); + bloom_bP_mutex = (pthread_mutex_t*) calloc(256,sizeof(pthread_mutex_t)); + + + if(bloom_bP == NULL || bloom_bP_checksums == NULL) { + fprintf(stderr,"[E] error calloc()\n"); + } fflush(stdout); for(i=0; i< 256; i++) { if(bloom_init2(&bloom_bP[i],itemsbloom,0.000001) == 1){ @@ -1172,9 +1279,9 @@ int main(int argc, char **argv) { exit(0); } bloom_bP_totalbytes += bloom_bP[i].bytes; - if(FLAGDEBUG) bloom_print(&bloom_bP[i]); + //if(FLAGDEBUG) bloom_print(&bloom_bP[i]); } - printf(": %.2f MB\n",(float)((uint64_t)bloom_bP_totalbytes/(uint64_t)1048576)); + printf(": %.2f MB\n",(float)((float)(uint64_t)bloom_bP_totalbytes/(float)(uint64_t)1048576)); //if(FLAGDEBUG) bloom_print(&bloom_bP); if(bloom_init2(&bloom_bPx2nd,itemsbloom2,0.000001) == 1){ @@ -1182,7 +1289,7 @@ int main(int argc, char **argv) { exit(0); } - if(FLAGDEBUG) bloom_print(&bloom_bPx2nd); + //if(FLAGDEBUG) bloom_print(&bloom_bPx2nd); printf("[+] Bloom filter for %" PRIu64 " elements : %.2f MB\n",bsgs_m2,(double)((double)bloom_bPx2nd.bytes/(double)1048576)); @@ -1233,14 +1340,13 @@ int main(int argc, char **argv) { if(FLAGSAVEREADFILE) { /*Reading file for 1st bloom filter */ - snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_3_%" PRIu64 ".blm",bsgs_m); + + 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); - FLAGREADEDFILE1 = 1; - for(i = 0; i < 256 && FLAGREADEDFILE1;i++) { + 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) { @@ -1253,48 +1359,115 @@ int main(int argc, char **argv) { 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(memcmp(bloom_bP[i].checksum,rawvalue,32) == 0 ) { /* Old File, we need to do the checksum*/ - if(FLAGDEBUG) printf("[D] bloom_bP.checksum is zero\n"); - sha256((char*)bloom_bP[i].bf,bloom_bP[i].bytes,bloom_bP[i].checksum); - memcpy(bloom_bP[i].checksum_backup,bloom_bP[i].checksum,32); - FLAGREADEDFILE1 = 0; /* We mark the FLAGREADEDFILE1 to 0 to write the file with the correct checkum*/ + sha256((char*)bloom_bP[i].bf,bloom_bP[i].bytes,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!\n"); + exit(0); } - else { /* new file, we need to verify the checksum */ - sha256((char*)bloom_bP[i].bf,bloom_bP[i].bytes,rawvalue); - if(memcmp(bloom_bP[i].checksum,rawvalue,32) == 0 ) { /* Verification */ - FLAGREADEDFILE1 = 1; /* OK */ + /* + if(FLAGDEBUG) { + hextemp = tohex(bloom_bP_checksums[i].data,32); + printf("Checksum %s\n",hextemp); + free(hextemp); + bloom_print(&bloom_bP[i]); + } + */ + } + 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); } - else { + */ + + 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); + sha256((char*)bloom_bP[i].bf,bloom_bP[i].bytes,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!\n"); exit(0); } + /* + else { + if(FLAGDEBUG) { + hextemp = tohex(bloom_bP_checksums[i].data,32); + printf("Checksum OK : %s\n",i,hextemp); + free(hextemp); + } + } + */ + + /* + if(FLAGDEBUG) { + printf("NEW Bloom filter %i\n",i); + bloom_print(bloom_bP); + printf("Press enter to continue... "); + fgets(rawvalue,1024,stdin); + } + */ + } + 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 } - - - - - - - - - - printf(" Done!\n"); - fclose(fd_aux1); - } - else { - FLAGREADEDFILE1 = 0; } /*Reading file for 2nd bloom filter */ - snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_1_%" PRIu64 ".blm",bsgs_m2); + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_5_%" PRIu64 ".blm",bsgs_m2); fd_aux2 = fopen(buffer_bloom_file,"rb"); if(fd_aux2 != NULL) { bf_ptr = (char*) bloom_bPx2nd.bf; /*We need to save the current bf pointer*/ - printf("[+] Reading bloom filter from file %s .. ",buffer_bloom_file); + printf("[+] Reading bloom filter from file %s ..",buffer_bloom_file); fflush(stdout); readed = fread(&bloom_bPx2nd,sizeof(struct bloom),1,fd_aux2); + if(readed != 1) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(0); @@ -1305,28 +1478,72 @@ int main(int argc, char **argv) { fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); exit(0); } + readed = fread(&bloom_bPx2nd_checksum,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(memcmp(bloom_bPx2nd.checksum,rawvalue,32) == 0 ) { /* Old File, we need to do the checksum*/ - if(FLAGDEBUG) printf("[D] bloom_bPx2nd.checksum is zero\n"); - sha256((char*)bloom_bPx2nd.bf,bloom_bPx2nd.bytes,bloom_bPx2nd.checksum); - memcpy(bloom_bPx2nd.checksum_backup,bloom_bPx2nd.checksum,32); - FLAGREADEDFILE2 = 0; /* We mark the FLAGREADEDFILE2 to 0 to write the file with the correct checkum*/ + sha256((char*)bloom_bPx2nd.bf,bloom_bPx2nd.bytes,rawvalue); + if(memcmp(bloom_bPx2nd_checksum.data,rawvalue,32) != 0 || memcmp(bloom_bPx2nd_checksum.backup,rawvalue,32) != 0 ) { /* Verification */ + fprintf(stderr,"[E] Error checksum file mismatch!\n"); + exit(0); } - else { /* new file, we need to verify the checksum */ - sha256((char*)bloom_bPx2nd.bf,bloom_bPx2nd.bytes,rawvalue); - if(memcmp(bloom_bPx2nd.checksum,rawvalue,32) == 0 ) { /* Verification */ - FLAGREADEDFILE2 = 1; /* OK */ + fclose(fd_aux2); + printf(" Done!\n"); + /* + if(FLAGDEBUG) { + hextemp = tohex(bloom_bPx2nd_checksum.data,32); + printf("Checksum %s\n",hextemp); + free(hextemp); + bloom_print(&bloom_bPx2nd); + } + */ + 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 { /* Checking for old file keyhunt_bsgs_1*/ + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_1_%" PRIu64 ".blm",bsgs_m2); + fd_aux2 = fopen(buffer_bloom_file,"rb"); + if(fd_aux2 != NULL) { + bf_ptr = (char*) bloom_bPx2nd.bf; /* We need to save the current bf pointer */ + printf("[+] Reading bloom filter from file %s .. ",buffer_bloom_file); + fflush(stdout); + readed = fread(&oldbloom_bP,sizeof(struct oldbloom),1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); } - else { + memcpy(&bloom_bPx2nd,&oldbloom_bP,sizeof(struct bloom));//We only need to copy the part data to the new bloom size, not from the old size + bloom_bPx2nd.bf = (uint8_t*)bf_ptr; /* Restoring the bf pointer*/ + readed = fread(bloom_bPx2nd.bf,bloom_bPx2nd.bytes,1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); + } + memcpy(bloom_bPx2nd_checksum.data,oldbloom_bP.checksum,32); + memcpy(bloom_bPx2nd_checksum.backup,oldbloom_bP.checksum_backup,32); + + sha256((char*)bloom_bPx2nd.bf,bloom_bPx2nd.bytes,rawvalue); + if(memcmp(bloom_bPx2nd_checksum.data,rawvalue,32) != 0 || memcmp(bloom_bPx2nd_checksum.backup,rawvalue,32) != 0 ) { /* Verification */ fprintf(stderr,"[E] Error checksum file mismatch!\n"); exit(0); } + printf("Done!\n"); + fclose(fd_aux2); + FLAGREADEDFILE2 = 1; /* OK */ + FLAGUPDATEFILE2 = 1; + } + else { + FLAGREADEDFILE2 = 0; } - printf("Done!\n"); - fclose(fd_aux2); - } - else { - FLAGREADEDFILE2 = 0; } /*Reading file for bPtable */ @@ -1349,104 +1566,181 @@ int main(int argc, char **argv) { printf(" Done!\n"); fclose(fd_aux3); FLAGREADEDFILE3 = 1; + /* + if(FLAGDEBUG) { + hextemp = tohex(checksum,32); + printf("Checksum %s\n",hextemp); + free(hextemp); + } + */ } else { FLAGREADEDFILE3 = 0; } } - if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 || !FLAGREADEDFILE3) { /*If just one of the files were not readed, then we need to calculate the content*/ - i = 0; - j = 0; + if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 || !FLAGREADEDFILE3) { /*If just one of the files were not readed, then we need to calculate the content of all because bloom*/ + AVAILABLE_THREADS = NTHREADS; + FINISHED_THREADS_COUNTER = 0; + FINISHED_THREADS_BP = 0; + FINISHED_ITEMS = 0; + salir = 0; BASE = 0; - PERTHREAD = bsgs_m /NTHREADS; - PERTHREAD_R = bsgs_m % NTHREADS; - temp = (struct bPload *) calloc(NTHREADS,sizeof(struct bPload)); + THREADCOUNTER = 0; + THREADCYCLES = bsgs_m /THREADBPWORKLOAD; + PERTHREAD_R = bsgs_m % THREADBPWORKLOAD; + //if(FLAGDEBUG) printf("[D] THREADCYCLES: %lu\n",THREADCYCLES); + if(PERTHREAD_R != 0) { + THREADCYCLES++; + //if(FLAGDEBUG) printf("[D] PERTHREAD_R: %lu\n",PERTHREAD_R); + } + + printf("\r[+] processing %lu/%lu bP points : %i%%\r",FINISHED_ITEMS,bsgs_m,(int) (((double)FINISHED_ITEMS/(double)bsgs_m)*100)); + fflush(stdout); + +#ifdef _WIN64 + tid = (HANDLE*)calloc(NTHREADS, sizeof(HANDLE)); +#else tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); - - - +#endif if(FLAGPRECALCUTED_P_FILE) { - printf("[+] Reading %lu bP points from file %s\n",bsgs_m,precalculated_p_filename); - for(i = 0; i < NTHREADS; i++) { - temp[i].threadid = i; - temp[i].counter = 0; - if(i < NTHREADS -1) { - temp[i].from = BASE +1; - temp[i].to = BASE + PERTHREAD; + do { + for(i = 0; i < AVAILABLE_THREADS && !salir; i++) { + bPload_temp_ptr = (struct bPload*) calloc(1,sizeof(struct bPload)); + bPload_temp_ptr->from = BASE +1; + bPload_temp_ptr->threadid = THREADCOUNTER; + if( THREADCOUNTER < THREADCYCLES-1) { + bPload_temp_ptr->to = BASE + THREADBPWORKLOAD; + } + else { + bPload_temp_ptr->to = BASE + THREADBPWORKLOAD + PERTHREAD_R; + salir = 1; + } + //if(FLAGDEBUG) printf("[I] %lu to %lu\n",bPload_temp_ptr->from,bPload_temp_ptr->to); +#ifdef _WIN64 + tid[0] = CreateThread(NULL, 0, thread_bPloadFile, (void*)bPload_temp_ptr, 0, &s); +#else + s = pthread_create(&tid[0],NULL,thread_bPloadFile,(void*)bPload_temp_ptr); +#endif + BASE+=THREADBPWORKLOAD; + THREADCOUNTER++; } - else { - temp[i].from = BASE + 1; - temp[i].to = BASE + PERTHREAD + PERTHREAD_R; + AVAILABLE_THREADS = 0; + + 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; } - if(FLAGDEBUG) printf("[I] %lu to %lu\n",temp[i].from,temp[i].to); - s = pthread_create(&tid[i],NULL,thread_bPloadFile,(void *)&temp[i]); - BASE+=PERTHREAD; - } + sleep_ms(10); +#ifdef _WIN64 + WaitForSingleObject(bPload_mutex, INFINITE); + AVAILABLE_THREADS = FINISHED_THREADS_BP; + FINISHED_THREADS_BP = 0; + ReleaseMutex(bPload_mutex); +#else + pthread_mutex_lock(&bPload_mutex); + AVAILABLE_THREADS = FINISHED_THREADS_BP; + FINISHED_THREADS_BP = 0; + pthread_mutex_unlock(&bPload_mutex); + #endif + FINISHED_THREADS_COUNTER+= AVAILABLE_THREADS; + FINISHED_ITEMS+= AVAILABLE_THREADS * THREADBPWORKLOAD; + + + }while(FINISHED_THREADS_COUNTER < THREADCYCLES); + printf("\r[+] processing %lu/%lu bP points : 100%% \n",bsgs_m,bsgs_m); } else { - for(i = 0; i < NTHREADS; i++) { - temp[i].counter = i; - if(i < NTHREADS -1) { - temp[i].from = BASE +1; - temp[i].to = BASE + PERTHREAD; - BASE+=PERTHREAD; + do { + for(i = 0; i < AVAILABLE_THREADS && !salir; i++) { + bPload_temp_ptr = (struct bPload*) calloc(1,sizeof(struct bPload)); + bPload_temp_ptr->from = BASE +1; + bPload_temp_ptr->threadid = THREADCOUNTER; + if( THREADCOUNTER < THREADCYCLES-1) { + bPload_temp_ptr->to = BASE + THREADBPWORKLOAD; + } + else { + bPload_temp_ptr->to = BASE + THREADBPWORKLOAD + PERTHREAD_R; + salir = 1; + //if(FLAGDEBUG) printf("[D] Salir OK\n"); + } + //if(FLAGDEBUG) printf("[I] %lu to %lu\n",bPload_temp_ptr->from,bPload_temp_ptr->to); +#ifdef _WIN64 + tid[0] = CreateThread(NULL, 0, thread_bPload, (void*)bPload_temp_ptr, 0, &s); +#else + s = pthread_create(&tid[0],NULL,thread_bPload,(void*)bPload_temp_ptr); +#endif + BASE+=THREADBPWORKLOAD; + THREADCOUNTER++; } - else { - temp[i].from = BASE + 1; - temp[i].to = BASE + PERTHREAD + PERTHREAD_R; - BASE+=(PERTHREAD + PERTHREAD_R); + AVAILABLE_THREADS = 0; + 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; } - if(FLAGDEBUG) printf("[I] %lu to %lu\n",temp[i].from,temp[i].to); - s = pthread_create(&tid[i],NULL,thread_bPload,(void *)&temp[i]); - } - } - total_precalculated = 0; - do { - sleep(1); - total_precalculated = 0; - for(i = 0; i < NTHREADS; i++) { - total_precalculated+=temp[i].counter; - } - printf("\r[+] processing %lu/%lu bP points : %i%%\r",total_precalculated,bsgs_m,(int) (((double)total_precalculated/(double)bsgs_m)*100)); - fflush(stdout); - } while(total_precalculated < bsgs_m); + sleep_ms(10); +#ifdef _WIN64 + WaitForSingleObject(bPload_mutex, INFINITE); + AVAILABLE_THREADS = FINISHED_THREADS_BP; + FINISHED_THREADS_BP = 0; + FINISHED_THREADS_COUNTER+= AVAILABLE_THREADS; + FINISHED_ITEMS+= AVAILABLE_THREADS * THREADBPWORKLOAD; + ReleaseMutex(bPload_mutex); +#else + pthread_mutex_lock(&bPload_mutex); + AVAILABLE_THREADS = FINISHED_THREADS_BP; + FINISHED_THREADS_BP = 0; + FINISHED_THREADS_COUNTER+= AVAILABLE_THREADS; + FINISHED_ITEMS+= AVAILABLE_THREADS * THREADBPWORKLOAD; + pthread_mutex_unlock(&bPload_mutex); +#endif - for(i = 0; i < NTHREADS; i++) { - pthread_join(tid[i], NULL); - } - printf("\n"); - free(temp); - free(tid); - + }while(FINISHED_THREADS_COUNTER < THREADCYCLES); + printf("\r[+] processing %lu/%lu bP points : 100%% \n",bsgs_m,bsgs_m); + } + + free(tid); } + + if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 ) { + printf("[+] Making checkums .. "); + fflush(stdout); + } if(!FLAGREADEDFILE1) { - for(i = 0; i < 256 ; i++) { - sha256((char*)bloom_bP[i].bf, bloom_bP[i].bytes, bloom_bP[i].checksum); - memcpy(bloom_bP[i].checksum_backup,bloom_bP[i].checksum,32); + sha256((char*)bloom_bP[i].bf, bloom_bP[i].bytes, bloom_bP_checksums[i].data); + memcpy(bloom_bP_checksums[i].backup,bloom_bP_checksums[i].data,32); } - - } - if(!FLAGREADEDFILE2) { - sha256((char*)bloom_bPx2nd.bf, bloom_bPx2nd.bytes, bloom_bPx2nd.checksum); - memcpy(bloom_bPx2nd.checksum_backup,bloom_bPx2nd.checksum,32); + sha256((char*)bloom_bPx2nd.bf, bloom_bPx2nd.bytes, bloom_bPx2nd_checksum.data); + memcpy(bloom_bPx2nd_checksum.backup,bloom_bPx2nd_checksum.data,32); } + if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 ) { + printf("done\n"); + fflush(stdout); + } if(!FLAGREADEDFILE3) { printf("[+] Sorting %lu elements... ",bsgs_m2); fflush(stdout); bsgs_sort(bPtable,bsgs_m2); - printf("Done!\n"); - fflush(stdout); sha256((char*)bPtable, bytes, checksum); memcpy(checksum_backup,checksum,32); + printf("Done!\n"); + fflush(stdout); } - if(FLAGSAVEREADFILE) { - if(!FLAGREADEDFILE1) { + if(FLAGSAVEREADFILE || FLAGUPDATEFILE1 || FLAGUPDATEFILE2 ) { + 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 */ - snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_3_%" PRIu64 ".blm",bsgs_m); + fd_aux1 = fopen(buffer_bloom_file,"wb"); if(fd_aux1 != NULL) { printf("[+] Writing bloom filter to file %s .. ",buffer_bloom_file); @@ -1462,6 +1756,19 @@ int main(int argc, char **argv) { 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(FLAGDEBUG) { + hextemp = tohex(bloom_bP_checksums[i].data,32); + printf("Checksum %s\n",hextemp); + free(hextemp); + bloom_print(&bloom_bP[i]); + } + */ } printf("Done!\n"); fclose(fd_aux1); @@ -1470,9 +1777,15 @@ int main(int argc, char **argv) { fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); } } - if(!FLAGREADEDFILE2) { + if(!FLAGREADEDFILE2 || FLAGUPDATEFILE2 ) { + + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_5_%" PRIu64 ".blm",bsgs_m2); + + if(FLAGUPDATEFILE1) { + printf("[W] Updating old file into a new one\n"); + } + /* Writing file for 2nd bloom filter */ - snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_1_%" PRIu64 ".blm",bsgs_m2); fd_aux2 = fopen(buffer_bloom_file,"wb"); if(fd_aux2 != NULL) { printf("[+] Writing bloom filter to file %s .. ",buffer_bloom_file); @@ -1487,15 +1800,27 @@ int main(int argc, char **argv) { fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); exit(0); } + readed = fwrite(&bloom_bPx2nd_checksum,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); + } printf("Done!\n"); fclose(fd_aux2); + /* + if(FLAGDEBUG) { + hextemp = tohex(bloom_bPx2nd_checksum.data,32); + printf("Checksum %s\n",hextemp); + free(hextemp); + bloom_print(&bloom_bPx2nd); + } + */ } else { fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); } } - if(!FLAGREADEDFILE3) { /* Writing file for bPtable */ snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_2_%" PRIu64 ".tbl",bsgs_m2); @@ -1514,7 +1839,14 @@ int main(int argc, char **argv) { exit(0); } printf("Done!\n"); - fclose(fd_aux3); + fclose(fd_aux3); + /* + if(FLAGDEBUG) { + hextemp = tohex(checksum,32); + printf("Checksum %s\n",hextemp); + free(hextemp); + } + */ } else { fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); @@ -1527,12 +1859,35 @@ int main(int argc, char **argv) { steps = (uint64_t *) calloc(NTHREADS,sizeof(uint64_t)); ends = (unsigned int *) calloc(NTHREADS,sizeof(int)); +#ifdef _WIN64 + tid = (HANDLE*)calloc(NTHREADS, sizeof(HANDLE)); +#else tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); +#endif for(i= 0;i < NTHREADS; i++) { tt = (tothread*) malloc(sizeof(struct tothread)); tt->nt = i; switch(FLAGBSGSMODE) { +#ifdef _WIN64 + case 0: + tid[i] = CreateThread(NULL, 0, thread_process_bsgs, (void*)tt, 0, &s); + break; + case 1: + tid[i] = CreateThread(NULL, 0, thread_process_bsgs_backward, (void*)tt, 0, &s); + break; + case 2: + tid[i] = CreateThread(NULL, 0, thread_process_bsgs_both, (void*)tt, 0, &s); + break; + case 3: + tid[i] = CreateThread(NULL, 0, thread_process_bsgs_random, (void*)tt, 0, &s); + break; + case 4: + tid[i] = CreateThread(NULL, 0, thread_process_bsgs_dance, (void*)tt, 0, &s); + break; + } +#else + case 0: s = pthread_create(&tid[i],NULL,thread_process_bsgs,(void *)tt); break; @@ -1548,9 +1903,14 @@ int main(int argc, char **argv) { case 4: s = pthread_create(&tid[i],NULL,thread_process_bsgs_dance,(void *)tt); break; +#endif } +#ifdef _WIN64 + if (tid[i] == NULL) { +#else if(s != 0) { - fprintf(stderr,"[E] pthread_create thread_process\n"); +#endif + fprintf(stderr,"[E] thread thread_process\n"); exit(0); } } @@ -1561,13 +1921,26 @@ int main(int argc, char **argv) { if(FLAGMODE != MODE_BSGS) { steps = (uint64_t *) calloc(NTHREADS,sizeof(uint64_t)); ends = (unsigned int *) calloc(NTHREADS,sizeof(int)); +#ifdef _WIN64 + tid = (HANDLE*)calloc(NTHREADS, sizeof(HANDLE)); +#else tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); - +#endif for(i= 0;i < NTHREADS; i++) { tt = (tothread*) malloc(sizeof(struct tothread)); tt->nt = i; steps[i] = 0; switch(FLAGMODE) { +#ifdef _WIN64 + case MODE_ADDRESS: + case MODE_XPOINT: + case MODE_RMD160: + tid[i] = CreateThread(NULL, 0, thread_process, (void*)tt, 0, &s); + break; + case MODE_PUB2RMD: + tid[i] = CreateThread(NULL, 0, thread_pub2rmd, (void*)tt, 0, &s); + break; +#else case MODE_ADDRESS: case MODE_XPOINT: case MODE_RMD160: @@ -1576,6 +1949,7 @@ int main(int argc, char **argv) { case MODE_PUB2RMD: s = pthread_create(&tid[i],NULL,thread_pub2rmd,(void *)tt); break; +#endif } if(s != 0) { fprintf(stderr,"[E] pthread_create thread_process\n"); @@ -1596,7 +1970,7 @@ int main(int argc, char **argv) { debugcount_mpz.Set(&BSGS_N); seconds.SetInt32(0); do { - sleep(1); + sleep_ms(1000); seconds.AddOne(); check_flag = 1; for(i = 0; i Set(dx); do { - if(FLAGRANDOM){ key_mpz.Rand(&n_range_start,&n_range_end); } else { if(n_range_start.IsLower(&n_range_end)) { +#ifdef _WIN64 + WaitForSingleObject(write_random, INFINITE); +#else pthread_mutex_lock(&write_random); +#endif key_mpz.Set(&n_range_start); n_range_start.Add(N_SECUENTIAL_MAX); + +#ifdef _WIN64 + ReleaseMutex(write_random); +#else pthread_mutex_unlock(&write_random); +#endif + } else { continue_flag = 0; @@ -1958,14 +2356,24 @@ void *thread_process(void *vargp) { found++; hextemp = key_mpz.GetBase16(); public_key_compressed_hex = tohex(public_key_compressed,33); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else pthread_mutex_lock(&write_keys); +#endif + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(keys != NULL) { fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_compressed_hex,public_address_compressed); fclose(keys); } printf("\nHIT!! PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_compressed_hex,public_address_compressed); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + free(public_key_compressed_hex); free(hextemp); } @@ -1981,14 +2389,23 @@ void *thread_process(void *vargp) { found++; hextemp = key_mpz.GetBase16(); public_key_uncompressed_hex = tohex(public_key_uncompressed,65); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else pthread_mutex_lock(&write_keys); +#endif + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(keys != NULL) { fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,public_address_uncompressed); fclose(keys); } printf("\nHIT!! PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,public_address_uncompressed); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif free(public_key_uncompressed_hex); free(hextemp); } @@ -2010,14 +2427,24 @@ void *thread_process(void *vargp) { hexstrpoint[1] = 'x'; tohex_dst(rawvalue+12,20,hexstrpoint+2); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else pthread_mutex_lock(&write_keys); +#endif + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(keys != NULL) { fprintf(keys,"PrivKey: %s\naddress: %s\n",hextemp,hexstrpoint); fclose(keys); } printf("\n Hit!!!! PrivKey: %s\naddress: %s\n",hextemp,hexstrpoint); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + free(hextemp); } } @@ -2046,14 +2473,24 @@ void *thread_process(void *vargp) { found++; hextemp = key_mpz.GetBase16(); public_key_compressed_hex = tohex(public_key_compressed,33); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else pthread_mutex_lock(&write_keys); +#endif + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(keys != NULL) { fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex); fclose(keys); } printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + free(public_key_compressed_hex); free(hextemp); } @@ -2068,14 +2505,23 @@ void *thread_process(void *vargp) { found++; hextemp = key_mpz.GetBase16(); public_key_uncompressed_hex = tohex(public_key_uncompressed,65); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else pthread_mutex_lock(&write_keys); +#endif keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(keys != NULL) { fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex); fclose(keys); } printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + free(public_key_uncompressed_hex); free(hextemp); } @@ -2094,13 +2540,23 @@ void *thread_process(void *vargp) { R = secp->ComputePublicKey(&key_mpz); public_key_compressed = secp->GetPublicKeyHex(true,R); printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else pthread_mutex_lock(&write_keys); +#endif + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(keys != NULL) { fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed); fclose(keys); } +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + free(public_key_compressed); free(hextemp); } @@ -2392,7 +2848,12 @@ int bsgs_searchbinary(struct bsgs_xvalue *buffer,char *data,int64_t _N,uint64_t return r; } +#ifdef _WIN64 +DWORD WINAPI thread_process_bsgs(LPVOID vargp) { +#else void *thread_process_bsgs(void *vargp) { +#endif + FILE *filekey; struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; @@ -2422,32 +2883,39 @@ void *thread_process_bsgs(void *vargp) { thread_number = tt->nt; free(tt); - pthread_mutex_lock(&bsgs_thread); - /* we need to set our base_key to the current BSGS_CURRENT value*/ - base_key.Set(&BSGS_CURRENT); - BSGS_CURRENT.Add(&BSGS_N); + - /*Then add BSGS_N to BSGS_CURRENT*/ /* We do this in an atomic pthread_mutex operation to not affect others threads so BSGS_CURRENT is never the same between threads */ +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else + pthread_mutex_lock(&bsgs_thread); +#endif + + base_key.Set(&BSGS_CURRENT); /* we need to set our base_key to the current BSGS_CURRENT value*/ + BSGS_CURRENT.Add(&BSGS_N); /*Then add BSGS_N to BSGS_CURRENT*/ +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); +#endif intaux.Set(&BSGS_M); intaux.Mult(CPU_GRP_SIZE/2); - flip_detector = 1000000; + flip_detector = FLIPBITLIMIT; /* while base_key is less than n_range_end then: */ while(base_key.IsLower(&n_range_end) ) { if(thread_number == 0 && flip_detector == 0) { - memorycheck(); - flip_detector = 1000000; + memorycheck_bsgs(); + flip_detector = FLIPBITLIMIT; } - if(FLAGMATRIX) { aux_c = base_key.GetBase16(); printf("[+] Thread 0x%s \n",aux_c); @@ -2481,7 +2949,12 @@ void *thread_process_bsgs(void *vargp) { aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],base_point); printf("[+] Publickey %s\n",aux_c); +#ifdef _WIN64 + 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); @@ -2489,8 +2962,11 @@ void *thread_process_bsgs(void *vargp) { } free(hextemp); free(aux_c); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); - +#endif bsgs_found[k] = 1; salir = 1; for(j = 0; j < bsgs_point_number && salir; j++) { @@ -2602,7 +3078,12 @@ void *thread_process_bsgs(void *vargp) { point_found = secp->ComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); +#ifdef _WIN64 + 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); @@ -2610,7 +3091,12 @@ void *thread_process_bsgs(void *vargp) { } free(hextemp); free(aux_c); - pthread_mutex_unlock(&write_keys); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else + pthread_mutex_unlock(&write_keys); +#endif + bsgs_found[k] = 1; salir = 1; for(j = 0; j < bsgs_point_number && salir; j++) { @@ -2649,17 +3135,32 @@ void *thread_process_bsgs(void *vargp) { } steps[thread_number]++; +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else pthread_mutex_lock(&bsgs_thread); +#endif + base_key.Set(&BSGS_CURRENT); BSGS_CURRENT.Add(&BSGS_N); +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); +#endif + flip_detector--; } ends[thread_number] = 1; return NULL; } +#ifdef _WIN64 +DWORD WINAPI thread_process_bsgs_random(LPVOID vargp) { +#else void *thread_process_bsgs_random(void *vargp) { +#endif + FILE *filekey; struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; @@ -2693,20 +3194,28 @@ void *thread_process_bsgs_random(void *vargp) { -b bit | Min bit value | Max bit value | -r A:B | A | B | */ +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else pthread_mutex_lock(&bsgs_thread); +#endif + base_key.Rand(&n_range_start,&n_range_end); +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); - +#endif intaux.Set(&BSGS_M); intaux.Mult(CPU_GRP_SIZE/2); - flip_detector = 1000000; + flip_detector = FLIPBITLIMIT; /* while base_key is less than n_range_end then: */ while(base_key.IsLower(&n_range_end)) { if(thread_number == 0 && flip_detector == 0) { - memorycheck(); - flip_detector = 1000000; + memorycheck_bsgs(); + flip_detector = FLIPBITLIMIT; } if(FLAGMATRIX) { aux_c = base_key.GetBase16(); @@ -2743,7 +3252,12 @@ void *thread_process_bsgs_random(void *vargp) { aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],base_point); printf("[+] Publickey %s\n",aux_c); +#ifdef _WIN64 + 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); @@ -2751,7 +3265,12 @@ void *thread_process_bsgs_random(void *vargp) { } free(hextemp); free(aux_c); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + bsgs_found[k] = 1; salir = 1; @@ -2864,7 +3383,12 @@ void *thread_process_bsgs_random(void *vargp) { point_found = secp->ComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); +#ifdef _WIN64 + 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); @@ -2872,7 +3396,12 @@ void *thread_process_bsgs_random(void *vargp) { } free(hextemp); free(aux_c); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + bsgs_found[k] = 1; salir = 1; for(j = 0; j < bsgs_point_number && salir; j++) { @@ -2917,9 +3446,18 @@ void *thread_process_bsgs_random(void *vargp) { } // End for with k bsgs_point_number steps[thread_number]++; +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else pthread_mutex_lock(&bsgs_thread); +#endif base_key.Rand(&n_range_start,&n_range_end); +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); +#endif + flip_detector--; } ends[thread_number] = 1; @@ -2983,12 +3521,17 @@ int bsgs_secondcheck(Int *start_range,uint32_t a,uint32_t k_index,Int *privateke return found; } +#ifdef _WIN64 +DWORD WINAPI thread_bPloadFile(LPVOID vargp) { +#else void *thread_bPloadFile(void *vargp) { +#endif + FILE *fd; char rawvalue[32],*hextemp; struct bPload *tt; uint32_t j; - uint64_t i; + uint64_t i,to; tt = (struct bPload *)vargp; fd = fopen(precalculated_p_filename,"rb"); if(fd == NULL) { @@ -2997,6 +3540,8 @@ void *thread_bPloadFile(void *vargp) { } i = tt->from -1; j = tt->from -1; + to = tt->to; + free(tt); if(fseek(fd,(uint64_t)(i*32),SEEK_SET) != 0) { fprintf(stderr,"Can't seek the file at index %" PRIu64 ", offset %" PRIu64 "\n",i,(uint64_t)(i*32)); exit(0); @@ -3009,25 +3554,60 @@ void *thread_bPloadFile(void *vargp) { memcpy(bPtable[j].value,rawvalue+16,BSGS_XVALUE_RAM); bPtable[j].index = j; } - if(!FLAGREADEDFILE2) + if(!FLAGREADEDFILE2) { +#ifdef _WIN64 + WaitForSingleObject(bloom_bPx2nd_mutex, INFINITE); +#else + pthread_mutex_lock(&bloom_bPx2nd_mutex); +#endif bloom_add(&bloom_bPx2nd, rawvalue, BSGS_BUFFERXPOINTLENGTH); +#ifdef _WIN64 + ReleaseMutex(bloom_bPx2nd_mutex); +#else + pthread_mutex_unlock(&bloom_bPx2nd_mutex); +#endif + } j++; } - if(!FLAGREADEDFILE1) + if(!FLAGREADEDFILE1) { +#ifdef _WIN64 + WaitForSingleObject(bloom_bP_mutex[((uint8_t)rawvalue[0])], INFINITE); +#else + pthread_mutex_lock(&bloom_bP_mutex[((uint8_t)rawvalue[0])]); +#endif bloom_add(&bloom_bP[((uint8_t)rawvalue[0])], rawvalue ,BSGS_BUFFERXPOINTLENGTH); +#ifdef _WIN64 + ReleaseMutex(bloom_bP_mutex[((uint8_t)rawvalue[0])]); +#else + pthread_mutex_unlock(&bloom_bP_mutex[((uint8_t)rawvalue[0])]); +#endif + } i++; - tt->counter++; } else { fprintf(stderr,"Can't read the file seen you have less items that the amount needed\n"); exit(0); } - } while( i < tt->to ); + } while( i < to ); +#ifdef _WIN64 + WaitForSingleObject(bPload_mutex, INFINITE); + FINISHED_THREADS_BP++; + ReleaseMutex(bPload_mutex); +#else + pthread_mutex_lock(&bPload_mutex); + FINISHED_THREADS_BP++; + pthread_mutex_unlock(&bPload_mutex); +#endif + + + +#ifndef _WIN64 pthread_exit(NULL); +#endif } void sleep_ms(int milliseconds) { // cross-platform sleep function -#ifdef WIN32 +#ifdef _WIN64 Sleep(milliseconds); #elif _POSIX_C_SOURCE >= 199309L struct timespec ts; @@ -3041,7 +3621,11 @@ void sleep_ms(int milliseconds) { // cross-platform sleep function #endif } +#ifdef _WIN64 +DWORD WINAPI thread_pub2rmd(LPVOID vargp) { +#else void *thread_pub2rmd(void *vargp) { +#endif FILE *fd; Int key_mpz; struct tothread *tt; @@ -3061,10 +3645,19 @@ void *thread_pub2rmd(void *vargp) { } else { if(n_range_start.IsLower(&n_range_end)) { +#ifdef _WIN64 + WaitForSingleObject(write_random, INFINITE); +#else pthread_mutex_lock(&write_random); +#endif key_mpz.Set(&n_range_start); n_range_start.Add(N_SECUENTIAL_MAX); +#ifdef _WIN64 + ReleaseMutex(write_random); +#else pthread_mutex_unlock(&write_random); +#endif + } else { pub2rmd_continue = 0; @@ -3101,10 +3694,20 @@ void *thread_pub2rmd(void *vargp) { printf("\nHit: Publickey found %s\n",temphex); fd = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(fd != NULL) { +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else pthread_mutex_lock(&write_keys); +#endif + fprintf(fd,"Publickey found %s\n",temphex); fclose(fd); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + } else { fprintf(stderr,"\nPublickey found %s\nbut the file can't be open\n",temphex); @@ -3124,10 +3727,20 @@ void *thread_pub2rmd(void *vargp) { printf("\nHit: Publickey found %s\n",temphex); fd = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(fd != NULL) { +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else pthread_mutex_lock(&write_keys); +#endif + fprintf(fd,"Publickey found %s\n",temphex); fclose(fd); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + } else { fprintf(stderr,"\nPublickey found %s\nbut the file can't be open\n",temphex); @@ -3160,11 +3773,16 @@ void init_generator() { _2Gn = secp->DoubleDirect(Gn[CPU_GRP_SIZE / 2 - 1]); } +#ifdef _WIN64 +DWORD WINAPI thread_bPload(LPVOID vargp) { +#else void *thread_bPload(void *vargp) { +#endif + char *hextemp,rawvalue[32]; struct bPload *tt; uint64_t j_counter,i_counter; - uint64_t i,j,nbStep; + uint64_t i,j,nbStep,to; IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); Point startP; Int dx[CPU_GRP_SIZE / 2 + 1]; @@ -3175,17 +3793,23 @@ void *thread_bPload(void *vargp) { Int _p; Point pp; Point pn; - int hLength = (CPU_GRP_SIZE / 2 - 1); + int hLength = (CPU_GRP_SIZE / 2 - 1) ,threadid; tt = (struct bPload *)vargp; Int km(tt->from); - if(FLAGDEBUG) printf("[D] thread %i from %" PRIu64 " to %" PRIu64 "\n",tt->threadid,tt->from,tt->to); + threadid = tt->threadid; + //if(FLAGDEBUG) printf("[D] thread %i from %" PRIu64 " to %" PRIu64 "\n",threadid,tt->from,tt->to); + i_counter = tt->from -1; j_counter = tt->from -1; nbStep = (tt->to - (tt->from-1)) / CPU_GRP_SIZE; + if( ((tt->to - (tt->from-1)) % CPU_GRP_SIZE ) != 0) { nbStep++; } + //if(FLAGDEBUG) printf("[D] thread %i nbStep %" PRIu64 "\n",threadid,nbStep); + to = tt->to; + free(tt); km.Add((uint64_t)(CPU_GRP_SIZE / 2)); startP = secp->ComputePublicKey(&km); grp->Set(dx); @@ -3275,14 +3899,35 @@ void *thread_bPload(void *vargp) { memcpy(bPtable[j_counter].value,rawvalue+16,BSGS_XVALUE_RAM); bPtable[j_counter].index = j_counter; } - if(!FLAGREADEDFILE2) + if(!FLAGREADEDFILE2) { +#ifdef _WIN64 + WaitForSingleObject(bloom_bPx2nd_mutex, INFINITE); +#else + pthread_mutex_lock(&bloom_bPx2nd_mutex); +#endif bloom_add(&bloom_bPx2nd, rawvalue, BSGS_BUFFERXPOINTLENGTH); +#ifdef _WIN64 + ReleaseMutex(bloom_bPx2nd_mutex); +#else + pthread_mutex_unlock(&bloom_bPx2nd_mutex); +#endif + } j_counter++; } - if(i_counter < tt->to) { - if(!FLAGREADEDFILE1) - bloom_add(&bloom_bP[((unsigned char)rawvalue[0])], rawvalue ,BSGS_BUFFERXPOINTLENGTH); - tt->counter++; + if(i_counter < to) { + if(!FLAGREADEDFILE1) { +#ifdef _WIN64 + WaitForSingleObject(bloom_bP_mutex[((uint8_t)rawvalue[0])], INFINITE); +#else + pthread_mutex_lock(&bloom_bP_mutex[((uint8_t)rawvalue[0])]); +#endif + bloom_add(&bloom_bP[((uint8_t)rawvalue[0])], rawvalue ,BSGS_BUFFERXPOINTLENGTH); +#ifdef _WIN64 + ReleaseMutex(bloom_bP_mutex[((uint8_t)rawvalue[0])]); +#else + pthread_mutex_unlock(&bloom_bP_mutex[((uint8_t)rawvalue[0])]); +#endif + } i_counter++; } } @@ -3302,8 +3947,24 @@ void *thread_bPload(void *vargp) { pp.y.ModSub(&_2Gn.y); startP = pp; } + //if(FLAGDEBUG) printf("[D] thread %i finished\n",threadid); delete grp; + +#ifdef _WIN64 + WaitForSingleObject(bPload_mutex, INFINITE); + FINISHED_THREADS_BP++; + ReleaseMutex(bPload_mutex); +#else + pthread_mutex_lock(&bPload_mutex); + FINISHED_THREADS_BP++; + pthread_mutex_unlock(&bPload_mutex); +#endif + +#ifndef _WIN64 pthread_exit(NULL); +#endif + return NULL; + } void KECCAK_256(uint8_t *source, size_t size,uint8_t *dst) { @@ -3317,14 +3978,19 @@ void generate_binaddress_eth(Point *publickey,unsigned char *dst_address) { unsigned char bin_publickey[64]; unsigned char bin_sha256[32]; size_t pubaddress_size = 50; - memset(dst_address,0,50); + memset(dst_address,0,32); publickey->x.Get32Bytes(bin_publickey); publickey->y.Get32Bytes(bin_publickey+32); KECCAK_256(bin_publickey, 64, dst_address); } +#ifdef _WIN64 +DWORD WINAPI thread_process_bsgs_dance(LPVOID vargp) { +#else void *thread_process_bsgs_dance(void *vargp) { +#endif + FILE *filekey; struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; @@ -3357,7 +4023,12 @@ void *thread_process_bsgs_dance(void *vargp) { entrar = 1; +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else pthread_mutex_lock(&bsgs_thread); +#endif + switch(rand() % 3) { case 0: //TOP base_key.Set(&n_range_end); @@ -3383,13 +4054,18 @@ void *thread_process_bsgs_dance(void *vargp) { base_key.Rand(&BSGS_CURRENT,&n_range_end); break; } +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); +#endif + intaux.Set(&BSGS_M); intaux.Mult(CPU_GRP_SIZE/2); - flip_detector = 1000000; + flip_detector = FLIPBITLIMIT; /* @@ -3397,8 +4073,8 @@ void *thread_process_bsgs_dance(void *vargp) { */ while( entrar ) { if(thread_number == 0 && flip_detector == 0) { - memorycheck(); - flip_detector = 1000000; + memorycheck_bsgs(); + flip_detector = FLIPBITLIMIT; } if(FLAGMATRIX) { @@ -3432,9 +4108,13 @@ void *thread_process_bsgs_dance(void *vargp) { hextemp = base_key.GetBase16(); printf("[+] Thread Key found privkey %s \n",hextemp); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],base_point); - printf("[+] Publickey %s\n",aux_c); - + printf("[+] Publickey %s\n",aux_c); +#ifdef _WIN64 + 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); @@ -3442,7 +4122,12 @@ void *thread_process_bsgs_dance(void *vargp) { } free(hextemp); free(aux_c); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + bsgs_found[k] = 1; salir = 1; @@ -3555,7 +4240,12 @@ void *thread_process_bsgs_dance(void *vargp) { point_found = secp->ComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); +#ifdef _WIN64 + 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); @@ -3563,7 +4253,12 @@ void *thread_process_bsgs_dance(void *vargp) { } free(hextemp); free(aux_c); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + bsgs_found[k] = 1; salir = 1; for(j = 0; j < bsgs_point_number && salir; j++) { @@ -3604,7 +4299,12 @@ void *thread_process_bsgs_dance(void *vargp) { steps[thread_number]++; flip_detector--; +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else pthread_mutex_lock(&bsgs_thread); +#endif + switch(rand() % 3) { case 0: //TOP base_key.Set(&n_range_end); @@ -3630,14 +4330,21 @@ void *thread_process_bsgs_dance(void *vargp) { base_key.Rand(&BSGS_CURRENT,&n_range_end); break; } +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); - +#endif } ends[thread_number] = 1; return NULL; } +#ifdef _WIN64 +DWORD WINAPI thread_process_bsgs_backward(LPVOID vargp) { +#else void *thread_process_bsgs_backward(void *vargp) { +#endif FILE *filekey; struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; @@ -3668,11 +4375,21 @@ void *thread_process_bsgs_backward(void *vargp) { free(tt); +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else pthread_mutex_lock(&bsgs_thread); +#endif + n_range_end.Sub(&BSGS_N); base_key.Set(&n_range_end); +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); +#endif + @@ -3681,7 +4398,7 @@ void *thread_process_bsgs_backward(void *vargp) { intaux.Set(&BSGS_M); intaux.Mult(CPU_GRP_SIZE/2); - flip_detector = 1000000; + flip_detector = FLIPBITLIMIT; entrar = 1; /* @@ -3689,8 +4406,8 @@ void *thread_process_bsgs_backward(void *vargp) { */ while( entrar ) { if(thread_number == 0 && flip_detector == 0) { - memorycheck(); - flip_detector = 1000000; + memorycheck_bsgs(); + flip_detector = FLIPBITLIMIT; } if(FLAGMATRIX) { @@ -3726,7 +4443,12 @@ void *thread_process_bsgs_backward(void *vargp) { aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],base_point); printf("[+] Publickey %s\n",aux_c); +#ifdef _WIN64 + 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); @@ -3734,8 +4456,11 @@ void *thread_process_bsgs_backward(void *vargp) { } free(hextemp); free(aux_c); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); - +#endif bsgs_found[k] = 1; salir = 1; for(j = 0; j < bsgs_point_number && salir; j++) { @@ -3847,7 +4572,12 @@ void *thread_process_bsgs_backward(void *vargp) { point_found = secp->ComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); +#ifdef _WIN64 + 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); @@ -3855,7 +4585,12 @@ void *thread_process_bsgs_backward(void *vargp) { } free(hextemp); free(aux_c); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + bsgs_found[k] = 1; salir = 1; for(j = 0; j < bsgs_point_number && salir; j++) { @@ -3896,7 +4631,12 @@ void *thread_process_bsgs_backward(void *vargp) { steps[thread_number]++; flip_detector--; +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else pthread_mutex_lock(&bsgs_thread); +#endif + n_range_end.Sub(&BSGS_N); if(n_range_end.IsLower(&n_range_start)) { entrar = 0; @@ -3904,14 +4644,23 @@ void *thread_process_bsgs_backward(void *vargp) { else { base_key.Set(&n_range_end); } +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); +#endif + } ends[thread_number] = 1; return NULL; } +#ifdef _WIN64 +DWORD WINAPI thread_process_bsgs_both(LPVOID vargp) { +#else void *thread_process_bsgs_both(void *vargp) { +#endif FILE *filekey; struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; @@ -3944,9 +4693,14 @@ void *thread_process_bsgs_both(void *vargp) { entrar = 1; +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else pthread_mutex_lock(&bsgs_thread); +#endif + r = rand() % 2; - if(FLAGDEBUG) printf("[D] was %s\n",r ? "Bottom":"TOP"); + //if(FLAGDEBUG) printf("[D] was %s\n",r ? "Bottom":"TOP"); switch(r) { case 0: //TOP base_key.Set(&n_range_end); @@ -3968,12 +4722,17 @@ void *thread_process_bsgs_both(void *vargp) { } break; } +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); +#endif + intaux.Set(&BSGS_M); intaux.Mult(CPU_GRP_SIZE/2); - flip_detector = 1000000; + flip_detector = FLIPBITLIMIT; /* @@ -3982,8 +4741,8 @@ void *thread_process_bsgs_both(void *vargp) { while( entrar ) { if(thread_number == 0 && flip_detector == 0) { - memorycheck(); - flip_detector = 1000000; + memorycheck_bsgs(); + flip_detector = FLIPBITLIMIT; } if(FLAGMATRIX) { aux_c = base_key.GetBase16(); @@ -4017,8 +4776,11 @@ void *thread_process_bsgs_both(void *vargp) { printf("[+] Thread Key found privkey %s \n",hextemp); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],base_point); printf("[+] Publickey %s\n",aux_c); - +#ifdef _WIN64 + 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); @@ -4026,7 +4788,11 @@ void *thread_process_bsgs_both(void *vargp) { } free(hextemp); free(aux_c); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif bsgs_found[k] = 1; salir = 1; @@ -4139,7 +4905,12 @@ void *thread_process_bsgs_both(void *vargp) { point_found = secp->ComputePublicKey(&keyfound); aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); printf("[+] Publickey %s\n",aux_c); +#ifdef _WIN64 + 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); @@ -4147,7 +4918,12 @@ void *thread_process_bsgs_both(void *vargp) { } free(hextemp); free(aux_c); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else pthread_mutex_unlock(&write_keys); +#endif + bsgs_found[k] = 1; salir = 1; for(j = 0; j < bsgs_point_number && salir; j++) { @@ -4188,7 +4964,12 @@ void *thread_process_bsgs_both(void *vargp) { steps[thread_number]++; flip_detector--; +#ifdef _WIN64 + WaitForSingleObject(bsgs_thread, INFINITE); +#else pthread_mutex_lock(&bsgs_thread); +#endif + switch(rand() % 2) { case 0: //TOP base_key.Set(&n_range_end); @@ -4210,17 +4991,20 @@ void *thread_process_bsgs_both(void *vargp) { } break; } +#ifdef _WIN64 + ReleaseMutex(bsgs_thread); +#else pthread_mutex_unlock(&bsgs_thread); - +#endif } ends[thread_number] = 1; return NULL; } -void memorycheck() { +void memorycheck_bsgs() { char current_checksum[32]; char *hextemp,*aux_c; - if(FLAGDEBUG )printf("[D] Performing Memory checksum \n"); + //if(FLAGDEBUG )printf("[D] Performing Memory checksum \n"); sha256((char*)bPtable,bytes,current_checksum); if(memcmp(current_checksum,checksum,32) != 0 || memcmp(current_checksum,checksum_backup,32) != 0) { fprintf(stderr,"[E] Memory checksum mismatch, this should not happen but actually happened\nA bit in the memory was flipped by : electrical malfuntion, radiation or a cosmic ray\n"); @@ -4233,4 +5017,3 @@ void memorycheck() { exit(0); } } - diff --git a/oldbloom/LICENSE b/oldbloom/LICENSE new file mode 100644 index 0000000..0263dae --- /dev/null +++ b/oldbloom/LICENSE @@ -0,0 +1,26 @@ + +Copyright (c) 2012,2015,2016,2017 Jyri J. Virkki +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/oldbloom/bloom.cpp b/oldbloom/bloom.cpp new file mode 100644 index 0000000..8c89f98 --- /dev/null +++ b/oldbloom/bloom.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2012-2019, Jyri J. Virkki + * All rights reserved. + * + * This file is under BSD license. See LICENSE file. + */ + +/* + * Refer to bloom.h for documentation on the public interfaces. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "oldbloom.h" +#include "../xxhash/xxhash.h" + +#define MAKESTRING(n) STRING(n) +#define STRING(n) #n +#define BLOOM_MAGIC "libbloom2" +#define BLOOM_VERSION_MAJOR 2 +#define BLOOM_VERSION_MINOR 200 + +inline static int oldtest_bit_set_bit(uint8_t *bf, uint64_t bit, int set_bit) +{ + uint64_t byte = bit >> 3; + uint8_t c = bf[byte]; // expensive memory access + uint8_t mask = 1 << (bit % 8); + if (c & mask) { + return 1; + } else { + if (set_bit) { + bf[byte] = c | mask; + } + return 0; + } +} + +inline static int oldtest_bit(uint8_t *bf, uint64_t bit) +{ + uint64_t byte = bit >> 3; + uint8_t c = bf[byte]; // expensive memory access + uint8_t mask = 1 << (bit % 8); + if (c & mask) { + return 1; + } else { + return 0; + } +} + +static int oldbloom_check_add(struct oldbloom * bloom, const void * buffer, int len, int add) +{ + if (bloom->ready == 0) { + printf("bloom at %p not initialized!\n", (void *)bloom); + return -1; + } + uint8_t hits = 0; + uint64_t a = XXH64(buffer, len, 0x59f2815b16f81798); + uint64_t b = XXH64(buffer, len, a); + uint64_t x; + uint8_t i; + int r; + for (i = 0; i < bloom->hashes; i++) { + x = (a + b*i) % bloom->bits; + pthread_mutex_lock(&bloom->mutex); + r = oldtest_bit_set_bit(bloom->bf, x, add); + pthread_mutex_unlock(&bloom->mutex); + if (r) { + hits++; + } else if (!add) { + // Don't care about the presence of all the bits. Just our own. + return 0; + } + } + if (hits == bloom->hashes) { + return 1; // 1 == element already in (or collision) + } + return 0; +} + +// DEPRECATED - Please migrate to bloom_init2. +int oldbloom_init(struct oldbloom * bloom, uint64_t entries, long double error) +{ + return oldbloom_init2(bloom, entries, error); +} + +int oldbloom_init2(struct oldbloom * bloom, uint64_t entries, long double error) +{ + memset(bloom, 0, sizeof(struct oldbloom)); + if (entries < 1000 || error <= 0 || error >= 1) { + return 1; + } + bloom->entries = entries; + bloom->error = error; + + long double num = -log(bloom->error); + long double denom = 0.480453013918201; // ln(2)^2 + bloom->bpe = (num / denom); + + long double dentries = (long double)entries; + long double allbits = dentries * bloom->bpe; + bloom->bits = (uint64_t)allbits; + + bloom->bytes = (uint64_t) bloom->bits / 8; + if (bloom->bits % 8) { + bloom->bytes +=1; + } + + bloom->hashes = (uint8_t)ceil(0.693147180559945 * bloom->bpe); // ln(2) + + bloom->bf = (uint8_t *)calloc(bloom->bytes, sizeof(uint8_t)); + if (bloom->bf == NULL) { // LCOV_EXCL_START + return 1; + } // LCOV_EXCL_STOP + + bloom->ready = 1; + bloom->major = BLOOM_VERSION_MAJOR; + bloom->minor = BLOOM_VERSION_MINOR; + return 0; +} + +int oldbloom_check(struct oldbloom * bloom, const void * buffer, int len) +{ + if (bloom->ready == 0) { + printf("bloom at %p not initialized!\n", (void *)bloom); + return -1; + } + uint8_t hits = 0; + uint64_t a = XXH64(buffer, len, 0x59f2815b16f81798); + uint64_t b = XXH64(buffer, len, a); + uint64_t x; + uint8_t i; + int r; + for (i = 0; i < bloom->hashes; i++) { + x = (a + b*i) % bloom->bits; + if (oldtest_bit(bloom->bf, x)) { + hits++; + } else { + return 0; + } + } + if (hits == bloom->hashes) { + return 1; // 1 == element already in (or collision) + } + return 0; +} + + +int oldbloom_add(struct oldbloom * bloom, const void * buffer, int len) +{ + return oldbloom_check_add(bloom, buffer, len, 1); +} + +void oldbloom_print(struct oldbloom * bloom) +{ + printf("bloom at %p\n", (void *)bloom); + if (!bloom->ready) { printf(" *** NOT READY ***\n"); } + printf(" ->version = %d.%d\n", bloom->major, bloom->minor); + printf(" ->entries = %" PRIu64 "\n", bloom->entries); + printf(" ->error = %Lf\n", bloom->error); + printf(" ->bits = %" PRIu64 "\n", bloom->bits); + printf(" ->bits per elem = %f\n", bloom->bpe); + printf(" ->bytes = %" PRIu64 "\n", bloom->bytes); + unsigned int KB = bloom->bytes / 1024; + unsigned int MB = KB / 1024; + printf(" (%u KB, %u MB)\n", KB, MB); + printf(" ->hash functions = %d\n", bloom->hashes); +} + +void oldbloom_free(struct oldbloom * bloom) +{ + if (bloom->ready) { + free(bloom->bf); + } + bloom->ready = 0; +} + +int oldbloom_reset(struct oldbloom * bloom) +{ + if (!bloom->ready) return 1; + memset(bloom->bf, 0, bloom->bytes); + return 0; +} + +/* +int oldbloom_save(struct oldbloom * bloom, char * filename) +{ + if (filename == NULL || filename[0] == 0) { + return 1; + } + + int fd = open(filename, O_WRONLY | O_CREAT, 0644); + if (fd < 0) { + return 1; + } + + ssize_t out = write(fd, BLOOM_MAGIC, strlen(BLOOM_MAGIC)); + if (out != strlen(BLOOM_MAGIC)) { goto save_error; } // LCOV_EXCL_LINE + + uint16_t size = sizeof(struct oldbloom); + out = write(fd, &size, sizeof(uint16_t)); + if (out != sizeof(uint16_t)) { goto save_error; } // LCOV_EXCL_LINE + + out = write(fd, bloom, sizeof(struct oldbloom)); + if (out != sizeof(struct oldbloom)) { goto save_error; } // LCOV_EXCL_LINE + + out = write(fd, bloom->bf, bloom->bytes); + if (out != bloom->bytes) { goto save_error; } // LCOV_EXCL_LINE + + close(fd); + return 0; + // LCOV_EXCL_START + save_error: + close(fd); + return 1; + // LCOV_EXCL_STOP +} + + +int oldbloom_load(struct oldbloom * bloom, char * filename) +{ + int rv = 0; + + if (filename == NULL || filename[0] == 0) { return 1; } + if (bloom == NULL) { return 2; } + + memset(bloom, 0, sizeof(struct oldbloom)); + + int fd = open(filename, O_RDONLY); + if (fd < 0) { return 3; } + + char line[30]; + memset(line, 0, 30); + ssize_t in = read(fd, line, strlen(BLOOM_MAGIC)); + + if (in != strlen(BLOOM_MAGIC)) { + rv = 4; + goto load_error; + } + + if (strncmp(line, BLOOM_MAGIC, strlen(BLOOM_MAGIC))) { + rv = 5; + goto load_error; + } + + uint16_t size; + in = read(fd, &size, sizeof(uint16_t)); + if (in != sizeof(uint16_t)) { + rv = 6; + goto load_error; + } + + if (size != sizeof(struct oldbloom)) { + rv = 7; + goto load_error; + } + + in = read(fd, bloom, sizeof(struct oldbloom)); + if (in != sizeof(struct oldbloom)) { + rv = 8; + goto load_error; + } + + bloom->bf = NULL; + if (bloom->major != BLOOM_VERSION_MAJOR) { + rv = 9; + goto load_error; + } + + bloom->bf = (unsigned char *)malloc(bloom->bytes); + if (bloom->bf == NULL) { rv = 10; goto load_error; } // LCOV_EXCL_LINE + + in = read(fd, bloom->bf, bloom->bytes); + if (in != bloom->bytes) { + rv = 11; + free(bloom->bf); + bloom->bf = NULL; + goto load_error; + } + + close(fd); + return rv; + + load_error: + close(fd); + bloom->ready = 0; + return rv; +} +*/ + +const char * oldbloom_version() +{ + return MAKESTRING(BLOOM_VERSION); +} diff --git a/oldbloom/bloom.h b/oldbloom/bloom.h new file mode 100644 index 0000000..22c2a05 --- /dev/null +++ b/oldbloom/bloom.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2012-2019, Jyri J. Virkki + * All rights reserved. + * + * This file is under BSD license. See LICENSE file. + */ + +#ifndef _OLDBLOOM_H +#define _OLDBLOOM_H + +#ifdef _WIN64 +#include +#else +#endif +#ifdef __cplusplus +extern "C" { +#endif + + +/** *************************************************************************** + * Structure to keep track of one bloom filter. Caller needs to + * allocate this and pass it to the functions below. First call for + * every struct must be to bloom_init(). + * + */ +struct oldbloom +{ + // These fields are part of the public interface of this structure. + // Client code may read these values if desired. Client code MUST NOT + // modify any of these. + uint64_t entries; + uint64_t bits; + uint64_t bytes; + uint8_t hashes; + long double error; + + // Fields below are private to the implementation. These may go away or + // change incompatibly at any moment. Client code MUST NOT access or rely + // on these. + uint8_t ready; + uint8_t major; + uint8_t minor; + double bpe; + uint8_t checksum[32]; + uint8_t checksum_backup[32]; + uint8_t *bf; +#ifdef _WIN64 + HANDLE mutex; +#else + pthread_mutex_t mutex; +#endif +}; +/* +Customs +*/ +/* +int oldbloom_loadcustom(struct oldbloom * bloom, char * filename); +int oldbloom_savecustom(struct oldbloom * bloom, char * filename); +*/ + +/** *************************************************************************** + * Initialize the bloom filter for use. + * + * The filter is initialized with a bit field and number of hash functions + * according to the computations from the wikipedia entry: + * http://en.wikipedia.org/wiki/Bloom_filter + * + * Optimal number of bits is: + * bits = (entries * ln(error)) / ln(2)^2 + * + * Optimal number of hash functions is: + * hashes = bpe * ln(2) + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * entries - The expected number of entries which will be inserted. + * Must be at least 1000 (in practice, likely much larger). + * error - Probability of collision (as long as entries are not + * exceeded). + * + * Return: + * ------- + * 0 - on success + * 1 - on failure + * + */ +int oldbloom_init2(struct oldbloom * bloom, uint64_t entries, long double error); + + +/** + * DEPRECATED. + * Kept for compatibility with libbloom v.1. To be removed in v3.0. + * + */ +int oldbloom_init(struct oldbloom * bloom, uint64_t entries, long double error); + + +/** *************************************************************************** + * Check if the given element is in the bloom filter. Remember this may + * return false positive if a collision occurred. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * buffer - Pointer to buffer containing element to check. + * len - Size of 'buffer'. + * + * Return: + * ------- + * 0 - element is not present + * 1 - element is present (or false positive due to collision) + * -1 - bloom not initialized + * + */ +int oldbloom_check(struct oldbloom * bloom, const void * buffer, int len); + + +/** *************************************************************************** + * Add the given element to the bloom filter. + * The return code indicates if the element (or a collision) was already in, + * so for the common check+add use case, no need to call check separately. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * buffer - Pointer to buffer containing element to add. + * len - Size of 'buffer'. + * + * Return: + * ------- + * 0 - element was not present and was added + * 1 - element (or a collision) had already been added previously + * -1 - bloom not initialized + * + */ +int oldbloom_add(struct oldbloom * bloom, const void * buffer, int len); + + +/** *************************************************************************** + * Print (to stdout) info about this bloom filter. Debugging aid. + * + */ +void oldbloom_print(struct oldbloom * bloom); + + +/** *************************************************************************** + * Deallocate internal storage. + * + * Upon return, the bloom struct is no longer usable. You may call bloom_init + * again on the same struct to reinitialize it again. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * + * Return: none + * + */ +void oldbloom_free(struct oldbloom * bloom); + + +/** *************************************************************************** + * Erase internal storage. + * + * Erases all elements. Upon return, the bloom struct returns to its initial + * (initialized) state. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * + * Return: + * 0 - on success + * 1 - on failure + * + */ +int oldbloom_reset(struct oldbloom * bloom); + + +/** *************************************************************************** + * Save a bloom filter to a file. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * filename - Create (or overwrite) bloom data to this file. + * + * Return: + * 0 - on success + * 1 - on failure + * + */ +//int oldbloom_save(struct oldbloom * bloom, char * filename); + + +/** *************************************************************************** + * Load a bloom filter from a file. + * + * This functions loads a file previously saved with bloom_save(). + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * filename - Load bloom filter data from this file. + * + * Return: + * 0 - on success + * > 0 - on failure + * + */ +//int oldbloom_load(struct oldbloom * bloom, char * filename); + + +/** *************************************************************************** + * Returns version string compiled into library. + * + * Return: version string + * + */ +const char * oldbloom_version(); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/oldbloom/oldbloom.h b/oldbloom/oldbloom.h new file mode 100644 index 0000000..56bbbd9 --- /dev/null +++ b/oldbloom/oldbloom.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2012-2019, Jyri J. Virkki + * All rights reserved. + * + * This file is under BSD license. See LICENSE file. + */ + +#ifndef _OLDBLOOM_H +#define _OLDBLOOM_H + +#ifdef _WIN64 +#include +#else +#endif +#ifdef __cplusplus +extern "C" { +#endif + + +/** *************************************************************************** + * Structure to keep track of one bloom filter. Caller needs to + * allocate this and pass it to the functions below. First call for + * every struct must be to bloom_init(). + * + */ +struct oldbloom +{ + // These fields are part of the public interface of this structure. + // Client code may read these values if desired. Client code MUST NOT + // modify any of these. + uint64_t entries; + uint64_t bits; + uint64_t bytes; + uint8_t hashes; + long double error; + + // Fields below are private to the implementation. These may go away or + // change incompatibly at any moment. Client code MUST NOT access or rely + // on these. + uint8_t ready; + uint8_t major; + uint8_t minor; + double bpe; + uint8_t checksum[32]; + uint8_t checksum_backup[32]; + uint8_t *bf; +#ifdef _WIN64 + HANDLE mutex; +#else + pthread_mutex_t mutex; +#endif +}; +/* +Customs +*/ +/* +int oldbloom_loadcustom(struct oldbloom * bloom, char * filename); +int oldbloom_savecustom(struct oldbloom * bloom, char * filename); +*/ + +/** *************************************************************************** + * Initialize the bloom filter for use. + * + * The filter is initialized with a bit field and number of hash functions + * according to the computations from the wikipedia entry: + * http://en.wikipedia.org/wiki/Bloom_filter + * + * Optimal number of bits is: + * bits = (entries * ln(error)) / ln(2)^2 + * + * Optimal number of hash functions is: + * hashes = bpe * ln(2) + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * entries - The expected number of entries which will be inserted. + * Must be at least 1000 (in practice, likely much larger). + * error - Probability of collision (as long as entries are not + * exceeded). + * + * Return: + * ------- + * 0 - on success + * 1 - on failure + * + */ +int oldbloom_init2(struct oldbloom * bloom, uint64_t entries, long double error); + + +/** + * DEPRECATED. + * Kept for compatibility with libbloom v.1. To be removed in v3.0. + * + */ +int oldbloom_init(struct oldbloom * bloom, uint64_t entries, long double error); + + +/** *************************************************************************** + * Check if the given element is in the bloom filter. Remember this may + * return false positive if a collision occurred. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * buffer - Pointer to buffer containing element to check. + * len - Size of 'buffer'. + * + * Return: + * ------- + * 0 - element is not present + * 1 - element is present (or false positive due to collision) + * -1 - bloom not initialized + * + */ +int oldbloom_check(struct oldbloom * bloom, const void * buffer, int len); + + +/** *************************************************************************** + * Add the given element to the bloom filter. + * The return code indicates if the element (or a collision) was already in, + * so for the common check+add use case, no need to call check separately. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * buffer - Pointer to buffer containing element to add. + * len - Size of 'buffer'. + * + * Return: + * ------- + * 0 - element was not present and was added + * 1 - element (or a collision) had already been added previously + * -1 - bloom not initialized + * + */ +int oldbloom_add(struct oldbloom * bloom, const void * buffer, int len); + + +/** *************************************************************************** + * Print (to stdout) info about this bloom filter. Debugging aid. + * + */ +void oldbloom_print(struct oldbloom * bloom); + + +/** *************************************************************************** + * Deallocate internal storage. + * + * Upon return, the bloom struct is no longer usable. You may call bloom_init + * again on the same struct to reinitialize it again. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * + * Return: none + * + */ +void oldbloom_free(struct oldbloom * bloom); + + +/** *************************************************************************** + * Erase internal storage. + * + * Erases all elements. Upon return, the bloom struct returns to its initial + * (initialized) state. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * + * Return: + * 0 - on success + * 1 - on failure + * + */ +int oldbloom_reset(struct oldbloom * bloom); + + +/** *************************************************************************** + * Save a bloom filter to a file. + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * filename - Create (or overwrite) bloom data to this file. + * + * Return: + * 0 - on success + * 1 - on failure + * + */ +//int oldbloom_save(struct oldbloom * bloom, char * filename); + + +/** *************************************************************************** + * Load a bloom filter from a file. + * + * This functions loads a file previously saved with bloom_save(). + * + * Parameters: + * ----------- + * bloom - Pointer to an allocated struct bloom (see above). + * filename - Load bloom filter data from this file. + * + * Return: + * 0 - on success + * > 0 - on failure + * + */ +//int oldbloom_load(struct oldbloom * bloom, char * filename); + + +/** *************************************************************************** + * Returns version string compiled into library. + * + * Return: version string + * + */ +const char * oldbloom_version(); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/secp256k1/Int.cpp b/secp256k1/Int.cpp index d404d15..5b8b786 100644 --- a/secp256k1/Int.cpp +++ b/secp256k1/Int.cpp @@ -920,7 +920,7 @@ void Int::GCD(Int *a) { // ------------------------------------------------ -void Int::SetBase10(char *value) { +void Int::SetBase10(const char *value) { CLEAR(); Int pw((uint64_t)1); Int c; @@ -937,7 +937,7 @@ void Int::SetBase10(char *value) { // ------------------------------------------------ -void Int::SetBase16(char *value) { +void Int::SetBase16(const char *value) { SetBaseN(16,"0123456789ABCDEF",value); } @@ -976,7 +976,7 @@ char * Int::GetC64Str(int nbDigit) { tmp[1] = 0; for (int i = 0; i< nbDigit; i++) { if (bits64[i] != 0) { -#ifdef WIN64 +#ifdef _WIN64 sprintf(bStr, "0x%016I64XULL", bits64[i]); #else sprintf(bStr, "0x%" PRIx64 "ULL", bits64[i]); @@ -993,17 +993,16 @@ char * Int::GetC64Str(int nbDigit) { // ------------------------------------------------ -void Int::SetBaseN(int n,char *charset,char *value) { - +void Int::SetBaseN(int n,const char *charset,const char *value) { CLEAR(); Int pw((uint64_t)1); Int nb((uint64_t)n); Int c; int lgth = (int)strlen(value); for(int i=lgth-1;i>=0;i--) { - char *p = strchr(charset,toupper(value[i])); + char *p = strchr((char*)charset,toupper(value[i])); if(!p) { - printf("Invalid charset !!\n"); + printf("Invalid charset !!\n"); return; } int id = (int)(p-charset); @@ -1016,7 +1015,7 @@ void Int::SetBaseN(int n,char *charset,char *value) { // ------------------------------------------------ -char* Int::GetBaseN(int n,char *charset) { +char* Int::GetBaseN(int n,const char *charset) { char *ret = (char*) calloc(1,1024); Int N(this); diff --git a/secp256k1/Int.h b/secp256k1/Int.h index 9aa5efe..3670b72 100644 --- a/secp256k1/Int.h +++ b/secp256k1/Int.h @@ -140,9 +140,9 @@ class Int { void SetInt64(uint64_t value); void SetInt32(uint32_t value); void Set(Int *a); - void SetBase10(char *value); - void SetBase16(char *value); - void SetBaseN(int n,char *charset,char *value); + void SetBase10(const char *value); + void SetBase16(const char *value); + void SetBaseN(int n,const char *charset,const char *value); void SetByte(int n,unsigned char byte); void SetDWord(int n, uint32_t b); void SetQWord(int n,uint64_t b); @@ -161,7 +161,7 @@ class Int { char* GetBase2(); char* GetBase10(); char* GetBase16(); - char* GetBaseN(int n,char *charset); + char* GetBaseN(int n,const char *charset); char* GetBlockStr(); char* GetC64Str(int nbDigit); @@ -195,7 +195,7 @@ class Int { // Inline routines -#ifndef WIN64 +#ifndef _WIN64 // Missing intrinsics static uint64_t inline _umul128(uint64_t a, uint64_t b, uint64_t *h) { diff --git a/secp256k1/IntMod.cpp b/secp256k1/IntMod.cpp index 48fb03f..55b640f 100644 --- a/secp256k1/IntMod.cpp +++ b/secp256k1/IntMod.cpp @@ -855,7 +855,7 @@ void Int::MontgomeryMult(Int *a, Int *b) { void Int::ModMulK1(Int *a, Int *b) { -#ifndef WIN64 +#ifndef _WIN64 #if (__GNUC__ > 7) || (__GNUC__ == 7 && (__GNUC_MINOR__ > 2)) unsigned char c; #else @@ -917,7 +917,7 @@ void Int::ModMulK1(Int *a, Int *b) { void Int::ModMulK1(Int *a) { -#ifndef WIN64 +#ifndef _WIN64 #if (__GNUC__ > 7) || (__GNUC__ == 7 && (__GNUC_MINOR__ > 2)) unsigned char c; #else @@ -977,7 +977,7 @@ void Int::ModMulK1(Int *a) { void Int::ModSquareK1(Int *a) { -#ifndef WIN64 +#ifndef _WIN64 #if (__GNUC__ > 7) || (__GNUC__ == 7 && (__GNUC_MINOR__ > 2)) unsigned char c; #else diff --git a/secp256k1/Point.cpp b/secp256k1/Point.cpp index 14f98d0..17943d5 100644 --- a/secp256k1/Point.cpp +++ b/secp256k1/Point.cpp @@ -75,16 +75,3 @@ void Point::Reduce() { bool Point::equals(Point &p) { return x.IsEqual(&p.x) && y.IsEqual(&p.y) && z.IsEqual(&p.z); } - -/* -std::string Point::toString() { - - std::string ret; - ret = "X=" + x.GetBase16() + "\n"; - ret += "Y=" + y.GetBase16() + "\n"; - ret += "Z=" + z.GetBase16() + "\n"; - return ret; - -} - -*/ diff --git a/secp256k1/Random.cpp b/secp256k1/Random.cpp index 279c3ec..ca92be8 100644 --- a/secp256k1/Random.cpp +++ b/secp256k1/Random.cpp @@ -53,7 +53,7 @@ void rk_seed(unsigned long seed, rk_state *state) #define UPPER_MASK 0x80000000UL #define LOWER_MASK 0x7fffffffUL -#ifdef WIN32 +#ifdef _WIN64 // Disable "unary minus operator applied to unsigned type, result still unsigned" warning. #pragma warning(disable : 4146) #endif diff --git a/secp256k1/SECP256K1.cpp b/secp256k1/SECP256K1.cpp index 55c267c..221a09a 100644 --- a/secp256k1/SECP256K1.cpp +++ b/secp256k1/SECP256K1.cpp @@ -19,7 +19,7 @@ #include #include "SECP256k1.h" #include "Point.h" -#include "util.h" +#include "../util.h" Secp256K1::Secp256K1() { } @@ -104,6 +104,7 @@ Point Secp256K1::Negation(Point &p) { Q.x.Set(&p.x); Q.y.Set(&this->P); Q.y.Sub(&p.y); + Q.z.SetInt32(1); return Q; } @@ -167,8 +168,8 @@ bool Secp256K1::ParsePublicKeyHex(char *str,Point &ret,bool &isCompressed) { } char* Secp256K1::GetPublicKeyHex(bool compressed, Point &pubKey) { - unsigned char publicKeyBytes[128]; - char *ret; + unsigned char publicKeyBytes[65]; + char *ret = NULL; if (!compressed) { //Uncompressed public key publicKeyBytes[0] = 0x4; @@ -185,8 +186,24 @@ char* Secp256K1::GetPublicKeyHex(bool compressed, Point &pubKey) { return ret; } +void Secp256K1::GetPublicKeyHex(bool compressed, Point &pubKey,char *dst){ + unsigned char publicKeyBytes[65]; + if (!compressed) { + //Uncompressed public key + publicKeyBytes[0] = 0x4; + pubKey.x.Get32Bytes(publicKeyBytes + 1); + pubKey.y.Get32Bytes(publicKeyBytes + 33); + tohex_dst((char*)publicKeyBytes,65,dst); + } + else { + // Compressed public key + publicKeyBytes[0] = pubKey.y.IsEven() ? 0x2 : 0x3; + pubKey.x.Get32Bytes(publicKeyBytes + 1); + tohex_dst((char*)publicKeyBytes,33,dst); + } +} + char* Secp256K1::GetPublicKeyRaw(bool compressed, Point &pubKey) { - unsigned char publicKeyBytes[128]; char *ret = (char*) malloc(65); if(ret == NULL) { ::fprintf(stderr,"Can't alloc memory\n"); @@ -206,6 +223,20 @@ char* Secp256K1::GetPublicKeyRaw(bool compressed, Point &pubKey) { return ret; } +void Secp256K1::GetPublicKeyRaw(bool compressed, Point &pubKey,char *dst) { + if (!compressed) { + //Uncompressed public key + dst[0] = 0x4; + pubKey.x.Get32Bytes((unsigned char*) (dst + 1)); + pubKey.y.Get32Bytes((unsigned char*) (dst + 33)); + } + else { + // Compressed public key + dst[0] = pubKey.y.IsEven() ? 0x2 : 0x3; + pubKey.x.Get32Bytes((unsigned char*) (dst + 1)); + } +} + Point Secp256K1::AddDirect(Point &p1,Point &p2) { Int _s; Int _p; @@ -452,3 +483,27 @@ bool Secp256K1::EC(Point &p) { _s.ModSub(&_p); return _s.IsZero(); // ( ((pow2(y) - (pow3(x) + 7)) % P) == 0 ); } + +Point Secp256K1::ScalarMultiplication(Point &P,Int *scalar) { + Point R,Q,T; + int no_of_bits, loop; + no_of_bits = scalar->GetBitLength(); + R.Clear(); + R.z.SetInt32(1); + if(!scalar->IsZero()) { + Q.Set(P); + if(scalar->GetBit(0) == 1) { + R.Set(P); + } + for(loop = 1; loop < no_of_bits; loop++) { + T = Double(Q); + Q.Set(T); + T.Set(R); + if(scalar->GetBit(loop)){ + R = Add(T,Q); + } + } + } + R.Reduce(); + return R; +} \ No newline at end of file diff --git a/secp256k1/SECP256k1.h b/secp256k1/SECP256k1.h index e57ea75..0f6d678 100644 --- a/secp256k1/SECP256k1.h +++ b/secp256k1/SECP256k1.h @@ -31,9 +31,15 @@ class Secp256K1 { Point ComputePublicKey(Int *privKey); Point NextKey(Point &key); bool EC(Point &p); - + + Point ScalarMultiplication(Point &P,Int *scalar); + char* GetPublicKeyHex(bool compressed, Point &p); + void GetPublicKeyHex(bool compressed, Point &pubKey,char *dst); + char* GetPublicKeyRaw(bool compressed, Point &p); + void GetPublicKeyRaw(bool compressed, Point &pubKey,char *dst); + bool ParsePublicKeyHex(char *str,Point &p,bool &isCompressed); Point Add(Point &p1, Point &p2);