diff --git a/CHANGELOG.md b/CHANGELOG.md index 20283ad..2880fd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# Version 0.2.211007 Chocolate ¡Beta! +- BSGS improvements: +-- 10x more Speed +-- new submodes for BSGS, secuential (default), backward, both, random and dance +-- automatic file generation for bloom filter file and bPtable file. +-- Good bye to bPfile. +- Memory check periodically for bloom filters and bP Table + # Version 0.1.20210420 secp256k1 - Solved Issues 49, 50 51 See: diff --git a/Makefile b/Makefile index 2ea9d5d..e0cecb8 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ default: 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 - gcc -O3 -c sha3/sha3.c -o sha3.o + g++ -O3 -c sha3/sha3.c -o sha3.o + g++ -O3 -c sha3/keccak.c -o keccak.o gcc -O3 -c xxhash/xxhash.c -o xxhash.o g++ -O3 -c util.c -o util.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Int.cpp -o Int.o @@ -12,8 +13,9 @@ 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 -lgmp -lm -lpthread - #gcc -O3 hexcharstoraw.c -o hexcharstoraw util.o -lm - g++ -o bPfile bPfile.c util.o -lgmp -lm -clean: + 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 rm -r *.o +clean: + rm keyhunt + rm bPfile + diff --git a/README.md b/README.md index 0981d57..352ca61 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,9 @@ Ethereum addresses is a work in develop To clone the repository: -`git clone https://github.com/albertobsd/keyhunt.git` +``` +git clone https://github.com/albertobsd/keyhunt.git +``` don't forget change to the keyhunt directory @@ -22,9 +24,13 @@ First compile: `make` -and then execute: +and then execute with `-h` to see the help + +```./keyhunt -h``` -`./keyhunt -h` + +## ¡Beta! +This version is still a beta version, there are a lot of things that can be fail. And absoluly there are some bugs # Modes @@ -35,6 +41,8 @@ The current availables modes are: - xpoint - bsgs +you can select them with `-m` + ## address mode This is the most basic approach to work, in this mode your text file need to have a list of the publicaddress to be search. @@ -82,65 +90,58 @@ To target that file we need to execute keyhunt with this line output: ``` -[+] Version 0.1.20210328 -[+] Setting mode address +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Mode address +[+] Matrix screen [+] Opening file tests/1to32.txt [+] Setting search for btc adddress [+] Allocating memory for 32 elements: 0.00 MB -[+] Initializing bloom filter for 32 elements. -[+] Loading data to the bloomfilter +[+] Bloom filter for 32 elements. +[+] Loading data to the bloomfilter total: 0.00 MB [+] Bloomfilter completed -[+] Sorting data -[+] 32 values were loaded and sorted -Thread 0 : Setting up base key: 0000000000000000000000000000000000000000000000000000000000000001 -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000001 +[+] Sorting data ... done! 32 values were loaded and sorted +Base key: 1 +HIT!! PrivKey: 1 pubkey: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000003 +HIT!! PrivKey: 3 pubkey: 02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9 address: 1CUNEBjYrCn2y1SdiUMohaKUi4wpP326Lb -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000007 +HIT!! PrivKey: 7 pubkey: 025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc address: 19ZewH8Kk1PDbSNdJ97FP4EiCjTRaZMZQA -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000008 +HIT!! PrivKey: 8 pubkey: 022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01 address: 1EhqbyUMvvs7BfL8goY6qcPbD6YKfPqb7e -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000015 -pubkey: 02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5 -address: 1E6NuFjCi27W5zoXg8TRdcSRq84zJeBW3k -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000031 -pubkey: 03f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530 -address: 1PitScNLyp2HCygzadCh7FveTnfmpPbfp8 (Output omitted) ``` -In this mode you can specify to seach only address compressed or uncompressed with `-l compress` o `-l compress` +In this mode you can specify to seach only address compressed or uncompressed with `-l compress` or `-l uncompress` Test your look with the random parameter `-R` againts the puzzle #64 -`./keyhunt -m address -f tests/64.txt -b 64 -l compress -R` +``` +./keyhunt -m address -f tests/64.txt -b 64 -l compress -R -q -s 10 +``` Please note the change from `-r 1:FFFFFFFF` to `-b 64`, with -b you can specify the bit range output: ``` -[+] Version 0.1.20210328 -[+] Setting mode address -[+] Min range: 8000000000000000 -[+] Max range: ffffffffffffffff +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Mode address [+] Search compress only -[+] Setting random mode. +[+] Random mode +[+] Quiet thread output +[+] Stats output every 10 seconds [+] Opening file tests/64.txt [+] Setting search for btc adddress [+] Allocating memory for 1 elements: 0.00 MB -[+] Initializing bloom filter for 1 elements. -[+] Loading data to the bloomfilter +[+] Bloom filter for 1 elements. +[+] Loading data to the bloomfilter total: 0.00 MB [+] Bloomfilter completed -[+] Sorting data -[+] 1 values were loaded and sorted -Thread 0 : Setting up base key: 000000000000000000000000000000000000000000000000adf754734f7cf61a -Total 26214400 keys in 150 seconds: 174762 keys/s -(Output omitted) +[+] Sorting data ... done! 1 values were loaded and sorted +[+] Total 6291456 keys in 20 seconds: 314572 keys/s ``` ## rmd160 mode @@ -190,58 +191,58 @@ d805f6f251f7479ebd853b3d0f4b9b2656d92f1d to target that file you need to execute the next line: -`./keyhunt -m rmd160 -f tests/1to32.rmd -r 1:FFFFFFFF -l compress` +``` +./keyhunt -m rmd160 -f tests/1to32.rmd -r 1:FFFFFFFF -l compress +``` output: ``` -[+] Version 0.1.20210328 -[+] Setting mode rmd160 +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Mode rmd160 [+] Search compress only [+] Opening file tests/1to32.rmd [+] Allocating memory for 32 elements: 0.00 MB -[+] Initializing bloom filter for 32 elements. -[+] Loading data to the bloomfilter +[+] Bloom filter for 32 elements. +[+] Loading data to the bloomfilter total: 0.00 MB [+] Bloomfilter completed -[+] Sorting data -[+] 32 values were loaded and sorted -Thread 0 : Setting up base key: 0000000000000000000000000000000000000000000000000000000000000001HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000001 +[+] Sorting data ... done! 32 values were loaded and sorted +HIT!! PrivKey: 1 pubkey: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000003 +HIT!! PrivKey: 3 pubkey: 02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9 -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000007 +HIT!! PrivKey: 7 pubkey: 025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000008 +HIT!! PrivKey: 8 pubkey: 022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01 -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000015 +HIT!! PrivKey: 15 pubkey: 02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5 -HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000031 -(Output omited) +HIT!! PrivKey: 31 +pubkey: 03f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530 ``` test your luck with the next file for th puzzle #64 -`./keyhunt -m rmd160 -f tests/64.rmd -b 64 -l compress -R` + +``` +./keyhunt -m rmd160 -f tests/64.rmd -b 64 -l compress -R -q +``` Output: ``` -[+] Version 0.1.20210328 -[+] Setting mode rmd160 -[+] Min range: 8000000000000000 -[+] Max range: ffffffffffffffff +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Mode rmd160 [+] Search compress only -[+] Setting random mode. +[+] Random mode +[+] Quiet thread output [+] Opening file tests/64.rmd [+] Allocating memory for 1 elements: 0.00 MB -[+] Initializing bloom filter for 1 elements. -[+] Loading data to the bloomfilter +[+] Bloom filter for 1 elements. +[+] Loading data to the bloomfilter total: 0.00 MB [+] Bloomfilter completed -[+] Sorting data -[+] 1 values were loaded and sorted -Thread 0 : Setting up base key: 000000000000000000000000000000000000000000000000f7d1beda50ed79d4 -Total 27262976 keys in 120 seconds: 227191 keys/s -(Output omited) +[+] Sorting data ... done! 1 values were loaded and sorted +[+] Total 34603008 keys in 30 seconds: ~1 Mkeys/s (1153433 keys/s) ``` BTW this rmd160 mode doesn't allow search by vanity address @@ -276,28 +277,26 @@ A few substracted values from puzzle *40* Now you can use keyhunt against some thousand values of the puzzle 40: -`./keyhunt -m xpoint -f tests/substracted40.txt -n 65536 -t 4 -b 40` +```./keyhunt -m xpoint -f tests/substracted40.txt -n 65536 -t 4 -b 40``` Output: ``` -[+] Version 0.1.20210330a -[+] Setting mode xpoint -[+] Setting 4 threads -[+] Min range: 8000000000 -[+] Max range: ffffffffff +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Mode xpoint +[+] Threads : 4 +[+] Quiet thread output [+] Opening file tests/substracted40.txt [+] Allocating memory for 6003 elements: 0.11 MB -[+] Initializing bloom filter for 6003 elements. -[+] Loading data to the bloomfilter +[+] Bloom filter for 6003 elements. +[+] Loading data to the bloomfilter total: 0.02 MB [+] Bloomfilter completed -[+] Sorting data -[+] 6003 values were loaded and sorted -Thread 3 : Setting up base key: 0000000000000000000000000000000000000000000000000000008001d00000 -Thread 0 : Setting up base key: 00000000000000000000000000000000000000000000000000000080025b0000 -HIT!! PrivKey: 000000000000000000000000000000000000000000000000000000800258a2ce +[+] Sorting data ... done! 6003 values were loaded and sorted +HIT!! PrivKey: 800258a2ce pubkey: 0274241b684e7c31e7933510b510aa14de9ac88ec3635bdd35a3bcf1d16da210be -Thread 1 : Setting up base key: 0000000000000000000000000000000000000000000000000000008002910000^C +HIT!! PrivKey: 8009c16fb9 +pubkey: 027c3463c3d4e034f328749e2ac17b47a24b42ad47aaab0ec09d4d0abeee3ab46d + ``` After the hit we need to search the substracted index and make a simple math operation to get the real privatek: @@ -309,6 +308,27 @@ The Operation is `800258a2ce` hex (+/-) in this case + `453856235784` decimal eq This is an easy example, I been trying the puzzle 120 with more than 500 millions of substracted keys and no luck. +Test you luck with the puzzle 120 with xpoint: + +```./keyhunt -m xpoint -f tests/120.txt -t 4 -b 120 -R -q``` + +Output: + +``` +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Mode xpoint +[+] Threads : 4 +[+] Random mode +[+] Quiet thread output +[+] Opening file tests/120.txt +[+] Allocating memory for 1 elements: 0.00 MB +[+] Bloom filter for 1 elements. +[+] Loading data to the bloomfilter total: 0.00 MB +[+] Bloomfilter completed +[+] Total 544210944 keys in 30 seconds: ~18 Mkeys/s (18140364 keys/s) +``` + + ## pub2rmd mode This method is made to try to get the puzzles publickey key it works a little more faster because it skip the EC Operations @@ -348,22 +368,22 @@ c01bf430a97cbcdaedddba87ef4ea21c456cebdb To target that file you need to do: -`./keyhunt -m pub2rmd -f tests/puzzleswopublickey.txt -q` +```./keyhunt -m pub2rmd -f tests/puzzleswopublickey.txt -t 6 -q``` Output: ``` -[+] Version 0.1.20210331 -[+] Setting mode pub2rmd -[+] Set quiet thread output +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Mode pub2rmd +[+] Threads : 6 +[+] Quiet thread output [+] Opening file tests/puzzleswopublickey.txt [+] Allocating memory for 29 elements: 0.00 MB -[+] Initializing bloom filter for 29 elements. +[+] Bloom filter for 29 elements. [+] Loading data to the bloomfilter total: 0.00 MB [+] Bloomfilter completed -[+] Sorting data -[+] 29 values were loaded and sorted -Total 76546048 keys in 90 seconds: 850511 keys/s +[+] Sorting data ... done! 29 values were loaded and sorted +[+] Total 207618048 keys in 60 seconds: ~3 Mkeys/s (3460300 keys/s) ``` You can let it run for a while together with others scripts, if you get one of those publickeys now you can target it with a better method like bsgs or another tools like kangaroo @@ -389,36 +409,103 @@ btw any word followed by and space after the publickey is ignored the file can b 046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69 ``` +### File creation + +the bsgs mode `-m bsgs` now can create automatically the files needed to speed up the initial load process of keyhunt this is the bloom filters creation and the bp table creation. + +To request to keyhunt to create those files automatically use `-S` Capital S for SAVE and READ files. +The 3 files needed for keyhunt can vary from size depending of your values of `-n` and `-k` , so make your test and stick to one combination of (n,k) values or you can end with hundreds of unnesesary files. + +The 3 Files size are the same amount of memory used in runtime. + +The files are created if they don't exist when you run the program the first time. + +example of file creation: + +``` +./keyhunt -m bsgs -f tests/120.txt -R -b 120 -q -S +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Random mode +[+] Quiet thread output +[+] Mode BSGS random +[+] Opening file tests/120.txt +[+] Added 1 points from file +[+] Bit Range 120 +[+] -- from : 0x800000000000000000000000000000 +[+] -- to : 0x1000000000000000000000000000000 +[+] N = 0x100000000000 +[+] Bloom filter for 4194304 elements : 14.00 MB +[+] Bloom filter for 209716 elements : 0.72 MB +[+] Allocating 3.00 MB for 209716 bP Points +[+] processing 4194304/4194304 bP points : 100% +[+] Sorting 209716 elements... Done! +[+] Writing bloom filter to file keyhunt_bsgs_0_4194304.blm .. Done! +[+] Writing bloom filter to file keyhunt_bsgs_1_209716.blm .. Done! +[+] Writing bP Table to file keyhunt_bsgs_2_209716.tbl .. Done! +[+] Total 439804651110400 keys in 30 seconds: ~14 Tkeys/s (14660155037013 keys/s) +[+] Total 897201488265216 keys in 60 seconds: ~14 Tkeys/s (14953358137753 keys/s) +``` + +when we run the program for second time the files are now readed and the bP Points processing is omited: + +``` +./keyhunt -m bsgs -f tests/120.txt -b 120 -q -S +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Quiet thread output +[+] Turn off stats output +[+] Mode BSGS secuential +[+] Opening file tests/120.txt +[+] Added 1 points from file +[+] Bit Range 120 +[+] -- from : 0x800000000000000000000000000000 +[+] -- to : 0x1000000000000000000000000000000 +[+] N = 0x100000000000 +[+] Bloom filter for 4194304 elements : 14.00 MB +[+] Bloom filter for 209716 elements : 0.72 MB +[+] Allocating 3.00 MB for 209716 bP Points +[+] Reading bloom filter from file keyhunt_bsgs_0_4194304.blm .. Done! +[+] Reading bloom filter from file keyhunt_bsgs_1_209716.blm .. Done! +[+] Reading bP Table from file keyhunt_bsgs_2_209716.tbl ..Done! +^C +``` + +All the next examples were made with the `-S` option I just ommit that part of the output to avoid confutions use `-S` if you want, but remember with a great `-n` there must also come great files + +### Examples + To try to find those privatekey this is the line of execution: -``./keyhunt -m bsgs -f tests/test120.txt -b 120`` +``` +time ./keyhunt -m bsgs -f tests/test120.txt -b 120 -S +``` Output: ``` -[+] Version 0.1.20210328 -[+] Setting mode BSGS -[+] Min range: 800000000000000000000000000000 -[+] Max range: ffffffffffffffffffffffffffffff +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Mode BSGS secuential [+] Opening file tests/test120.txt [+] Added 2 points from file [+] Bit Range 120 -[+] Setting N up to 17592186044416. -[+] Init 1st bloom filter for 4194304 elements : 14.00 MB -[+] Init 2nd bloom filter for 209716 elements : 0.00 MB -[+] Allocating 128.0 MB for 4194304 aMP Points -[+] Precalculating 4194304 aMP points +[+] -- from : 0x800000000000000000000000000000 +[+] -- to : 0x1000000000000000000000000000000 +[+] N = 0x100000000000 +[+] Bloom filter for 4194304 elements : 14.00 MB +[+] Bloom filter for 209716 elements : 0.72 MB [+] Allocating 3.00 MB for 209716 bP Points -[+] processing 4194304/4194304 bP points : 100 % -[+] Sorting 209716 elements -[+] Thread 0: 0000000000000000000000000000000000800000000000000000000000000000 -[+] Thread 0 Key found privkey 0000000000000000000000000000000000800000000000000000100000000000 +[+] Reading bloom filter from file keyhunt_bsgs_0_4194304.blm .. Done! +[+] Reading bloom filter from file keyhunt_bsgs_1_209716.blm .. Done! +[+] Reading bP Table from file keyhunt_bsgs_2_209716.tbl ..Done! +[+] Thread Key found privkey 800000000000000000100000000000 [+] Publickey 043ffa1cc011a8d23dec502c7656fb3f93dbe4c61f91fd443ba444b4ec2dd8e6f0406c36edf3d8a0dfaa7b8f309b8f1276a5c04131762c23594f130a023742bdde -[+] Thread 0: 0000000000000000000000000000000000800000000000000000100000000000 -Total 17592186044416 keys in 30 seconds: 586406201480 keys/s -[+] Thread 0 Key found privkey 0000000000000000000000000000000000800000000000000000200000000000 +[+] Thread Key found privkey 800000000000000000200000000000 [+] Publickey 046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69 All points were found + +real 0m3.642s +user 0m3.637s +sys 0m0.005s + ``` Test the puzzle 120 with the next publickey: @@ -427,132 +514,372 @@ Test the puzzle 120 with the next publickey: 02CEB6CBBCDBDF5EF7150682150F4CE2C6F4807B349827DCDBDD1F2EFA885A2630 ``` -Line of execution in random mode **-R** +Line of execution in random mode `-R` or -B random + +```./keyhunt -m bsgs -f tests/120.txt -b 120 -q -s 10 -R``` -`./keyhunt -m bsgs -f tests/120.txt -b 120 -R` +```./keyhunt -m bsgs -f tests/120.txt -b 120 -q -s 10 -B random``` Example Output: ``` -[+] Version 0.1.20210328 -[+] Setting mode BSGS -[+] Min range: 800000000000000000000000000000 -[+] Max range: ffffffffffffffffffffffffffffff -[+] Setting random mode. +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Quiet thread output +[+] Stats output every 10 seconds +[+] Mode BSGS random [+] Opening file tests/120.txt [+] Added 1 points from file [+] Bit Range 120 -[+] Setting N up to 17592186044416. -[+] Init 1st bloom filter for 4194304 elements : 14.00 MB -[+] Init 2nd bloom filter for 209716 elements : 0.00 MB -[+] Allocating 128.0 MB for 4194304 aMP Points -[+] Precalculating 4194304 aMP points +[+] -- from : 0x800000000000000000000000000000 +[+] -- to : 0x1000000000000000000000000000000 +[+] N = 0x100000000000 +[+] Bloom filter for 4194304 elements : 14.00 MB +[+] Bloom filter for 209716 elements : 0.72 MB [+] Allocating 3.00 MB for 209716 bP Points -[+] processing 4194304/4194304 bP points : 100 % -[+] Sorting 209716 elements -[+] Thread 0: 0000000000000000000000000000000000d79219eeaef3d014d3effc55327b00 -Total 35184372088832 keys in 30 seconds: 1172812402961 keys/s +[+] processing 4194304/4194304 bP points : 100% +[+] Sorting 209716 elements... Done! +^C] Total 439804651110400 keys in 30 seconds: ~14 Tkeys/s (14660155037013 keys/s) ``` -Good speed no? 1.1 Terakeys/s for one single thread +Good speed no? 14.6 Terakeys/s for one single thread -**Total 70368744177664 keys in 60 seconds: 1172812402961 keys/s** +**[+] Total 439804651110400 keys in 30 seconds: ~14 Tkeys/s (14660155037013 keys/s)** We can speed up our process selecting a bigger K value `-k value` btw the n value is the total length of item tested in the radom range, a bigger k value means more ram to be use: Example: -`$ ./keyhunt -m bsgs -f tests/120.txt -b 120 -R -k 20` +``` +./keyhunt -m bsgs -f tests/120.txt -b 120 -R -k 20 +``` -Example output: +Output: ``` -[+] Version 0.1.20210328 -[+] Setting mode BSGS -[+] Min range: 800000000000000000000000000000 -[+] Max range: ffffffffffffffffffffffffffffff -[+] Setting random mode. -[+] Setting k factor to 20 +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Random mode +[+] K factor 20 +[+] Mode BSGS random [+] Opening file tests/120.txt [+] Added 1 points from file [+] Bit Range 120 -[+] Setting N up to 17592253153280. -[+] Init 1st bloom filter for 83886080 elements : 287.00 MB -[+] Init 2nd bloom filter for 4194304 elements : 14.00 MB -[+] Allocating 6.0 MB for 209716 aMP Points -[+] Precalculating 209716 aMP points +[+] -- from : 0x800000000000000000000000000000 +[+] -- to : 0x1000000000000000000000000000000 +[+] N = 0xfffff000000 +[+] Bloom filter for 83886080 elements : 287.00 MB +[+] Bloom filter for 4194304 elements : 14.38 MB [+] Allocating 64.00 MB for 4194304 bP Points -[+] processing 83886080/83886080 bP points : 100 % -[+] Sorting 83886080 elements -[+] Thread 0: 0000000000000000000000000000000000e6389dbe5f63a094d7fcc748e2ccba -Total 703690126131200 keys in 30 seconds: 23456337537706 keys/s -(Thread output omited....) +[+] processing 83886080/83886080 bP points : 100% +^C] Thread 0xc769b6007dccced55c48c28db483f3 : ~252 Tkeys/s (252740831805440 keys/s) ``` -**23 Terakeys/s for one single thread** +**~252 Terakeys/s for one single thread** + +Note the value of N `0xfffff000000` with k = 20 this mean that the N value is less than the default value `0x100000000000` that is because k is not a 2^X number -Want to more Speed use a bigger -k value like 128, it will use some 2.5 GB of RAM +if you want to more Speed use a bigger -k value like 128, it will use some 2.5 GB of RAM ``` -[+] Version 0.1.20210328 -[+] Setting mode BSGS -[+] Min range: 800000000000000000000000000000 -[+] Max range: ffffffffffffffffffffffffffffff -[+] Setting random mode. -[+] Setting k factor to 128 +./keyhunt -m bsgs -f tests/120.txt -b 120 -R -k 128 +``` + +Output + +``` +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Random mode +[+] K factor 128 +[+] Mode BSGS random [+] Opening file tests/120.txt [+] Added 1 points from file [+] Bit Range 120 -[+] Setting N up to 17592186044416. -[+] Init 1st bloom filter for 536870912 elements : 1840.00 MB -[+] Init 2nd bloom filter for 26843546 elements : 92.00 MB -[+] Allocating 1.0 MB for 32768 aMP Points -[+] Precalculating 32768 aMP points -[+] Allocating 409.00 MB for 26843546 bP Points -[+] processing 536870912/536870912 bP points : 100 % -[+] Sorting 26843546 elements -[+] Thread 0: 000000000000000000000000000000000086a2afb9eac0a5ea30e7a554a88aec -(Thread output omited....) -Total 4679521487814656 keys in 30 seconds: 155984049593821 keys/s +[+] -- from : 0x800000000000000000000000000000 +[+] -- to : 0x1000000000000000000000000000000 +[+] N = 0x100000000000 +[+] Bloom filter for 536870912 elements : 1840.00 MB +[+] Bloom filter for 26843546 elements : 92.02 MB +[+] processing 536870912/536870912 bP points : 100% +^C] Thread 0xa6be81c8ac15f65047f322862e37c4 s: ~1 Pkeys/s (1600302523840375 keys/s ``` -**~155 Terakeys/s for one single thread** +**~1.6 Pkeys/s for one single thread** OK at this point maybe you want to use ALL your RAM memory to solve the puzzle 120, just a bigger -k value -I already tested it with some **24 GB **used with `-k 1024` and I get **1.16 Petakeys/s per thread.** +I already tested it with some **18 GB ** used with `-k 1024` and I get **~46 Petakeys/s per thread.** with 6 threads -`./keyhunt -m bsgs -f tests/120.txt -b 120 -R -k 1024 -q -p ./bPfile.bin -t 6` +`./keyhunt -m bsgs -f tests/120.txt -b 120 -R -k 1024 -q -t 6` Output: ``` -[+] Version 0.1.20210328 -[+] Setting mode BSGS -[+] Min range: 800000000000000000000000000000 -[+] Max range: ffffffffffffffffffffffffffffff -[+] Setting random mode. -[+] Setting k factor to 1024 -[+] Set quiet thread output -[+] Setting 6 threads +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Random mode +[+] K factor 1024 +[+] Quiet thread output +[+] Threads : 6 +[+] Mode BSGS random [+] Opening file tests/120.txt [+] Added 1 points from file [+] Bit Range 120 -[+] Setting N up to 17592186044416. -[+] Init 1st bloom filter for 4294967296 elements : 14722.00 MB -[+] Init 2nd bloom filter for 214748365 elements : 736.00 MB -[+] Allocating 0.0 MB for 4096 aMP Points -[+] Precalculating 4096 aMP points +[+] -- from : 0x800000000000000000000000000000 +[+] -- to : 0x1000000000000000000000000000000 +[+] N = 0x100000000000 +[+] Bloom filter for 4294967296 elements : 14722.00 MB +[+] Bloom filter for 214748365 elements : 736.13 MB [+] Allocating 3276.00 MB for 214748365 bP Points -[+] Reading 4294967296 bP points from file ./bPfile.bin -[+] processing 4294967296/4294967296 bP points : 100 % [+] Sorting 214748365 elements -Total 157238958864990208 keys in 30 seconds: 5241298628833006 keys/s +[+] Total 5607544486029688832 keys in 120 seconds: ~46 Pkeys/s (46729537383580740 keys/s) +``` +I get ~46 Petakeys/s total + +Warning: the default n value have a maximun K of `4096` if that value is exceed the program can have an unknow behavior or suboptimal speed. +If you want to use a bigger K I recomend use a bigger N value `-n 0x400000000000` and half your K value. + +Just as comparation with the BSGS program of JLP +Same publickeys and ranged used by his sample: + +publickeys: +``` +0459A3BFDAD718C9D3FAC7C187F1139F0815AC5D923910D516E186AFDA28B221DC994327554CED887AAE5D211A2407CDD025CFC3779ECB9C9D7F2F1A1DDF3E9FF8 +04A50FBBB20757CC0E9C41C49DD9DF261646EE7936272F3F68C740C9DA50D42BCD3E48440249D6BC78BC928AA52B1921E9690EBA823CBC7F3AF54B3707E6A73F34 +0404A49211C0FE07C9F7C94695996F8826E09545375A3CF9677F2D780A3EB70DE3BD05357CAF8340CB041B1D46C5BB6B88CD9859A083B0804EF63D498B29D31DD1 +040B39E3F26AF294502A5BE708BB87AEDD9F895868011E60C1D2ABFCA202CD7A4D1D18283AF49556CF33E1EA71A16B2D0E31EE7179D88BE7F6AA0A7C5498E5D97F +04837A31977A73A630C436E680915934A58B8C76EB9B57A42C3C717689BE8C0493E46726DE04352832790FD1C99D9DDC2EE8A96E50CAD4DCC3AF1BFB82D51F2494 +040ECDB6359D41D2FD37628C718DDA9BE30E65801A88A00C3C5BDF36E7EE6ADBBAD71A2A535FCB54D56913E7F37D8103BA33ED6441D019D0922AC363FCC792C29A +0422DD52FCFA3A4384F0AFF199D019E481D335923D8C00BADAD42FFFC80AF8FCF038F139D652842243FC841E7C5B3E477D901F88C5AB0B88EE13D80080E413F2ED +04DB4F1B249406B8BD662F78CBA46F5E90E20FE27FC69D0FBAA2F06E6E50E536695DF83B68FD0F396BB9BFCF6D4FE312F32A43CF3FA1FE0F81DF70C877593B64E0 +043BD0330D7381917F8860F1949ACBCCFDC7863422EEE2B6DB7EDD551850196687528B6D2BC0AA7A5855D168B26C6BAF9DDCD04B585D42C7B9913F60421716D37A +04332A02CA42C481EAADB7ADB97DF89033B23EA291FDA809BEA3CE5C3B73B20C49C410D1AD42A9247EB8FF217935C9E28411A08B325FBF28CC2AF8182CE2B5CE38 +04513981849DE1A1327DEF34B51F5011C5070603CA22E6D868263CB7C908525F0C19EBA6BD2A8DCF651E4342512EDEACB6EA22DA323A194E25C6A1614ABD259BC0 +04D4E6FA664BD75A508C0FF0ED6F2C52DA2ADD7C3F954D9C346D24318DBD2ECFC6805511F46262E10A25F252FD525AF1CBCC46016B6CD0A7705037364309198DA1 +0456B468963752924DBF56112633DC57F07C512E3671A16CD7375C58469164599D1E04011D3E9004466C814B144A9BCB7E47D5BACA1B90DA0C4752603781BF5873 +04D5BE7C653773CEE06A238020E953CFCD0F22BE2D045C6E5B4388A3F11B4586CBB4B177DFFD111F6A15A453009B568E95798B0227B60D8BEAC98AF671F31B0E2B +04B1985389D8AB680DEDD67BBA7CA781D1A9E6E5974AAD2E70518125BAD5783EB5355F46E927A030DB14CF8D3940C1BED7FB80624B32B349AB5A05226AF15A2228 +0455B95BEF84A6045A505D015EF15E136E0A31CC2AA00FA4BCA62E5DF215EE981B3B4D6BCE33718DC6CF59F28B550648D7E8B2796AC36F25FF0C01F8BC42A16FD9 ``` -I get 5.2 Petakeys/s total + +set range + +``` +-r 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e0000000000000000:49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5effffffffffffffff +``` + +the n value to get the same baby step table: + + +``` +-n 1152921504606846976 +``` + +number of threads + +``` +-t 6 +``` + +Hidding the speed: + +``` +-s 0 +``` + +command: + +``` +time ./keyhunt -m bsgs -t 6 -f tests/in.txt -r 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e0000000000000000:49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5effffffffffffffff -n 0x1000000000000000 -M -s 0 +``` + +Output: +``` +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Threads : 6 +[+] Matrix screen +[+] Turn off stats output +[+] Mode BSGS secuential +[+] Opening file tests/in.txt +[+] Added 16 points from file +[+] Range +[+] -- from : 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e0000000000000000 +[+] -- to : 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5effffffffffffffff +[+] N = 0x1000000000000000 +[+] Bloom filter for 1073741824 elements : 3680.00 MB +[+] Bloom filter for 53687092 elements : 184.03 MB +[+] Allocating 819.00 MB for 53687092 bP Points +[+] processing 1073741824/1073741824 bP points : 100% +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e0000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e2000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e1000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e3000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e4000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e5000000000000000 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e5698aaab6cac52b3 +[+] Publickey 0404a49211c0fe07c9f7c94695996f8826e09545375a3cf9677f2d780a3eb70de3bd05357caf8340cb041b1d46c5bb6b88cd9859a083b0804ef63d498b29d31dd1 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e59c839258c2ad7a0 +[+] Publickey 040b39e3f26af294502a5be708bb87aedd9f895868011e60c1d2abfca202cd7a4d1d18283af49556cf33e1ea71a16b2d0e31ee7179d88be7f6aa0a7c5498e5d97f +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e38160da9ebeaecd7 +[+] Publickey 04db4f1b249406b8bd662f78cba46f5e90e20fe27fc69d0fbaa2f06e6e50e536695df83b68fd0f396bb9bfcf6d4fe312f32a43cf3fa1fe0f81df70c877593b64e0 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e54cad3cfbc2a9c2b +[+] Publickey 04332a02ca42c481eaadb7adb97df89033b23ea291fda809bea3ce5c3b73b20c49c410d1ad42a9247eb8ff217935c9e28411a08b325fbf28cc2af8182ce2b5ce38 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e0d5eccc38d0230e6 +[+] Publickey 04513981849de1a1327def34b51f5011c5070603ca22e6d868263cb7c908525f0c19eba6bd2a8dcf651e4342512edeacb6ea22da323a194e25c6a1614abd259bc0 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e2452dd26bc983cd5 +[+] Publickey 04b1985389d8ab680dedd67bba7ca781d1a9e6e5974aad2e70518125bad5783eb5355f46e927a030db14cf8d3940c1bed7fb80624b32b349ab5a05226af15a2228 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e6000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e7000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e8000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e9000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5ea000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5eb000000000000000 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5ebb3ef3883c1866d4 +[+] Publickey 0459a3bfdad718c9d3fac7c187f1139f0815ac5d923910d516e186afda28b221dc994327554ced887aae5d211a2407cdd025cfc3779ecb9c9d7f2f1a1ddf3e9ff8 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5eb5abc43bebad3207 +[+] Publickey 04a50fbbb20757cc0e9c41c49dd9df261646ee7936272f3f68c740c9da50d42bcd3e48440249d6bc78bc928aa52b1921e9690eba823cbc7f3af54b3707e6a73f34 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e765fb411e63b92b9 +[+] Publickey 04837a31977a73a630c436e680915934a58b8c76eb9b57a42c3c717689be8c0493e46726de04352832790fd1c99d9ddc2ee8a96e50cad4dcc3af1bfb82d51f2494 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e7d0e6081c7e0e865 +[+] Publickey 040ecdb6359d41d2fd37628c718dda9be30e65801a88a00c3c5bdf36e7ee6adbbad71a2a535fcb54d56913e7f37d8103ba33ed6441d019d0922ac363fcc792c29a +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e79d808cab1decf8d +[+] Publickey 043bd0330d7381917f8860f1949acbccfdc7863422eee2b6db7edd551850196687528b6d2bc0aa7a5855d168b26c6baf9ddcd04b585d42c7b9913f60421716d37a +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e7c43b8e079ae7278 +[+] Publickey 0456b468963752924dbf56112633dc57f07c512e3671a16cd7375c58469164599d1e04011d3e9004466c814b144a9bcb7e47d5baca1b90da0c4752603781bf5873 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e8d63ef128ef66b42 +[+] Publickey 04d5be7c653773cee06a238020e953cfcd0f22be2d045c6e5b4388a3f11b4586cbb4b177dffd111f6a15a453009b568e95798b0227b60d8beac98af671f31b0e2b +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5e7ad38337c7f173c7 +[+] Publickey 0455b95bef84a6045a505d015ef15e136e0a31cc2aa00fa4bca62e5df215ee981b3b4d6bce33718dc6cf59f28b550648d7e8b2796ac36f25ff0c01f8bc42a16fd9 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5ec000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5ed000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5ee000000000000000 +[+] Thread 0x49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5ef000000000000000 +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5ec737344ca673ce28 +[+] Publickey 0422dd52fcfa3a4384f0aff199d019e481d335923d8c00badad42fffc80af8fcf038f139d652842243fc841e7c5b3e477d901f88c5ab0b88ee13d80080e413f2ed +[+] Thread Key found privkey 49dccfd96dc5df56487436f5a1b18c4f5d34f65ddb48cb5ee3579364de939b0c +[+] Publickey 04d4e6fa664bd75a508c0ff0ed6f2c52da2add7c3f954d9c346d24318dbd2ecfc6805511f46262e10a25f252fd525af1cbcc46016b6cd0a7705037364309198da1 +All points were found + +real 164m32.904s +user 973m8.387s +sys 0m26.803s +``` + +Amount of RAM used ~4.5 GB, time to solve the sixteen publickeys in the range of 64 bits key-space: 164 min (~2.7 hrs) using 6 threads + +if we run the same command with `-n 0x1000000000000000 -k 4 -t 6` it use ~18 GB or RAM and solve the same keys in 60 minutes + +``` +All points were found + +real 59m50.533s +user 329m29.836s +sys 0m22.752s +``` + +There are several variations to play with the values `-n` and `-k` but there are some minimal values required, n can not be less than 1048576 (2^20) + +To get optimal performance the k values need to be base 2^x values, this is 1,2,4,8,16,32 ... + +### 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 | ++---------------------------+-------------+---------------------------+ + + +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 case you can missing some hits. + +Of course you can use a bigger number N like 2^64 or 2^70 if you have enough memory for it. + +Note for user that want use it with SWAP memory. IT DON'T WORK swap memory was made to small chucks of memory also is slowly. + + +### Testing puzzle 63 bits + +Publickey: + +``` +0365ec2994b8cc0a20d40dd69edfe55ca32a54bcbbaa6b0ddcff36049301a54579 +``` + +Command +``` +time ./keyhunt -m bsgs -t 6 -f tests/63.pub -n 0x1000000000000000 -M -s 0 -S -k 4 -b 63 +``` + +output: + +``` +[+] Version 0.2.211007 Chocolate ¡Beta! +[+] Threads : 6 +[+] Matrix screen +[+] Turn off stats output +[+] K factor 4 +[+] Mode BSGS secuential +[+] Opening file tests/63.pub +[+] Added 1 points from file +[+] Bit Range 63 +[+] -- from : 0x4000000000000000 +[+] -- to : 0x8000000000000000 +[+] N = 0x1000000000000000 +[+] Bloom filter for 4294967296 elements : 14722.00 MB +[+] Bloom filter for 214748365 elements : 736.13 MB +[+] Allocating 3276.00 MB for 214748365 bP Points +[+] Reading bloom filter from file keyhunt_bsgs_0_4294967296.blm .. Done! +[+] Reading bloom filter from file keyhunt_bsgs_1_214748365.blm .. Done! +[+] Reading bP Table from file keyhunt_bsgs_2_214748365.tbl ..Done! +[+] Thread 0x6000000000000000 +[+] Thread 0x5000000000000000 +[+] Thread 0x4000000000000000 +[+] Thread 0x7000000000000000 +[+] Thread Key found privkey 7cce5efdaccf6808 +[+] Publickey 0365ec2994b8cc0a20d40dd69edfe55ca32a54bcbbaa6b0ddcff36049301a54579 +All points were found + +real 4m58.644s +user 7m52.332s +sys 0m11.803s + +``` + +Please note that number of threads was setting to 6 but only 4 threads were used, this is because the range 63 bits is small for BSGS and we only need four times the current N value to fill it, to avoid this we can use a smaller N value but with some multiplier K in that way w we can achieve the same speed and also be able to launch more threads. Repeat only in case that the range was small like this. + +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 +``` + +``` +real 4m4.719s +user 2m15.706s +sys 0m13.009s +``` + ## FAQ @@ -561,13 +888,31 @@ R: In a file called `KEYFOUNDKEYFOUND.txt` - Is available for Windows? R: It can be compiled with mingw, It can be executed in the Ubuntu shell for windows 10 +Updated: Yes, thanks to @WanderingPhilosopher +Available in: https://github.com/WanderingPhilosopher/keyhunt/releases/tag/v1.0 + +- 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 + +- 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. + ## Dependencies - pthread Tested under Debian, Termux, Ubuntu Shell for windows 10 -## Donation +## Thanks + +This program was possible thanks to +- IceLand +- kanhavishva +- All the group of CryptoHunters that made this program possible +- All the users that tested it, report bugs, requested improvements and shared his knowledge. + +## Donations - BTC: 1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW - ETH: 0x6222978c984C22d21b11b5b6b0Dd839C75821069 diff --git a/bPfile.c b/bPfile.c deleted file mode 100644 index 61e119a..0000000 --- a/bPfile.c +++ /dev/null @@ -1,260 +0,0 @@ -/* -Develop by Luis Alberto -email: alberto.bsd@gmail.com - -gcc -o bPfile bPfile.c -lgmp -lm - -Hint: compile in the keyhunt directory -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "util.h" - -uint64_t BSGS_BUFFERXPOINTLENGTH = 32; -uint64_t BSGS_BUFFERREGISTERLENGTH = 36; - -struct Point { - mpz_t x; - mpz_t y; -}; - -struct Elliptic_Curve { - mpz_t p; - mpz_t n; -}; - -const char *EC_constant_N = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; -const char *EC_constant_P = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"; -const char *EC_constant_Gx = "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"; -const char *EC_constant_Gy = "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"; -struct Point DoublingG[256]; - -void Point_Doubling(struct Point *P, struct Point *R); -void Point_Addition(struct Point *P, struct Point *Q, struct Point *R); -void Scalar_Multiplication(struct Point P, struct Point *R, mpz_t m); -void Point_Negation(struct Point *A, struct Point *S); - -void init_doublingG(struct Point *P); - - -struct Elliptic_Curve EC; -struct Point G; - -int main(int argc, char **argv) { - mpz_t temp; - FILE *p_file; - char temporal[512],rawvalue[BSGS_BUFFERXPOINTLENGTH]; - long int i,m,sz; - - mpz_t M; - struct Point point_t,P; - - if(argc < 3) { - printf("Create bP File usage\n"); - printf("%s \n\n",argv[0]); - printf("Example to create a File with 1 Billion items:\n%s 1000000000 Pfile.bin\n",argv[0]); - printf("If the file exists, only the missing bP items will be added○\n"); - exit(0); - } - - mpz_init_set_str(M,argv[1],10); - - mpz_init_set_str(EC.p, EC_constant_P, 16); - mpz_init_set_str(EC.n, EC_constant_N, 16); - mpz_init_set_str(G.x , EC_constant_Gx, 16); - mpz_init_set_str(G.y , EC_constant_Gy, 16); - init_doublingG(&G); - - - mpz_init(point_t.x); - mpz_init(point_t.y); - - mpz_init(temp); - - - m = mpz_get_ui(M); - - mpz_init_set(P.x,G.x); - mpz_init_set(P.y,G.y); - - p_file = fopen(argv[2],"wb"); - - if(p_file == NULL) { - printf("Can't create file %s\n",argv[2]); - exit(0); - } - /* - fseek(p_file, 0L, SEEK_END); - sz = ftell(p_file); - if(sz % 32 != 0) { - printf("Invalid filesize\n"); - exit(0); - } - printf("Current numeber of items %li\n",(long int)(sz/32)); - if(m <= sz/32 ) { - printf("The current file have %li items\n",m); - } - else { - i = m-(sz/32); - printf("OK, items missing %li\n",i); - } - mpz_set_ui(temp,i) - */ - i = 0; - printf("[+] precalculating %li bP elements in file %s\n",m,argv[2]); - do { - mpz_set(point_t.x,P.x); - mpz_set(point_t.y,P.y); - gmp_sprintf(temporal,"%0.64Zx",P.x); - hexs2bin(temporal,(unsigned char *)rawvalue); - fwrite(rawvalue,1,32,p_file); - Point_Addition(&G,&point_t,&P); - i++; - } while(i < m); -} - -void Point_Doubling(struct Point *P, struct Point *R) { - mpz_t slope, temp; - mpz_init(temp); - mpz_init(slope); - if(mpz_cmp_ui(P->y, 0) != 0) { - mpz_mul_ui(temp, P->y, 2); - mpz_invert(temp, temp, EC.p); - mpz_mul(slope, P->x, P->x); - mpz_mul_ui(slope, slope, 3); - mpz_mul(slope, slope, temp); - mpz_mod(slope, slope, EC.p); - mpz_mul(R->x, slope, slope); - mpz_sub(R->x, R->x, P->x); - mpz_sub(R->x, R->x, P->x); - mpz_mod(R->x, R->x, EC.p); - mpz_sub(temp, P->x, R->x); - mpz_mul(R->y, slope, temp); - mpz_sub(R->y, R->y, P->y); - mpz_mod(R->y, R->y, EC.p); - } else { - mpz_set_ui(R->x, 0); - mpz_set_ui(R->y, 0); - } - mpz_clear(temp); - mpz_clear(slope); -} - -void Point_Addition(struct Point *P, struct Point *Q, struct Point *R) { - mpz_t PA_temp,PA_slope; - mpz_init(PA_temp); - mpz_init(PA_slope); - mpz_mod(Q->x, Q->x, EC.p); - mpz_mod(Q->y, Q->y, EC.p); - mpz_mod(P->x, P->x, EC.p); - mpz_mod(P->y, P->y, EC.p); - if(mpz_cmp_ui(P->x, 0) == 0 && mpz_cmp_ui(P->y, 0) == 0) { - mpz_set(R->x, Q->x); - mpz_set(R->y, Q->y); - } - else { - /* This is commented because Q never 0,0, always is kG point*/ - /* - if(mpz_cmp_ui(Q->x, 0) == 0 && mpz_cmp_ui(Q->y, 0) == 0) { - mpz_set(R->x, P->x); - mpz_set(R->y, P->y); - } - else { - */ - if(mpz_cmp_ui(Q->y, 0) != 0) { - mpz_sub(PA_temp, EC.p, Q->y); - mpz_mod(PA_temp, PA_temp, EC.p); - } - else { - mpz_set_ui(PA_temp, 0); - } - if(mpz_cmp(P->y, PA_temp) == 0 && mpz_cmp(P->x, Q->x) == 0) { - mpz_set_ui(R->x, 0); - mpz_set_ui(R->y, 0); - } - else { - if(mpz_cmp(P->x, Q->x) == 0 && mpz_cmp(P->y, Q->y) == 0) { - Point_Doubling(P, R); - } - else { - mpz_set_ui(PA_slope, 0); - mpz_sub(PA_temp, P->x, Q->x); - mpz_mod(PA_temp, PA_temp, EC.p); - mpz_invert(PA_temp, PA_temp, EC.p); - mpz_sub(PA_slope, P->y, Q->y); - mpz_mul(PA_slope, PA_slope, PA_temp); - mpz_mod(PA_slope, PA_slope, EC.p); - mpz_mul(R->x, PA_slope, PA_slope); - mpz_sub(R->x, R->x, P->x); - mpz_sub(R->x, R->x, Q->x); - mpz_mod(R->x, R->x, EC.p); - mpz_sub(PA_temp, P->x, R->x); - mpz_mul(R->y, PA_slope, PA_temp); - mpz_sub(R->y, R->y, P->y); - mpz_mod(R->y, R->y, EC.p); - } - } - //} - } - mpz_clear(PA_temp); - mpz_clear(PA_slope); -} - -void Scalar_Multiplication(struct Point P, struct Point *R, mpz_t m) { - char strtemp[65]; - struct Point SM_T,SM_Q; - long no_of_bits, i; - no_of_bits = mpz_sizeinbase(m, 2); - mpz_init_set_ui(SM_Q.x,0); - mpz_init_set_ui(SM_Q.y,0); - mpz_init_set_ui(SM_T.x,0); - mpz_init_set_ui(SM_T.y,0); - mpz_set_ui(R->x, 0); - mpz_set_ui(R->y, 0); - if(mpz_cmp_ui(m, 0) != 0) { - mpz_set(SM_Q.x, P.x); - mpz_set(SM_Q.y, P.y); - for(i = 0; i < no_of_bits; i++) { - if(mpz_tstbit(m, i)) { - mpz_set(SM_T.x, R->x); - mpz_set(SM_T.y, R->y); - mpz_set(SM_Q.x,DoublingG[i].x); - mpz_set(SM_Q.y,DoublingG[i].y); - Point_Addition(&SM_T, &SM_Q, R); - } - } - } - mpz_clear(SM_T.x); - mpz_clear(SM_T.y); - mpz_clear(SM_Q.x); - mpz_clear(SM_Q.y); -} - -void Point_Negation(struct Point *A, struct Point *S) { - mpz_sub(S->y, EC.p, A->y); - mpz_set(S->x, A->x); -} - -void init_doublingG(struct Point *P) { - int i = 0; - mpz_init(DoublingG[i].x); - mpz_init(DoublingG[i].y); - mpz_set(DoublingG[i].x,P->x); - mpz_set(DoublingG[i].y,P->y); - i = 1; - while(i < 256){ - mpz_init(DoublingG[i].x); - mpz_init(DoublingG[i].y); - Point_Doubling(&DoublingG[i-1] ,&DoublingG[i]); - mpz_mod(DoublingG[i].x, DoublingG[i].x, EC.p); - mpz_mod(DoublingG[i].y, DoublingG[i].y, EC.p); - i++; - } -} diff --git a/bloom/bloom.c b/bloom/bloom.c index 7973f2a..dbfdd83 100644 --- a/bloom/bloom.c +++ b/bloom/bloom.c @@ -29,7 +29,7 @@ #define STRING(n) #n #define BLOOM_MAGIC "libbloom2" #define BLOOM_VERSION_MAJOR 2 -#define BLOOM_VERSION_MINOR 1 +#define BLOOM_VERSION_MINOR 200 inline static int test_bit_set_bit(unsigned char * buf, uint64_t bit, int set_bit) { @@ -105,7 +105,12 @@ int bloom_init2(struct bloom * bloom, uint64_t entries, long double error) } bloom->hashes = (uint8_t)ceil(0.693147180559945 * bloom->bpe); // ln(2) - + + /* + printf("\nBPE: %lu\n",bloom->bpe); + printf("BITS: %lu\n",bloom->bits); + printf("BYTES: %lu\n",bloom->bytes); + */ bloom->bf = (uint8_t *)calloc(bloom->bytes, sizeof(uint8_t)); if (bloom->bf == NULL) { // LCOV_EXCL_START return 1; diff --git a/bloom/bloom.h b/bloom/bloom.h index 6ee120e..d395be6 100644 --- a/bloom/bloom.h +++ b/bloom/bloom.h @@ -37,6 +37,8 @@ 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; }; diff --git a/keyhunt.c b/keyhunt.c index 6c87133..41e197e 100644 --- a/keyhunt.c +++ b/keyhunt.c @@ -1,6 +1,7 @@ /* Develop by Luis Alberto email: alberto.bsd@gmail.com + */ #include @@ -41,6 +42,7 @@ email: alberto.bsd@gmail.com #define MODE_RMD160 3 #define MODE_PUB2RMD 4 + #define SEARCH_UNCOMPRESS 0 #define SEARCH_COMPRESS 1 #define SEARCH_BOTH 2 @@ -56,9 +58,9 @@ struct address_value { }; struct tothread { - int nt; //Number thread - char *rs; //range start - char *rpt; //rng per thread + int nt; //Number thread + char *rs; //range start + char *rpt; //rng per thread }; struct bPload { @@ -73,13 +75,13 @@ struct __attribute__((__packed__)) publickey { union { uint8_t data8[32]; uint32_t data32[8]; - uint64_t data64[4]; + uint64_t data64[4]; } X; }; -const char *version = "0.1.20210412 secp256k1"; +const char *version = "0.2.211007 Chocolate ¡Beta!"; -const char *bloomnames[256] = {"bloom_0","bloom_1","bloom_2","bloom_3","bloom_4","bloom_5","bloom_6","bloom_7","bloom_8","bloom_9","bloom_10","bloom_11","bloom_12","bloom_13","bloom_14","bloom_15","bloom_16","bloom_17","bloom_18","bloom_19","bloom_20","bloom_21","bloom_22","bloom_23","bloom_24","bloom_25","bloom_26","bloom_27","bloom_28","bloom_29","bloom_30","bloom_31","bloom_32","bloom_33","bloom_34","bloom_35","bloom_36","bloom_37","bloom_38","bloom_39","bloom_40","bloom_41","bloom_42","bloom_43","bloom_44","bloom_45","bloom_46","bloom_47","bloom_48","bloom_49","bloom_50","bloom_51","bloom_52","bloom_53","bloom_54","bloom_55","bloom_56","bloom_57","bloom_58","bloom_59","bloom_60","bloom_61","bloom_62","bloom_63","bloom_64","bloom_65","bloom_66","bloom_67","bloom_68","bloom_69","bloom_70","bloom_71","bloom_72","bloom_73","bloom_74","bloom_75","bloom_76","bloom_77","bloom_78","bloom_79","bloom_80","bloom_81","bloom_82","bloom_83","bloom_84","bloom_85","bloom_86","bloom_87","bloom_88","bloom_89","bloom_90","bloom_91","bloom_92","bloom_93","bloom_94","bloom_95","bloom_96","bloom_97","bloom_98","bloom_99","bloom_100","bloom_101","bloom_102","bloom_103","bloom_104","bloom_105","bloom_106","bloom_107","bloom_108","bloom_109","bloom_110","bloom_111","bloom_112","bloom_113","bloom_114","bloom_115","bloom_116","bloom_117","bloom_118","bloom_119","bloom_120","bloom_121","bloom_122","bloom_123","bloom_124","bloom_125","bloom_126","bloom_127","bloom_128","bloom_129","bloom_130","bloom_131","bloom_132","bloom_133","bloom_134","bloom_135","bloom_136","bloom_137","bloom_138","bloom_139","bloom_140","bloom_141","bloom_142","bloom_143","bloom_144","bloom_145","bloom_146","bloom_147","bloom_148","bloom_149","bloom_150","bloom_151","bloom_152","bloom_153","bloom_154","bloom_155","bloom_156","bloom_157","bloom_158","bloom_159","bloom_160","bloom_161","bloom_162","bloom_163","bloom_164","bloom_165","bloom_166","bloom_167","bloom_168","bloom_169","bloom_170","bloom_171","bloom_172","bloom_173","bloom_174","bloom_175","bloom_176","bloom_177","bloom_178","bloom_179","bloom_180","bloom_181","bloom_182","bloom_183","bloom_184","bloom_185","bloom_186","bloom_187","bloom_188","bloom_189","bloom_190","bloom_191","bloom_192","bloom_193","bloom_194","bloom_195","bloom_196","bloom_197","bloom_198","bloom_199","bloom_200","bloom_201","bloom_202","bloom_203","bloom_204","bloom_205","bloom_206","bloom_207","bloom_208","bloom_209","bloom_210","bloom_211","bloom_212","bloom_213","bloom_214","bloom_215","bloom_216","bloom_217","bloom_218","bloom_219","bloom_220","bloom_221","bloom_222","bloom_223","bloom_224","bloom_225","bloom_226","bloom_227","bloom_228","bloom_229","bloom_230","bloom_231","bloom_232","bloom_233","bloom_234","bloom_235","bloom_236","bloom_237","bloom_238","bloom_239","bloom_240","bloom_241","bloom_242","bloom_243","bloom_244","bloom_245","bloom_246","bloom_247","bloom_248","bloom_249","bloom_250","bloom_251","bloom_252","bloom_253","bloom_254","bloom_255"}; +#define CPU_GRP_SIZE 1024 std::vector Gn; Point _2Gn; @@ -87,11 +89,6 @@ Point _2Gn; std::vector GSn; Point _2GSn; -std::vector GS2n; -Point _2GS2n; - -int CPU_GRP_SIZE = 1024; - void init_generator(); @@ -119,19 +116,27 @@ int bsgs_secondcheck(Int *start_range,uint32_t a,uint32_t k_index,Int *privateke void *thread_process(void *vargp); void *thread_process_bsgs(void *vargp); +void *thread_process_bsgs_backward(void *vargp); +void *thread_process_bsgs_both(void *vargp); void *thread_process_bsgs_random(void *vargp); +void *thread_process_bsgs_dance(void *vargp); void *thread_bPload(void *vargp); void *thread_bPloadFile(void *vargp); void *thread_pub2rmd(void *vargp); char *publickeytohashrmd160(char *pkey,int length); char *pubkeytopubaddress(char *pkey,int length); -//char *pubkeytopubaddress_eth(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(); int THREADOUTPUT = 0; char *bit_range_str_min; char *bit_range_str_max; +const char *bsgs_modes[5] {"secuential","backward","both","random","dance"}; const char *modes[5] = {"xpoint","address","bsgs","rmd160","pub2rmd"}; const char *cryptos[3] = {"btc","eth","all"}; const char *publicsearch[3] = {"uncompress","compress","both"}; @@ -143,11 +148,10 @@ pthread_mutex_t write_random; pthread_mutex_t bsgs_thread; -struct bloom dummybloom; struct bloom bloom; -unsigned int *steps = NULL; +uint64_t *steps = NULL; unsigned int *ends = NULL; uint64_t N = 0; @@ -156,14 +160,23 @@ uint64_t N_SECUENTIAL_MAX = 0xffffffff; uint64_t DEBUGCOUNT = 0x100000; + + Int OUTPUTSECONDS; + +int FLAGBSGSMODE = 0; int FLAGDEBUG = 0; int FLAGQUIET = 0; +int FLAGMATRIX = 0; int KFACTOR = 1; int MAXLENGTHADDRESS = -1; int NTHREADS = 1; +int FLAGSAVEREADFILE = 0; +int FLAGREADEDFILE1 = 0; +int FLAGREADEDFILE2 = 0; +int FLAGREADEDFILE3 = 0; int FLAGSEARCH = 2; int FLAGBITRANGE = 0; int FLAGRANGE = 0; @@ -176,11 +189,10 @@ int FLAGRAWDATA = 0; int FLAGRANDOM = 0; int FLAG_N = 0; int FLAGPRECALCUTED_P_FILE = 0; -int FLAGPRECALCUTED_MP_FILE = 0; -int FLAGBLOOMFILTER = 0; int len_vanity; int bitrange; +char *str_N; char *vanity; char *range_start; char *range_end; @@ -196,10 +208,12 @@ int *bsgs_found; std::vector OriginalPointsBSGS; bool *OriginalPointsBSGScompressed; - +uint64_t bytes; +char checksum[32],checksum_backup[32]; +char buffer_bloom_file[1024]; struct bsgs_xvalue *bPtable; struct address_value *addressTable; -struct bloom bloom_bP[256]; +struct bloom bloom_bP; struct bloom bloom_bPx2nd; //Second Bloom filter check uint64_t bloom_bP_totalbytes = 0; char *precalculated_p_filename; @@ -209,6 +223,12 @@ uint64_t bsgs_m2; unsigned long int bsgs_aux; uint32_t bsgs_point_number; +const char *str_limits_prefixs[7] = {"Mkeys/s","Gkeys/s","Tkeys/s","Pkeys/s","Ekeys/s","Zkeys/s","Ykeys/s"}; +const char *str_limits[7] = {"1000000","1000000000","1000000000000","1000000000000000","1000000000000000000","1000000000000000000000","1000000000000000000000000"}; +Int int_limits[6]; + + + Int BSGS_GROUP_SIZE; Int BSGS_CURRENT; @@ -225,9 +245,7 @@ Point BSGS_P; //Original P is actually G, but this P value change over time fo Point BSGS_MP; //MP values this is m * P Point BSGS_MP2; //MP values this is m2 * P - -std::vector BSGS_AMP,BSGS_AMP2; - +std::vector BSGS_AMP2; Point point_temp,point_temp2; //Temp value for some process @@ -236,21 +254,21 @@ Int n_range_end; Int n_range_diff; Int n_range_aux; - Secp256K1 *secp; int main(int argc, char **argv) { - char buffer[1024]; + char buffer[2048]; char temporal[65]; 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; - FILE *fd; - uint64_t j,total_precalculated,i,PERTHREAD,BASE,PERTHREAD_R,itemsbloom,itemsbloom2; - int readed,s,continue_flag,check_flag,r,lenaux,lendiff,c; - Int total,pretotal,debugcount_mpz,seconds; + char *filename,*precalculated_mp_filename,*hextemp,*aux,*aux2,*pointx_str,*pointy_str,*str_seconds,*str_total,*str_pretotal,*str_divpretotal,*bf_ptr; + FILE *fd,*fd_aux1,*fd_aux2,*fd_aux3; + uint64_t j,total_precalculated,i,PERTHREAD,BASE,PERTHREAD_R; + int readed,s,continue_flag,check_flag,r,lenaux,lendiff,c,salir,index_value; + Int total,pretotal,debugcount_mpz,seconds,div_pretotal; struct bPload *temp; + srand (time(NULL)); secp = new Secp256K1(); secp->Init(); @@ -260,45 +278,50 @@ int main(int argc, char **argv) { BSGS_GROUP_SIZE.SetInt32(CPU_GRP_SIZE); rseed(clock() + time(NULL)); - printf("[+] Version %s\n",version); + printf("[+] Version %s, developed by AlbertoBSD\n",version); - while ((c = getopt(argc, argv, "dehqRwzb:c:f:g:k:l:m:n:p:r:s:t:v:G:")) != -1) { + while ((c = getopt(argc, argv, "dehMqRwzSB:b:c:E:f:k:l:m:n:p:r:s:t:v:G:")) != -1) { switch(c) { case 'h': printf("\nUsage:\n-h\t\tshow this help\n"); - printf("-a file\t\tfile is a binary raw file with the aMP points precalculated. Just work with -m bsgs\n"); + printf("-B Mode\t\tBSGS now have some modes \n"); printf("-b bits\t\tFor some puzzles you only need some numbers of bits in the test keys.\n"); printf("\t\tThis option only is valid with the Random option -R\n"); printf("-c crypto\tSearch for specific crypo. < btc, eth, all > valid only w/ -m address \n"); - printf("-e\t\tThe file is already Sorted descendent. This skip the sorting process.\n"); printf("\t\tYour file MUST be sordted if no you are going to lose collisions\n"); printf("-f file\t\tSpecify filename with addresses or xpoints or uncompressed public keys\n"); printf("-g count\tJust for the stats, mark as counted every debugcount keys \n"); printf("-k value\tUse this only with bsgs mode, k value is factor for M, more speed but more RAM use wisely\n"); printf("-l look\tWhat type of address/hash160 are you looking for < compress , uncompress , both>\n"); printf("-m mode\t\tmode of search for cryptos. ( bsgs , xpoint , rmd160 , address ) default: address (more slow)\n"); + printf("-M\t\tMatrix screen, feel like a h4x0r, but performance will droped\n"); printf("-n uptoN\tCheck for N secuential numbers before the random chossen this only work with -R option\n"); printf("\t\tUse -n to set the N for the BSGS process. Bigger N more RAM needed\n"); printf("-p file\t\tfile is a binary raw file with the bP points precalculated. Just work with -m bsgs\n"); - printf("-q\t\tset quiet the thread output\n"); + printf("-q\t\tQuiet the thread output\n"); printf("-r SR:EN\tStarRange:EndRange, the end range can be omited for search from start range to N-1 ECC value\n"); printf("-R\t\tRandom this is the default behaivor\n"); printf("-s ns\t\tNumber of seconds for the stats output, 0 to omit output.\n"); + printf("-S\t\tCapital S is for SAVING in files BSGS data (Bloom filters and bPtable)\n"); printf("-t tn\t\tThreads number, must be positive integer\n"); printf("-v va\t\tSearch for vanity Address, only with -m address\n"); printf("-w\t\tMark the input file as RAW data xpoint fixed 32 byte each point. Valid only with -m xpoint\n"); - //printf("-z\t\tSave and load bloom bloomfilter from File\n"); - printf("\t\tUse the hexcharstoraw tool to create a raw file from your current hexadecimal file\n"); printf("\nExample\n\n"); - printf("%s -t 16 -r 00000001:FFFFFFFF -s 0\n\n",argv[0]); - printf("This line run the program with 16 threads from the range 00000001 to FFFFFFFF without stats output\n\n"); + printf("%s -t 16 -r 1:FFFFFFFF -s 0\n\n",argv[0]); + printf("This line run the program with 16 threads from the range 1 to FFFFFFFF without stats output\n\n"); printf("Developed by AlbertoBSD\tTips BTC: 1ABSD1rMTmNZHJrJP8AJhDNG1XbQjWcRz7\n"); - printf("Thanks to Iceland always helping and sharing his ideas, Tips to Iceland: bc1q39meky2mn5qjq704zz0nnkl0v7kj4uz6r529at\n\n"); + printf("Thanks to Iceland always helping and sharing his ideas.\nTips to Iceland: bc1q39meky2mn5qjq704zz0nnkl0v7kj4uz6r529at\n\n"); exit(0); break; - case 'a': - FLAGPRECALCUTED_MP_FILE = 1; - precalculated_mp_filename = optarg; + case 'B': + index_value = indexOf(optarg,bsgs_modes,5); + if(index_value >= 0 && index_value <= 4) { + FLAGBSGSMODE = index_value; + //printf("[+] BSGS mode %s\n",optarg); + } + else { + fprintf(stderr,"[W] Ignoring unknow bsgs mode %s\n",optarg); + } break; case 'b': bitrange = strtol(optarg,NULL,10); @@ -316,8 +339,6 @@ int main(int argc, char **argv) { fprintf(stderr,"[E] error malloc()\n"); exit(0); } - printf("[+] Min range: %s\n",bit_range_str_min); - printf("[+] Max range: %s\n",bit_range_str_max); FLAGBITRANGE = 1; } else { @@ -325,23 +346,25 @@ int main(int argc, char **argv) { } break; case 'c': - switch(indexOf(optarg,cryptos,3)) { - case 0: //btc - FLAGCRYPTO = CRYPTO_BTC; - printf("[+] Setting search for btc adddress.\n"); - break; - case 1: //eth - FLAGCRYPTO = CRYPTO_ETH; - printf("[+] Setting search for eth adddress.\n"); - break; - case 2: //all - FLAGCRYPTO = CRYPTO_ALL; - printf("[+] Setting search for all cryptocurrencies avaible [btc].\n"); - break; - default: - FLAGCRYPTO = CRYPTO_NONE; - fprintf(stderr,"[E] Unknow crypto value %s\n",optarg); - break; + index_value = indexOf(optarg,cryptos,3); + switch(index_value) { + case 0: //btc + FLAGCRYPTO = CRYPTO_BTC; + printf("[+] Setting search for BTC adddress.\n"); + break; + case 1: //eth + FLAGCRYPTO = CRYPTO_ETH; + printf("[+] Setting search for ETH adddress.\n"); + break; + case 2: //all + FLAGCRYPTO = CRYPTO_ALL; + printf("[+] Setting search for all cryptocurrencies avaible [btc].\n"); + break; + default: + FLAGCRYPTO = CRYPTO_NONE; + fprintf(stderr,"[E] Unknow crypto value %s\n",optarg); + exit(0); + break; } break; case 'd': @@ -355,19 +378,13 @@ int main(int argc, char **argv) { FLAGFILE = 1; filename = optarg; break; - case 'g': - DEBUGCOUNT = strtol(optarg,NULL,10); - if(DEBUGCOUNT == 0) { - DEBUGCOUNT = 0x100000; - fprintf(stderr,"[E] invalid -g option value: %s.\n",optarg); - } - break; + case 'k': KFACTOR = (int)strtol(optarg,NULL,10); if(KFACTOR <= 0) { KFACTOR = 1; } - printf("[+] Setting k factor to %i\n",KFACTOR); + printf("[+] K factor %i\n",KFACTOR); break; case 'l': @@ -386,53 +403,54 @@ int main(int argc, char **argv) { break; } break; + case 'M': + FLAGMATRIX = 1; + printf("[+] Matrix screen\n"); + break; case 'm': switch(indexOf(optarg,modes,5)) { case MODE_XPOINT: //xpoint FLAGMODE = MODE_XPOINT; - printf("[+] Setting mode xpoint\n"); + printf("[+] Mode xpoint\n"); break; case MODE_ADDRESS: //address FLAGMODE = MODE_ADDRESS; - printf("[+] Setting mode address\n"); + printf("[+] Mode address\n"); break; case MODE_BSGS: FLAGMODE = MODE_BSGS; - printf("[+] Setting mode BSGS\n"); + //printf("[+] Mode BSGS\n"); break; case MODE_RMD160: FLAGMODE = MODE_RMD160; - printf("[+] Setting mode rmd160\n"); + printf("[+] Mode rmd160\n"); break; case MODE_PUB2RMD: FLAGMODE = MODE_PUB2RMD; - printf("[+] Setting mode pub2rmd\n"); + printf("[+] Mode pub2rmd\n"); break; default: - FLAGMODE = MODE_ADDRESS; - fprintf(stderr,"[+] Unknow mode value %s.\n",optarg); + fprintf(stderr,"[E] Unknow mode value %s\n",optarg); + exit(0); break; } break; case 'n': FLAG_N = 1; - N_SECUENTIAL_MAX = strtol(optarg,NULL,10); - if(N_SECUENTIAL_MAX <= 0) { - FLAG_N = 0; - N_SECUENTIAL_MAX = 0xFFFFFFFF; - } + str_N = optarg; break; case 'q': FLAGQUIET = 1; - printf("[+] Set quiet thread output\n"); + printf("[+] Quiet thread output\n"); break; case 'p': FLAGPRECALCUTED_P_FILE = 1; precalculated_p_filename = optarg; break; case 'R': + printf("[+] Random mode\n"); FLAGRANDOM = 1; - printf("[+] Setting random mode.\n"); + FLAGBSGSMODE = 3; break; case 'r': if(optarg != NULL) { @@ -441,8 +459,8 @@ int main(int argc, char **argv) { case 1: range_start = nextToken(&t); if(isValidHex(range_start)) { - FLAGRANGE = 1; - range_end = secp->order.GetBase16(); + FLAGRANGE = 1; + range_end = secp->order.GetBase16(); } else { fprintf(stderr,"[E] Invalid hexstring : %s.\n",range_start); @@ -483,12 +501,15 @@ int main(int argc, char **argv) { free(hextemp); } break; + case 'S': + FLAGSAVEREADFILE = 1; + break; case 't': NTHREADS = strtol(optarg,NULL,10); if(NTHREADS <= 0) { NTHREADS = 1; } - printf((NTHREADS > 1) ? "[+] Setting %u threads\n": "[+] Setting %u thread\n",NTHREADS); + printf((NTHREADS > 1) ? "[+] Threads : %u\n": "[+] Thread : %u\n",NTHREADS); break; case 'v': FLAGVANITY = 1; @@ -500,20 +521,15 @@ int main(int argc, char **argv) { printf("[+] Data marked as RAW\n"); FLAGRAWDATA = 1; break; - case 'z': - printf("[+] Bloom filter marked to be saved\n"); - FLAGBLOOMFILTER = 1; - break; default: - printf("[E] Unknow opcion %c\n",c); + printf("[E] Unknow opcion -%c\n",c); break; } } + init_generator(); - - if(DEBUGCOUNT > N_SECUENTIAL_MAX) { - DEBUGCOUNT = N_SECUENTIAL_MAX - 1; - + if(FLAGMODE == MODE_BSGS ) { + printf("[+] Mode BSGS %s\n",bsgs_modes[FLAGBSGSMODE]); } if(FLAGFILE == 0) { filename =(char*) default_filename; @@ -556,6 +572,7 @@ int main(int argc, char **argv) { } } if(FLAGMODE != MODE_BSGS) { + BSGS_N.SetInt32(DEBUGCOUNT); if(FLAGRANGE == 0 && FLAGBITRANGE == 0) { n_range_start.SetInt32(1); n_range_end.Set(&secp->order); @@ -577,7 +594,31 @@ int main(int argc, char **argv) { } } N = 0; - if(FLAGMODE != MODE_BSGS) { + + if(FLAGMODE != MODE_BSGS ) { + if(FLAG_N){ + if(str_N[0] == '0' && str_N[1] == 'x') { + N_SECUENTIAL_MAX =strtol(str_N,NULL,16); + } + else { + N_SECUENTIAL_MAX =strtol(str_N,NULL,10); + } + + if(N_SECUENTIAL_MAX < 1024) { + fprintf(stderr,"[I] n value need to be equal or great than 1024, back to defaults\n"); + FLAG_N = 0; + N_SECUENTIAL_MAX = 0xFFFFFFFF; + } + if(N_SECUENTIAL_MAX % 1024 != 0) { + fprintf(stderr,"[I] n value need to be multiplier of 1024\n"); + FLAG_N = 0; + N_SECUENTIAL_MAX = 0xFFFFFFFF; + } + } + + + + aux =(char*) malloc(1000); if(aux == NULL) { fprintf(stderr,"[E] error malloc()\n"); @@ -659,15 +700,15 @@ int main(int argc, char **argv) { fprintf(stderr,"[E] Can't alloc memory for %" PRIu64 " elements\n",N); exit(0); } - printf("[+] Initializing bloom filter for %" PRIu64 " elements.\n",N); + printf("[+] Bloom filter for %" PRIu64 " elements.\n",N); if(N <= 1000) { - if(bloom_init2(&bloom,1000,0.00001) == 1){ + if(bloom_init2(&bloom,1000,0.000001) == 1){ fprintf(stderr,"[E] error bloom_init for 10000 elements.\n"); exit(0); } } else { - if(bloom_init2(&bloom,N,0.00001) == 1){ + if(bloom_init2(&bloom,N,0.000001) == 1){ fprintf(stderr,"[E] error bloom_init for %" PRIu64 " elements.\n",N); fprintf(stderr,"[+] man enough is enough stop it\n"); exit(0); @@ -850,8 +891,8 @@ int main(int argc, char **argv) { printf(" done! %" PRIu64 " values were loaded and sorted\n",N); } } - if(FLAGMODE == MODE_BSGS) { - DEBUGCOUNT = N_SECUENTIAL_MAX ; + if(FLAGMODE == MODE_BSGS ) { + aux = (char*) malloc(1024); if(aux == NULL) { fprintf(stderr,"[E] error malloc()\n"); @@ -903,24 +944,6 @@ int main(int argc, char **argv) { } break; - - /* Somebody use this? To be removed 5/Nov */ - /* - case 128: //Without the 04 - memcpy(pointx_str,aux2,64); - memcpy(pointy_str,aux2+64,64); - if(isValidHex(pointx_str) && isValidHex(pointy_str)) { - mpz_init_set_str(OriginalPointsBSGS[i].x,pointx_str,16); - mpz_init_set_str(OriginalPointsBSGS[i].y,pointy_str,16); - //printf("Adding point ( %s , %s )\n",pointx_str,pointy_str); - i++; - } - else { - fprintf(stderr,"[E] Some invalid hexdata in the file: %s\n",aux2); - N--; - } - break; - */ case 130: //With the 04 if(secp->ParsePublicKeyHex(aux2,OriginalPointsBSGS[i],OriginalPointsBSGScompressed[i])) { @@ -951,27 +974,23 @@ int main(int argc, char **argv) { } BSGS_N.SetInt32(0); BSGS_M.SetInt32(0); - /* - hextemp = BSGS_N.GetBase10(); - printf("[+] BSGS_N: %s\n",hextemp); - free(hextemp); - hextemp = BSGS_M.GetBase10(); - printf("[+] BSGS_M: %s\n",hextemp); - free(hextemp); - */ + + BSGS_M.SetInt64(bsgs_m); - //printf("[+] bsgs_m: %"PRIu64"\n",bsgs_m); - /* - hextemp = BSGS_N.GetBase10(); - printf("[+] BSGS_N: %s\n",hextemp); - free(hextemp); - hextemp = BSGS_M.GetBase10(); - printf("[+] BSGS_M: %s\n",hextemp); - free(hextemp); - */ + if(FLAG_N) { //Custom N by the -n param - BSGS_N.SetInt64(N_SECUENTIAL_MAX); + + /* Here we need to validate if the given string is a valid hexadecimal number or a base 10 number*/ + + /* Now the conversion*/ + if(str_N[0] == '0' && str_N[1] == 'x' ) { /*We expedted a hexadecimal value after 0x -> str_N +2 */ + BSGS_N.SetBase16((char*)(str_N+2)); + } + else { + BSGS_N.SetBase10(str_N); + } + } else { //Default N BSGS_N.SetInt64((uint64_t)0x100000000000); @@ -985,28 +1004,20 @@ int main(int argc, char **argv) { fprintf(stderr,"[E] -n param doesn't have exact square root\n"); exit(0); } - /* - hextemp = BSGS_N.GetBase16(); - printf("[+] BSGS_N: %s\n",hextemp); - free(hextemp); - hextemp = BSGS_M.GetBase16(); - printf("[+] BSGS_M: %s\n",hextemp); - free(hextemp); - */ BSGS_AUX.Set(&BSGS_M); - BSGS_AUX.Mod(&BSGS_GROUP_SIZE); - if(!BSGS_AUX.IsZero()){ + BSGS_AUX.Mod(&BSGS_GROUP_SIZE); + + if(!BSGS_AUX.IsZero()){ //If M is not divisible by BSGS_GROUP_SIZE (1024) hextemp = BSGS_GROUP_SIZE.GetBase10(); fprintf(stderr,"[E] M value is not divisible by %s\n",hextemp); exit(0); } bsgs_m = BSGS_M.GetInt64(); - BSGS_N.Set(&BSGS_M); - BSGS_N.Mult(&BSGS_M); - DEBUGCOUNT = bsgs_m * bsgs_m; + + if(FLAGRANGE || FLAGBITRANGE) { if(FLAGBITRANGE) { // Bit Range @@ -1016,6 +1027,13 @@ int main(int argc, char **argv) { n_range_diff.Set(&n_range_end); n_range_diff.Sub(&n_range_start); printf("[+] Bit Range %i\n",bitrange); + printf("[+] -- from : 0x%s\n",bit_range_str_min); + printf("[+] -- to : 0x%s\n",bit_range_str_max); + } + else { + printf("[+] Range \n"); + printf("[+] -- from : 0x%s\n",range_start); + printf("[+] -- to : 0x%s\n",range_end); } } else { //Random start @@ -1026,43 +1044,11 @@ int main(int argc, char **argv) { n_range_start.Set(&n_range_diff); } BSGS_CURRENT.Set(&n_range_start); - /* - hextemp = BSGS_N.GetBase16(); - printf("[+] BSGS_N: %s\n",hextemp); - free(hextemp); - hextemp = BSGS_M.GetBase16(); - printf("[+] BSGS_M: %s\n",hextemp); - free(hextemp); - */ - - if(n_range_diff.IsLower(&BSGS_N) ) { - BSGS_N.Set(&n_range_diff); - - if(BSGS_N.HasSqrt()) { //If the root is exact - BSGS_M.Set(&BSGS_N); - BSGS_M.ModSqrt(); - /* - hextemp = BSGS_N.GetBase16(); - printf("[+] BSGS_N: %s\n",hextemp); - free(hextemp); - hextemp = BSGS_M.GetBase16(); - printf("[+] BSGS_M: %s\n",hextemp); - free(hextemp); - */ - } - else { - fprintf(stderr,"[E] the range is small and doesn't have exact square root\n"); - exit(0); - } - - bsgs_m = BSGS_M.GetInt64(); - BSGS_N.Set(&BSGS_M); - BSGS_N.Mult(&BSGS_M); - DEBUGCOUNT = bsgs_m * bsgs_m; - bsgs_m = BSGS_M.GetInt64(); - DEBUGCOUNT = (uint64_t)((uint64_t)bsgs_m * (uint64_t)bsgs_m); + if(n_range_diff.IsLower(&BSGS_N) ) { + fprintf(stderr,"[E] the given range is small\n"); + exit(0); } BSGS_M.Mult((uint64_t)KFACTOR); @@ -1072,89 +1058,37 @@ int main(int argc, char **argv) { BSGS_M2.Set(&BSGS_M); BSGS_M2.Div(&BSGS_AUX); - if(!BSGS_R.IsZero()) { + if(!BSGS_R.IsZero()) { /* If BSGS_M modulo 20 is not 0*/ BSGS_M2.AddOne(); } - - bsgs_m2 = BSGS_M2.GetInt64(); BSGS_AUX.Set(&BSGS_N); BSGS_AUX.Div(&BSGS_M); BSGS_R.Set(&BSGS_N); BSGS_R.Mod(&BSGS_M); - if(!BSGS_R.IsZero()) { + if(!BSGS_R.IsZero()) { /* if BSGS_N modulo BSGS_M is not 0*/ BSGS_N.Set(&BSGS_M); BSGS_N.Mult(&BSGS_AUX); } - bsgs_m = (uint64_t)((uint64_t) bsgs_m * (uint64_t)KFACTOR); - bsgs_aux = BSGS_AUX.GetInt64(); - DEBUGCOUNT = (uint64_t)((uint64_t)bsgs_m * (uint64_t)bsgs_aux); - - printf("[+] Setting N up to %" PRIu64 ".\n",DEBUGCOUNT); - - itemsbloom = ((uint64_t)(bsgs_m/256)) > 10000 ? (uint64_t)(bsgs_m/256) : 10000; - itemsbloom2 = bsgs_m2 > 1000 ? bsgs_m : 10000; - - if( FLAGBLOOMFILTER == 1 ) { - int continuebloom = 1; - int numberbloom = 0; - for(i=0; i< 256 && continuebloom; i++) { - if(bloom_loadcustom(&bloom_bP[i],(char*)bloomnames[i]) == 1){ - continuebloom = 0; - } - else { - if(bloom_dummy(&dummybloom,itemsbloom,0.000001) == 0){ - numberbloom++; - if(dummybloom.bytes != bloom_bP[i].bytes) { - continuebloom = 0; - } - } - else { - continuebloom = 0; - } - } - } - if(continuebloom == 1) { - if(bloom_loadcustom(&bloom_bPx2nd,(char*)"bPx2nd") == 1) { - continuebloom == 0; - } - else { - if(bloom_dummy(&dummybloom,itemsbloom2,0.000001) == 0){ - if(dummybloom.bytes != bloom_bPx2nd.bytes) { - continuebloom = 0; - } - if(continuebloom == 0) { - bloom_free(&bloom_bPx2nd); - } - } - } - } - if(continuebloom == 0) { - fprintf(stderr,"[E] Some bloom file fail or missmatch size\n"); - FLAGBLOOMFILTER = 0; - for(i=0; i < numberbloom ; i++) { - bloom_free(&bloom_bP[i]); - } - } - } + bsgs_m = BSGS_M.GetInt64(); + bsgs_aux = BSGS_AUX.GetInt64(); + hextemp = BSGS_N.GetBase16(); + printf("[+] N = 0x%s\n",hextemp); + free(hextemp); -/* - if( FLAGBLOOMFILTER == 0) { -*/ - for(i=0; i< 256; i++) { - if(bloom_init2(&bloom_bP[i],itemsbloom,0.000001) == 1){ - fprintf(stderr,"[E] error bloom_init [%" PRIu64 "]\n",i); - exit(0); - } - bloom_bP_totalbytes += bloom_bP[i].bytes; - if(FLAGDEBUG) bloom_print(&bloom_bP[i]); + printf("[+] Bloom filter for %" PRIu64 " elements ",bsgs_m); + fflush(stdout); + if(bloom_init2(&bloom_bP,bsgs_m,0.000001) == 1){ + fprintf(stderr,"\n[E] error bloom_init\n"); + exit(0); } - printf("[+] Init 1st bloom filter for %lu elements : %.2f MB\n",bsgs_m,(float)((uint64_t)bloom_bP_totalbytes/(uint64_t)1048576)); + printf(": %.2f MB\n",(float)((uint64_t)bloom_bP.bytes/(uint64_t)1048576)); + if(FLAGDEBUG) bloom_print(&bloom_bP); if(bsgs_m2 > 1000) { if(bloom_init2(&bloom_bPx2nd,bsgs_m2,0.000001) == 1){ @@ -1169,186 +1103,365 @@ int main(int argc, char **argv) { } } if(FLAGDEBUG) bloom_print(&bloom_bPx2nd); - printf("[+] Init 2nd bloom filter for %lu elements : %.2f MB\n",bsgs_m2,(double)((double)bloom_bPx2nd.bytes/(double)1048576)); - //bloom_print(&bloom_bPx2nd); - /* - hextemp = BSGS_M.GetBase16(); - printf("[+] BSGS_M: %s\n",hextemp); - free(hextemp); - hextemp = BSGS_M2.GetBase16(); - printf("[+] BSGS_M2: %s\n",hextemp); - free(hextemp); - */ + printf("[+] Bloom filter for %" PRIu64 " elements : %.2f MB\n",bsgs_m2,(double)((double)bloom_bPx2nd.bytes/(double)1048576)); BSGS_MP = secp->ComputePublicKey(&BSGS_M); BSGS_MP2 = secp->ComputePublicKey(&BSGS_M2); - - - printf("[+] Allocating %.1f MB for %" PRIu64 " aMP Points\n",(double)(((double)(bsgs_aux*sizeof(Point)))/(double)1048576),bsgs_aux); - i = 0; - BSGS_AMP.reserve(bsgs_aux); - //printf("[+] Allocating %.1f MB for aMP Points (2nd)\n",(float)(((uint64_t)(bsgs_m2*sizeof(struct strPoint)))/(uint64_t)1048576)); + BSGS_AMP2.reserve(bsgs_m2); + GSn.reserve(CPU_GRP_SIZE/2); i= 0; - if(FLAGPRECALCUTED_MP_FILE) { - printf("[+] Reading aMP points from file %s\n",precalculated_mp_filename); - fd = fopen(precalculated_mp_filename,"rb"); - if(fd != NULL) { - while(!feof(fd) && i < bsgs_aux ) { - if(fread(temporal,1,64,fd) == 64) { - BSGS_AMP[i].x.Set32Bytes((unsigned char*)temporal); - BSGS_AMP[i].x.Set32Bytes((unsigned char*)(temporal+32)); - i++; - } + + + /* New aMP table just to keep the same code of JLP */ + Point bsP = secp->Negation(BSGS_MP); + Point g = bsP; + + GSn[0] = g; + + g = secp->DoubleDirect(g); + GSn[1] = g; + + for(int i = 2; i < CPU_GRP_SIZE / 2; i++) { + g = secp->AddDirect(g,bsP); + GSn[i] = g; + + } + + _2GSn = secp->DoubleDirect(GSn[CPU_GRP_SIZE / 2 - 1]); + + point_temp.Set(BSGS_MP2); + BSGS_AMP2[0] = secp->Negation(point_temp); + point_temp = secp->DoubleDirect(BSGS_MP2); + + for(i = 1; i < 20; i++) { + BSGS_AMP2[i] = secp->Negation(point_temp); + point_temp2 = secp->AddDirect(point_temp,BSGS_MP2); + point_temp.Set(point_temp2); + } + bytes = (uint64_t)bsgs_m2 * (uint64_t) sizeof(struct bsgs_xvalue); + printf("[+] Allocating %.2f MB for %" PRIu64 " bP Points\n",(double)(bytes/1048576),bsgs_m2); + + bPtable = (struct bsgs_xvalue*) malloc(bytes); + if(bPtable == NULL) { + printf("[E] error malloc()\n"); + exit(0); + } + memset(bPtable,0,bytes); + + if(FLAGSAVEREADFILE) { + /*Reading file for 1st bloom filter */ + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_0_%" PRIu64 ".blm",bsgs_m); + fd_aux1 = fopen(buffer_bloom_file,"rb"); + if(fd_aux1 != NULL) { + bf_ptr = (char*) bloom_bP.bf; /*We need to save the current bf pointer*/ + printf("[+] Reading bloom filter from file %s ..",buffer_bloom_file); + fflush(stdout); + readed = fread(&bloom_bP,sizeof(struct bloom),1,fd_aux1); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); } - if(i < bsgs_aux) { //If the input file have less item than bsgs_m - printf("[+] Fixme file contains less items than the amount of items needed\n"); + bloom_bP.bf = (uint8_t*)bf_ptr; /* Restoring the bf pointer*/ + readed = fread(bloom_bP.bf,bloom_bP.bytes,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.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.bf,bloom_bP.bytes,bloom_bP.checksum); + memcpy(bloom_bP.checksum_backup,bloom_bP.checksum,32); + FLAGREADEDFILE1 = 0; /* We mark the FLAGREADEDFILE1 to 0 to write the file with the correct checkum*/ + } + else { /* new file, we need to verify the checksum */ + sha256((char*)bloom_bP.bf,bloom_bP.bytes,rawvalue); + if(memcmp(bloom_bP.checksum,rawvalue,32) == 0 ) { /* Verification */ + FLAGREADEDFILE1 = 1; /* OK */ + } + else { + fprintf(stderr,"[E] Error checksum file mismatch!\n"); + exit(0); + } + + } + + + printf(" Done!\n"); + fclose(fd_aux1); } else { - fprintf(stderr,"[E] Can't open file %s falling back to the calculation mode\n",filename); - printf("[+] Precalculating %lu aMP points\n",bsgs_aux); - point_temp.Set(BSGS_MP); - for(i = 0; i < bsgs_aux; i++) { - BSGS_AMP[i] = secp->Negation(point_temp); - if(i == 0) { - printf("\n[+] point_temp vs BSGS_MP %s\n",point_temp.equals(BSGS_MP) ? "Si iguales":"No, diferentes"); - } - if(point_temp.equals(BSGS_MP)) { - point_temp2 = secp->DoubleDirect(BSGS_MP); + FLAGREADEDFILE1 = 0; + } + + /*Reading file for 2nd bloom filter */ + 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(&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); + } + 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); + } + 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*/ + } + 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 */ } else { - point_temp2 = secp->AddDirect(point_temp,BSGS_MP); + fprintf(stderr,"[E] Error checksum file mismatch!\n"); + exit(0); } - point_temp.Set(point_temp2); } + printf("Done!\n"); + fclose(fd_aux2); } - } - else { - printf("[+] Precalculating %" PRIu64 " aMP points\n",bsgs_aux); - point_temp.Set(BSGS_MP); - for(i = 0; i < bsgs_aux; i++) { - BSGS_AMP[i] = secp->Negation(point_temp); - if(i == 0) { - point_temp2 = secp->DoubleDirect(BSGS_MP); + else { + FLAGREADEDFILE2 = 0; + } + + /*Reading file for bPtable */ + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_2_%" PRIu64 ".tbl",bsgs_m2); + fd_aux3 = fopen(buffer_bloom_file,"rb"); + if(fd_aux3 != NULL) { + printf("[+] Reading bP Table from file %s ..",buffer_bloom_file); + fflush(stdout); + fread(bPtable,bytes,1,fd_aux3); + if(readed != 1) { + fprintf(stderr,"[E] Error reading the file %s\n",buffer_bloom_file); + exit(0); } - else { - point_temp2 = secp->AddDirect(point_temp,BSGS_MP); + fread(checksum,32,1,fd_aux3); + sha256((char*)bPtable,bytes,checksum_backup); + if(memcmp(checksum,checksum_backup,32) != 0) { + fprintf(stderr,"[E] Checksum from file %s mismatch!!\n",buffer_bloom_file); + exit(0); } - point_temp.Set(point_temp2); + printf(" Done!\n"); + fclose(fd_aux3); + FLAGREADEDFILE3 = 1; + } + 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; + BASE = 0; + PERTHREAD = bsgs_m /NTHREADS; + PERTHREAD_R = bsgs_m % NTHREADS; + temp = (struct bPload *) calloc(NTHREADS,sizeof(struct bPload)); + tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); - point_temp.Set(BSGS_MP2); - for(i = 0; i < 20; i++) { - BSGS_AMP2[i] = secp->Negation(point_temp); - if(i == 0) { - point_temp2 = secp->DoubleDirect(BSGS_MP2); + + + 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; + } + else { + temp[i].from = BASE + 1; + temp[i].to = BASE + PERTHREAD + PERTHREAD_R; + } + 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; + } } else { - point_temp2 = secp->AddDirect(point_temp,BSGS_MP2); + 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; + } + else { + temp[i].from = BASE + 1; + temp[i].to = BASE + PERTHREAD + PERTHREAD_R; + BASE+=(PERTHREAD + PERTHREAD_R); + } + 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]); + } } - point_temp.Set(point_temp2); - } - printf("[+] Allocating %.2f MB for %" PRIu64 " bP Points\n",(double)((double)((uint64_t)bsgs_m2*(uint64_t)sizeof(struct bsgs_xvalue))/(double)1048576),bsgs_m2); - //printf("[+] Allocating %.2f MB for bP Points\n",(float)((uint64_t)((uint64_t)bsgs_m*(uint64_t)sizeof(struct bsgs_xvalue))/(uint64_t)1048576)); - bPtable = (struct bsgs_xvalue*) calloc(bsgs_m2,sizeof(struct bsgs_xvalue)); - if(bPtable == NULL) { - printf("[E] error malloc()\n"); - exit(0); - } - i = 0; - j = 0; - BASE = 0; - PERTHREAD = bsgs_m /NTHREADS; - PERTHREAD_R = bsgs_m % NTHREADS; - temp = (struct bPload *) calloc(NTHREADS,sizeof(struct bPload)); - tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); + 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); - 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; + pthread_join(tid[i], NULL); + } + printf("\n"); + free(temp); + free(tid); + + } + if(!FLAGREADEDFILE1) { + sha256((char*)bloom_bP.bf, bloom_bP.bytes, bloom_bP.checksum); + memcpy(bloom_bP.checksum_backup,bloom_bP.checksum,32); + } + + if(!FLAGREADEDFILE2) { + sha256((char*)bloom_bPx2nd.bf, bloom_bPx2nd.bytes, bloom_bPx2nd.checksum); + memcpy(bloom_bPx2nd.checksum_backup,bloom_bPx2nd.checksum,32); + } + 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); + } + if(FLAGSAVEREADFILE) { + if(!FLAGREADEDFILE1) { + /* Writing file for 1st bloom filter */ + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_0_%" 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); + fflush(stdout); + readed = fwrite(&bloom_bP,sizeof(struct bloom),1,fd_aux1); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); + exit(0); + } + readed = fwrite(bloom_bP.bf,bloom_bP.bytes,1,fd_aux1); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); + exit(0); + } + printf("Done!\n"); + fclose(fd_aux1); } else { - temp[i].from = BASE + 1; - temp[i].to = BASE + PERTHREAD + PERTHREAD_R; + fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); } - 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; } - } - else { - for(i = 0; i < NTHREADS; i++) { - temp[i].counter = 0; - if(i < NTHREADS -1) { - temp[i].from = BASE +1; - temp[i].to = BASE + PERTHREAD; - BASE+=PERTHREAD; + if(!FLAGREADEDFILE2) { + /* 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); + fflush(stdout); + readed = fwrite(&bloom_bPx2nd,sizeof(struct bloom),1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); + exit(0); + } + readed = fwrite(bloom_bPx2nd.bf,bloom_bPx2nd.bytes,1,fd_aux2); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); + exit(0); + } + printf("Done!\n"); + fclose(fd_aux2); } else { - temp[i].from = BASE + 1; - temp[i].to = BASE + PERTHREAD + PERTHREAD_R; - BASE+=(PERTHREAD + PERTHREAD_R); + fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); } - 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; + + + if(!FLAGREADEDFILE3) { + /* Writing file for bPtable */ + snprintf(buffer_bloom_file,1024,"keyhunt_bsgs_2_%" PRIu64 ".tbl",bsgs_m2); + fd_aux3 = fopen(buffer_bloom_file,"wb"); + if(fd_aux3 != NULL) { + printf("[+] Writing bP Table to file %s .. ",buffer_bloom_file); + fflush(stdout); + readed = fwrite(bPtable,bytes,1,fd_aux3); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); + exit(0); + } + readed = fwrite(checksum,32,1,fd_aux3); + if(readed != 1) { + fprintf(stderr,"[E] Error writing the file %s\n",buffer_bloom_file); + exit(0); + } + printf("Done!\n"); + fclose(fd_aux3); } - printf("\r[+] processing %lu/%lu bP points : %i%%",total_precalculated,bsgs_m,(int) (((double)total_precalculated/(double)bsgs_m)*100)); - fflush(stdout); - } while(total_precalculated < bsgs_m); - - for(i = 0; i < NTHREADS; i++) { - pthread_join(tid[i], NULL); + else { + fprintf(stderr,"[E] Error can't create the file %s\n",buffer_bloom_file); + } + } } - printf("\n"); - free(temp); - free(tid); - printf("[+] Sorting %lu elements... ",bsgs_m2); - bsgs_sort(bPtable,bsgs_m2); - printf("Done!\n"); i = 0; - steps = (unsigned int *) calloc(NTHREADS,sizeof(int)); + steps = (uint64_t *) calloc(NTHREADS,sizeof(uint64_t)); ends = (unsigned int *) calloc(NTHREADS,sizeof(int)); tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); - DEBUGCOUNT = (uint64_t)((uint64_t)bsgs_m * (uint64_t)bsgs_aux); + for(i= 0;i < NTHREADS; i++) { tt = (tothread*) malloc(sizeof(struct tothread)); tt->nt = i; - if(FLAGRANDOM) { - s = pthread_create(&tid[i],NULL,thread_process_bsgs_random,(void *)tt); - } - else { - s = pthread_create(&tid[i],NULL,thread_process_bsgs,(void *)tt); + switch(FLAGBSGSMODE) { + case 0: + s = pthread_create(&tid[i],NULL,thread_process_bsgs,(void *)tt); + break; + case 1: + s = pthread_create(&tid[i],NULL,thread_process_bsgs_backward,(void *)tt); + break; + case 2: + s = pthread_create(&tid[i],NULL,thread_process_bsgs_both,(void *)tt); + break; + case 3: + s = pthread_create(&tid[i],NULL,thread_process_bsgs_random,(void *)tt); + break; + case 4: + s = pthread_create(&tid[i],NULL,thread_process_bsgs_dance,(void *)tt); + break; } - if(s != 0) { fprintf(stderr,"[E] pthread_create thread_process\n"); exit(0); } } + + free(aux); } if(FLAGMODE != MODE_BSGS) { - steps = (unsigned int *) calloc(NTHREADS,sizeof(int)); + steps = (uint64_t *) calloc(NTHREADS,sizeof(uint64_t)); ends = (unsigned int *) calloc(NTHREADS,sizeof(int)); tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); @@ -1372,10 +1485,17 @@ int main(int argc, char **argv) { } } } + i = 0; + + while(i < 7) { + int_limits[i].SetBase10((char*)str_limits[i]); + i++; + } + continue_flag = 1; total.SetInt32(0); pretotal.SetInt32(0); - debugcount_mpz.SetInt64(DEBUGCOUNT); + debugcount_mpz.Set(&BSGS_N); seconds.SetInt32(0); do { sleep(1); @@ -1399,19 +1519,56 @@ int main(int argc, char **argv) { total.Add(&pretotal); i++; } + + pthread_mutex_lock(&bsgs_thread); pretotal.Set(&total); pretotal.Div(&seconds); str_seconds = seconds.GetBase10(); str_pretotal = pretotal.GetBase10(); str_total = total.GetBase10(); - pthread_mutex_lock(&bsgs_thread); - if(THREADOUTPUT == 1) { - sprintf(buffer,"\nTotal %s keys in %s seconds: %s keys/s\r",str_total,str_seconds,str_pretotal); + + + if(pretotal.IsLower(&int_limits[0])) { + if(FLAGMATRIX) { + sprintf(buffer,"[+] Total %s keys in %s seconds: %s keys/s\n",str_total,str_seconds,str_pretotal); + } + else { + sprintf(buffer,"\r[+] Total %s keys in %s seconds: %s keys/s\r",str_total,str_seconds,str_pretotal); + } } else { - sprintf(buffer,"\rTotal %s keys in %s seconds: %s keys/s\r",str_total,str_seconds,str_pretotal); - } - printf("%s",buffer); + i = 0; + salir = 0; + while( i < 6 && !salir) { + if(pretotal.IsLower(&int_limits[i+1])) { + salir = 1; + } + else { + i++; + } + } + + div_pretotal.Set(&pretotal); + div_pretotal.Div(&int_limits[salir ? i : i-1]); + str_divpretotal = div_pretotal.GetBase10(); + if(FLAGMATRIX) { + sprintf(buffer,"[+] Total %s keys in %s seconds: ~%s %s (%s keys/s)\n",str_total,str_seconds,str_divpretotal,str_limits_prefixs[salir ? i : i-1],str_pretotal); + } + else { + if(THREADOUTPUT == 1) { + sprintf(buffer,"\r[+] Total %s keys in %s seconds: ~%s %s (%s keys/s)\r",str_total,str_seconds,str_divpretotal,str_limits_prefixs[salir ? i : i-1],str_pretotal); + } + else { + sprintf(buffer,"\r[+] Total %s keys in %s seconds: ~%s %s (%s keys/s)\r",str_total,str_seconds,str_divpretotal,str_limits_prefixs[salir ? i : i-1],str_pretotal); + } + } + free(str_divpretotal); + + } + + + + printf("%s",buffer); fflush(stdout); THREADOUTPUT = 0; pthread_mutex_unlock(&bsgs_thread); @@ -1423,26 +1580,6 @@ int main(int argc, char **argv) { }while(continue_flag); } - -/* -char *pubkeytopubaddress_eth(char *pkey,int length) { - char *temp,*pubaddress = calloc(MAXLENGTHADDRESS,1); - char *digest = malloc(32); - if(digest == NULL || pubaddress == NULL) { - fprintf(stderr,"error malloc()\n"); - exit(0); - } - pubaddress[0] = '0'; - pubaddress[1] = 'x'; - shake256(digest, 256,(const uint8_t* ) pkey, length); - temp = tohex(digest+12,20); - strcpy(pubaddress+2,temp); - free(temp); - free(digest); - return pubaddress; -} -*/ - char *pubkeytopubaddress(char *pkey,int length) { char *pubaddress = (char*) calloc(MAXLENGTHADDRESS+10,1); char *digest = (char*) calloc(60,1); @@ -1524,9 +1661,8 @@ void *thread_process(void *vargp) { Point pp; Point pn; int hLength = (CPU_GRP_SIZE / 2 - 1); - uint64_t i,j; + uint64_t i,j,count; Point R,temporal; - uint64_t count = 0; int r,thread_number,found,continue_flag = 1; char *public_key_compressed,*public_key_uncompressed,hexstrpoint[65],rawvalue[32]; char *publickeyhashrmd160_compress,*publickeyhashrmd160_uncompress; @@ -1542,11 +1678,12 @@ void *thread_process(void *vargp) { found = 0; grp->Set(dx); do { + if(FLAGRANDOM){ key_mpz.Rand(&n_range_start,&n_range_end); } else { - if(n_range_start.IsLower(&n_range_end)){ + if(n_range_start.IsLower(&n_range_end)) { pthread_mutex_lock(&write_random); key_mpz.Set(&n_range_start); n_range_start.Add(N_SECUENTIAL_MAX); @@ -1559,69 +1696,77 @@ void *thread_process(void *vargp) { if(continue_flag) { count = 0; do { - - if(FLAGQUIET == 0){ - hextemp = key_mpz.GetBase16(); - printf("\rBase key: %s ",hextemp); - fflush(stdout); - free(hextemp); - THREADOUTPUT = 1; + if(FLAGMATRIX) { + hextemp = key_mpz.GetBase16(); + printf("Base key: %s\n",hextemp); + fflush(stdout); + free(hextemp); + } + else { + if(FLAGQUIET == 0){ + hextemp = key_mpz.GetBase16(); + printf("\rBase key: %s \r",hextemp); + fflush(stdout); + free(hextemp); + THREADOUTPUT = 1; + } } key_mpz.Add((uint64_t)CPU_GRP_SIZE / 2); startP = secp->ComputePublicKey(&key_mpz); key_mpz.Sub((uint64_t)CPU_GRP_SIZE / 2); for(i = 0; i < hLength; i++) { - dx[i].ModSub(&Gn[i].x,&startP.x); - } + dx[i].ModSub(&Gn[i].x,&startP.x); + } + dx[i].ModSub(&Gn[i].x,&startP.x); // For the first point dx[i + 1].ModSub(&_2Gn.x,&startP.x); // For the next center point - grp->ModInv(); + grp->ModInv(); - pts[CPU_GRP_SIZE / 2] = startP; + pts[CPU_GRP_SIZE / 2] = startP; - for(i = 0; iSet(dx); + + tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); @@ -2158,120 +2324,234 @@ void *thread_process_bsgs(void *vargp) { /* 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 */ pthread_mutex_unlock(&bsgs_thread); + + intaux.Set(&BSGS_M); + intaux.Mult(CPU_GRP_SIZE/2); + + flip_detector = 1000000; + /* while base_key is less than n_range_end then: */ while(base_key.IsLower(&n_range_end) ) { - //gmp_printf("While cycle: base_key : %Zd < n_range_end: %Zd\n",base_key,n_range_end); - if(FLAGQUIET == 0){ + if(thread_number == 0 && flip_detector == 0) { + memorycheck(); + flip_detector = 1000000; + } + + if(FLAGMATRIX) { aux_c = base_key.GetBase16(); - printf("\r[+] Thread %s ",aux_c); + printf("[+] Thread 0x%s \n",aux_c); fflush(stdout); free(aux_c); - THREADOUTPUT = 1; } - /* - Set base_point in to base_key * G - base_point = base_key * G - */ - // printf("[D] bsgs_point_number %u\n",bsgs_point_number); + else { + if(FLAGQUIET == 0){ + aux_c = base_key.GetBase16(); + printf("\r[+] Thread 0x%s \r",aux_c); + fflush(stdout); + free(aux_c); + THREADOUTPUT = 1; + } + } + base_point = secp->ComputePublicKey(&base_key); - /* - We are going to need -( base_point * G) - point_aux = -( base_point * G) - */ - point_aux = secp->Negation(base_point); - /* - hextemp = secp->GetPublicKeyHex(false,point_aux); - printf("point_aux %s\n",hextemp); - free(hextemp); - hextemp = secp->GetPublicKeyHex(false,base_point); - printf("base_point %s\n",hextemp); - free(hextemp); - */ + km.Set(&base_key); + km.Neg(); + + km.Add(&secp->order); + km.Sub(&intaux); + point_aux = secp->ComputePublicKey(&km); + for(k = 0; k < bsgs_point_number ; k++) { if(bsgs_found[k] == 0) { - /*reset main variabler before the do-while cicle*/ - /* Main cycle - for every a in 0 to bsgs_m - */ - salir = 0; - i = 0; - BSGS_Q = secp->AddDirect(OriginalPointsBSGS[k],point_aux); - BSGS_S.Set(BSGS_Q); - - do { - /* - if(i == 52428 || i == 0 || i == 1) { - aux_c = secp->GetPublicKeyHex(false,BSGS_S); - hextemp = secp->GetPublicKeyHex(false,BSGS_AMP[i]); - printf("\r[d] Debug: %s : %u\n",aux_c,i); - printf("[d] Debug: BSGS_AMP %s : %u\n",hextemp,i); - free(aux_c); - free(hextemp); + if(base_point.equals(OriginalPointsBSGS[k])) { + 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); + + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); } - */ - /* We need to test individually every point in BSGS_Q */ - /*Extract BSGS_S.x into xpoint_raw*/ - BSGS_S.x.Get32Bytes((unsigned char*)xpoint_raw); + } + else { + startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); + int j = 0; + while( j < bsgs_aux/1024 && bsgs_found[k]== 0 ) { + + int i; + + for(i = 0; i < hLength; i++) { + dx[i].ModSub(&GSn[i].x,&startP.x); + } + dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point + dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point - /* Lookup for the xpoint_raw into the bloom filter*/ + // Grouped ModInv + grp->ModInv(); + + /* + We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse + We compute key in the positive and negative way from the center of the group + */ - r = bloom_check(&bloom_bP[((unsigned char)xpoint_raw[0])],xpoint_raw,32); - if(r) { - bloom_counter++; - /* Lookup for the xpoint_raw into the full sorted list*/ - //r = bsgs_searchbinary(bPtable,xpoint_raw,bsgs_m,&j); - r = bsgs_secondcheck(&base_key,i,k,&keyfound); + // center point + pts[CPU_GRP_SIZE / 2] = startP; + + for(i = 0; iComputePublicKey(&keyfound); - aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_aux2); + pp = startP; + pn = startP; + + // P = startP + i*G + dy.ModSub(&GSn[i].y,&pp.y); + + _s.ModMulK1(&dy,&dx[i]); // s = (p2.y-p1.y)*inverse(p2.x-p1.x); + _p.ModSquareK1(&_s); // _p = pow2(s) + + pp.x.ModNeg(); + pp.x.ModAdd(&_p); + pp.x.ModSub(&GSn[i].x); // rx = pow2(s) - p1.x - p2.x; + +#if 0 + pp.y.ModSub(&GSn[i].x,&pp.x); + pp.y.ModMulK1(&_s); + pp.y.ModSub(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x); +#endif + + // P = startP - i*G , if (x,y) = i*G then (x,-y) = -i*G + dyn.Set(&GSn[i].y); + dyn.ModNeg(); + dyn.ModSub(&pn.y); + + _s.ModMulK1(&dyn,&dx[i]); // s = (p2.y-p1.y)*inverse(p2.x-p1.x); + _p.ModSquareK1(&_s); // _p = pow2(s) + + pn.x.ModNeg(); + pn.x.ModAdd(&_p); + pn.x.ModSub(&GSn[i].x); // rx = pow2(s) - p1.x - p2.x; + +#if 0 + pn.y.ModSub(&GSn[i].x,&pn.x); + pn.y.ModMulK1(&_s); + pn.y.ModAdd(&GSn[i].y); // ry = - p2.y - s*(ret.x-p2.x); +#endif + + + pts[CPU_GRP_SIZE / 2 + (i + 1)] = pp; + pts[CPU_GRP_SIZE / 2 - (i + 1)] = pn; - printf("[+] Publickey %s\n",aux_c); - pthread_mutex_lock(&write_keys); - filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); - if(filekey != NULL) { - fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); - fclose(filekey); - } - pthread_mutex_unlock(&write_keys); - free(hextemp); - free(aux_c); - bsgs_found[k] = 1; - salir = 1; - for(j = 0; j < bsgs_point_number && salir; j++) { - salir &= bsgs_found[j]; - } - if(salir) { - printf("All points were found\n"); - exit(0); - } } - } - BSGS_Q_AMP = secp->AddDirect(BSGS_Q,BSGS_AMP[i]); - BSGS_S.Set(BSGS_Q_AMP); - i++; - }while( i < bsgs_aux && !bsgs_found[k]); - } //end if - }// End for + + // First point (startP - (GRP_SZIE/2)*G) + pn = startP; + dyn.Set(&GSn[i].y); + dyn.ModNeg(); + dyn.ModSub(&pn.y); + + _s.ModMulK1(&dyn,&dx[i]); + _p.ModSquareK1(&_s); + + pn.x.ModNeg(); + pn.x.ModAdd(&_p); + pn.x.ModSub(&GSn[i].x); + +#if 0 + pn.y.ModSub(&GSn[i].x,&pn.x); + pn.y.ModMulK1(&_s); + pn.y.ModAdd(&GSn[i].y); +#endif + + pts[0] = pn; + + for(int i = 0; iComputePublicKey(&keyfound); + aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); + printf("[+] Publickey %s\n",aux_c); + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); + } + } //End if second check + }//End if first check + + }// For for pts variable + + // Next start point (startP += (bsSize*GRP_SIZE).G) + + pp = startP; + dy.ModSub(&_2GSn.y,&pp.y); + + _s.ModMulK1(&dy,&dx[i + 1]); + _p.ModSquareK1(&_s); + + pp.x.ModNeg(); + pp.x.ModAdd(&_p); + pp.x.ModSub(&_2GSn.x); + + pp.y.ModSub(&_2GSn.x,&pp.x); + pp.y.ModMulK1(&_s); + pp.y.ModSub(&_2GSn.y); + startP = pp; + + j++; + }//while all the aMP points + }// end else + }// End if + } + steps[thread_number]++; pthread_mutex_lock(&bsgs_thread); base_key.Set(&BSGS_CURRENT); BSGS_CURRENT.Add(&BSGS_N); pthread_mutex_unlock(&bsgs_thread); - - if(FLAGDEBUG ) printf("%u of %" PRIu64 "\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number)); - bloom_counter = 0; + flip_detector--; } ends[thread_number] = 1; return NULL; @@ -2282,101 +2562,263 @@ void *thread_process_bsgs_random(void *vargp) { struct tothread *tt; char xpoint_raw[32],*aux_c,*hextemp; Int base_key,keyfound,n_range_random; - Point base_point,point_aux,point_aux2,point_found,BSGS_S,BSGS_Q,BSGS_Q_AMP; - uint32_t i,j,k,r,salir,thread_number,bloom_counter = 0; + Point base_point,point_aux,point_found; + uint32_t i,j,k,r,salir,thread_number,flip_detector; + + IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); + Point startP; + + int hLength = (CPU_GRP_SIZE / 2 - 1); + + Int dx[CPU_GRP_SIZE / 2 + 1]; + Point pts[CPU_GRP_SIZE]; + + Int dy; + Int dyn; + Int _s; + Int _p; + Int km,intaux; + Point pp; + Point pn; + grp->Set(dx); + + tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); - - pthread_mutex_lock(&bsgs_thread); - /* | Start Range | End Range | - None | 1 | EC.N | --b bit | Min bit value |Max bit value | --r A:B | A | B | + /* | Start Range | End Range | + None | 1 | EC.N | + -b bit | Min bit value | Max bit value | + -r A:B | A | B | */ - // set base_key = random(end_range - start range) + pthread_mutex_lock(&bsgs_thread); base_key.Rand(&n_range_start,&n_range_end); pthread_mutex_unlock(&bsgs_thread); + + intaux.Set(&BSGS_M); + intaux.Mult(CPU_GRP_SIZE/2); + flip_detector = 1000000; /* while base_key is less than n_range_end then: */ while(base_key.IsLower(&n_range_end)) { - //gmp_printf("While cycle: base_key : %Zd < n_range_end: %Zd\n",base_key,n_range_end); - if(FLAGQUIET == 0){ - aux_c = base_key.GetBase16(); - printf("\r[+] Thread %s",aux_c); - fflush(stdout); - free(aux_c); - THREADOUTPUT = 1; + if(thread_number == 0 && flip_detector == 0) { + memorycheck(); + flip_detector = 1000000; + } + if(FLAGMATRIX) { + aux_c = base_key.GetBase16(); + printf("[+] Thread 0x%s \n",aux_c); + fflush(stdout); + free(aux_c); + } + else{ + if(FLAGQUIET == 0){ + aux_c = base_key.GetBase16(); + printf("\r[+] Thread 0x%s \r",aux_c); + fflush(stdout); + free(aux_c); + THREADOUTPUT = 1; + } } - /* - Set base_point in to base_key * G - base_point = base_key * G - */ base_point = secp->ComputePublicKey(&base_key); - /* - We are going to need -( base_point * G) - point_aux = -( base_point * G) - */ - point_aux = secp->Negation(base_point); + km.Set(&base_key); + km.Neg(); + + + km.Add(&secp->order); + km.Sub(&intaux); + point_aux = secp->ComputePublicKey(&km); /* We need to test individually every point in BSGS_Q */ for(k = 0; k < bsgs_point_number ; k++) { if(bsgs_found[k] == 0) { - /*reset main variables before the do-while cicle*/ - salir = 0; - i = 0; - /* Main cycle for every a in 0 to bsgs_aux - */ - BSGS_Q = secp->AddDirect(OriginalPointsBSGS[k],point_aux); - BSGS_S.Set(BSGS_Q); - do { - BSGS_S.x.Get32Bytes((unsigned char*)xpoint_raw); - r = bloom_check(&bloom_bP[((unsigned char)xpoint_raw[0])],xpoint_raw,32); - if(r) { - bloom_counter++; - /* Lookup for the xpoint_raw into the full sorted list*/ - r = bsgs_secondcheck(&base_key,i,k,&keyfound); - if(r) { - hextemp = keyfound.GetBase16(); - printf("\n[+] Thread Key found privkey %s\n",hextemp); - point_aux2 = secp->ComputePublicKey(&keyfound); - aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_aux2); - printf("[+] Publickey %s\n",aux_c); - pthread_mutex_lock(&write_keys); - filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); - if(filekey != NULL) { - fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); - fclose(filekey); - } - free(hextemp); - free(aux_c); - pthread_mutex_unlock(&write_keys); - bsgs_found[k] = 1; - salir = 1; - for(j = 0; j < bsgs_point_number && salir; j++) { - salir &= bsgs_found[j]; - } - if(salir) { - printf("All points were found\n"); - exit(0); - } - } + if(base_point.equals(OriginalPointsBSGS[k])) { + 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); + + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); } - BSGS_Q_AMP = secp->AddDirect(BSGS_AMP[i],BSGS_Q); - BSGS_S.Set(BSGS_Q_AMP); - i++; - } while( i < bsgs_aux && !bsgs_found[k]); + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); + } + } + else { + + startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); + int j = 0; + while( j < bsgs_aux/1024 && bsgs_found[k]== 0 ) { + + int i; + for(i = 0; i < hLength; i++) { + dx[i].ModSub(&GSn[i].x,&startP.x); + } + dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point + dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point + + // Grouped ModInv + grp->ModInv(); + + /* + We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse + We compute key in the positive and negative way from the center of the group + */ + + // center point + pts[CPU_GRP_SIZE / 2] = startP; + + for(i = 0; iComputePublicKey(&keyfound); + aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); + printf("[+] Publickey %s\n",aux_c); + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); + } + } //End if second check + }//End if first check + + }// For for pts variable + + // Next start point (startP += (bsSize*GRP_SIZE).G) + + pp = startP; + dy.ModSub(&_2GSn.y,&pp.y); + + _s.ModMulK1(&dy,&dx[i + 1]); + _p.ModSquareK1(&_s); + + pp.x.ModNeg(); + pp.x.ModAdd(&_p); + pp.x.ModSub(&_2GSn.x); + + pp.y.ModSub(&_2GSn.x,&pp.x); + pp.y.ModMulK1(&_s); + pp.y.ModSub(&_2GSn.y); + startP = pp; + + j++; + + } //End While + + + + } //End else + + } //End if } // End for with k bsgs_point_number + steps[thread_number]++; pthread_mutex_lock(&bsgs_thread); base_key.Rand(&n_range_start,&n_range_end); pthread_mutex_unlock(&bsgs_thread); - if(FLAGDEBUG ) printf("%u of %" PRIu64 "\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number)); - bloom_counter = 0; + flip_detector--; } ends[thread_number] = 1; return NULL; @@ -2384,7 +2826,7 @@ void *thread_process_bsgs_random(void *vargp) { /* The bsgs_secondcheck function is made to perform a second BSGS search in a Range of less size. - This funtion is made with the especific purpouse to USE a smaller bPTable in RAM. + This funtion is made with the especific purpouse to USE a smaller bPtable in RAM. This new and small bPtable is around ~ squareroot( K *squareroot(N)) */ int bsgs_secondcheck(Int *start_range,uint32_t a,uint32_t k_index,Int *privatekey) { @@ -2461,12 +2903,16 @@ void *thread_bPloadFile(void *vargp) { if(fread(rawvalue,1,32,fd) == 32) { if(i < bsgs_m2) { - memcpy(bPtable[j].value,rawvalue+16,BSGS_XVALUE_RAM); - bPtable[j].index = j; - bloom_add(&bloom_bPx2nd, rawvalue, BSGS_BUFFERXPOINTLENGTH); + if(!FLAGREADEDFILE3) { + memcpy(bPtable[j].value,rawvalue+16,BSGS_XVALUE_RAM); + bPtable[j].index = j; + } + if(!FLAGREADEDFILE2) + bloom_add(&bloom_bPx2nd, rawvalue, BSGS_BUFFERXPOINTLENGTH); j++; } - bloom_add(&bloom_bP[((uint8_t)rawvalue[0])], rawvalue ,BSGS_BUFFERXPOINTLENGTH); + if(!FLAGREADEDFILE1) + bloom_add(&bloom_bP, rawvalue ,BSGS_BUFFERXPOINTLENGTH); i++; tt->counter++; } @@ -2499,7 +2945,7 @@ void *thread_pub2rmd(void *vargp) { struct tothread *tt; uint64_t i,limit,j; char digest160[20]; - char digest256[32]; + char digest256[32]; char *temphex; int thread_number,r; int pub2rmd_continue = 1; @@ -2526,43 +2972,52 @@ void *thread_pub2rmd(void *vargp) { key_mpz.Get32Bytes(pub.X.data8); pub.parity = 0x02; pub.X.data32[7] = 0; - if(FLAGQUIET == 0) { + if(FLAGMATRIX) { temphex = tohex((char*)&pub,33); - printf("\r[+] Thread %s",temphex); + printf("[+] Thread 0x%s \n",temphex); + free(temphex); fflush(stdout); - THREADOUTPUT = 1; } - for(i = 0 ; i < limit ; i++) { - pub.parity = 0x02; - sha256((char*)&pub, 33, digest256); - RMD160Data((const unsigned char*)digest256,32, digest160); - r = bloom_check(&bloom,digest160,MAXLENGTHADDRESS); - if(r) { - r = searchbinary(addressTable,digest160,N); - if(r) { - temphex = tohex((char*)&pub,33); - printf("\nHit: Publickey found %s\n",temphex); - fd = fopen("KEYFOUNDKEYFOUND.txt","a+"); - if(fd != NULL) { - pthread_mutex_lock(&write_keys); - fprintf(fd,"Publickey found %s\n",temphex); - fclose(fd); - pthread_mutex_unlock(&write_keys); - } - else { - fprintf(stderr,"\nPublickey found %s\nbut the file can't be open\n",temphex); - exit(0); + else { + if(FLAGQUIET == 0) { + temphex = tohex((char*)&pub,33); + printf("\r[+] Thread %s \r",temphex); + free(temphex); + fflush(stdout); + THREADOUTPUT = 1; + } + } + for(i = 0 ; i < limit ; i++) { + pub.parity = 0x02; + sha256((char*)&pub, 33, digest256); + RMD160Data((const unsigned char*)digest256,32, digest160); + r = bloom_check(&bloom,digest160,MAXLENGTHADDRESS); + if(r) { + r = searchbinary(addressTable,digest160,N); + if(r) { + temphex = tohex((char*)&pub,33); + printf("\nHit: Publickey found %s\n",temphex); + fd = fopen("KEYFOUNDKEYFOUND.txt","a+"); + if(fd != NULL) { + pthread_mutex_lock(&write_keys); + fprintf(fd,"Publickey found %s\n",temphex); + fclose(fd); + pthread_mutex_unlock(&write_keys); + } + else { + fprintf(stderr,"\nPublickey found %s\nbut the file can't be open\n",temphex); + exit(0); + } + free(temphex); } - free(temphex); - } - } - pub.parity = 0x03; - sha256((char*)&pub, 33, digest256); - RMD160Data((const unsigned char*)digest256,32, digest160); + } + pub.parity = 0x03; + sha256((char*)&pub, 33, digest256); + RMD160Data((const unsigned char*)digest256,32, digest160); r = bloom_check(&bloom,digest160,MAXLENGTHADDRESS); if(r) { r = searchbinary(addressTable,digest160,N); - if(r) { + if(r) { temphex = tohex((char*)&pub,33); printf("\nHit: Publickey found %s\n",temphex); fd = fopen("KEYFOUNDKEYFOUND.txt","a+"); @@ -2577,15 +3032,15 @@ void *thread_pub2rmd(void *vargp) { exit(0); } free(temphex); - } - } - pub.X.data32[7]++; - if(pub.X.data32[7] % DEBUGCOUNT == 0) { + } + } + pub.X.data32[7]++; + if(pub.X.data32[7] % DEBUGCOUNT == 0) { steps[thread_number]++; - } - } /* End for */ + } + } /* End for */ } /* End if */ - } while(pub2rmd_continue); + }while(pub2rmd_continue); ends[thread_number] = 1; return NULL; } @@ -2597,9 +3052,9 @@ void init_generator() { g = secp->DoubleDirect(g); Gn[1] = g; for(int i = 2; i < CPU_GRP_SIZE / 2; i++) { - g = secp->AddDirect(g,secp->G); - Gn[i] = g; - } + g = secp->AddDirect(g,secp->G); + Gn[i] = g; + } _2Gn = secp->DoubleDirect(Gn[CPU_GRP_SIZE / 2 - 1]); } @@ -2613,13 +3068,12 @@ void *thread_bPload(void *vargp) { Int dx[CPU_GRP_SIZE / 2 + 1]; Point pts[CPU_GRP_SIZE]; Int dy; - Int dyn; - Int _s; - Int _p; - Point pp; - Point pn; + Int dyn; + Int _s; + Int _p; + Point pp; + Point pn; int hLength = (CPU_GRP_SIZE / 2 - 1); - 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); @@ -2636,113 +3090,1044 @@ void *thread_bPload(void *vargp) { for(uint64_t s=0;sModInv(); // We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse - // We compute key in the positive and negative way from the center of the group - - // center point + // We compute key in the positive and negative way from the center of the group + // center point + pts[CPU_GRP_SIZE / 2] = startP; //Center point for(i = 0; ito) { - bloom_add(&bloom_bP[((uint8_t)rawvalue[0])], rawvalue ,BSGS_BUFFERXPOINTLENGTH); + if(!FLAGREADEDFILE1) + bloom_add(&bloom_bP, rawvalue ,BSGS_BUFFERXPOINTLENGTH); tt->counter++; i_counter++; } } // Next start point (startP + GRP_SIZE*G) - pp = startP; - dy.ModSub(&_2Gn.y,&pp.y); - - _s.ModMulK1(&dy,&dx[i + 1]); - _p.ModSquareK1(&_s); + pp = startP; + dy.ModSub(&_2Gn.y,&pp.y); - pp.x.ModNeg(); - pp.x.ModAdd(&_p); - pp.x.ModSub(&_2Gn.x); + _s.ModMulK1(&dy,&dx[i + 1]); + _p.ModSquareK1(&_s); - pp.y.ModSub(&_2Gn.x,&pp.x); - pp.y.ModMulK1(&_s); - pp.y.ModSub(&_2Gn.y); - startP = pp; + pp.x.ModNeg(); + pp.x.ModAdd(&_p); + pp.x.ModSub(&_2Gn.x); + pp.y.ModSub(&_2Gn.x,&pp.x); + pp.y.ModMulK1(&_s); + pp.y.ModSub(&_2Gn.y); + startP = pp; } delete grp; pthread_exit(NULL); } + +void KECCAK_256(uint8_t *source, size_t size,uint8_t *dst) { + SHA3_256_CTX ctx; + SHA3_256_Init(&ctx); + SHA3_256_Update(&ctx,source,size); + KECCAK_256_Final(dst,&ctx); +} + +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); + publickey->x.Get32Bytes(bin_publickey); + publickey->y.Get32Bytes(bin_publickey+32); + KECCAK_256(bin_publickey, 64, dst_address); +} + + +void *thread_process_bsgs_dance(void *vargp) { + FILE *filekey; + struct tothread *tt; + char xpoint_raw[32],*aux_c,*hextemp; + Int base_key,keyfound; + Point base_point,point_aux,point_found; + uint32_t i,j,k,r,salir,thread_number,flip_detector,entrar; + + IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); + Point startP; + + int hLength = (CPU_GRP_SIZE / 2 - 1); + + Int dx[CPU_GRP_SIZE / 2 + 1]; + Point pts[CPU_GRP_SIZE]; + + Int dy; + Int dyn; + Int _s; + Int _p; + Int km,intaux; + Point pp; + Point pn; + grp->Set(dx); + + + tt = (struct tothread *)vargp; + thread_number = tt->nt; + free(tt); + + + entrar = 1; + + pthread_mutex_lock(&bsgs_thread); + switch(rand() % 3) { + case 0: //TOP + base_key.Set(&n_range_end); + base_key.Sub(&BSGS_N); + n_range_end.Sub(&BSGS_N); + if(base_key.IsLower(&BSGS_CURRENT)) { + entrar = 0; + } + else { + n_range_end.Sub(&BSGS_N); + } + break; + case 1: //BOTTOM + base_key.Set(&BSGS_CURRENT); + if(base_key.IsGreater(&n_range_end)) { + entrar = 0; + } + else { + BSGS_CURRENT.Add(&BSGS_N); + } + break; + case 2: //random - middle + base_key.Rand(&BSGS_CURRENT,&n_range_end); + break; + } + pthread_mutex_unlock(&bsgs_thread); + + + intaux.Set(&BSGS_M); + intaux.Mult(CPU_GRP_SIZE/2); + + flip_detector = 1000000; + + + /* + while base_key is less than n_range_end then: + */ + while( entrar ) { + if(thread_number == 0 && flip_detector == 0) { + memorycheck(); + flip_detector = 1000000; + } + + if(FLAGMATRIX) { + aux_c = base_key.GetBase16(); + printf("[+] Thread 0x%s \n",aux_c); + fflush(stdout); + free(aux_c); + } + else { + if(FLAGQUIET == 0){ + aux_c = base_key.GetBase16(); + printf("\r[+] Thread 0x%s \r",aux_c); + fflush(stdout); + free(aux_c); + THREADOUTPUT = 1; + } + } + + base_point = secp->ComputePublicKey(&base_key); + + km.Set(&base_key); + km.Neg(); + + km.Add(&secp->order); + km.Sub(&intaux); + point_aux = secp->ComputePublicKey(&km); + + for(k = 0; k < bsgs_point_number ; k++) { + if(bsgs_found[k] == 0) { + if(base_point.equals(OriginalPointsBSGS[k])) { + 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); + + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); + } + } + else { + startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); + int j = 0; + while( j < bsgs_aux/1024 && bsgs_found[k]== 0 ) { + + int i; + + for(i = 0; i < hLength; i++) { + dx[i].ModSub(&GSn[i].x,&startP.x); + } + dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point + dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point + + // Grouped ModInv + grp->ModInv(); + + /* + We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse + We compute key in the positive and negative way from the center of the group + */ + + // center point + pts[CPU_GRP_SIZE / 2] = startP; + + for(i = 0; iComputePublicKey(&keyfound); + aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); + printf("[+] Publickey %s\n",aux_c); + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); + } + } //End if second check + }//End if first check + + }// For for pts variable + + // Next start point (startP += (bsSize*GRP_SIZE).G) + + pp = startP; + dy.ModSub(&_2GSn.y,&pp.y); + + _s.ModMulK1(&dy,&dx[i + 1]); + _p.ModSquareK1(&_s); + + pp.x.ModNeg(); + pp.x.ModAdd(&_p); + pp.x.ModSub(&_2GSn.x); + + pp.y.ModSub(&_2GSn.x,&pp.x); + pp.y.ModMulK1(&_s); + pp.y.ModSub(&_2GSn.y); + startP = pp; + + j++; + }//while all the aMP points + }// end else + }// End if + } + + steps[thread_number]++; + flip_detector--; + + pthread_mutex_lock(&bsgs_thread); + switch(rand() % 3) { + case 0: //TOP + base_key.Set(&n_range_end); + base_key.Sub(&BSGS_N); + n_range_end.Sub(&BSGS_N); + if(base_key.IsLower(&BSGS_CURRENT)) { + entrar = 0; + } + else { + n_range_end.Sub(&BSGS_N); + } + break; + case 1: //BOTTOM + base_key.Set(&BSGS_CURRENT); + if(base_key.IsGreater(&n_range_end)) { + entrar = 0; + } + else { + BSGS_CURRENT.Add(&BSGS_N); + } + break; + case 2: //random - middle + base_key.Rand(&BSGS_CURRENT,&n_range_end); + break; + } + pthread_mutex_unlock(&bsgs_thread); + + } + ends[thread_number] = 1; + return NULL; +} + +void *thread_process_bsgs_backward(void *vargp) { + FILE *filekey; + struct tothread *tt; + char xpoint_raw[32],*aux_c,*hextemp; + Int base_key,keyfound; + Point base_point,point_aux,point_found; + uint32_t i,j,k,r,salir,thread_number,flip_detector,entrar; + + IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); + Point startP; + + int hLength = (CPU_GRP_SIZE / 2 - 1); + + Int dx[CPU_GRP_SIZE / 2 + 1]; + Point pts[CPU_GRP_SIZE]; + + Int dy; + Int dyn; + Int _s; + Int _p; + Int km,intaux; + Point pp; + Point pn; + grp->Set(dx); + + + tt = (struct tothread *)vargp; + thread_number = tt->nt; + free(tt); + + + pthread_mutex_lock(&bsgs_thread); + n_range_end.Sub(&BSGS_N); + base_key.Set(&n_range_end); + + pthread_mutex_unlock(&bsgs_thread); + + + + + + intaux.Set(&BSGS_M); + intaux.Mult(CPU_GRP_SIZE/2); + + flip_detector = 1000000; + entrar = 1; + + /* + while base_key is less than n_range_end then: + */ + while( entrar ) { + if(thread_number == 0 && flip_detector == 0) { + memorycheck(); + flip_detector = 1000000; + } + + if(FLAGMATRIX) { + aux_c = base_key.GetBase16(); + printf("[+] Thread 0x%s \n",aux_c); + fflush(stdout); + free(aux_c); + } + else { + if(FLAGQUIET == 0){ + aux_c = base_key.GetBase16(); + printf("\r[+] Thread 0x%s \r",aux_c); + fflush(stdout); + free(aux_c); + THREADOUTPUT = 1; + } + } + + base_point = secp->ComputePublicKey(&base_key); + + km.Set(&base_key); + km.Neg(); + + km.Add(&secp->order); + km.Sub(&intaux); + point_aux = secp->ComputePublicKey(&km); + + for(k = 0; k < bsgs_point_number ; k++) { + if(bsgs_found[k] == 0) { + if(base_point.equals(OriginalPointsBSGS[k])) { + 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); + + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); + } + } + else { + startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); + int j = 0; + while( j < bsgs_aux/1024 && bsgs_found[k]== 0 ) { + + int i; + + for(i = 0; i < hLength; i++) { + dx[i].ModSub(&GSn[i].x,&startP.x); + } + dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point + dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point + + // Grouped ModInv + grp->ModInv(); + + /* + We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse + We compute key in the positive and negative way from the center of the group + */ + + // center point + pts[CPU_GRP_SIZE / 2] = startP; + + for(i = 0; iComputePublicKey(&keyfound); + aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); + printf("[+] Publickey %s\n",aux_c); + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); + } + } //End if second check + }//End if first check + + }// For for pts variable + + // Next start point (startP += (bsSize*GRP_SIZE).G) + + pp = startP; + dy.ModSub(&_2GSn.y,&pp.y); + + _s.ModMulK1(&dy,&dx[i + 1]); + _p.ModSquareK1(&_s); + + pp.x.ModNeg(); + pp.x.ModAdd(&_p); + pp.x.ModSub(&_2GSn.x); + + pp.y.ModSub(&_2GSn.x,&pp.x); + pp.y.ModMulK1(&_s); + pp.y.ModSub(&_2GSn.y); + startP = pp; + + j++; + }//while all the aMP points + }// end else + }// End if + } + + steps[thread_number]++; + flip_detector--; + + pthread_mutex_lock(&bsgs_thread); + n_range_end.Sub(&BSGS_N); + if(n_range_end.IsLower(&n_range_start)) { + entrar = 0; + } + else { + base_key.Set(&n_range_end); + } + pthread_mutex_unlock(&bsgs_thread); + } + ends[thread_number] = 1; + return NULL; +} + + +void *thread_process_bsgs_both(void *vargp) { + FILE *filekey; + struct tothread *tt; + char xpoint_raw[32],*aux_c,*hextemp; + Int base_key,keyfound; + Point base_point,point_aux,point_found; + uint32_t i,j,k,r,salir,thread_number,flip_detector,entrar; + + IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); + Point startP; + + int hLength = (CPU_GRP_SIZE / 2 - 1); + + Int dx[CPU_GRP_SIZE / 2 + 1]; + Point pts[CPU_GRP_SIZE]; + + Int dy; + Int dyn; + Int _s; + Int _p; + Int km,intaux; + Point pp; + Point pn; + grp->Set(dx); + + + tt = (struct tothread *)vargp; + thread_number = tt->nt; + free(tt); + + + entrar = 1; + + pthread_mutex_lock(&bsgs_thread); + r = rand() % 2; + if(FLAGDEBUG) printf("[D] was %s\n",r ? "Bottom":"TOP"); + switch(r) { + case 0: //TOP + base_key.Set(&n_range_end); + base_key.Sub(&BSGS_N); + if(base_key.IsLowerOrEqual(&BSGS_CURRENT)) { + entrar = 0; + } + else { + n_range_end.Sub(&BSGS_N); + } + break; + case 1: //BOTTOM + base_key.Set(&BSGS_CURRENT); + if(base_key.IsGreaterOrEqual(&n_range_end)) { + entrar = 0; + } + else { + BSGS_CURRENT.Add(&BSGS_N); + } + break; + } + pthread_mutex_unlock(&bsgs_thread); + + intaux.Set(&BSGS_M); + intaux.Mult(CPU_GRP_SIZE/2); + + flip_detector = 1000000; + + + /* + while BSGS_CURRENT is less than n_range_end + */ + while( entrar ) { + + if(thread_number == 0 && flip_detector == 0) { + memorycheck(); + flip_detector = 1000000; + } + if(FLAGMATRIX) { + aux_c = base_key.GetBase16(); + printf("[+] Thread 0x%s \n",aux_c); + fflush(stdout); + free(aux_c); + } + else { + if(FLAGQUIET == 0){ + aux_c = base_key.GetBase16(); + printf("\r[+] Thread 0x%s \r",aux_c); + fflush(stdout); + free(aux_c); + THREADOUTPUT = 1; + } + } + + base_point = secp->ComputePublicKey(&base_key); + + km.Set(&base_key); + km.Neg(); + + km.Add(&secp->order); + km.Sub(&intaux); + point_aux = secp->ComputePublicKey(&km); + + for(k = 0; k < bsgs_point_number ; k++) { + if(bsgs_found[k] == 0) { + if(base_point.equals(OriginalPointsBSGS[k])) { + 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); + + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); + } + } + else { + startP = secp->AddDirect(OriginalPointsBSGS[k],point_aux); + int j = 0; + while( j < bsgs_aux/1024 && bsgs_found[k]== 0 ) { + + int i; + + for(i = 0; i < hLength; i++) { + dx[i].ModSub(&GSn[i].x,&startP.x); + } + dx[i].ModSub(&GSn[i].x,&startP.x); // For the first point + dx[i+1].ModSub(&_2GSn.x,&startP.x); // For the next center point + + // Grouped ModInv + grp->ModInv(); + + /* + We use the fact that P + i*G and P - i*G has the same deltax, so the same inverse + We compute key in the positive and negative way from the center of the group + */ + + // center point + pts[CPU_GRP_SIZE / 2] = startP; + + for(i = 0; iComputePublicKey(&keyfound); + aux_c = secp->GetPublicKeyHex(OriginalPointsBSGScompressed[k],point_found); + printf("[+] Publickey %s\n",aux_c); + pthread_mutex_lock(&write_keys); + filekey = fopen("KEYFOUNDKEYFOUND.txt","a"); + if(filekey != NULL) { + fprintf(filekey,"Key found privkey %s\nPublickey %s\n",hextemp,aux_c); + fclose(filekey); + } + free(hextemp); + free(aux_c); + pthread_mutex_unlock(&write_keys); + bsgs_found[k] = 1; + salir = 1; + for(j = 0; j < bsgs_point_number && salir; j++) { + salir &= bsgs_found[j]; + } + if(salir) { + printf("All points were found\n"); + exit(0); + } + } //End if second check + }//End if first check + + }// For for pts variable + + // Next start point (startP += (bsSize*GRP_SIZE).G) + + pp = startP; + dy.ModSub(&_2GSn.y,&pp.y); + + _s.ModMulK1(&dy,&dx[i + 1]); + _p.ModSquareK1(&_s); + + pp.x.ModNeg(); + pp.x.ModAdd(&_p); + pp.x.ModSub(&_2GSn.x); + + pp.y.ModSub(&_2GSn.x,&pp.x); + pp.y.ModMulK1(&_s); + pp.y.ModSub(&_2GSn.y); + startP = pp; + + j++; + }//while all the aMP points + }// end else + }// End if + } + + steps[thread_number]++; + flip_detector--; + + pthread_mutex_lock(&bsgs_thread); + switch(rand() % 2) { + case 0: //TOP + base_key.Set(&n_range_end); + base_key.Sub(&BSGS_N); + if(base_key.IsLowerOrEqual(&BSGS_CURRENT)) { + entrar = 0; + } + else { + n_range_end.Sub(&BSGS_N); + } + break; + case 1: //BOTTOM + base_key.Set(&BSGS_CURRENT); + if(base_key.IsGreaterOrEqual(&n_range_end)) { + entrar = 0; + } + else { + BSGS_CURRENT.Add(&BSGS_N); + } + break; + } + pthread_mutex_unlock(&bsgs_thread); + + } + ends[thread_number] = 1; + return NULL; +} + +void memorycheck() { + char current_checksum[32]; + char *hextemp,*aux_c; + 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"); + hextemp = tohex(current_checksum,32); + aux_c = tohex(checksum,32); + fprintf(stderr,"Current Checksum: %s\n",hextemp); + fprintf(stderr,"Saved Checksum: %s\n",aux_c); + aux_c = tohex(checksum_backup,32); + fprintf(stderr,"Backup Checksum: %s\nExit!\n",aux_c); + exit(0); + } +} \ No newline at end of file diff --git a/secp256k1/SECP256K1.cpp b/secp256k1/SECP256K1.cpp index 914633f..55c267c 100644 --- a/secp256k1/SECP256K1.cpp +++ b/secp256k1/SECP256K1.cpp @@ -231,6 +231,7 @@ Point Secp256K1::AddDirect(Point &p1,Point &p2) { return r; } + Point Secp256K1::Add2(Point &p1, Point &p2) { // P2.z = 1 Int u; diff --git a/secp256k1/test b/secp256k1/test deleted file mode 100755 index 8bcb34b..0000000 Binary files a/secp256k1/test and /dev/null differ diff --git a/secp256k1/test.c b/secp256k1/test.c deleted file mode 100644 index 3aa9966..0000000 --- a/secp256k1/test.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - gcc -o test test.c -*/ - -#include -#include -#include -//#include -#include "SECP256k1.h" -#include "Point.h" -#include "Int.h" - -#include "util.h" - -Secp256K1 *secp; - -int main() { - char dst[32]; - Int key; - char *test; - secp = new Secp256K1(); - key = new Int(); - secp->Init(); - Point punto; - bool parity; - if(secp->ParsePublicKeyHex((char*)"04ceb6cbbcdbdf5ef7150682150f4ce2c6f4807b349827dcdbdd1f2efa885a26302b195386bea3f5f002dc033b92cfc2c9e71b586302b09cfe535e1ff290b1b5ac",punto,parity)) { - test = punto.x.GetBase16(); - printf("%s\n",test); - free(test); - test = punto.y.GetBase16(); - printf("%s\n",test); - free(test); - } - else { - printf("Is not a valid point"); - } - printf("%i\n",sizeof(Point)); - punto.x.Get32Bytes((unsigned char*)dst); - test = tohex(dst,32); - printf("%s\n",test); - free(test); -} diff --git a/sha3/sha3.c b/sha3/sha3.c index edee7a5..f4cebc1 100644 --- a/sha3/sha3.c +++ b/sha3/sha3.c @@ -52,7 +52,7 @@ explicit_memset(void *buf, int c, size_t n) static inline uint64_t le64dec(const void *buf) { - const uint8_t *p = buf; + const uint8_t *p = (const uint8_t *)buf; return (((uint64_t)p[0]) | ((uint64_t)p[1] << 8) | @@ -67,7 +67,7 @@ le64dec(const void *buf) static inline void le64enc(void *buf, uint64_t v) { - uint8_t *p = buf; + uint8_t *p = (uint8_t *)buf; *p++ = v; v >>= 8; *p++ = v; v >>= 8; @@ -437,7 +437,7 @@ KECCAK_512_Final(uint8_t h[SHA3_512_DIGEST_LENGTH], SHA3_512_CTX *C) static void sha3_selftest_prng(void *buf, size_t len, uint32_t seed) { - uint8_t *p = buf; + uint8_t *p = (uint8_t *)buf; size_t n = len; uint32_t t, a, b; diff --git a/tests/63.pub b/tests/63.pub new file mode 100644 index 0000000..44565bc --- /dev/null +++ b/tests/63.pub @@ -0,0 +1,2 @@ +0365ec2994b8cc0a20d40dd69edfe55ca32a54bcbbaa6b0ddcff36049301a54579 + diff --git a/tests/in.txt b/tests/in.txt new file mode 100644 index 0000000..87b9919 --- /dev/null +++ b/tests/in.txt @@ -0,0 +1,17 @@ +0459A3BFDAD718C9D3FAC7C187F1139F0815AC5D923910D516E186AFDA28B221DC994327554CED887AAE5D211A2407CDD025CFC3779ECB9C9D7F2F1A1DDF3E9FF8 +04A50FBBB20757CC0E9C41C49DD9DF261646EE7936272F3F68C740C9DA50D42BCD3E48440249D6BC78BC928AA52B1921E9690EBA823CBC7F3AF54B3707E6A73F34 +0404A49211C0FE07C9F7C94695996F8826E09545375A3CF9677F2D780A3EB70DE3BD05357CAF8340CB041B1D46C5BB6B88CD9859A083B0804EF63D498B29D31DD1 +040B39E3F26AF294502A5BE708BB87AEDD9F895868011E60C1D2ABFCA202CD7A4D1D18283AF49556CF33E1EA71A16B2D0E31EE7179D88BE7F6AA0A7C5498E5D97F +04837A31977A73A630C436E680915934A58B8C76EB9B57A42C3C717689BE8C0493E46726DE04352832790FD1C99D9DDC2EE8A96E50CAD4DCC3AF1BFB82D51F2494 +040ECDB6359D41D2FD37628C718DDA9BE30E65801A88A00C3C5BDF36E7EE6ADBBAD71A2A535FCB54D56913E7F37D8103BA33ED6441D019D0922AC363FCC792C29A +0422DD52FCFA3A4384F0AFF199D019E481D335923D8C00BADAD42FFFC80AF8FCF038F139D652842243FC841E7C5B3E477D901F88C5AB0B88EE13D80080E413F2ED +04DB4F1B249406B8BD662F78CBA46F5E90E20FE27FC69D0FBAA2F06E6E50E536695DF83B68FD0F396BB9BFCF6D4FE312F32A43CF3FA1FE0F81DF70C877593B64E0 +043BD0330D7381917F8860F1949ACBCCFDC7863422EEE2B6DB7EDD551850196687528B6D2BC0AA7A5855D168B26C6BAF9DDCD04B585D42C7B9913F60421716D37A +04332A02CA42C481EAADB7ADB97DF89033B23EA291FDA809BEA3CE5C3B73B20C49C410D1AD42A9247EB8FF217935C9E28411A08B325FBF28CC2AF8182CE2B5CE38 +04513981849DE1A1327DEF34B51F5011C5070603CA22E6D868263CB7C908525F0C19EBA6BD2A8DCF651E4342512EDEACB6EA22DA323A194E25C6A1614ABD259BC0 +04D4E6FA664BD75A508C0FF0ED6F2C52DA2ADD7C3F954D9C346D24318DBD2ECFC6805511F46262E10A25F252FD525AF1CBCC46016B6CD0A7705037364309198DA1 +0456B468963752924DBF56112633DC57F07C512E3671A16CD7375C58469164599D1E04011D3E9004466C814B144A9BCB7E47D5BACA1B90DA0C4752603781BF5873 +04D5BE7C653773CEE06A238020E953CFCD0F22BE2D045C6E5B4388A3F11B4586CBB4B177DFFD111F6A15A453009B568E95798B0227B60D8BEAC98AF671F31B0E2B +04B1985389D8AB680DEDD67BBA7CA781D1A9E6E5974AAD2E70518125BAD5783EB5355F46E927A030DB14CF8D3940C1BED7FB80624B32B349AB5A05226AF15A2228 +0455B95BEF84A6045A505D015EF15E136E0A31CC2AA00FA4BCA62E5DF215EE981B3B4D6BCE33718DC6CF59F28B550648D7E8B2796AC36F25FF0C01F8BC42A16FD9 + diff --git a/util.c b/util.c index 4827b1c..b2f4b54 100644 --- a/util.c +++ b/util.c @@ -108,6 +108,17 @@ char *tohex(char *ptr,int length){ return buffer; } +void tohex_dst(char *ptr,int length,char *dst) { + int offset = 0; + unsigned char c; + for (int i = 0; i