Browse Source

Merge pull request #86 from freeacetone/master

vanity generator optimization
pull/87/head
orignal 1 year ago committed by GitHub
parent
commit
40d335a427
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 69
      vanity.hpp
  2. 242
      vanitygen.cpp

69
vanity.hpp

@ -1,69 +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)
#define DEF_OUTNAME "private.dat"
//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)
};

242
vanitygen.cpp

@ -1,15 +1,72 @@
#include "vanity.hpp" #include "Crypto.h"
#include "Identity.h"
#include "I2PEndian.h"
#include "common/key.hpp"
#include <regex> #include <regex>
#include <mutex> #include <mutex>
#include <getopt.h> #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 static struct
{ {
bool reg=false; bool reg = false;
int threads=-1; int threads = -1;
i2p::data::SigningKeyType signature; i2p::data::SigningKeyType signature;
std::string outputpath=""; std::string outputpath = "";
std::regex regex; std::regex regex;
bool sig_type = true; bool sig_type = true;
} options; } options;
@ -23,7 +80,7 @@ void check_sig_type()
} }
} }
static void inline CalculateW (const uint8_t block[64], uint32_t W[64]) void inline CalculateW (const uint8_t block[64], uint32_t W[64])
{ {
/** /**
* implementation of orignal * implementation of orignal
@ -39,7 +96,7 @@ static void inline CalculateW (const uint8_t block[64], uint32_t W[64])
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; 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]) void inline TransformBlock (uint32_t state[8], const uint32_t W[64])
{ {
/** /**
* implementation of orignal * implementation of orignal
@ -78,9 +135,9 @@ void inline HashNextBlock (uint32_t state[8], const uint8_t * block)
TransformBlock (state, W); TransformBlock (state, W);
} }
static bool check_prefix(const char * buf) bool check_prefix(const char * buf)
{ {
unsigned short size_str=0; unsigned short size_str = 0;
while(*buf) while(*buf)
{ {
if(!((*buf > 49 && *buf < 56) || (*buf > 96 && *buf < 123)) || size_str > 52) if(!((*buf > 49 && *buf < 56) || (*buf > 96 && *buf < 123)) || size_str > 52)
@ -91,7 +148,7 @@ static bool check_prefix(const char * buf)
return true; return true;
} }
static inline size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen) inline size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen)
{ {
size_t ret = 0, pos = 1; size_t ret = 0, pos = 1;
int bits = 8, tmp = inBuf[0]; int bits = 8, tmp = inBuf[0];
@ -122,11 +179,11 @@ static inline size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char
return ret; return ret;
} }
static inline bool NotThat(const char * what, const std::regex & reg){ inline bool NotThat(const char * what, const std::regex & reg){
return std::regex_match(what,reg) == 1 ? false : true; return std::regex_match(what,reg) == 1 ? false : true;
} }
static inline bool NotThat(const char * a, const char *b) inline bool NotThat(const char * a, const char *b)
{ {
while(*b) while(*b)
if(*a++!=*b++) if(*a++!=*b++)
@ -134,29 +191,53 @@ static inline bool NotThat(const char * a, const char *b)
return false; return false;
} }
std::mutex mtx; void processFlipper(const std::string string)
static inline bool thread_find(uint8_t * buf, const char * prefix, int id_thread, unsigned long long throughput)
{ {
/** constexpr char SYMBOLS[] {'-', '\\', '|', '/'};
* Thanks to orignal ^-^ uint8_t symbol_counter = 0;
* For idea and example ^-^ std::string payload = string;
* Orignal is sensei of crypto ;) if (payload.back() != ' ') payload += ' ';
*/
mtx.lock(); size_t current_state = payload.size();
std::cout << "[+] thread " << id_thread << " bound" << std::endl; enum { left, right } direction = left;
mtx.unlock();
/* std::cout << payload << SYMBOLS[symbol_counter++];
union while (!found)
{ {
uint8_t b[391]; std::cout << '\b' << SYMBOLS[symbol_counter++];
uint32_t ll; std::cout.flush();
} local;
union if (symbol_counter == sizeof(SYMBOLS))
{ {
uint8_t b[32]; if (direction == left)
uint32_t ll[8]; {
} hash; 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]; uint8_t b[391];
uint32_t hash[8]; uint32_t hash[8];
@ -185,8 +266,13 @@ static inline bool thread_find(uint8_t * buf, const char * prefix, int id_thread
char addr[53]; char addr[53];
uint32_t state1[8]; uint32_t state1[8];
while(throughput-- and !found) while(!found)
{ {
if (! throughput--)
{
throughput = original_throughput;
}
memcpy (state1, state, 32); memcpy (state1, state, 32);
// calculate hash of block with nonce // calculate hash of block with nonce
HashNextBlock (state1, b + 320); HashNextBlock (state1, b + 320);
@ -196,32 +282,22 @@ static inline bool thread_find(uint8_t * buf, const char * prefix, int id_thread
for (int j = 8; j--;) for (int j = 8; j--;)
hash[j] = htobe32(state1[j]); hash[j] = htobe32(state1[j]);
ByteStreamToBase32 ((uint8_t*)hash, 32, addr, len); 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( ( options.reg ? !NotThat(addr, options.regex) : !NotThat(addr,prefix) ) )
// if(result)
{ {
ByteStreamToBase32 ((uint8_t*)hash, 32, addr, 52); ByteStreamToBase32 ((uint8_t*)hash, 32, addr, 52);
std::cout << "\nFound address: " << addr << std::endl; std::cout << "\nFound address: " << addr << std::endl;
found=true; found = true;
FoundNonce=*nonce;
// free(hash);
// free(b);
return true; return true;
} }
(*nonce)++; (*nonce)++;
hashescounter++;
if (found) if (found)
{ {
// free(hash);
// free(b);
break; break;
} }
} // while }
return true; return true;
} }
@ -292,6 +368,7 @@ int main (int argc, char * argv[])
usage(); usage();
return 0; return 0;
} }
parsing( argc > 2 ? argc-1 : argc, argc > 2 ? argv+1 : argv); parsing( argc > 2 ? argc-1 : argc, argc > 2 ? argv+1 : argv);
// //
if(!options.reg && !check_prefix( argv[1] )) if(!options.reg && !check_prefix( argv[1] ))
@ -301,25 +378,17 @@ int main (int argc, char * argv[])
return 1; return 1;
}else{ }else{
options.regex=std::regex(argv[1]); 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, true, true, false); i2p::crypto::InitCrypto (false, true, true, false);
options.signature = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519; options.signature = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519;
///////////////
//For while
if(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; std::cout << "ED25519-SHA512 are currently the only signing keys supported." << std::endl;
return 0; return 0;
} }
///////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (!options.sig_type) return -2; if (!options.sig_type) return -2;
auto keys = i2p::data::PrivateKeys::CreateRandomKeys (options.signature); auto keys = i2p::data::PrivateKeys::CreateRandomKeys (options.signature);
switch(options.signature) switch(options.signature)
@ -362,55 +431,28 @@ int main (int argc, char * argv[])
if(options.threads <= 0) if(options.threads <= 0)
{ {
#if defined(WIN32) options.threads = std::thread::hardware_concurrency();
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 << "Vanity generator started in " << options.threads << " threads" << std::endl;
std::cout << "Initializing vanity generator (" << options.threads << " threads)\n" << std::endl; std::vector<std::thread> threads(options.threads);
unsigned long long thoughtput = 0x4F4B5A37;
unsigned short attempts = 0;
while(!found)
{ // while
{ // stack(for destructors(vector/thread))
std::vector<std::thread> threads(options.threads);
unsigned long long thoughtput = 0x4F4B5A37;
std::cout << "Starting attempt #" << ++attempts << ":" << std::endl;
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 );
}
} // stack for (unsigned int j = options.threads; j--; )
} // while {
threads[j] = std::thread(thread_find, KeyBuf, argv[1], j, thoughtput);
thoughtput += 1000;
}
memcpy (KeyBuf + MutateByte, &FoundNonce, 4); processFlipper(argv[1]);
std::cout << "Hashes calculated: " << hashescounter << std::endl;
for (unsigned int j = 0; j < (unsigned int)options.threads;j++)
threads[j].join();
if(options.outputpath.size() == 0) options.outputpath.assign(DEF_OUTNAME); if(options.outputpath.empty()) options.outputpath.assign(DEF_OUTNAME);
std::ofstream f (options.outputpath, std::ofstream::binary | std::ofstream::out); std::ofstream f (options.outputpath, std::ofstream::binary);
if (f) if (f)
{ {
f.write ((char *)KeyBuf, keys.GetFullLen ()); f.write ((char *)KeyBuf, keys.GetFullLen ());

Loading…
Cancel
Save