From 37920b0000fdcfab30de2cae7fdf7ad032b89e23 Mon Sep 17 00:00:00 2001 From: AlbertoBSD Date: Mon, 29 Mar 2021 05:01:58 +0200 Subject: [PATCH] multithread for generate or read bP points, see CHANGELOG --- .gitignore | 6 +- CHANGELOG.md | 5 + Makefile | 5 +- README.md | 615 +++++++++++++++++++++++++----------- bloom/bloom.c | 48 ++- bloom/bloom.h | 22 +- bloom/murmur2/MurmurHash2.c | 64 ---- bloom/murmur2/README | 9 - bloom/murmur2/murmurhash2.h | 7 - keyhunt.c | 352 +++++++++++++-------- tests/1to32.rmd | 33 ++ tests/1to32.txt | 33 ++ 12 files changed, 756 insertions(+), 443 deletions(-) delete mode 100644 bloom/murmur2/MurmurHash2.c delete mode 100644 bloom/murmur2/README delete mode 100644 bloom/murmur2/murmurhash2.h create mode 100644 tests/1to32.rmd create mode 100644 tests/1to32.txt diff --git a/.gitignore b/.gitignore index 9a318dd..6429592 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,7 @@ bPfile hexcharstoraw *.bin keyhunt -test_bloom.c -xpoints.c -heapsort.c -insertionsorttest.c -introsort.c +KEYFOUNDKEYFOUND.txt # Prerequisites *.d diff --git a/CHANGELOG.md b/CHANGELOG.md index b65e788..56e0a6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# Version 0.1.20210328 +- Added a progress counter (this solve bug https://github.com/albertobsd/keyhunt/issues/18 ) +- Added multithread for precalculating bP items or reading then from file +- Fixed the code to avoid warnings (this solve the issue https://github.com/albertobsd/keyhunt/issues/19) + # Version 0.1.20210322 - Added xxhash for bloomfilter it hash better performance than murmurhash2. And it is 64 bits hash :) - We reduce the number of items of the bPtable in ram using a second bloom filter, thanks @iceland2k14 diff --git a/Makefile b/Makefile index 57381dc..ae00f39 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,12 @@ default: - gcc -O3 -c bloom/bloom.c -o bloom.o -I./bloom/murmur2 - gcc -O3 -c bloom/murmur2/MurmurHash2.c -o murmurhash2.o + gcc -O3 -c bloom/bloom.c -o bloom.o gcc -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 gcc -O3 -c xxhash/xxhash.c -o xxhash.o gcc -O3 -c keyhunt.c -o keyhunt.o -lm - gcc -o keyhunt keyhunt.o base58.o rmd160.o sha256.o bloom.o murmurhash2.o xxhash.o -lgmp -lm -lpthread + gcc -o keyhunt keyhunt.o base58.o rmd160.o sha256.o bloom.o xxhash.o -lgmp -lm -lpthread gcc -O3 hexcharstoraw.c -o hexcharstoraw -lm gcc -o bPfile bPfile.c -lgmp -lm clean: diff --git a/README.md b/README.md index 3fc203b..8b8440e 100644 --- a/README.md +++ b/README.md @@ -1,186 +1,429 @@ -# keyhunt -privkey hunt for crypto currencies that use secp256k1 elliptic curve - -Post: https://bitcointalk.org/index.php?topic=5322040.0 - -Work for btc in this moment, only legacy Addresses that start with '1' - -Ethereum addresses is a work in develop - -# How to use -First compile: - -``make`` - -and then execute: - -``./keyhunt`` - -you need to have some file called **adddress.txt** or specify other file with the **-f** option - -``./keyhunt -f ~/some/path/to/other/file.txt`` - -if you want more threads use the **-t** option - -``./keyhunt -f ~/some/path/to/other/file.txt -t 8`` - -if you want to know the full help just use **-h** param - -``./keyhunt -h`` - -al the hunted keys are saved in a file keys.txt - -The default behaivor ot keyhunt is to choose a random key and check secuentialy for the next 4.2 billions keys, this is **4294967295** or **0xffffffff** - -# BSGS ( Baby step giant step) - -The new version of keyhunt implement the BSGS algorimth to search privatekeys for a knowed publickey. - -The address.txt file need to have a 130 hexadecimal characters uncompress publickey per line any other word followed by an space is ignored example of the file: - -``` -043ffa1cc011a8d23dec502c7656fb3f93dbe4c61f91fd443ba444b4ec2dd8e6f0406c36edf3d8a0dfaa7b8f309b8f1276a5c04131762c23594f130a023742bdde # 0000000000000000000000000000000000800000000000000000100000000000 -046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69 # 0000000000000000000000000000000000800000000000000000200000000000 -``` - -This example contains 2 publickeys followed by his privatekey just to test the correct behaivor of the application - -btw any word followed by and space after the publickey is ignored the file can be only the publickeys: - -``` -043ffa1cc011a8d23dec502c7656fb3f93dbe4c61f91fd443ba444b4ec2dd8e6f0406c36edf3d8a0dfaa7b8f309b8f1276a5c04131762c23594f130a023742bdde -046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69 -``` - -To try to find those privatekey this is the line of execution: - -``./keyhunt -m bsgs -f test_120.txt -r 800000000000000000000000000000:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF`` - -Output: - -``` -$ ./keyhunt -m bsgs -f test_120.txt -r 800000000000000000000000000000:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -[+] Version 0.1.20210112 BSGS -[+] Setting mode BSGS -[+] Opening file test_120.txt -[+] Added 2 points from file -[+] Setting N up to 17592186044416. -[+] Init bloom filter for 4194304 elements : 7.00 MB -[+] Allocating 128.00 MB for aMP Points -[+] Precalculating 4194304 aMP points -[+] Allocating 144.00 MB for bP Points -[+] precalculating 4194304 bP points -[+] Sorting 4194304 elements -[+] Thread 0: 0000000000000000000000000000000000800000000000000000000000000000 -[+] Thread 0 Key found privkey 0000000000000000000000000000000000800000000000000000100000000000 -[+] Publickey 043ffa1cc011a8d23dec502c7656fb3f93dbe4c61f91fd443ba444b4ec2dd8e6f0406c36edf3d8a0dfaa7b8f309b8f1276a5c04131762c23594f130a023742bdde -[+] Thread 0: 0000000000000000000000000000000000800000000000000000100000000000 -Total 17592186044416 keys in 30 seconds: 586406201480 keys/s -[+] Thread 0 Key found privkey 0000000000000000000000000000000000800000000000000000200000000000 -[+] Publickey 046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69 -All points were found -``` - -Test the puzzle 120 with the next publickey: - -``` -04ceb6cbbcdbdf5ef7150682150f4ce2c6f4807b349827dcdbdd1f2efa885a26302b195386bea3f5f002dc033b92cfc2c9e71b586302b09cfe535e1ff290b1b5ac # Compressed Address : 17s2b9ksz5y7abUm92cHwG8jEPCzK3dLnT -``` - -Line of execution in random mode **-R** -``./keyhunt -m bsgs -f 120.txt -b 120 -R`` - - -Example Output: - -``` -$ ./keyhunt -m bsgs -f 120.txt -r 800000000000000000000000000000:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -R -[+] Version 0.1.20210112 BSGS -[+] Setting mode BSGS -[+] Setting random mode. -[+] Opening file 120.txt -[+] Added 1 points from file -[+] Setting N up to 17592186044416. -[+] Init bloom filter for 4194304 elements : 7.00 MB -[+] Allocating 128.00 MB for aMP Points -[+] Precalculating 4194304 aMP points -[+] Allocating 144.00 MB for bP Points -[+] precalculating 4194304 bP points -[+] Sorting 4194304 elements -[+] Thread 0: 0000000000000000000000000000000000d80083712e9650075586dd5e162d44 -[+] Thread 0: 0000000000000000000000000000000000f92eb8e27b7fb1bd2ec4eb4ac223a1 -[+] Thread 0: 0000000000000000000000000000000000dda9ebacc83b0f0d1d36829fcc17b7 -Total 35184372088832 keys in 30 seconds: 1172812402961 keys/s -[+] Thread 0: 0000000000000000000000000000000000ac445f232e0207b9cf46b73e106fed -``` - -Good speed no? 1.1 Terakeys/s for one single thread - -**Total 35184372088832 keys in 30 seconds: 1172812402961 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 120.txt -b 120 -k 20`` - -Example output: - -``` -$ ./keyhunt -m bsgs -f 120.txt -b 120 -k 20 -R -[+] Version 0.1.20210306 K*BSGS -[+] Setting mode BSGS -[+] Min range: 800000000000000000000000000000 -[+] Max range: ffffffffffffffffffffffffffffff -[+] Setting k factor to 20 -[+] Setting random mode. -[+] Opening file 120.txt -[+] Added 1 points from file -[+] Bit Range 120 -[+] Setting N up to 17592253153280. -[+] Init bloom filter for 83886080 elements : 239.00 MB -[+] Allocating 6.00 MB for aMP Points -[+] Precalculating 209716 aMP points -[+] Allocating 1280.00 MB for bP Points -[+] precalculating 83886080 bP points -[+] Sorting 83886080 elements -(Thread output omited....) -Total 562952100904960 keys in 30 seconds: 18765070030165 keys/s -(Thread output omited....) -Total 2445323188305920 keys in 120 seconds: 20377693235882 keys/s -``` - -**20 Terakeys/s for one single thread** - -Want to more Speed use a bigger -k value like 120, it will use some 9 GB of RAM - - -``` -[+] Version 0.1.20210306 K*BSGS -[+] Setting mode BSGS -[+] Min range: 800000000000000000000000000000 -[+] Max range: ffffffffffffffffffffffffffffff -[+] Setting k factor to 120 -[+] Setting random mode. -[+] Opening file 120.txt -[+] Added 1 points from file -[+] Bit Range 120 -[+] Setting N up to 17592420925440. -[+] Init bloom filter for 503316480 elements : 1437.00 MB -[+] Allocating 1.00 MB for aMP Points -[+] Precalculating 34953 aMP points -[+] Allocating 7680.00 MB for bP Points -[+] precalculating 503316480 bP points -[+] Sorting 503316480 elements -(Thread output omited....) -Total 3465706922311680 keys in 30 seconds: 115523564077056 keys/s -```` - -**~100 Terakeys/s for one single thread** - - - -# Dependencies -- libgmp -- pthread - -Tested under Debian +# keyhunt +Tool for hunt privatekeys for crypto currencies that use secp256k1 elliptic curve + +Post: https://bitcointalk.org/index.php?topic=5322040.0 + +Work for btc in this moment, only legacy Addresses that start with '1' + +Ethereum addresses is a work in develop + +# How to build +First compile: + +``make`` + +and then execute: + +``./keyhunt`` + +# Modes + +Keyhunt can work in diferents ways at different speeds. +The current availables modes are: +- address +- rmd160 +- xpoint +- bsgs + +## address mode + +This is the most basic approach to work, in this mode your text file need to have a list of the publickeys to be search. + +Example of address from solved puzzles, this file is already on the repository `tests/1to32.txt` + +``` +1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH +1CUNEBjYrCn2y1SdiUMohaKUi4wpP326Lb +19ZewH8Kk1PDbSNdJ97FP4EiCjTRaZMZQA +1EhqbyUMvvs7BfL8goY6qcPbD6YKfPqb7e +1E6NuFjCi27W5zoXg8TRdcSRq84zJeBW3k +1PitScNLyp2HCygzadCh7FveTnfmpPbfp8 +1McVt1vMtCC7yn5b9wgX1833yCcLXzueeC +1M92tSqNmQLYw33fuBvjmeadirh1ysMBxK +1CQFwcjw1dwhtkVWBttNLDtqL7ivBonGPV +1LeBZP5QCwwgXRtmVUvTVrraqPUokyLHqe +1PgQVLmst3Z314JrQn5TNiys8Hc38TcXJu +1DBaumZxUkM4qMQRt2LVWyFJq5kDtSZQot +1Pie8JkxBT6MGPz9Nvi3fsPkr2D8q3GBc1 +1ErZWg5cFCe4Vw5BzgfzB74VNLaXEiEkhk +1QCbW9HWnwQWiQqVo5exhAnmfqKRrCRsvW +1BDyrQ6WoF8VN3g9SAS1iKZcPzFfnDVieY +1HduPEXZRdG26SUT5Yk83mLkPyjnZuJ7Bm +1GnNTmTVLZiqQfLbAdp9DVdicEnB5GoERE +1NWmZRpHH4XSPwsW6dsS3nrNWfL1yrJj4w +1HsMJxNiV7TLxmoF6uJNkydxPFDog4NQum +14oFNXucftsHiUMY8uctg6N487riuyXs4h +1CfZWK1QTQE3eS9qn61dQjV89KDjZzfNcv +1L2GM8eE7mJWLdo3HZS6su1832NX2txaac +1rSnXMr63jdCuegJFuidJqWxUPV7AtUf7 +15JhYXn6Mx3oF4Y7PcTAv2wVVAuCFFQNiP +1JVnST957hGztonaWK6FougdtjxzHzRMMg +128z5d7nN7PkCuX5qoA4Ys6pmxUYnEy86k +12jbtzBb54r97TCwW3G1gCFoumpckRAPdY +19EEC52krRUK1RkUAEZmQdjTyHT7Gp1TYT +1LHtnpd8nU5VHEMkG2TMYYNUjjLc992bps +1LhE6sCTuGae42Axu1L1ZB7L96yi9irEBE +1FRoHA9xewq7DjrZ1psWJVeTer8gHRqEvR +``` + +To targert that file we need to execute keyhunt with this line + +`./keyhunt -m address -f tests/1to32.txt -r 1:FFFFFFFF` + +output: +``` +[+] Version 0.1.20210328 +[+] Setting mode address +[+] 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 +[+] Bloomfilter completed +[+] Sorting data +[+] 32 values were loaded and sorted +Thread 0 : Setting up base key: 0000000000000000000000000000000000000000000000000000000000000001 +HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000001 +pubkey: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 +address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH +HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000003 +pubkey: 02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9 +address: 1CUNEBjYrCn2y1SdiUMohaKUi4wpP326Lb +HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000007 +pubkey: 025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc +address: 19ZewH8Kk1PDbSNdJ97FP4EiCjTRaZMZQA +HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000008 +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` + +Test your look with the random parameter `-R` againts the puzzle #64 + +`./keyhunt -m address -f tests/64.txt -b 64 -l compress -R` + +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 +[+] Search compress only +[+] Setting random mode. +[+] 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 +[+] 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) +``` + +## rmd160 mode + +rmd stand for RIPE Message Digest (see https://en.wikipedia.org/wiki/RIPEMD ) + +mode rmd160 work in the same why than address, but the diference is that file need to have hash rmd160 instead of addresses. + +This mode is almost two times faster than addres mode + +example: + +``` +751e76e8199196d454941c45d1b3a323f1433bd6 +7dd65592d0ab2fe0d0257d571abf032cd9db93dc +5dedfbf9ea599dd4e3ca6a80b333c472fd0b3f69 +9652d86bedf43ad264362e6e6eba6eb764508127 +8f9dff39a81ee4abcbad2ad8bafff090415a2be8 +f93ec34e9e34a8f8ff7d600cdad83047b1bcb45c +e2192e8a7dd8dd1c88321959b477968b941aa973 +dce76b2613052ea012204404a97b3c25eac31715 +7d0f6c64afb419bbd7e971e943d7404b0e0daab4 +d7729816650e581d7462d52ad6f732da0e2ec93b +f8c698da3164ef8fa4258692d118cc9a902c5acc +85a1f9ba4da24c24e582d9b891dacbd1b043f971 +f932d0188616c964416b91fb9cf76ba9790a921e +97f9281a1383879d72ac52a6a3e9e8b9a4a4f655 +fe7c45126731f7384640b0b0045fd40bac72e2a2 +7025b4efb3ff42eb4d6d71fab6b53b4f4967e3dd +b67cb6edeabc0c8b927c9ea327628e7aa63e2d52 +ad1e852b08eba53df306ec9daa8c643426953f94 +ebfbe6819fcdebab061732ce91df7d586a037dee +b907c3a2a3b27789dfb509b730dd47703c272868 +29a78213caa9eea824acf08022ab9dfc83414f56 +7ff45303774ef7a52fffd8011981034b258cb86b +d0a79df189fe1ad5c306cc70497b358415da579e +0959e80121f36aea13b3bad361c15dac26189e2f +2f396b29b27324300d0c59b17c3abc1835bd3dbb +bfebb73562d4541b32a02ba664d140b5a574792f +0c7aaf6caa7e5424b63d317f0f8f1f9fa40d5560 +1306b9e4ff56513a476841bac7ba48d69516b1da +5a416cc9148f4a377b672c8ae5d3287adaafadec +d39c4704664e1deb76c9331e637564c257d68a08 +d805f6f251f7479ebd853b3d0f4b9b2656d92f1d +9e42601eeaedc244e15f17375adb0e2cd08efdc9 +``` + +to target that file you need to execute the next line: + +`./keyhunt -m rmd160 -f tests/1to32.rmd -r 1:FFFFFFFF -l compress` + +output: + +``` +[+] Version 0.1.20210328 +[+] Setting 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 +[+] Bloomfilter completed +[+] Sorting data +[+] 32 values were loaded and sorted +Thread 0 : Setting up base key: 0000000000000000000000000000000000000000000000000000000000000001HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000001 +pubkey: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 +HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000003 +pubkey: 02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9 +HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000007 +pubkey: 025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc +HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000008 +pubkey: 022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01 +HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000015 +pubkey: 02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5 +HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000031 +(Output omited) +``` + +test your luck with the next file for th puzzle #64 + +`./keyhunt -m rmd160 -f tests/64.rmd -b 64 -l compress -R` + +Output: + +``` +[+] Version 0.1.20210328 +[+] Setting mode rmd160 +[+] Min range: 8000000000000000 +[+] Max range: ffffffffffffffff +[+] Search compress only +[+] Setting random mode. +[+] Opening file tests/64.rmd +[+] Allocating memory for 1 elements: 0.00 MB +[+] Initializing bloom filter for 1 elements. +[+] Loading data to the bloomfilter +[+] 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) + +``` + +BTW this rmd160 mode doesn't allow search by vanity address + +## bsgs mode (baby step giant step) + +The new version of keyhunt implement the BSGS algorimth to search privatekeys for a knowed publickey. + +The address.txt file need to have a 130 hexadecimal characters uncompress publickey per line any other word followed by an space is ignored example of the file: + +``` +043ffa1cc011a8d23dec502c7656fb3f93dbe4c61f91fd443ba444b4ec2dd8e6f0406c36edf3d8a0dfaa7b8f309b8f1276a5c04131762c23594f130a023742bdde # 0000000000000000000000000000000000800000000000000000100000000000 +046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69 # 0000000000000000000000000000000000800000000000000000200000000000 +``` + +This example contains 2 publickeys followed by his privatekey just to test the correct behaivor of the application + +btw any word followed by and space after the publickey is ignored the file can be only the publickeys: + +``` +043ffa1cc011a8d23dec502c7656fb3f93dbe4c61f91fd443ba444b4ec2dd8e6f0406c36edf3d8a0dfaa7b8f309b8f1276a5c04131762c23594f130a023742bdde +046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69 +``` + +To try to find those privatekey this is the line of execution: + +``./keyhunt -m bsgs -f tests/test120.txt -b 120`` + +Output: + +``` +[+] Version 0.1.20210328 +[+] Setting mode BSGS +[+] Min range: 800000000000000000000000000000 +[+] Max range: ffffffffffffffffffffffffffffff +[+] 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 +[+] 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 +[+] Publickey 043ffa1cc011a8d23dec502c7656fb3f93dbe4c61f91fd443ba444b4ec2dd8e6f0406c36edf3d8a0dfaa7b8f309b8f1276a5c04131762c23594f130a023742bdde +[+] Thread 0: 0000000000000000000000000000000000800000000000000000100000000000 +Total 17592186044416 keys in 30 seconds: 586406201480 keys/s +[+] Thread 0 Key found privkey 0000000000000000000000000000000000800000000000000000200000000000 +[+] Publickey 046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69 +All points were found +``` + +Test the puzzle 120 with the next publickey: + +``` +02CEB6CBBCDBDF5EF7150682150F4CE2C6F4807B349827DCDBDD1F2EFA885A2630 +``` + +Line of execution in random mode **-R** + +`./keyhunt -m bsgs -f tests/120.txt -b 120 -R` + + +Example Output: + +``` +[+] Version 0.1.20210328 +[+] Setting mode BSGS +[+] Min range: 800000000000000000000000000000 +[+] Max range: ffffffffffffffffffffffffffffff +[+] Setting random mode. +[+] 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 +[+] 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 +``` + +Good speed no? 1.1 Terakeys/s for one single thread + +**Total 70368744177664 keys in 60 seconds: 1172812402961 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` + +Example output: + +``` +[+] Version 0.1.20210328 +[+] Setting mode BSGS +[+] Min range: 800000000000000000000000000000 +[+] Max range: ffffffffffffffffffffffffffffff +[+] Setting random mode. +[+] Setting k factor to 20 +[+] 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 +[+] 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....) +``` + +**23 Terakeys/s for one single thread** + +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 +[+] 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 +``` + +**~155 Terakeys/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.** + +with 6 threads + +`./keyhunt -m bsgs -f tests/120.txt -b 120 -R -k 1024 -q -p ./bPfile.bin -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 +[+] 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 +[+] 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 +``` +I get 5.2 Petakeys/s total + +# Dependencies +- libgmp +- pthread + +Tested under Debian diff --git a/bloom/bloom.c b/bloom/bloom.c index a58494d..bc0a9c1 100644 --- a/bloom/bloom.c +++ b/bloom/bloom.c @@ -17,11 +17,11 @@ #include #include #include +#include #include #include #include "bloom.h" -#include "murmurhash2.h" #include "../xxhash/xxhash.h" #define MAKESTRING(n) STRING(n) @@ -32,10 +32,9 @@ inline static int test_bit_set_bit(unsigned char * buf, uint64_t bit, int set_bit) { - unsigned int byte = bit >> 3; - unsigned char c = buf[byte]; // expensive memory access - unsigned char mask = 1 << (bit % 8); - + uint64_t byte = bit >> 3; + uint8_t c = buf[byte]; // expensive memory access + uint8_t mask = 1 << (bit % 8); if (c & mask) { return 1; } else { @@ -47,20 +46,17 @@ inline static int test_bit_set_bit(unsigned char * buf, uint64_t bit, int set_bi } -static int bloom_check_add(struct bloom * bloom, - const void * buffer, int len, int add) +static int bloom_check_add(struct bloom * bloom, const void * buffer, int len, int add) { if (bloom->ready == 0) { printf("bloom at %p not initialized!\n", (void *)bloom); return -1; } - - unsigned char hits = 0; - uint64_t a = XXH64(buffer, len, 0x59f2815b16f81798);/*0x9747b28c); */ + uint8_t hits = 0; + uint64_t a = XXH64(buffer, len, 0x59f2815b16f81798); uint64_t b = XXH64(buffer, len, a); uint64_t x; - unsigned char i; - + uint8_t i; for (i = 0; i < bloom->hashes; i++) { x = (a + b*i) % bloom->bits; if (test_bit_set_bit(bloom->bf, x, add)) { @@ -70,26 +66,23 @@ static int bloom_check_add(struct bloom * bloom, return 0; } } - if (hits == bloom->hashes) { return 1; // 1 == element already in (or collision) } - return 0; } // DEPRECATED - Please migrate to bloom_init2. -int bloom_init(struct bloom * bloom, unsigned long long int entries, long double error) +int bloom_init(struct bloom * bloom, uint64_t entries, long double error) { return bloom_init2(bloom, entries, error); } -int bloom_init2(struct bloom * bloom, unsigned long long int entries, long double error) +int bloom_init2(struct bloom * bloom, uint64_t entries, long double error) { memset(bloom, 0, sizeof(struct bloom)); - if (entries < 1000 || error <= 0 || error >= 1) { return 1; } @@ -103,26 +96,23 @@ int bloom_init2(struct bloom * bloom, unsigned long long int entries, long doubl long double dentries = (long double)entries; long double allbits = dentries * bloom->bpe; - bloom->bits = (unsigned long long int)allbits; + bloom->bits = (uint64_t)allbits; + bloom->bytes = (uint64_t) bloom->bits / 8; if (bloom->bits % 8) { - bloom->bytes = (unsigned long long int) (bloom->bits / 8) + 1; - } else { - bloom->bytes = (unsigned long long int) bloom->bits / 8; + bloom->bytes +=1; } - bloom->hashes = (unsigned char)ceil(0.693147180559945 * bloom->bpe); // ln(2) + bloom->hashes = (uint8_t)ceil(0.693147180559945 * bloom->bpe); // ln(2) - bloom->bf = (unsigned char *)calloc((unsigned long long int)bloom->bytes, sizeof(unsigned char)); + bloom->bf = (uint8_t *)calloc(bloom->bytes, sizeof(uint8_t)); if (bloom->bf == NULL) { // LCOV_EXCL_START return 1; } // LCOV_EXCL_STOP bloom->ready = 1; - bloom->major = BLOOM_VERSION_MAJOR; bloom->minor = BLOOM_VERSION_MINOR; - return 0; } @@ -144,11 +134,11 @@ void bloom_print(struct bloom * bloom) printf("bloom at %p\n", (void *)bloom); if (!bloom->ready) { printf(" *** NOT READY ***\n"); } printf(" ->version = %d.%d\n", bloom->major, bloom->minor); - printf(" ->entries = %llu\n", bloom->entries); - printf(" ->error = %lf\n", bloom->error); - printf(" ->bits = %llu\n", bloom->bits); + printf(" ->entries = %"PRIu64"\n", bloom->entries); + printf(" ->error = %Lf\n", bloom->error); + printf(" ->bits = %"PRIu64"\n", bloom->bits); printf(" ->bits per elem = %f\n", bloom->bpe); - printf(" ->bytes = %llu", bloom->bytes); + printf(" ->bytes = %"PRIu64"\n", bloom->bytes); unsigned int KB = bloom->bytes / 1024; unsigned int MB = KB / 1024; printf(" (%u KB, %u MB)\n", KB, MB); diff --git a/bloom/bloom.h b/bloom/bloom.h index 64ff63b..e90295a 100644 --- a/bloom/bloom.h +++ b/bloom/bloom.h @@ -24,20 +24,20 @@ struct bloom // These fields are part of the public interface of this structure. // Client code may read these values if desired. Client code MUST NOT // modify any of these. - unsigned long long int entries; - unsigned long long int bits; - unsigned long long int bytes; - unsigned char hashes; + uint64_t entries; + uint64_t bits; + uint64_t bytes; + uint8_t hashes; long double error; // Fields below are private to the implementation. These may go away or // change incompatibly at any moment. Client code MUST NOT access or rely // on these. - unsigned char ready; - unsigned char major; - unsigned char minor; + uint8_t ready; + uint8_t major; + uint8_t minor; double bpe; - unsigned char * bf; + uint8_t *bf; }; @@ -68,7 +68,7 @@ struct bloom * 1 - on failure * */ -int bloom_init2(struct bloom * bloom, unsigned long long int entries, long double error); +int bloom_init2(struct bloom * bloom, uint64_t entries, long double error); /** @@ -76,7 +76,7 @@ int bloom_init2(struct bloom * bloom, unsigned long long int entries, long doubl * Kept for compatibility with libbloom v.1. To be removed in v3.0. * */ -int bloom_init(struct bloom * bloom, unsigned long long int entries, long double error); +int bloom_init(struct bloom * bloom, uint64_t entries, long double error); /** *************************************************************************** @@ -207,4 +207,4 @@ const char * bloom_version(); } #endif -#endif \ No newline at end of file +#endif diff --git a/bloom/murmur2/MurmurHash2.c b/bloom/murmur2/MurmurHash2.c deleted file mode 100644 index 32c4c32..0000000 --- a/bloom/murmur2/MurmurHash2.c +++ /dev/null @@ -1,64 +0,0 @@ -//----------------------------------------------------------------------------- -// MurmurHash2, by Austin Appleby - -// Note - This code makes a few assumptions about how your machine behaves - - -// 1. We can read a 4-byte value from any address without crashing -// 2. sizeof(int) == 4 - -// And it has a few limitations - - -// 1. It will not work incrementally. -// 2. It will not produce the same results on little-endian and big-endian -// machines. - -unsigned int murmurhash2(const void * key, int len, const unsigned int seed) -{ - // 'm' and 'r' are mixing constants generated offline. - // They're not really 'magic', they just happen to work well. - - const unsigned int m = 0x5bd1e995; - const int r = 24; - - // Initialize the hash to a 'random' value - - unsigned int h = seed ^ len; - - // Mix 4 bytes at a time into the hash - - const unsigned char * data = (const unsigned char *)key; - - while(len >= 4) - { - unsigned int k = *(unsigned int *)data; - - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - - data += 4; - len -= 4; - } - - // Handle the last few bytes of the input array - - switch(len) - { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; - h *= m; - }; - - // Do a few final mixes of the hash to ensure the last few - // bytes are well-incorporated. - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; -} diff --git a/bloom/murmur2/README b/bloom/murmur2/README deleted file mode 100644 index ce24d71..0000000 --- a/bloom/murmur2/README +++ /dev/null @@ -1,9 +0,0 @@ - -MurmurHash2.c is taken from - -http://sites.google.com/site/murmurhash/ - -According to the above document: - - All code is released to the public domain. For business purposes, - Murmurhash is under the MIT license. diff --git a/bloom/murmur2/murmurhash2.h b/bloom/murmur2/murmurhash2.h deleted file mode 100644 index e607381..0000000 --- a/bloom/murmur2/murmurhash2.h +++ /dev/null @@ -1,7 +0,0 @@ - -#ifndef _BLOOM_MURMURHASH2 -#define _BLOOM_MURMURHASH2 - -unsigned int murmurhash2(const void * key, int len, const unsigned int seed); - -#endif diff --git a/keyhunt.c b/keyhunt.c index 5fccbf8..cfdb402 100644 --- a/keyhunt.c +++ b/keyhunt.c @@ -12,6 +12,7 @@ email: alberto.bsd@gmail.com #include #include #include +#include #include "base58/libbase58.h" #include "rmd160/rmd160.h" #include "sha256/sha256.h" @@ -55,7 +56,14 @@ struct tothread { char *rpt; //rng per thread }; -const char *version = "0.1.20210322"; +struct bPload { + uint64_t from; + uint64_t to; + uint64_t counter; +}; + + +const char *version = "0.1.20210328"; const char *EC_constant_N = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; const char *EC_constant_P = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"; const char *EC_constant_Gx = "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"; @@ -67,6 +75,7 @@ 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); int searchbinary(char *BUFFER,char *data,int length,int _N); +void sleep_ms(int milliseconds); void _sort(char *arr,int N); void _insertionsort(char *arr, int n); @@ -89,16 +98,18 @@ int bsgs_searchbinary(struct bsgs_xvalue *arr,char *data,int64_t _N,uint64_t *r_ int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct Point *target,mpz_t *private); void *thread_process(void *vargp); - void *thread_process_bsgs(void *vargp); void *thread_process_bsgs_random(void *vargp); +void *thread_bPload(void *vargp); +void *thread_bPloadFile(void *vargp); + void init_doublingG(struct Point *P); char *publickeytohashrmd160(char *pkey,int length); char *pubkeytopubaddress(char *pkey,int length); //char *pubkeytopubaddress_eth(char *pkey,int length); - +int THREADOUTPUT = 0; char *bit_range_str_min; char *bit_range_str_max; @@ -166,7 +177,7 @@ struct bloom bloom_bP[256]; uint64_t bloom_bP_totalbytes = 0; struct bloom bloom_bPx; struct bloom bloom_bPx2nd; //Second Bloom filter check - +char *precalculated_p_filename; uint64_t bsgs_m; uint64_t bsgs_m2; @@ -194,19 +205,20 @@ mpz_t n_range_diff; mpz_t n_range_aux; int main(int argc, char **argv) { + char buffer[1024]; char temporal[65]; char rawvalue[32]; struct tothread *tt; //tothread Tokenizer t,tokenizerbsgs; //tokenizer - char *filename,*precalculated_p_filename,*precalculated_mp_filename; + char *filename,*precalculated_mp_filename; FILE *fd; char *hextemp,*aux,*aux2,*pointx_str,*pointy_str; - uint64_t i; - uint64_t j; + uint64_t i,seconds; + uint64_t j,total_precalculated,PERTHREAD,BASE,PERTHREAD_R; int readed,s,continue_flag,check_flag,r,lenaux,lendiff; mpz_t total,pretotal,debugcount_mpz,Ysquared,mpz_aux,mpz_aux2; clock_t c_beging,c_ending, time_spent; - uint32_t seconds = 0; + struct bPload *temp; int c; gmp_randinit_mt(state); @@ -218,7 +230,7 @@ int main(int argc, char **argv) { mpz_init_set_str(G.y , EC_constant_Gy, 16); init_doublingG(&G); mpz_init_set_ui(TWO,2); - + while ((c = getopt(argc, argv, "dehqRwb:c:f:g:k:l:m:n:p:r:s:t:v:-:")) != -1) { switch(c) { @@ -261,8 +273,6 @@ int main(int argc, char **argv) { bitrange = strtol(optarg,NULL,10); if(bitrange > 0 && bitrange <=256 ) { mpz_init(MPZAUX); - /*Buscar bit_range_str_min and bit_range_str_max*/ - mpz_pow_ui(MPZAUX,TWO,bitrange-1); bit_range_str_min = mpz_get_str(NULL,16,MPZAUX); mpz_pow_ui(MPZAUX,TWO,bitrange); @@ -326,7 +336,7 @@ int main(int argc, char **argv) { } printf("[+] Setting k factor to %i\n",KFACTOR); break; - + case 'l': switch(indexOf(optarg,publicsearch,3)) { case SEARCH_UNCOMPRESS: @@ -388,7 +398,7 @@ int main(int argc, char **argv) { printf("[+] Setting random mode.\n"); break; case 'r': - if(optarg != NULL) { + if(optarg != NULL) { stringtokenizer(optarg,&t); switch(t.n) { case 1: @@ -478,7 +488,7 @@ int main(int argc, char **argv) { mpz_init(n_range_start); mpz_init(n_range_end); mpz_init(n_range_diff); - + if(FLAGRANGE) { mpz_set_str(n_range_start,range_start,16); mpz_set_str(n_range_end,range_end,16); @@ -523,7 +533,7 @@ int main(int argc, char **argv) { } } } - + N =0; if(FLAGMODE != MODE_BSGS) { aux = malloc(1000); @@ -676,7 +686,7 @@ int main(int argc, char **argv) { if(hextemp == aux) { trim(aux," \t\n\r"); lenaux = strlen(aux); - + if(isValidHex(aux)) { switch(lenaux) { case 64: /*X value*/ @@ -696,7 +706,7 @@ int main(int argc, char **argv) { } break; case 130: /* Uncompress publickey length*/ - memset(temporal,0,65); + memset(temporal,0,65); memcpy(temporal,aux+2,64); if(hexs2bin(temporal,(unsigned char*)(DATABUFFER + (uint64_t)(i*MAXLENGTHADDRESS)))) { bloom_add(&bloom,(char*)( DATABUFFER + (uint64_t)(i*MAXLENGTHADDRESS)),MAXLENGTHADDRESS); @@ -705,7 +715,7 @@ int main(int argc, char **argv) { fprintf(stderr,"[E] error hexs2bin\n"); } break; - default: + default: if(lenaux < 64) { /*Some *GENIUS* scripts omit the zeros at the beginning og the hash that is OK, but the hexs2bin expect an even size strings */ memset(temporal,'0',64); temporal[64] = '\0'; @@ -1000,14 +1010,14 @@ int main(int argc, char **argv) { mpz_init(BSGS_R); mpz_init(BSGS_AUX); mpz_init(BSGS_M2); - + mpz_mul_ui(BSGS_M,BSGS_M,KFACTOR); - - + + mpz_cdiv_q_ui(BSGS_M2,BSGS_M,20); bsgs_m2 = mpz_get_ui(BSGS_M2); - - + + mpz_cdiv_q(BSGS_AUX,BSGS_N,BSGS_M); mpz_cdiv_r(BSGS_R,BSGS_N,BSGS_M); if(mpz_cmp_ui(BSGS_R,0) != 0 ) { @@ -1018,17 +1028,17 @@ int main(int argc, char **argv) { DEBUGCOUNT = (uint64_t)((uint64_t)bsgs_m * (uint64_t)bsgs_aux); printf("[+] Setting N up to %llu.\n",(long long unsigned int)DEBUGCOUNT); - + for(i=0; i< 256; i++) { if(((int)(bsgs_m/256)) > 1000) { if(bloom_init2(&bloom_bP[i],(int)(bsgs_m/256),0.000001) == 1){ - fprintf(stderr,"[E] error bloom_init [%i]\n",i); + fprintf(stderr,"[E] error bloom_init [%"PRIu64"]\n",i); exit(0); } } else { if(bloom_init2(&bloom_bP[i],1000,0.000001) == 1){ - fprintf(stderr,"[E] error bloom_init for 1000 elements [%i]\n",i); + fprintf(stderr,"[E] error bloom_init for 1000 elements [%"PRIu64"]\n",i); exit(0); } } @@ -1036,10 +1046,7 @@ int main(int argc, char **argv) { if(FLAGDEBUG) bloom_print(&bloom_bP[i]); } printf("[+] Init 1st bloom filter for %lu elements : %.2f MB\n",bsgs_m,(float)((uint64_t)bloom_bP_totalbytes/(uint64_t)1048576)); - - - - + if(bsgs_m2 > 1000) { if(bloom_init2(&bloom_bPx2nd,bsgs_m2,0.000001) == 1){ fprintf(stderr,"[E] error bloom_init for %lu elements\n",bsgs_m2); @@ -1053,27 +1060,27 @@ 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,(float)((uint64_t)bloom_bPx2nd.bytes/(uint64_t)1048576)); + printf("[+] Init 2nd bloom filter for %lu elements : %.2f MB\n",bsgs_m2,(double)((double)bloom_bPx2nd.bytes/(double)1048576)); //bloom_print(&bloom_bPx2nd); Scalar_Multiplication(G,&BSGS_MP,BSGS_M); Scalar_Multiplication(G,&BSGS_MP2,BSGS_M2); - printf("[+] Allocating %.1f MB for %llu aMP Points\n",(float)(((uint64_t)(bsgs_aux*sizeof(struct Point)))/(uint64_t)1048576),bsgs_aux); + printf("[+] Allocating %.1f MB for %"PRIu64" aMP Points\n",(double)(((double)(bsgs_aux*sizeof(struct Point)))/(double)1048576),bsgs_aux); i = 0; BSGS_AMP = malloc((uint64_t)((uint64_t)bsgs_aux*(uint64_t)sizeof(struct Point))); if(BSGS_AMP == NULL) { printf("[E] error malloc()\n"); exit(0); } - + //printf("[+] Allocating %.1f MB for aMP Points (2nd)\n",(float)(((uint64_t)(bsgs_m2*sizeof(struct Point)))/(uint64_t)1048576)); BSGS_AMP2 = malloc((uint64_t)((uint64_t)bsgs_m2*(uint64_t)sizeof(struct Point))); if(BSGS_AMP2 == NULL) { printf("[E] error malloc()\n"); exit(0); } - + i= 0; if(FLAGPRECALCUTED_MP_FILE) { printf("[+] Reading aMP points from file %s\n",precalculated_mp_filename); @@ -1111,7 +1118,7 @@ int main(int argc, char **argv) { } } else { - printf("[+] Precalculating %lu aMP points\n",bsgs_aux); + printf("[+] Precalculating %"PRIu64" aMP points\n",bsgs_aux); mpz_set(point_temp.x,BSGS_MP.x); mpz_set(point_temp.y,BSGS_MP.y); for(i = 0; i < bsgs_aux; i++) { @@ -1123,7 +1130,7 @@ int main(int argc, char **argv) { mpz_set(point_temp.y,point_temp2.y); } } - + //printf("[+] Precalculating 20 aMP points (2nd)\n"); mpz_set(point_temp.x,BSGS_MP2.x); mpz_set(point_temp.y,BSGS_MP2.y); @@ -1135,7 +1142,7 @@ int main(int argc, char **argv) { mpz_set(point_temp.x,point_temp2.x); mpz_set(point_temp.y,point_temp2.y); } - printf("[+] Allocating %.2f MB for %llu bP Points\n",(float)((uint64_t)((uint64_t)bsgs_m2*(uint64_t)sizeof(struct bsgs_xvalue))/(uint64_t)1048576),bsgs_m2); + 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 = calloc(bsgs_m2,sizeof(struct bsgs_xvalue)); if(bPtable == NULL) { @@ -1144,77 +1151,63 @@ int main(int argc, char **argv) { } i = 0; j = 0; - + BASE = 0; + PERTHREAD = bsgs_m /NTHREADS; + PERTHREAD_R = bsgs_m % NTHREADS; + temp = calloc(NTHREADS,sizeof(struct bPload)); + tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t)); + if(FLAGPRECALCUTED_P_FILE) { printf("[+] Reading %lu bP points from file %s\n",bsgs_m,precalculated_p_filename); - fd = fopen(precalculated_p_filename,"rb"); - if(fd != NULL) { - while(!feof(fd) && i < bsgs_m ) { - if(fread(rawvalue,1,32,fd) == 32) { - if(i < bsgs_m2) { - memcpy(bPtable[i].value,rawvalue,BSGS_XVALUE_RAM); - bPtable[i].index = j; - bloom_add(&bloom_bPx2nd, rawvalue, BSGS_BUFFERXPOINTLENGTH); - } - //printf("Valor %i\n",((unsigned char)rawvalue[0])); - bloom_add(&bloom_bP[((unsigned char)rawvalue[0])], rawvalue, BSGS_BUFFERXPOINTLENGTH); - - i++; - j++; - } + for(i = 0; i < NTHREADS; i++) { + temp[i].counter = 0; + if(i < NTHREADS -1) { + temp[i].from = BASE +1; + temp[i].to = BASE + PERTHREAD; } - if(i < bsgs_m) { //If the input file have less item than bsgs_m - printf("[+] Fixme, file contains less items than the amount of items needed\n"); - exit(0); + else { + temp[i].from = BASE + 1; + temp[i].to = BASE + PERTHREAD + PERTHREAD_R; } - } - else { - fprintf(stderr,"[E] Can't open file %s falling back to the calculation mode\n",precalculated_p_filename); - printf("[+] Precalculating %lu bP points\n",bsgs_m); - do { - mpz_set(point_temp.x,BSGS_P.x); - mpz_set(point_temp.y,BSGS_P.y); - gmp_sprintf(temporal,"%0.64Zx",BSGS_P.x); - hexs2bin(temporal,(unsigned char*)rawvalue); - if(i 0) { mpz_fdiv_q_ui(pretotal,total,seconds); pthread_mutex_lock(&bsgs_thread); - gmp_printf("Total %Zu keys in %llu seconds: %Zu keys/s\n",total,seconds,pretotal); + if(THREADOUTPUT == 1) { + gmp_sprintf(buffer,"\nTotal %Zu keys in %"PRIu64 " seconds: %Zu keys/s\r",total,seconds,pretotal); + } + else { + gmp_sprintf(buffer,"\rTotal %Zu keys in %"PRIu64" seconds: %Zu keys/s\r",total,seconds,pretotal); + } + printf("%s",buffer); + fflush(stdout); + THREADOUTPUT = 0; pthread_mutex_unlock(&bsgs_thread); } } } - /* - c_ending = clock(); - time_spent = (double)(c_ending-c_beging) / CLOCKS_PER_SEC; - printf("[I] Time wasted %f seconds\n",time_spent); - */ }while(continue_flag); + + } void Point_Doubling(struct Point *P, struct Point *R) { @@ -1565,10 +1564,10 @@ void *thread_process(void *vargp) { } if(continue_flag) { if(FLAGQUIET == 0){ - hextemp = malloc(65); - gmp_sprintf(hextemp,"%0.64Zx",key_mpz); - printf("Thread %i : Setting up base key: %s\n",thread_number,hextemp); - free(hextemp); + gmp_sprintf(hexstrpoint,"%0.64Zx",key_mpz); + printf("\rThread %i : Setting up base key: %s",thread_number,hexstrpoint); + fflush(stdout); + THREADOUTPUT = 1; } Scalar_Multiplication(G, &R, key_mpz); count = 0; @@ -1656,7 +1655,7 @@ void *thread_process(void *vargp) { } free(public_address_compressed); } - + if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){ r = bloom_check(&bloom,public_address_uncompressed,MAXLENGTHADDRESS); if(r) { @@ -1679,7 +1678,7 @@ void *thread_process(void *vargp) { } } free(public_address_uncompressed); - } + } if( (FLAGCRYPTO & CRYPTO_ETH) != 0) { /* mpz_export((public_key_uncompressed+1),&longtemp,1,8,1,0,R.x); @@ -1722,7 +1721,7 @@ void *thread_process(void *vargp) { publickeyhashrmd160_uncompress = publickeytohashrmd160(public_key_uncompressed,65); break; } - + if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){ r = bloom_check(&bloom,publickeyhashrmd160_compress,MAXLENGTHADDRESS); if(r) { @@ -2147,7 +2146,9 @@ void *thread_process_bsgs(void *vargp) { //gmp_printf("While cycle: base_key : %Zd < n_range_end: %Zd\n",base_key,n_range_end); if(FLAGQUIET == 0){ gmp_sprintf(xpoint_str,"%0.64Zx",base_key); - printf("[+] Thread %i: %s\n",thread_number,xpoint_str); + printf("\r[+] Thread %i: %s",thread_number,xpoint_str); + fflush(stdout); + THREADOUTPUT = 1; } /* Set base_point in to base_key * G @@ -2171,7 +2172,7 @@ void *thread_process_bsgs(void *vargp) { Point_Addition(&OriginalPointsBSGS[k],&point_aux,&BSGS_Q); mpz_set(BSGS_S.x,BSGS_Q.x); mpz_set(BSGS_S.y,BSGS_Q.y); - + do { /* We need to test individually every point in BSGS_Q */ /*Extract BSGS_S.x into xpoint_str*/ @@ -2187,10 +2188,10 @@ void *thread_process_bsgs(void *vargp) { /* 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,&OriginalPointsBSGS[k],&keyfound); - + if(r) { gmp_sprintf(xpoint_str,"%0.64Zx",keyfound); - printf("[+] Thread %i Key found privkey %s\n",thread_number,xpoint_str); + printf("\n[+] Thread %i Key found privkey %s\n",thread_number,xpoint_str); Scalar_Multiplication(G,&point_aux2,keyfound); gmp_sprintf(pubkey,"04%0.64Zx%0.64Zx",point_aux2.x,point_aux2.y); printf("[+] Publickey %s\n",pubkey); @@ -2224,10 +2225,10 @@ void *thread_process_bsgs(void *vargp) { mpz_set(base_key,BSGS_CURRENT); mpz_add(BSGS_CURRENT,BSGS_CURRENT,BSGS_N); pthread_mutex_unlock(&bsgs_thread); - if(FLAGDEBUG ) printf("%u of %llu\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number)); + if(FLAGDEBUG ) printf("%u of %"PRIu64"\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number)); bloom_counter = 0; } - + mpz_clear(BSGS_Q.x); mpz_clear(BSGS_Q.y); mpz_clear(BSGS_S.x); @@ -2299,7 +2300,9 @@ void *thread_process_bsgs_random(void *vargp) { //gmp_printf("While cycle: base_key : %Zd < n_range_end: %Zd\n",base_key,n_range_end); if(FLAGQUIET == 0){ gmp_sprintf(xpoint_str,"%0.64Zx",base_key); - printf("[+] Thread %i: %s\n",thread_number,xpoint_str); + printf("\r[+] Thread %i: %s",thread_number,xpoint_str); + fflush(stdout); + THREADOUTPUT = 1; } /* Set base_point in to base_key * G @@ -2331,13 +2334,11 @@ void *thread_process_bsgs_random(void *vargp) { 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,&OriginalPointsBSGS[k],&keyfound); if(r) { gmp_sprintf(xpoint_str,"%0.64Zx",keyfound); - printf("[+] Thread %i Key found privkey %s\n",thread_number,xpoint_str); + printf("\n[+] Thread %i Key found privkey %s\n",thread_number,xpoint_str); Scalar_Multiplication(G,&point_aux2,keyfound); gmp_sprintf(pubkey,"04%0.64Zx%0.64Zx",point_aux2.x,point_aux2.y); printf("[+] Publickey %s\n",pubkey); @@ -2371,14 +2372,14 @@ void *thread_process_bsgs_random(void *vargp) { mpz_urandomm (n_range_random,state,n_range_diff); mpz_add(base_key,n_range_start,n_range_random); pthread_mutex_unlock(&bsgs_thread); - if(FLAGDEBUG ) printf("%u of %llu\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number)); + if(FLAGDEBUG ) printf("%u of %"PRIu64"\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number)); bloom_counter = 0; } mpz_clear(BSGS_Q.x); mpz_clear(BSGS_Q.y); mpz_clear(BSGS_S.x); mpz_clear(BSGS_S.y); - + mpz_clear(base_key); mpz_clear(keyfound); mpz_clear(base_point.x); @@ -2404,7 +2405,7 @@ int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct Point *target,mpz_t *pr struct Point base_point,point_aux; struct Point BSGS_Q, BSGS_S,BSGS_Q_AMP; char pubkey[131],xpoint_str[65],xpoint_raw[32]; - + mpz_init(base_key); mpz_init(base_point.x); mpz_init(base_point.y); @@ -2416,18 +2417,18 @@ int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct Point *target,mpz_t *pr mpz_init(BSGS_Q_AMP.x); mpz_init(point_aux.y); mpz_init(point_aux.x); - - + + mpz_mul_ui(base_key,BSGS_M,a); mpz_add(base_key,base_key,start_range); - + Scalar_Multiplication(G,&base_point,base_key); Point_Negation(&base_point,&point_aux); Point_Addition(target,&point_aux,&BSGS_S); - + mpz_set(BSGS_Q.x,BSGS_S.x); mpz_set(BSGS_Q.y,BSGS_S.y); - + //gmp_printf("bsgs_secondcheck\nBase key %0.64Zx\nM2 %Zu\n",base_key,BSGS_M2); do { gmp_sprintf(xpoint_str,"%0.64Zx",BSGS_S.x); @@ -2478,7 +2479,100 @@ int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct Point *target,mpz_t *pr mpz_clear(BSGS_Q_AMP.x); mpz_clear(point_aux.y); mpz_clear(point_aux.x); - return found; } +void *thread_bPload(void *vargp) { + char hexvalue[65],rawvalue[32]; + struct bPload *tt; + struct Point P,temp; + mpz_t base; + uint32_t j; + uint64_t i; + tt = (struct bPload *)vargp; + mpz_init(base); + mpz_init(P.x); + mpz_init(P.y); + mpz_init(temp.x); + mpz_init(temp.y); + mpz_set_ui(base,tt->from); + Scalar_Multiplication(G,&P,base); + i = tt->from -1; + j = tt->from -1; + do { + mpz_set(temp.x,P.x); + mpz_set(temp.y,P.y); + gmp_sprintf(hexvalue,"%0.64Zx",P.x); + hexs2bin(hexvalue,(unsigned char*) rawvalue ); + if(i < bsgs_m2) { + memcpy(bPtable[j].value,rawvalue,BSGS_XVALUE_RAM); + bPtable[j].index = j; + bloom_add(&bloom_bPx2nd, rawvalue, BSGS_BUFFERXPOINTLENGTH); + j++; + } + bloom_add(&bloom_bP[((uint8_t)rawvalue[0])], rawvalue ,BSGS_BUFFERXPOINTLENGTH); + Point_Addition(&G,&temp,&P); + i++; + tt->counter++; + } while( i < tt->to ); + mpz_clear(base); + mpz_clear(P.x); + mpz_clear(P.y); + mpz_clear(temp.x); + mpz_clear(temp.y); + pthread_exit(NULL); +} + +void *thread_bPloadFile(void *vargp) { + FILE *fd; + char rawvalue[32]; + struct bPload *tt; + + uint32_t j; + uint64_t i; + tt = (struct bPload *)vargp; + fd = fopen(precalculated_p_filename,"rb"); + if(fd == NULL) { + fprintf(stderr,"Can't open file\n"); + exit(0); + } + i = tt->from -1; + j = tt->from -1; + if(fseek(fd,i*32,SEEK_SET) != 0) { + fprintf(stderr,"Can't seek the file\n"); + exit(0); + } + do { + if(fread(rawvalue,1,32,fd) == 32) { + if(i < bsgs_m2) { + memcpy(bPtable[j].value,rawvalue,BSGS_XVALUE_RAM); + bPtable[j].index = j; + bloom_add(&bloom_bPx2nd, rawvalue, BSGS_BUFFERXPOINTLENGTH); + j++; + } + bloom_add(&bloom_bP[((uint8_t)rawvalue[0])], rawvalue ,BSGS_BUFFERXPOINTLENGTH); + i++; + tt->counter++; + } + else { + fprintf(stderr,"Can't read the file seen you have less items that the amount needed\n"); + exit(0); + } + } while( i < tt->to ); + pthread_exit(NULL); +} + +void sleep_ms(int milliseconds) { // cross-platform sleep function +#ifdef WIN32 + Sleep(milliseconds); +#elif _POSIX_C_SOURCE >= 199309L + struct timespec ts; + ts.tv_sec = milliseconds / 1000; + ts.tv_nsec = (milliseconds % 1000) * 1000000; + nanosleep(&ts, NULL); +#else + if (milliseconds >= 1000) + sleep(milliseconds / 1000); + usleep((milliseconds % 1000) * 1000); +#endif +} diff --git a/tests/1to32.rmd b/tests/1to32.rmd new file mode 100644 index 0000000..d6ff43c --- /dev/null +++ b/tests/1to32.rmd @@ -0,0 +1,33 @@ +751e76e8199196d454941c45d1b3a323f1433bd6 +7dd65592d0ab2fe0d0257d571abf032cd9db93dc +5dedfbf9ea599dd4e3ca6a80b333c472fd0b3f69 +9652d86bedf43ad264362e6e6eba6eb764508127 +8f9dff39a81ee4abcbad2ad8bafff090415a2be8 +f93ec34e9e34a8f8ff7d600cdad83047b1bcb45c +e2192e8a7dd8dd1c88321959b477968b941aa973 +dce76b2613052ea012204404a97b3c25eac31715 +7d0f6c64afb419bbd7e971e943d7404b0e0daab4 +d7729816650e581d7462d52ad6f732da0e2ec93b +f8c698da3164ef8fa4258692d118cc9a902c5acc +85a1f9ba4da24c24e582d9b891dacbd1b043f971 +f932d0188616c964416b91fb9cf76ba9790a921e +97f9281a1383879d72ac52a6a3e9e8b9a4a4f655 +fe7c45126731f7384640b0b0045fd40bac72e2a2 +7025b4efb3ff42eb4d6d71fab6b53b4f4967e3dd +b67cb6edeabc0c8b927c9ea327628e7aa63e2d52 +ad1e852b08eba53df306ec9daa8c643426953f94 +ebfbe6819fcdebab061732ce91df7d586a037dee +b907c3a2a3b27789dfb509b730dd47703c272868 +29a78213caa9eea824acf08022ab9dfc83414f56 +7ff45303774ef7a52fffd8011981034b258cb86b +d0a79df189fe1ad5c306cc70497b358415da579e +0959e80121f36aea13b3bad361c15dac26189e2f +2f396b29b27324300d0c59b17c3abc1835bd3dbb +bfebb73562d4541b32a02ba664d140b5a574792f +0c7aaf6caa7e5424b63d317f0f8f1f9fa40d5560 +1306b9e4ff56513a476841bac7ba48d69516b1da +5a416cc9148f4a377b672c8ae5d3287adaafadec +d39c4704664e1deb76c9331e637564c257d68a08 +d805f6f251f7479ebd853b3d0f4b9b2656d92f1d +9e42601eeaedc244e15f17375adb0e2cd08efdc9 + diff --git a/tests/1to32.txt b/tests/1to32.txt new file mode 100644 index 0000000..ba2ed89 --- /dev/null +++ b/tests/1to32.txt @@ -0,0 +1,33 @@ +1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH +1CUNEBjYrCn2y1SdiUMohaKUi4wpP326Lb +19ZewH8Kk1PDbSNdJ97FP4EiCjTRaZMZQA +1EhqbyUMvvs7BfL8goY6qcPbD6YKfPqb7e +1E6NuFjCi27W5zoXg8TRdcSRq84zJeBW3k +1PitScNLyp2HCygzadCh7FveTnfmpPbfp8 +1McVt1vMtCC7yn5b9wgX1833yCcLXzueeC +1M92tSqNmQLYw33fuBvjmeadirh1ysMBxK +1CQFwcjw1dwhtkVWBttNLDtqL7ivBonGPV +1LeBZP5QCwwgXRtmVUvTVrraqPUokyLHqe +1PgQVLmst3Z314JrQn5TNiys8Hc38TcXJu +1DBaumZxUkM4qMQRt2LVWyFJq5kDtSZQot +1Pie8JkxBT6MGPz9Nvi3fsPkr2D8q3GBc1 +1ErZWg5cFCe4Vw5BzgfzB74VNLaXEiEkhk +1QCbW9HWnwQWiQqVo5exhAnmfqKRrCRsvW +1BDyrQ6WoF8VN3g9SAS1iKZcPzFfnDVieY +1HduPEXZRdG26SUT5Yk83mLkPyjnZuJ7Bm +1GnNTmTVLZiqQfLbAdp9DVdicEnB5GoERE +1NWmZRpHH4XSPwsW6dsS3nrNWfL1yrJj4w +1HsMJxNiV7TLxmoF6uJNkydxPFDog4NQum +14oFNXucftsHiUMY8uctg6N487riuyXs4h +1CfZWK1QTQE3eS9qn61dQjV89KDjZzfNcv +1L2GM8eE7mJWLdo3HZS6su1832NX2txaac +1rSnXMr63jdCuegJFuidJqWxUPV7AtUf7 +15JhYXn6Mx3oF4Y7PcTAv2wVVAuCFFQNiP +1JVnST957hGztonaWK6FougdtjxzHzRMMg +128z5d7nN7PkCuX5qoA4Ys6pmxUYnEy86k +12jbtzBb54r97TCwW3G1gCFoumpckRAPdY +19EEC52krRUK1RkUAEZmQdjTyHT7Gp1TYT +1LHtnpd8nU5VHEMkG2TMYYNUjjLc992bps +1LhE6sCTuGae42Axu1L1ZB7L96yi9irEBE +1FRoHA9xewq7DjrZ1psWJVeTer8gHRqEvR +