mirror of
https://github.com/PurpleI2P/i2pd-tools
synced 2025-01-15 17:20:08 +00:00
Merge pull request #90 from wipedlifepotato/master
multiple search addresses (vain) + #80 add -latomic to routerinfo and famtool
This commit is contained in:
commit
99d0881c86
8
Makefile
8
Makefile
@ -12,7 +12,8 @@ INCFLAGS = -I$(LIBI2PD_PATH) -I$(LIBI2PD_CLIENT_PATH)
|
||||
DEFINES = -DOPENSSL_SUPPRESS_DEPRECATED
|
||||
|
||||
LDFLAGS =
|
||||
LDLIBS = $(I2PD_PATH)/$(I2PD_LIB) -lboost_system$(BOOST_SUFFIX) -lboost_date_time$(BOOST_SUFFIX) -lboost_filesystem$(BOOST_SUFFIX) -lboost_program_options$(BOOST_SUFFIX) -lssl -lcrypto -lz
|
||||
LDLIBS = $(I2PD_PATH)/$(I2PD_LIB) -lboost_system$(BOOST_SUFFIX) -lboost_date_time$(BOOST_SUFFIX) -lboost_filesystem$(BOOST_SUFFIX) -lboost_program_options$(BOOST_SUFFIX) -lssl -lcrypto -lz
|
||||
|
||||
|
||||
ifeq ($(UNAME),Linux)
|
||||
CXXFLAGS += -g
|
||||
@ -43,11 +44,12 @@ else
|
||||
LDFLAGS += -s -static
|
||||
endif
|
||||
|
||||
|
||||
all: $(I2PD_LIB) vain keygen keyinfo famtool routerinfo regaddr regaddr_3ld i2pbase64 offlinekeys b33address regaddralias x25519 verifyhost
|
||||
vain: vain.o $(I2PD_LIB)
|
||||
$(CXX) -o vain $(LDFLAGS) vain.o $(LDLIBS)
|
||||
routerinfo: routerinfo.o $(I2PD_LIB)
|
||||
$(CXX) -o routerinfo $(LDFLAGS) routerinfo.o $(LDLIBS)
|
||||
$(CXX) -o routerinfo $(LDFLAGS) routerinfo.o $(LDLIBS) -latomic
|
||||
|
||||
keygen: keygen.o $(I2PD_LIB)
|
||||
$(CXX) -o keygen $(DEFINES) $(LDFLAGS) keygen.o $(LDLIBS)
|
||||
@ -56,7 +58,7 @@ keyinfo: keyinfo.o $(I2PD_LIB)
|
||||
$(CXX) -o keyinfo $(DEFINES) $(LDFLAGS) keyinfo.o $(LDLIBS)
|
||||
|
||||
famtool: famtool.o $(I2PD_LIB)
|
||||
$(CXX) -o famtool $(DEFINES) $(LDFLAGS) famtool.o $(LDLIBS)
|
||||
$(CXX) -o famtool $(DEFINES) $(LDFLAGS) famtool.o $(LDLIBS) -latomic
|
||||
|
||||
regaddr: regaddr.o $(I2PD_LIB)
|
||||
$(CXX) -o regaddr $(DEFINES) $(LDFLAGS) regaddr.o $(LDLIBS)
|
||||
|
45
README.md
45
README.md
@ -79,6 +79,13 @@ or
|
||||
| RED25519-SHA512 | 11 |
|
||||
|
||||
For more information on the types of signatures, see the [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/tunnels/#signature-types).
|
||||
### vain
|
||||
|
||||
Vanity generation address.
|
||||
|
||||
#### Usage
|
||||
|
||||
./vain --usage
|
||||
|
||||
#### Time to Generate on a 2.70GHz Processor
|
||||
| characters| time to generate (approx.) |
|
||||
@ -143,3 +150,41 @@ Send output of auth_string to http://reg.i2p/add and http://stats.i2p/i2p/addkey
|
||||
### x25519
|
||||
|
||||
Generate key pair with output in base64 encoding. Now the x25519 keys are used for authentication with an encrypted LeaseSet.
|
||||
|
||||
### famtool
|
||||
[this is program for works with family of routers in i2p-network. ](https://i2pd.readthedocs.io/en/latest/user-guide/family/)
|
||||
|
||||
usage: ```./famtool [-h] [-v] [-g -n family -c family.crt -k family.pem] [-s -n family -k family.pem -i router.keys -f router.info] [-V -c family.crt -f router.info]```
|
||||
|
||||
generate a new family signing key for family called ``i2pfam''
|
||||
```./famtool -g -n i2pfam -c myfam.crt -k myfam.pem```
|
||||
|
||||
sign a router info with family signing key
|
||||
```./famtool -s -n i2pfam -k myfam.pem -i router.keys -f router.info```
|
||||
|
||||
verify signed router.info
|
||||
```./famtool -V -n i2pfam -c myfam.pem -f router.info```
|
||||
#### Example of usage
|
||||
$ ./famtool -g -n i2pfam -c myfam.crt -k myfam.pem
|
||||
family i2pfam made
|
||||
$ cat myfam.crt
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB3TCCAYOgAwIBAgIBADAKBggqhkjOPQQDAjB4MQswCQYDVQQGEwJYWDELMAkG
|
||||
A1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnltb3VzIE5l
|
||||
dHdvcmsxDzANBgNVBAsMBmZhbWlseTEeMBwGA1UEAwwVaTJwZmFtLmZhbWlseS5p
|
||||
MnAubmV0MB4XDTIzMDczMTE5MjQ1MFoXDTMzMDcyODE5MjQ1MFoweDELMAkGA1UE
|
||||
BhMCWFgxCzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDEeMBwGA1UECgwVSTJQIEFu
|
||||
b255bW91cyBOZXR3b3JrMQ8wDQYDVQQLDAZmYW1pbHkxHjAcBgNVBAMMFWkycGZh
|
||||
bS5mYW1pbHkuaTJwLm5ldDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLejNp1Y
|
||||
1tnMGFaUIuzNpNL8B9KvaeSSh+OWhRcHn2x1D8TPCVA4IMS0jiMIodCcdyTmz0Qg
|
||||
SXsWDqT2CbBMENQwCgYIKoZIzj0EAwIDSAAwRQIgU58CeHXlluPZNxpmxb7HSHsJ
|
||||
STCA8C946oas+8uLU+MCIQDe6Km/h8w+oCh+j6UHobN0EAVtQPQGwkq2XXs1jqX2
|
||||
bQ==
|
||||
-----END CERTIFICATE-----
|
||||
$ cat myfam.pem
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIAFA82vZzZN8nZIOVnadSS73G2NNc5pUsh4qmpK2M0nsoAoGCCqGSM49
|
||||
AwEHoUQDQgAEt6M2nVjW2cwYVpQi7M2k0vwH0q9p5JKH45aFFwefbHUPxM8JUDgg
|
||||
xLSOIwih0Jx3JObPRCBJexYOpPYJsEwQ1A==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
||||
|
@ -1,467 +0,0 @@
|
||||
#include "Crypto.h"
|
||||
#include "Identity.h"
|
||||
#include "I2PEndian.h"
|
||||
#include "common/key.hpp"
|
||||
|
||||
#include <regex>
|
||||
#include <mutex>
|
||||
#include <getopt.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// sha256
|
||||
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
|
||||
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
|
||||
#define SHR(x, n) (x >> n)
|
||||
#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
|
||||
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
|
||||
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
|
||||
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
|
||||
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
|
||||
|
||||
#define RND(a, b, c, d, e, f, g, h, k) \
|
||||
t0 = h + S1(e) + Ch(e, f, g) + k; \
|
||||
t1 = S0(a) + Maj(a, b, c); \
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
#define RNDr(S, W, i, k) \
|
||||
RND(S[(64 - i) % 8], S[(65 - i) % 8], \
|
||||
S[(66 - i) % 8], S[(67 - i) % 8], \
|
||||
S[(68 - i) % 8], S[(69 - i) % 8], \
|
||||
S[(70 - i) % 8], S[(71 - i) % 8], \
|
||||
W[i] + k)
|
||||
|
||||
#define DEF_OUTNAME "private.dat"
|
||||
|
||||
static bool found = false;
|
||||
static size_t MutateByte;
|
||||
static uint8_t * KeyBuf;
|
||||
|
||||
unsigned int count_cpu;
|
||||
|
||||
const uint8_t lastBlock[64] =
|
||||
{
|
||||
0x05, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x80, // 7 bytes EdDSA certificate
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x38 // 3128 bits (391 bytes)
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
bool reg = false;
|
||||
int threads = -1;
|
||||
i2p::data::SigningKeyType signature;
|
||||
std::string outputpath = "";
|
||||
std::regex regex;
|
||||
bool sig_type = true;
|
||||
} options;
|
||||
|
||||
void check_sig_type()
|
||||
{
|
||||
if (SigTypeToName(options.signature).find("unknown") != std::string::npos)
|
||||
{
|
||||
std::cerr << "Incorrect signature type" << std::endl;
|
||||
options.sig_type = false;
|
||||
}
|
||||
}
|
||||
|
||||
void inline CalculateW (const uint8_t block[64], uint32_t W[64])
|
||||
{
|
||||
/**
|
||||
* implementation of orignal
|
||||
*/
|
||||
for (int i = 0; i < 16; i++)
|
||||
#ifdef _WIN32
|
||||
W[i] = htobe32(((uint32_t *)(block))[i]);
|
||||
#else // from big endian to little endian ( swap )
|
||||
W[i] = be32toh(((uint32_t *)(block))[i]);
|
||||
#endif
|
||||
|
||||
for (int i = 16; i < 64; i++)
|
||||
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
void inline TransformBlock (uint32_t state[8], const uint32_t W[64])
|
||||
{
|
||||
/**
|
||||
* implementation of orignal
|
||||
*/
|
||||
uint32_t S[8];
|
||||
memcpy(S, state, 32);
|
||||
|
||||
uint32_t t0, t1;
|
||||
RNDr(S, W, 0, 0x428a2f98); RNDr(S, W, 1, 0x71374491); RNDr(S, W, 2, 0xb5c0fbcf); RNDr(S, W, 3, 0xe9b5dba5);
|
||||
RNDr(S, W, 4, 0x3956c25b); RNDr(S, W, 5, 0x59f111f1); RNDr(S, W, 6, 0x923f82a4); RNDr(S, W, 7, 0xab1c5ed5);
|
||||
RNDr(S, W, 8, 0xd807aa98); RNDr(S, W, 9, 0x12835b01); RNDr(S, W, 10, 0x243185be); RNDr(S, W, 11, 0x550c7dc3);
|
||||
RNDr(S, W, 12, 0x72be5d74); RNDr(S, W, 13, 0x80deb1fe); RNDr(S, W, 14, 0x9bdc06a7); RNDr(S, W, 15, 0xc19bf174);
|
||||
RNDr(S, W, 16, 0xe49b69c1); RNDr(S, W, 17, 0xefbe4786); RNDr(S, W, 18, 0x0fc19dc6); RNDr(S, W, 19, 0x240ca1cc);
|
||||
RNDr(S, W, 20, 0x2de92c6f); RNDr(S, W, 21, 0x4a7484aa); RNDr(S, W, 22, 0x5cb0a9dc); RNDr(S, W, 23, 0x76f988da);
|
||||
RNDr(S, W, 24, 0x983e5152); RNDr(S, W, 25, 0xa831c66d); RNDr(S, W, 26, 0xb00327c8); RNDr(S, W, 27, 0xbf597fc7);
|
||||
RNDr(S, W, 28, 0xc6e00bf3); RNDr(S, W, 29, 0xd5a79147); RNDr(S, W, 30, 0x06ca6351); RNDr(S, W, 31, 0x14292967);
|
||||
RNDr(S, W, 32, 0x27b70a85); RNDr(S, W, 33, 0x2e1b2138); RNDr(S, W, 34, 0x4d2c6dfc); RNDr(S, W, 35, 0x53380d13);
|
||||
RNDr(S, W, 36, 0x650a7354); RNDr(S, W, 37, 0x766a0abb); RNDr(S, W, 38, 0x81c2c92e); RNDr(S, W, 39, 0x92722c85);
|
||||
RNDr(S, W, 40, 0xa2bfe8a1); RNDr(S, W, 41, 0xa81a664b); RNDr(S, W, 42, 0xc24b8b70); RNDr(S, W, 43, 0xc76c51a3);
|
||||
RNDr(S, W, 44, 0xd192e819); RNDr(S, W, 45, 0xd6990624); RNDr(S, W, 46, 0xf40e3585); RNDr(S, W, 47, 0x106aa070);
|
||||
RNDr(S, W, 48, 0x19a4c116); RNDr(S, W, 49, 0x1e376c08); RNDr(S, W, 50, 0x2748774c); RNDr(S, W, 51, 0x34b0bcb5);
|
||||
RNDr(S, W, 52, 0x391c0cb3); RNDr(S, W, 53, 0x4ed8aa4a); RNDr(S, W, 54, 0x5b9cca4f); RNDr(S, W, 55, 0x682e6ff3);
|
||||
RNDr(S, W, 56, 0x748f82ee); RNDr(S, W, 57, 0x78a5636f); RNDr(S, W, 58, 0x84c87814); RNDr(S, W, 59, 0x8cc70208);
|
||||
RNDr(S, W, 60, 0x90befffa); RNDr(S, W, 61, 0xa4506ceb); RNDr(S, W, 62, 0xbef9a3f7); RNDr(S, W, 63, 0xc67178f2);
|
||||
|
||||
for (int i = 0; i < 8; i++) state[i] += S[i];
|
||||
}
|
||||
|
||||
void inline HashNextBlock (uint32_t state[8], const uint8_t * block)
|
||||
{
|
||||
/**
|
||||
* implementation of orignal
|
||||
*/
|
||||
uint32_t W[64];
|
||||
CalculateW (block, W);
|
||||
TransformBlock (state, W);
|
||||
}
|
||||
|
||||
bool check_prefix(const char * buf)
|
||||
{
|
||||
unsigned short size_str = 0;
|
||||
while(*buf)
|
||||
{
|
||||
if(!((*buf > 49 && *buf < 56) || (*buf > 96 && *buf < 123)) || size_str > 52)
|
||||
return false;
|
||||
size_str++;
|
||||
buf++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen)
|
||||
{
|
||||
size_t ret = 0, pos = 1;
|
||||
int bits = 8, tmp = inBuf[0];
|
||||
while (ret < outLen && (bits > 0 || pos < len))
|
||||
{
|
||||
if (bits < 5)
|
||||
{
|
||||
if (pos < len)
|
||||
{
|
||||
tmp <<= 8;
|
||||
tmp |= inBuf[pos] & 0xFF;
|
||||
pos++;
|
||||
bits += 8;
|
||||
}
|
||||
else // last byte
|
||||
{
|
||||
tmp <<= (5 - bits);
|
||||
bits = 5;
|
||||
}
|
||||
}
|
||||
|
||||
bits -= 5;
|
||||
int ind = (tmp >> bits) & 0x1F;
|
||||
outBuf[ret] = (ind < 26) ? (ind + 'a') : ((ind - 26) + '2');
|
||||
ret++;
|
||||
}
|
||||
outBuf[ret]='\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool NotThat(const char * what, const std::regex & reg){
|
||||
return std::regex_match(what,reg) == 1 ? false : true;
|
||||
}
|
||||
|
||||
inline bool NotThat(const char * a, const char *b)
|
||||
{
|
||||
while(*b)
|
||||
if(*a++!=*b++)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void processFlipper(const std::string string)
|
||||
{
|
||||
constexpr char SYMBOLS[] {'-', '\\', '|', '/'};
|
||||
uint8_t symbol_counter = 0;
|
||||
std::string payload = string;
|
||||
if (payload.back() != ' ') payload += ' ';
|
||||
|
||||
size_t current_state = payload.size();
|
||||
enum { left, right } direction = left;
|
||||
|
||||
std::cout << payload << SYMBOLS[symbol_counter++];
|
||||
while (!found)
|
||||
{
|
||||
std::cout << '\b' << SYMBOLS[symbol_counter++];
|
||||
std::cout.flush();
|
||||
|
||||
if (symbol_counter == sizeof(SYMBOLS))
|
||||
{
|
||||
if (direction == left)
|
||||
{
|
||||
std::cout << '\b';
|
||||
std::cout.flush();
|
||||
symbol_counter = 0;
|
||||
if (!--current_state)
|
||||
{
|
||||
direction = right;
|
||||
}
|
||||
}
|
||||
else if (direction == right)
|
||||
{
|
||||
std::cout << '\b' << payload[current_state] << " ";
|
||||
std::cout.flush();
|
||||
symbol_counter = 0;
|
||||
|
||||
if (++current_state == payload.size())
|
||||
{
|
||||
direction = left;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(80));
|
||||
}
|
||||
}
|
||||
|
||||
bool thread_find(uint8_t * buf, const char * prefix, int id_thread, unsigned long long throughput)
|
||||
{
|
||||
const unsigned long long original_throughput = throughput;
|
||||
uint8_t b[391];
|
||||
uint32_t hash[8];
|
||||
|
||||
memcpy (b, buf, 391);
|
||||
|
||||
size_t len = 52;
|
||||
|
||||
if (!options.reg)
|
||||
len = strlen(prefix);
|
||||
|
||||
// precalculate first 5 blocks (320 bytes)
|
||||
uint32_t state[8] = { 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
|
||||
HashNextBlock (state, b);
|
||||
HashNextBlock (state, b + 64);
|
||||
HashNextBlock (state, b + 128);
|
||||
HashNextBlock (state, b + 192);
|
||||
HashNextBlock (state, b + 256);
|
||||
|
||||
// pre-calculate last W
|
||||
uint32_t lastW[64];
|
||||
CalculateW (lastBlock, lastW);
|
||||
|
||||
uint32_t * nonce = (uint32_t *)(b+320);
|
||||
(*nonce) += id_thread*throughput;
|
||||
|
||||
char addr[53];
|
||||
uint32_t state1[8];
|
||||
|
||||
while(!found)
|
||||
{
|
||||
if (! throughput--)
|
||||
{
|
||||
throughput = original_throughput;
|
||||
}
|
||||
|
||||
memcpy (state1, state, 32);
|
||||
// calculate hash of block with nonce
|
||||
HashNextBlock (state1, b + 320);
|
||||
// apply last block
|
||||
TransformBlock (state1, lastW);
|
||||
// get final hash
|
||||
for (int j = 8; j--;)
|
||||
hash[j] = htobe32(state1[j]);
|
||||
ByteStreamToBase32 ((uint8_t*)hash, 32, addr, len);
|
||||
|
||||
if( options.reg ? !NotThat(addr, options.regex) : !NotThat(addr, prefix) )
|
||||
{
|
||||
ByteStreamToBase32 ((uint8_t*)hash, 32, addr, 52);
|
||||
std::cout << "\nFound address: " << addr << std::endl;
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
(*nonce)++;
|
||||
if (found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void usage(void){
|
||||
const constexpr char * help="Usage:\n"
|
||||
" vain [text-pattern|regex-pattern] [options]\n\n"
|
||||
"OPTIONS:\n"
|
||||
" -h --help show this help (same as --usage)\n"
|
||||
" -r --reg use regexp instead of simple text pattern, ex.: vain '(one|two).*' -r\n"
|
||||
" -t --threads number of threads to use (default: one per processor)\n"
|
||||
// " -s --signature (signature type)\n" // NOT IMPLEMENTED FUCKING PLAZ!
|
||||
" -o --output privkey output file name (default: ./" DEF_OUTNAME ")\n"
|
||||
"";
|
||||
puts(help);
|
||||
}
|
||||
|
||||
void parsing(int argc, char ** args){
|
||||
int option_index;
|
||||
static struct option long_options[]={
|
||||
{"help",no_argument,0,'h'},
|
||||
{"reg", no_argument,0,'r'},
|
||||
{"threads", required_argument, 0, 't'},
|
||||
{"signature", required_argument,0,'s'},
|
||||
{"output", required_argument,0,'o'},
|
||||
{"usage", no_argument,0,0},
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
int c;
|
||||
while( (c=getopt_long(argc,args, "hrt:s:o:", long_options, &option_index))!=-1){
|
||||
switch(c){
|
||||
case 0:
|
||||
if ( std::string(long_options[option_index].name) == std::string("usage") ){
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
case 'h':
|
||||
usage();
|
||||
exit(0);
|
||||
break;
|
||||
case 'r':
|
||||
options.reg=true;
|
||||
break;
|
||||
case 't':
|
||||
options.threads=atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
options.signature = NameToSigType(std::string(optarg));
|
||||
check_sig_type();
|
||||
break;
|
||||
case 'o':
|
||||
options.outputpath=optarg;
|
||||
break;
|
||||
case '?':
|
||||
std::cerr << "Undefined argument" << std::endl;
|
||||
default:
|
||||
std::cerr << args[0] << " --usage / --help" << std::endl;
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char * argv[])
|
||||
{
|
||||
if ( argc < 2 )
|
||||
{
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
parsing( argc > 2 ? argc-1 : argc, argc > 2 ? argv+1 : argv);
|
||||
//
|
||||
if(!options.reg && !check_prefix( argv[1] ))
|
||||
{
|
||||
std::cout << "Invalid pattern." << std::endl;
|
||||
usage();
|
||||
return 1;
|
||||
}else{
|
||||
options.regex=std::regex(argv[1]);
|
||||
}
|
||||
|
||||
i2p::crypto::InitCrypto (false, true, true, false);
|
||||
options.signature = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519;
|
||||
|
||||
if(options.signature != i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
|
||||
{
|
||||
std::cout << "ED25519-SHA512 are currently the only signing keys supported." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!options.sig_type) return -2;
|
||||
auto keys = i2p::data::PrivateKeys::CreateRandomKeys (options.signature);
|
||||
switch(options.signature)
|
||||
{
|
||||
case i2p::data::SIGNING_KEY_TYPE_DSA_SHA1:
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||
case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
std::cout << "Sorry, selected signature type is not supported for address generation." << std::endl;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO: for other types.
|
||||
switch(options.signature)
|
||||
{
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
MutateByte=320;
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
break;
|
||||
}
|
||||
|
||||
KeyBuf = new uint8_t[keys.GetFullLen()];
|
||||
keys.ToBuffer (KeyBuf, keys.GetFullLen ());
|
||||
|
||||
if(options.threads <= 0)
|
||||
{
|
||||
options.threads = std::thread::hardware_concurrency();
|
||||
}
|
||||
|
||||
std::cout << "Vanity generator started in " << options.threads << " threads" << std::endl;
|
||||
|
||||
std::vector<std::thread> threads(options.threads);
|
||||
unsigned long long thoughtput = 0x4F4B5A37;
|
||||
|
||||
for (unsigned int j = options.threads; j--; )
|
||||
{
|
||||
threads[j] = std::thread(thread_find, KeyBuf, argv[1], j, thoughtput);
|
||||
thoughtput += 1000;
|
||||
}
|
||||
|
||||
processFlipper(argv[1]);
|
||||
|
||||
for (unsigned int j = 0; j < (unsigned int)options.threads;j++)
|
||||
threads[j].join();
|
||||
|
||||
if(options.outputpath.empty()) options.outputpath.assign(DEF_OUTNAME);
|
||||
|
||||
std::ofstream f (options.outputpath, std::ofstream::binary);
|
||||
if (f)
|
||||
{
|
||||
f.write ((char *)KeyBuf, keys.GetFullLen ());
|
||||
delete [] KeyBuf;
|
||||
}
|
||||
else
|
||||
std::cout << "Can't create output file: " << options.outputpath << std::endl;
|
||||
|
||||
i2p::crypto::TerminateCrypto ();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,417 +0,0 @@
|
||||
#include "vanity.hpp"
|
||||
#include<regex>
|
||||
#include<getopt.h>
|
||||
|
||||
|
||||
static struct{
|
||||
bool reg=false;
|
||||
int threads=-1;
|
||||
i2p::data::SigningKeyType signature;
|
||||
std::string outputpath="";
|
||||
std::regex regex;
|
||||
|
||||
}options;
|
||||
|
||||
|
||||
static void inline CalculateW (const uint8_t block[64], uint32_t W[64])
|
||||
{
|
||||
/*
|
||||
implementation of orignal
|
||||
*/
|
||||
for (int i = 0; i < 16; i++)
|
||||
#ifdef _WIN32
|
||||
W[i] = htobe32(((uint32_t *)(block))[i]);
|
||||
#else // from big endian to little endian ( swap )
|
||||
W[i] = be32toh(((uint32_t *)(block))[i]);
|
||||
#endif
|
||||
|
||||
for (int i = 16; i < 64; i++)
|
||||
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
static void inline TransformBlock (uint32_t state[8], const uint32_t W[64])
|
||||
{
|
||||
/*
|
||||
implementation of orignal
|
||||
*/
|
||||
uint32_t S[8];
|
||||
memcpy(S, state, 32);
|
||||
|
||||
uint32_t t0, t1;
|
||||
RNDr(S, W, 0, 0x428a2f98); RNDr(S, W, 1, 0x71374491); RNDr(S, W, 2, 0xb5c0fbcf); RNDr(S, W, 3, 0xe9b5dba5);
|
||||
RNDr(S, W, 4, 0x3956c25b); RNDr(S, W, 5, 0x59f111f1); RNDr(S, W, 6, 0x923f82a4); RNDr(S, W, 7, 0xab1c5ed5);
|
||||
RNDr(S, W, 8, 0xd807aa98); RNDr(S, W, 9, 0x12835b01); RNDr(S, W, 10, 0x243185be); RNDr(S, W, 11, 0x550c7dc3);
|
||||
RNDr(S, W, 12, 0x72be5d74); RNDr(S, W, 13, 0x80deb1fe); RNDr(S, W, 14, 0x9bdc06a7); RNDr(S, W, 15, 0xc19bf174);
|
||||
RNDr(S, W, 16, 0xe49b69c1); RNDr(S, W, 17, 0xefbe4786); RNDr(S, W, 18, 0x0fc19dc6); RNDr(S, W, 19, 0x240ca1cc);
|
||||
RNDr(S, W, 20, 0x2de92c6f); RNDr(S, W, 21, 0x4a7484aa); RNDr(S, W, 22, 0x5cb0a9dc); RNDr(S, W, 23, 0x76f988da);
|
||||
RNDr(S, W, 24, 0x983e5152); RNDr(S, W, 25, 0xa831c66d); RNDr(S, W, 26, 0xb00327c8); RNDr(S, W, 27, 0xbf597fc7);
|
||||
RNDr(S, W, 28, 0xc6e00bf3); RNDr(S, W, 29, 0xd5a79147); RNDr(S, W, 30, 0x06ca6351); RNDr(S, W, 31, 0x14292967);
|
||||
RNDr(S, W, 32, 0x27b70a85); RNDr(S, W, 33, 0x2e1b2138); RNDr(S, W, 34, 0x4d2c6dfc); RNDr(S, W, 35, 0x53380d13);
|
||||
RNDr(S, W, 36, 0x650a7354); RNDr(S, W, 37, 0x766a0abb); RNDr(S, W, 38, 0x81c2c92e); RNDr(S, W, 39, 0x92722c85);
|
||||
RNDr(S, W, 40, 0xa2bfe8a1); RNDr(S, W, 41, 0xa81a664b); RNDr(S, W, 42, 0xc24b8b70); RNDr(S, W, 43, 0xc76c51a3);
|
||||
RNDr(S, W, 44, 0xd192e819); RNDr(S, W, 45, 0xd6990624); RNDr(S, W, 46, 0xf40e3585); RNDr(S, W, 47, 0x106aa070);
|
||||
RNDr(S, W, 48, 0x19a4c116); RNDr(S, W, 49, 0x1e376c08); RNDr(S, W, 50, 0x2748774c); RNDr(S, W, 51, 0x34b0bcb5);
|
||||
RNDr(S, W, 52, 0x391c0cb3); RNDr(S, W, 53, 0x4ed8aa4a); RNDr(S, W, 54, 0x5b9cca4f); RNDr(S, W, 55, 0x682e6ff3);
|
||||
RNDr(S, W, 56, 0x748f82ee); RNDr(S, W, 57, 0x78a5636f); RNDr(S, W, 58, 0x84c87814); RNDr(S, W, 59, 0x8cc70208);
|
||||
RNDr(S, W, 60, 0x90befffa); RNDr(S, W, 61, 0xa4506ceb); RNDr(S, W, 62, 0xbef9a3f7); RNDr(S, W, 63, 0xc67178f2);
|
||||
|
||||
for (int i = 0; i < 8; i++) state[i] += S[i];
|
||||
}
|
||||
|
||||
void inline HashNextBlock (uint32_t state[8], const uint8_t * block)
|
||||
{
|
||||
/*
|
||||
implementation of orignal
|
||||
*/
|
||||
uint32_t W[64];
|
||||
CalculateW (block, W);
|
||||
TransformBlock (state, W);
|
||||
}
|
||||
|
||||
static bool check_prefix(const char * buf)
|
||||
{
|
||||
unsigned short size_str=0;
|
||||
while(*buf)
|
||||
{
|
||||
if(*buf < 48 || (*buf > 57 && *buf < 65) || (*buf > 64 && *buf < 94) || *buf > 125 || size_str > 52)
|
||||
return false;
|
||||
size_str++;
|
||||
buf++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen)
|
||||
{
|
||||
size_t ret = 0, pos = 1;
|
||||
int bits = 8, tmp = inBuf[0];
|
||||
while (ret < outLen && (bits > 0 || pos < len))
|
||||
{
|
||||
if (bits < 5)
|
||||
{
|
||||
if (pos < len)
|
||||
{
|
||||
tmp <<= 8;
|
||||
tmp |= inBuf[pos] & 0xFF;
|
||||
pos++;
|
||||
bits += 8;
|
||||
}
|
||||
else // last byte
|
||||
{
|
||||
tmp <<= (5 - bits);
|
||||
bits = 5;
|
||||
}
|
||||
}
|
||||
|
||||
bits -= 5;
|
||||
int ind = (tmp >> bits) & 0x1F;
|
||||
outBuf[ret] = (ind < 26) ? (ind + 'a') : ((ind - 26) + '2');
|
||||
ret++;
|
||||
}
|
||||
outBuf[ret]='\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool NotThat(const char * what, const std::regex & reg){
|
||||
return std::regex_match(what,reg) == 1 ? false : true;
|
||||
}
|
||||
|
||||
static inline bool NotThat(const char * a, const char *b)
|
||||
{
|
||||
while(*b)
|
||||
if(*a++!=*b++)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool thread_find(uint8_t * buf, const char * prefix, int id_thread, unsigned long long throughput)
|
||||
{
|
||||
/*
|
||||
Thanks to orignal ^-^
|
||||
For idea and example ^-^
|
||||
Orignal is sensei of crypto ;)
|
||||
*/
|
||||
std::cout << "Thread " << id_thread << " binded" << std::endl;
|
||||
/*
|
||||
union
|
||||
{
|
||||
uint8_t b[391];
|
||||
uint32_t ll;
|
||||
} local;
|
||||
union
|
||||
{
|
||||
uint8_t b[32];
|
||||
uint32_t ll[8];
|
||||
} hash;
|
||||
*/
|
||||
uint8_t b[391];
|
||||
uint32_t hash[8];
|
||||
|
||||
memcpy (b, buf, 391);
|
||||
|
||||
auto len = strlen (prefix);
|
||||
// precalculate first 5 blocks (320 bytes)
|
||||
uint32_t state[8] = { 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
|
||||
HashNextBlock (state, b);
|
||||
HashNextBlock (state, b + 64);
|
||||
HashNextBlock (state, b + 128);
|
||||
HashNextBlock (state, b + 192);
|
||||
HashNextBlock (state, b + 256);
|
||||
|
||||
// pre-calculate last W
|
||||
uint32_t lastW[64];
|
||||
CalculateW (lastBlock, lastW);
|
||||
|
||||
uint32_t * nonce = (uint32_t *)(b+320);
|
||||
(*nonce) += id_thread*throughput;
|
||||
|
||||
char addr[53];
|
||||
uint32_t state1[8];
|
||||
|
||||
while(throughput-- and !found)
|
||||
{
|
||||
memcpy (state1, state, 32);
|
||||
// calculate hash of block with nonce
|
||||
HashNextBlock (state1, b + 320);
|
||||
// apply last block
|
||||
TransformBlock (state1, lastW);
|
||||
// get final hash
|
||||
for (int j = 8; j--;)
|
||||
hash[j] = htobe32(state1[j]);
|
||||
ByteStreamToBase32 ((uint8_t*)hash, 32, addr, len);
|
||||
// std::cout << addr << std::endl;
|
||||
|
||||
//bool result = options.reg ? !NotThat(addr, &options.regex) : !NotThat(addr,prefix);
|
||||
|
||||
if( ( options.reg ? !NotThat(addr, options.regex) : !NotThat(addr,prefix) ) )
|
||||
// if(result)
|
||||
{
|
||||
ByteStreamToBase32 ((uint8_t*)hash, 32, addr, 52);
|
||||
std::cout << "Address found " << addr << " in " << id_thread << std::endl;
|
||||
found=true;
|
||||
FoundNonce=*nonce;
|
||||
// free(hash);
|
||||
// free(b);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
(*nonce)++;
|
||||
hashescounter++;
|
||||
if (found)
|
||||
{
|
||||
// free(hash);
|
||||
// free(b);
|
||||
break;
|
||||
}
|
||||
}//while
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void usage(void){
|
||||
const constexpr char * help="vain pattern [options]\n"
|
||||
"-h --help help menu\n"
|
||||
"-r --reg regexp instead just text pattern\n"
|
||||
"--threads -t (default count of system)\n"
|
||||
"--signature -s (signature type)\n"
|
||||
"-o --output output file(default private.dat)\n"
|
||||
"--usage usage\n"
|
||||
//"--prefix -p\n"
|
||||
"";
|
||||
puts(help);
|
||||
}
|
||||
|
||||
|
||||
void parsing(int argc, char ** args){
|
||||
int option_index;
|
||||
static struct option long_options[]={
|
||||
{"help",no_argument,0,'h'},
|
||||
{"reg", no_argument,0,'r'},
|
||||
{"threads", required_argument, 0, 't'},
|
||||
{"signature", required_argument,0,'s'},
|
||||
{"output", required_argument,0,'o'},
|
||||
{"usage", no_argument,0,0},
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
int c;
|
||||
while( (c=getopt_long(argc,args, "hrt:s:o:", long_options, &option_index))!=-1){
|
||||
switch(c){
|
||||
case 0:
|
||||
if ( std::string(long_options[option_index].name) == std::string("usage") ){
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
case 'h':
|
||||
usage();
|
||||
exit(0);
|
||||
break;
|
||||
case 'r':
|
||||
options.reg=true;
|
||||
break;
|
||||
case 't':
|
||||
options.threads=atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
options.signature = NameToSigType(std::string(optarg));
|
||||
break;
|
||||
case 'o':
|
||||
options.outputpath=optarg;
|
||||
break;
|
||||
case '?':
|
||||
std::cerr << "Undefined argument" << std::endl;
|
||||
default:
|
||||
std::cerr << args[0] << " --usage / --help" << std::endl;
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char * argv[])
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
if ( argc < 2 )
|
||||
{
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
parsing( argc > 2 ? argc-1 : argc, argc > 2 ? argv+1 : argv);
|
||||
//
|
||||
if(!options.reg && !check_prefix( argv[1] ))
|
||||
{
|
||||
std::cout << "Not correct prefix(just string)" << std::endl;
|
||||
return 1;
|
||||
}else{
|
||||
options.regex=std::regex(argv[1]);
|
||||
// int ret = regcomp( &options.regex, argv[1], REG_EXTENDED );
|
||||
// if( ret != 0 ){
|
||||
// std::cerr << "Can't create regexp pattern from " << argv[1] << std::endl;
|
||||
// return 1;
|
||||
// }
|
||||
}
|
||||
|
||||
i2p::crypto::InitCrypto (false);
|
||||
options.signature = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519;
|
||||
///////////////
|
||||
//For while
|
||||
if(options.signature != i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
|
||||
{
|
||||
std::cout << "For a while only ED25519-SHA512" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
///////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
auto keys = i2p::data::PrivateKeys::CreateRandomKeys (options.signature);
|
||||
switch(options.signature)
|
||||
{
|
||||
case i2p::data::SIGNING_KEY_TYPE_DSA_SHA1:
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||
case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
std::cout << "Sorry, i don't can generate adress for this signature type" << std::endl;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO: for other types.
|
||||
switch(options.signature)
|
||||
{
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
MutateByte=320;
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
break;
|
||||
}
|
||||
|
||||
KeyBuf = new uint8_t[keys.GetFullLen()];
|
||||
keys.ToBuffer (KeyBuf, keys.GetFullLen ());
|
||||
|
||||
if(options.threads <= 0)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
SYSTEM_INFO siSysInfo;
|
||||
GetSystemInfo(&siSysInfo);
|
||||
options.threads = siSysInfo.dwNumberOfProcessors;
|
||||
#elif defined(_SC_NPROCESSORS_CONF)
|
||||
options.threads = sysconf(_SC_NPROCESSORS_CONF);
|
||||
#elif defined(HW_NCPU)
|
||||
int req[] = { CTL_HW, HW_NCPU };
|
||||
size_t len = sizeof(options.threads);
|
||||
v = sysctl(req, 2, &options.threads, &len, NULL, 0);
|
||||
#else
|
||||
options.threads = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::cout << "Start vanity generator in " << options.threads << " threads" << std::endl;
|
||||
|
||||
unsigned short attempts = 0;
|
||||
while(!found)
|
||||
{//while
|
||||
{//stack(for destructors(vector/thread))
|
||||
|
||||
std::vector<std::thread> threads(options.threads);
|
||||
unsigned long long thoughtput = 0x4F4B5A37;
|
||||
|
||||
for ( unsigned int j = options.threads;j--;)
|
||||
{
|
||||
threads[j] = std::thread(thread_find,KeyBuf,argv[1],j,thoughtput);
|
||||
thoughtput+=1000;
|
||||
}//for
|
||||
|
||||
for(unsigned int j = 0; j < (unsigned int)options.threads;j++)
|
||||
threads[j].join();
|
||||
|
||||
if(FoundNonce == 0)
|
||||
{
|
||||
RAND_bytes( KeyBuf+MutateByte , 90 );
|
||||
std::cout << "Attempts #" << ++attempts << std::endl;
|
||||
}
|
||||
|
||||
}//stack
|
||||
}//while
|
||||
|
||||
memcpy (KeyBuf + MutateByte, &FoundNonce, 4);
|
||||
std::cout << "Hashes: " << hashescounter << std::endl;
|
||||
|
||||
if(options.outputpath.size() == 0) options.outputpath="private.dat";
|
||||
|
||||
std::ofstream f (options.outputpath, std::ofstream::binary | std::ofstream::out);
|
||||
if (f)
|
||||
{
|
||||
f.write ((char *)KeyBuf, keys.GetFullLen ());
|
||||
delete [] KeyBuf;
|
||||
}
|
||||
else
|
||||
std::cout << "Can't create file " << options.outputpath << std::endl;
|
||||
|
||||
i2p::crypto::TerminateCrypto ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
@ -1,66 +0,0 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "Crypto.h"
|
||||
#include "Identity.h"
|
||||
#include "I2PEndian.h"
|
||||
#include "common/key.hpp"
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// sha256
|
||||
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
|
||||
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
|
||||
#define SHR(x, n) (x >> n)
|
||||
#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
|
||||
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
|
||||
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
|
||||
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
|
||||
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
|
||||
|
||||
#define RND(a, b, c, d, e, f, g, h, k) \
|
||||
t0 = h + S1(e) + Ch(e, f, g) + k; \
|
||||
t1 = S0(a) + Maj(a, b, c); \
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
#define RNDr(S, W, i, k) \
|
||||
RND(S[(64 - i) % 8], S[(65 - i) % 8], \
|
||||
S[(66 - i) % 8], S[(67 - i) % 8], \
|
||||
S[(68 - i) % 8], S[(69 - i) % 8], \
|
||||
S[(70 - i) % 8], S[(71 - i) % 8], \
|
||||
W[i] + k)
|
||||
|
||||
|
||||
//static i2p::data::SigningKeyType type;
|
||||
//static i2p::data::PrivateKeys keys;
|
||||
static bool found=false;
|
||||
|
||||
static size_t MutateByte;
|
||||
|
||||
static uint32_t FoundNonce=0;
|
||||
|
||||
static uint8_t * KeyBuf;
|
||||
|
||||
//static uint8_t * PaddingBuf;
|
||||
static unsigned long long hashescounter;
|
||||
unsigned int count_cpu;
|
||||
|
||||
const uint8_t lastBlock[64] =
|
||||
{
|
||||
0x05, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x80, // 7 bytes EdDSA certificate
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x38 // 3128 bits (391 bytes)
|
||||
};
|
281
vain.cpp
281
vain.cpp
@ -3,24 +3,10 @@
|
||||
#include<getopt.h>
|
||||
#include<string>
|
||||
#include<boost/filesystem.hpp>
|
||||
//#include<boost/algorithm/string/predicate.hpp>
|
||||
//#include<format> // is not supports for me
|
||||
|
||||
/// Crypto InitCrypto. TODO: to makefile/another place get the macro
|
||||
#ifndef PRECOMPUTATION_CRYPTO
|
||||
#define PRECOMPUTATION_CRYPTO false
|
||||
#endif
|
||||
#ifndef AESNI_CRYPTO
|
||||
#define AESNI_CRYPTO false
|
||||
#endif
|
||||
#ifndef AVX_CRYPTO
|
||||
#define AVX_CRYPTO false
|
||||
#endif
|
||||
#ifndef FORCE_CRYPTO
|
||||
#define FORCE_CRYPTO false
|
||||
#endif
|
||||
|
||||
#define DEF_OUT_FILE "private.dat"
|
||||
|
||||
// some global vars in vanitygen.hpp
|
||||
static struct{
|
||||
bool reg=false;
|
||||
int threads=-1;
|
||||
@ -240,6 +226,7 @@ void usage(void){
|
||||
"-o --output output file(default " DEF_OUT_FILE ")\n"
|
||||
//"--usage usage\n"
|
||||
//"--prefix -p\n"
|
||||
"--multiplymode -m - multiple addresses search"
|
||||
"";
|
||||
puts(help);
|
||||
}
|
||||
@ -253,18 +240,22 @@ void parsing(int argc, char ** args){
|
||||
{"threads", required_argument, 0, 't'},
|
||||
{"signature", required_argument,0,'s'},
|
||||
{"output", required_argument,0,'o'},
|
||||
{"multiplymode", no_argument, 0, 'm'},
|
||||
//{"usage", no_argument,0,0},
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
int c;
|
||||
while( (c=getopt_long(argc,args, "hrt:s:o:", long_options, &option_index))!=-1){
|
||||
while( (c=getopt_long(argc,args, "hrt:s:o:m", long_options, &option_index))!=-1){
|
||||
switch(c){
|
||||
//case 0:
|
||||
// if ( std::string(long_options[option_index].name) == std::string("usage") ){
|
||||
// usage();
|
||||
// exit(1);
|
||||
// }
|
||||
case 'm':
|
||||
multipleSearchMode=true;
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
exit(0);
|
||||
@ -357,129 +348,145 @@ int main (int argc, char * argv[])
|
||||
if ( !std::regex_match( std::string(argv[1]), std::regex("[a-zA-Z0-9\\.]{1,}")) ) {
|
||||
std::cerr << "Please, change the outputfile name" << std::endl;
|
||||
}
|
||||
auto keys = i2p::data::PrivateKeys::CreateRandomKeys (options.signature);
|
||||
// IDK type, and don't want to check. so...
|
||||
auto createDumpFile = [/*keys*/](std::string outFile, i2p::data::PrivateKeys keys){
|
||||
std::cout <<" Create a outFile " << outFile << std::endl;
|
||||
std::ofstream f(outFile, std::ofstream::binary | std::ofstream:: out);
|
||||
if (!f) {
|
||||
std::cerr << "Can't to create a dump file before search address" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
size_t len = keys.GetFullLen ();
|
||||
uint8_t * buf = new uint8_t[len];
|
||||
len = keys.ToBuffer (buf, len);
|
||||
f.write ((char *)buf, len);
|
||||
delete[] buf;
|
||||
}; // is double of code. we can found simillar in keygen.cpp. WE would to create a library like
|
||||
// libi2pdtools
|
||||
// TODO: create libi2pd_tools
|
||||
// If file not exists we create a dump file. (a bug was found in issues)
|
||||
switch(options.signature)
|
||||
{
|
||||
case i2p::data::SIGNING_KEY_TYPE_DSA_SHA1:
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||
case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
std::cout << "Sorry, i don't can generate adress for this signature type" << std::endl;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
//
|
||||
if ( options . outputpath . empty () ) options . outputpath . assign ( DEF_OUT_FILE ) ;
|
||||
static std::string outPutFileName = options.outputpath;
|
||||
auto doSearch = [argc,argv] () {
|
||||
auto keys = i2p::data::PrivateKeys::CreateRandomKeys (options.signature);
|
||||
// IDK type, and don't want to check. so...
|
||||
auto createDumpFile = [/*keys*/](std::string outFile, i2p::data::PrivateKeys keys){
|
||||
std::cout <<" Create a outFile " << outFile << std::endl;
|
||||
std::ofstream f(outFile, std::ofstream::binary | std::ofstream:: out);
|
||||
if (!f) {
|
||||
std::cerr << "Can't to create a dump file before search address" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
size_t len = keys.GetFullLen ();
|
||||
uint8_t * buf = new uint8_t[len];
|
||||
len = keys.ToBuffer (buf, len);
|
||||
f.write ((char *)buf, len);
|
||||
delete[] buf;
|
||||
}; // is double of code. we can found simillar in keygen.cpp. WE would to create a library like
|
||||
// libi2pdtools
|
||||
// TODO: create libi2pd_tools
|
||||
// If file not exists we create a dump file. (a bug was found in issues)
|
||||
switch(options.signature)
|
||||
{
|
||||
case i2p::data::SIGNING_KEY_TYPE_DSA_SHA1:
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||
case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
std::cout << "Sorry, i don't can generate adress for this signature type" << std::endl;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO: for other types.
|
||||
switch(options.signature)
|
||||
{
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
MutateByte=320;
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
break;
|
||||
}
|
||||
// there we gen key to buffer. That we mem allocate...
|
||||
KeyBuf = new uint8_t[keys.GetFullLen()];
|
||||
keys.ToBuffer (KeyBuf, keys.GetFullLen ());
|
||||
/// there was some things for cpu 665% usage, but is not helpful even
|
||||
std::cout << "Start vanity generator in " << options.threads << " threads" << std::endl;
|
||||
// there we start to change byte in our private key. we can change another bytes too
|
||||
// but we just change 1 byte in all key. So. TODO: change all bytes not one?
|
||||
unsigned short attempts = 0;// it can be disabled, it's just for a statistic. For CPU this is a trash?
|
||||
while(!found)
|
||||
{//while
|
||||
{//stack(for destructors(vector/thread))
|
||||
|
||||
std::vector<std::thread> threads(options.threads);
|
||||
unsigned long long thoughtput = 0x4F4B5A37; // is a magic number.
|
||||
|
||||
for ( unsigned int j = options.threads;j--;)
|
||||
{
|
||||
// our buf is our key, but in uint8 type, unsigned integ... another argument
|
||||
// is our prefix that we search in address
|
||||
// and j is magic number, is thread id.
|
||||
// thoughtput is our magic number that we increment on 1000 everytime
|
||||
// so we just change a one a byte in key and convert private key to address
|
||||
// after we check it.
|
||||
threads[j] = std::thread(thread_find,KeyBuf,argv[1],j,thoughtput);
|
||||
thoughtput+=1000;
|
||||
}//for
|
||||
|
||||
//There will be proccessFlipper by accetone
|
||||
// if I correctly understand it's drop a payload things in a prefix/search data
|
||||
// or simmilar. We can just use regex. I would to use regex
|
||||
|
||||
// So I put it ^^^
|
||||
for(unsigned int j = 0; j < (unsigned int)options.threads;j++)
|
||||
threads[j].join();
|
||||
|
||||
if(FoundNonce == 0)
|
||||
{
|
||||
RAND_bytes( KeyBuf+MutateByte , 90 ); // FoundNonce is
|
||||
std::cout << "Attempts #" << ++attempts << std::endl;
|
||||
}
|
||||
|
||||
}//stack
|
||||
}//while
|
||||
// before we write result we would to create private.dat a file. dump file. we can use for it keygen
|
||||
// so.
|
||||
memcpy (KeyBuf + MutateByte, &FoundNonce, 4);
|
||||
std::cout << "Hashes: " << hashescounter << std::endl;
|
||||
|
||||
// IDK. what for acetone change this line to if (options.output...empty() ... assign
|
||||
// cplusplus.com/reference/string/string/assign yes we can. but I would don't change this
|
||||
//if(options.outputpath.size() == 0) options.outputpath = DEF_OUT_FILE;
|
||||
options.outputpath = options.outputpath + std::to_string(foundKeys) + std::string(".dat");
|
||||
|
||||
//TODO: for other types.
|
||||
switch(options.signature)
|
||||
{
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
MutateByte=320;
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
break;
|
||||
}
|
||||
// there we gen key to buffer. That we mem allocate...
|
||||
KeyBuf = new uint8_t[keys.GetFullLen()];
|
||||
keys.ToBuffer (KeyBuf, keys.GetFullLen ());
|
||||
/// there was some things for cpu 665% usage, but is not helpful even
|
||||
std::cout << "Start vanity generator in " << options.threads << " threads" << std::endl;
|
||||
// there we start to change byte in our private key. we can change another bytes too
|
||||
// but we just change 1 byte in all key. So. TODO: change all bytes not one?
|
||||
unsigned short attempts = 0;// it can be disabled, it's just for a statistic. For CPU this is a trash?
|
||||
while(!found)
|
||||
{//while
|
||||
{//stack(for destructors(vector/thread))
|
||||
//if ( ! boost::algorithm::ends_with(options.outputpath, ".dat") )
|
||||
// options.outputpath = options.outputpath + ".dat";
|
||||
|
||||
// there we generate a key, like as in keygen.cpp
|
||||
// before a mining we would to create a dump file
|
||||
|
||||
std::cout << "outpath for a now: " << options.outputpath << std::endl;
|
||||
if( ! boost::filesystem::exists(options.outputpath) ) createDumpFile(options.outputpath, keys);
|
||||
|
||||
std::ofstream f (options.outputpath, std::ofstream::binary | std::ofstream::out);
|
||||
if (f)
|
||||
{
|
||||
f.write ((char *)KeyBuf, keys.GetFullLen ());
|
||||
delete [] KeyBuf;
|
||||
}
|
||||
else
|
||||
std::cout << "Can't create file " << options.outputpath << std::endl;
|
||||
|
||||
}; // void doSearch lamda
|
||||
|
||||
std::vector<std::thread> threads(options.threads);
|
||||
unsigned long long thoughtput = 0x4F4B5A37; // is a magic number.
|
||||
do {
|
||||
doSearch();
|
||||
foundKeys++;
|
||||
options.outputpath.assign(outPutFileName);
|
||||
found = false;
|
||||
FoundNonce = 0;
|
||||
} while(multipleSearchMode);
|
||||
|
||||
for ( unsigned int j = options.threads;j--;)
|
||||
{
|
||||
// our buf is our key, but in uint8 type, unsigned integ... another argument
|
||||
// is our prefix that we search in address
|
||||
// and j is magic number, is thread id.
|
||||
// thoughtput is our magic number that we increment on 1000 everytime
|
||||
// so we just change a one a byte in key and convert private key to address
|
||||
// after we check it.
|
||||
threads[j] = std::thread(thread_find,KeyBuf,argv[1],j,thoughtput);
|
||||
thoughtput+=1000;
|
||||
}//for
|
||||
|
||||
//There will be proccessFlipper by accetone
|
||||
// if I correctly understand it's drop a payload things in a prefix/search data
|
||||
// or simmilar. We can just use regex. I would to use regex
|
||||
|
||||
// So I put it ^^^
|
||||
for(unsigned int j = 0; j < (unsigned int)options.threads;j++)
|
||||
threads[j].join();
|
||||
|
||||
if(FoundNonce == 0)
|
||||
{
|
||||
RAND_bytes( KeyBuf+MutateByte , 90 ); // FoundNonce is
|
||||
std::cout << "Attempts #" << ++attempts << std::endl;
|
||||
}
|
||||
|
||||
}//stack
|
||||
}//while
|
||||
// before we write result we would to create private.dat a file. dump file. we can use for it keygen
|
||||
// so.
|
||||
memcpy (KeyBuf + MutateByte, &FoundNonce, 4);
|
||||
std::cout << "Hashes: " << hashescounter << std::endl;
|
||||
|
||||
// IDK. what for acetone change this line to if (options.output...empty() ... assign
|
||||
// cplusplus.com/reference/string/string/assign yes we can. but I would don't change this
|
||||
//if(options.outputpath.size() == 0) options.outputpath = DEF_OUT_FILE;
|
||||
if ( options . outputpath . empty () ) options . outputpath . assign ( DEF_OUT_FILE ) ;
|
||||
|
||||
// there we generate a key, like as in keygen.cpp
|
||||
// before a mining we would to create a dump file
|
||||
|
||||
std::cout << "outpath for a now: " << options.outputpath << std::endl;
|
||||
if( ! boost::filesystem::exists(options.outputpath) ) createDumpFile(options.outputpath, keys);
|
||||
|
||||
std::ofstream f (options.outputpath, std::ofstream::binary | std::ofstream::out);
|
||||
if (f)
|
||||
{
|
||||
f.write ((char *)KeyBuf, keys.GetFullLen ());
|
||||
delete [] KeyBuf;
|
||||
}
|
||||
else
|
||||
std::cout << "Can't create file " << options.outputpath << std::endl;
|
||||
|
||||
i2p::crypto::TerminateCrypto ();
|
||||
|
||||
return 0;
|
||||
i2p::crypto::TerminateCrypto ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
21
vanity.hpp
21
vanity.hpp
@ -41,8 +41,27 @@
|
||||
|
||||
//static i2p::data::SigningKeyType type;
|
||||
//static i2p::data::PrivateKeys keys;
|
||||
static bool found=false;
|
||||
|
||||
|
||||
// for InitCrypto. TODO: to makefile/another place get the macro
|
||||
#ifndef PRECOMPUTATION_CRYPTO
|
||||
#define PRECOMPUTATION_CRYPTO false
|
||||
#endif
|
||||
#ifndef AESNI_CRYPTO
|
||||
#define AESNI_CRYPTO false
|
||||
#endif
|
||||
#ifndef AVX_CRYPTO
|
||||
#define AVX_CRYPTO false
|
||||
#endif
|
||||
#ifndef FORCE_CRYPTO
|
||||
#define FORCE_CRYPTO false
|
||||
#endif
|
||||
// def out file name
|
||||
#define DEF_OUT_FILE "private"
|
||||
// Global vars
|
||||
static bool found=false;
|
||||
static bool multipleSearchMode = false;
|
||||
static unsigned int foundKeys = 0;
|
||||
static size_t MutateByte;
|
||||
|
||||
static uint32_t FoundNonce=0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user