multithread for generate or read bP points, see CHANGELOG

This commit is contained in:
AlbertoBSD
2021-03-29 05:01:58 +02:00
parent c056b4a554
commit 37920b0000
12 changed files with 756 additions and 443 deletions

6
.gitignore vendored
View File

@@ -2,11 +2,7 @@ bPfile
hexcharstoraw
*.bin
keyhunt
test_bloom.c
xpoints.c
heapsort.c
insertionsorttest.c
introsort.c
KEYFOUNDKEYFOUND.txt
# Prerequisites
*.d

View File

@@ -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

View File

@@ -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:

615
README.md
View File

@@ -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

View File

@@ -17,11 +17,11 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <inttypes.h>
#include <sys/types.h>
#include <unistd.h>
#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);

View File

@@ -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
#endif

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -1,7 +0,0 @@
#ifndef _BLOOM_MURMURHASH2
#define _BLOOM_MURMURHASH2
unsigned int murmurhash2(const void * key, int len, const unsigned int seed);
#endif

352
keyhunt.c
View File

@@ -12,6 +12,7 @@ email: alberto.bsd@gmail.com
#include <pthread.h>
#include <math.h>
#include <time.h>
#include <inttypes.h>
#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 <bsgs_m2) {
memcpy(bPtable[i].value,rawvalue,BSGS_XVALUE_RAM);
bPtable[i].index = j;
bloom_add(&bloom_bPx2nd, rawvalue, BSGS_BUFFERXPOINTLENGTH);
}
bloom_add(&bloom_bP[((unsigned char)rawvalue[0])], rawvalue,BSGS_BUFFERXPOINTLENGTH);
Point_Addition(&G,&point_temp,&BSGS_P);
i++;
j++;
} while( i < bsgs_m );
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 {
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 <bsgs_m2) {
memcpy(bPtable[i].value,rawvalue,BSGS_XVALUE_RAM);
bPtable[i].index = j;
bloom_add(&bloom_bPx2nd, rawvalue, BSGS_BUFFERXPOINTLENGTH);
for(i = 0; i < NTHREADS; i++) {
temp[i].counter = 0;
if(i < NTHREADS -1) {
temp[i].from = BASE +1;
temp[i].to = BASE + PERTHREAD;
}
bloom_add(&bloom_bP[((unsigned char)rawvalue[0])], rawvalue ,BSGS_BUFFERXPOINTLENGTH);
Point_Addition(&G,&point_temp,&BSGS_P);
i++;
j++;
} while( i < bsgs_m );
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_bPload,(void *)&temp[i]);
BASE+=PERTHREAD;
}
}
total_precalculated = 0;
do {
sleep_ms(100);
total_precalculated = 0;
for(i = 0; i < NTHREADS; i++) {
total_precalculated+=temp[i].counter;
}
printf("\r[+] processing %lu/%lu bP points : %i %%",total_precalculated,bsgs_m,(int) (((double)total_precalculated/(double)bsgs_m)*100));
} while(total_precalculated < bsgs_m);
for(i = 0; i < NTHREADS; i++) {
pthread_join(tid[i], NULL);
}
printf("\n");
free(temp);
free(tid);
printf("[+] Sorting %lu elements\n",bsgs_m2);
//c_beging = clock();
bsgs_sort(bPtable,bsgs_m2);
/*
c_ending = clock();
time_spent = (double)(c_ending-c_beging) / CLOCKS_PER_SEC;
printf("[+] Sorted %lu elements in %f seconds\n",bsgs_m2 ,time_spent);
*/
i = 0;
@@ -1262,6 +1255,7 @@ int main(int argc, char **argv) {
mpz_init(debugcount_mpz);
sprintf(temporal,"%llu",(long long unsigned int)DEBUGCOUNT);
mpz_set_str(debugcount_mpz,temporal,10);
seconds = 0;
do {
sleep(1);
//c_beging = clock();
@@ -1286,17 +1280,22 @@ int main(int argc, char **argv) {
if(mpz_cmp_ui(total,0) > 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
}

33
tests/1to32.rmd Normal file
View File

@@ -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

33
tests/1to32.txt Normal file
View File

@@ -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