R4SAS
4 years ago
commit
7b64aba9da
7 changed files with 576 additions and 0 deletions
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
/obj |
||||
/sygcpp* |
||||
/syg-*.txt |
||||
/sygcpp.conf |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
SYS := $(shell $(CXX) -dumpmachine) |
||||
CXX = g++ |
||||
|
||||
SYG_SRC = sygcpp.cpp |
||||
SYGCPP = sygcpp |
||||
|
||||
LDFLAGS = -O3 -s |
||||
LDLIBS = -lcrypto -lpthread |
||||
|
||||
SYG_OBJS += $(patsubst %.cpp,obj/%.o,$(SYG_SRC)) |
||||
|
||||
ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS))) |
||||
include Makefile.mingw |
||||
endif |
||||
|
||||
all: mk_obj_dir $(SYGCPP) |
||||
|
||||
mk_obj_dir: |
||||
@mkdir -p obj/windows |
||||
|
||||
clean: |
||||
$(RM) -r obj $(SYGCPP) |
||||
|
||||
obj/%.o: %.cpp |
||||
$(CXX) -c -o $@ $< |
||||
|
||||
$(SYGCPP): $(SYG_OBJS) |
||||
$(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS) |
||||
|
||||
.PHONY: all |
||||
.PHONY: clean |
||||
.PHONY: mk_obj_dir |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
WINDRES = windres |
||||
|
||||
SYG_RC = windows/resource.rc |
||||
|
||||
LDFLAGS = -O3 -s -Wl,-Bstatic |
||||
LDLIBS = -static-libgcc -lcrypto -lws2_32 -lpthread |
||||
|
||||
SYG_OBJS += $(patsubst %.rc,obj/%.o,$(SYG_RC)) |
||||
|
||||
obj/%.o: %.rc |
||||
$(WINDRES) -i $< -o $@ |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
# SYGCPP |
||||
|
||||
### How build on windows under MSYS2 shell |
||||
|
||||
* Run MSYS2 MinGW 64-bit shell |
||||
* Install required packages |
||||
|
||||
```bash |
||||
pacman -S make mingw-w64-x86_64-gcc mingw-w64-x86_64-openssl |
||||
``` |
||||
|
||||
* Compile application |
||||
|
||||
```bash |
||||
make -f Makefile.mingw |
||||
``` |
||||
|
||||
* Run it using `sygcpp.exe` |
||||
|
||||
### How build on Linux |
||||
|
||||
* Install required packages |
||||
|
||||
``` |
||||
sudo apt-get install make g++ libssl-dev |
||||
``` |
||||
|
||||
* Compile application |
||||
|
||||
``` |
||||
make -f Makefile.linux |
||||
``` |
||||
|
||||
* Run it using `./sygcpp` |
@ -0,0 +1,459 @@
@@ -0,0 +1,459 @@
|
||||
/**
|
||||
* Thanks PurpleI2P Project for support to writing that code. |
||||
* |
||||
* IRC: irc.ilita.i2p port 6667 || 303:60d4:3d32:a2b9::3 port 16667 |
||||
* general channels: #ru and #howtoygg |
||||
* |
||||
* git: notabug.org/acetone/SimpleYggGen-CPP |
||||
* |
||||
* acetone, 2020 (c) GPLv3 |
||||
* |
||||
*/ |
||||
|
||||
#include <openssl/evp.h> // библиотека OpenSSL |
||||
#include <openssl/sha.h> |
||||
#include <openssl/bn.h> |
||||
#include <iostream> // вывод на экран |
||||
#include <string> |
||||
#include <sstream> |
||||
#include <fstream> // файловые потоки |
||||
#include <iomanip> // форматированный вывод строк |
||||
#include <bitset> // побитовое чтение |
||||
#include <vector> |
||||
#include <thread> // многопоточность |
||||
#include <mutex> |
||||
#include <chrono> // для паузы в заставке |
||||
#include <ctime> |
||||
|
||||
////////////////////////////////////////////////// Заставка
|
||||
|
||||
void intro() |
||||
{ |
||||
std::cout << std::endl |
||||
<< " +----------------------------------------------------------------------------+" << std::endl |
||||
<< " | SimpleYggGen C++ 1.1-train |" << std::endl |
||||
<< " | OpenSSL inside: x25519 -> sha512 |" << std::endl |
||||
<< " | notabug.org/acetone/SimpleYggGen-CPP |" << std::endl |
||||
<< " | |" << std::endl |
||||
<< " | developers: acetone, lialh4, orignal, R4SAS |" << std::endl |
||||
<< " | GPLv3 (c) 2020 |" << std::endl |
||||
<< " +"; |
||||
for(int i = 0; i < 76; ++i) |
||||
{ |
||||
std::cout << "-"; |
||||
std::cout.flush(); |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20)); |
||||
} |
||||
std::cout << "+" << std::endl; |
||||
} |
||||
|
||||
////////////////////////////////////////////////// Суть вопроса
|
||||
|
||||
#define KEYSIZE 32 |
||||
std::mutex mtx; |
||||
|
||||
int conf_proc = 0; |
||||
int conf_mode = 0; |
||||
int conf_log = 0; |
||||
int conf_high = 0; |
||||
std::string conf_search; |
||||
std::string log_file; |
||||
|
||||
uint64_t totalcount = 0; // счетчик основного цикла
|
||||
uint64_t totalcountfortune = 0; // счетчик нахождений
|
||||
bool newline = true; // используется для вывода счетчика
|
||||
|
||||
int config() |
||||
{ |
||||
std::ifstream conffile ("sygcpp.conf"); |
||||
|
||||
if(!conffile) // проверка наличия конфига
|
||||
{ |
||||
std::cout << " Configuration file not found..." << std::endl; |
||||
conffile.close(); |
||||
std::ofstream newconf ("sygcpp.conf"); // создание конфига
|
||||
if(!newconf) |
||||
{ |
||||
std::cerr << " Config (sygcpp.conf) creation failed :(" << std::endl; |
||||
return -1; |
||||
} |
||||
newconf << "1 0 1 9 ::\n" |
||||
<< "| | | | ^Pattern for search by name.\n" |
||||
<< "| | | ^Start position for high addresses search.\n" |
||||
<< "| | ^Logging mode (0 - console output only, 1 - log to file).\n" |
||||
<< "| ^Mining mode (0 - by name, 1 - high address).\n" |
||||
<< "^Count of thread (mining streams).\n\n" |
||||
<< "Parameters are separated by spaces."; |
||||
newconf.close(); |
||||
std::ifstream conffile ("sygcpp.conf"); |
||||
if(conffile) |
||||
std::cout << " Config successfully created :)" << std::endl; |
||||
config(); |
||||
return 0; |
||||
} else { |
||||
conffile >> conf_proc >> conf_mode >> conf_log >> conf_high >> conf_search; |
||||
conffile.close(); |
||||
if(conf_mode > 1 || conf_mode < 0 || conf_log > 1 || conf_log < 0 || conf_high < 0) // проверка полученных значений
|
||||
{ |
||||
std::cerr << " Invalid config found!\n" |
||||
<< " Check it:\n" |
||||
<< " - 2 field - mining mode: 0 or 1 only\n" |
||||
<< " - 3 field - logging mode: 0 or 1 only\n" |
||||
<< " - 5 field - string to search by name: a-z, 0-9 and ':' symbols only\n" |
||||
<< " Remove or correct sygcpp.conf and run SYG again."<< std::endl; |
||||
return -2; |
||||
} |
||||
|
||||
unsigned int processor_count = std::thread::hardware_concurrency(); // кол-во процессоров
|
||||
if(conf_proc > (int)processor_count) |
||||
conf_proc = (int)processor_count; |
||||
} |
||||
|
||||
// вывод конфигурации на экран
|
||||
std::cout << " Threads: " << conf_proc << ", "; |
||||
|
||||
if(conf_mode) |
||||
std::cout << "search high addresses (" << conf_high << "), "; |
||||
else |
||||
std::cout << "search by name (" << conf_search << "), "; |
||||
|
||||
if(conf_log) |
||||
std::cout << "logging to text file." << std::endl; |
||||
else |
||||
std::cout << "console log only." << std::endl; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void testoutput() |
||||
{ |
||||
if(conf_log) // проверка включено ли логирование
|
||||
{ |
||||
if(conf_mode) |
||||
log_file = "syg-high.txt"; |
||||
else |
||||
log_file = "syg-byname.txt"; |
||||
|
||||
std::ifstream test(log_file); |
||||
if(!test) // проверка наличия выходного файла
|
||||
{ |
||||
test.close(); |
||||
std::ofstream output(log_file); |
||||
output << "**************************************************************************\n" |
||||
<< "Change EncryptionPublicKey and EncryptionPrivateKey to your yggdrasil.conf\n" |
||||
<< "Windows: C:\\ProgramData\\Yggdrasil\\yggdrasil.conf\n" |
||||
<< "Debian: /etc/yggdrasil.conf\n\n" |
||||
<< "Visit HowTo.Ygg wiki for more information (russian language page):\n" |
||||
<< "http://[300:529f:150c:eafe::6]/doku.php?id=yggdrasil:simpleygggen_cpp\n" |
||||
<< "**************************************************************************\n"; |
||||
output.close(); |
||||
} else test.close(); |
||||
} |
||||
} |
||||
|
||||
struct BoxKeys |
||||
{ |
||||
uint8_t PublicKey[KEYSIZE]; |
||||
uint8_t PrivateKey[KEYSIZE]; |
||||
}; |
||||
|
||||
BoxKeys getKeyPair() |
||||
{ |
||||
BoxKeys keys; |
||||
size_t len = KEYSIZE; |
||||
|
||||
EVP_PKEY_CTX * Ctx; |
||||
EVP_PKEY * Pkey = nullptr; |
||||
Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL); |
||||
|
||||
EVP_PKEY_keygen_init (Ctx); |
||||
EVP_PKEY_keygen (Ctx, &Pkey); |
||||
|
||||
EVP_PKEY_get_raw_public_key (Pkey, keys.PublicKey, &len); |
||||
EVP_PKEY_get_raw_private_key (Pkey, keys.PrivateKey, &len); |
||||
|
||||
EVP_PKEY_CTX_free(Ctx); |
||||
EVP_PKEY_free(Pkey); |
||||
|
||||
return keys; |
||||
} |
||||
|
||||
int getOnes(const unsigned char HashValue[SHA512_DIGEST_LENGTH]) |
||||
{ |
||||
bool done = false; |
||||
int lOnes = 0; // кол-во лидирующих единиц
|
||||
|
||||
std::vector<std::bitset<8>> bytes; // вектор с однобайтовыми битсетами (двумерный массив)
|
||||
for(int i = 0; i < 32; ++i) // всего 32 байта, т.к. лидирующих единиц больше быть не может (32*8 = 256 бит, а ff = 255)
|
||||
bytes.push_back(HashValue[i]); // вставка в вектор с битсетами одного i-того байта хэша
|
||||
|
||||
for(auto vector_count = bytes.begin(); vector_count != bytes.end() && !done; vector_count++) |
||||
{ |
||||
for(int i = 7; i >= 0 && !done; --i) |
||||
{ |
||||
if((*vector_count)[i] == 1) // обращение к i-тому элементу битсета
|
||||
++lOnes; |
||||
if((*vector_count)[i] == 0) |
||||
done = true; |
||||
} |
||||
} |
||||
return lOnes; |
||||
} |
||||
|
||||
std::string getAddress(unsigned char HashValue[SHA512_DIGEST_LENGTH]) |
||||
{ |
||||
// функция "портит" массив хэша, т.к. копирование массива не происходит
|
||||
int lErase = getOnes(HashValue) + 1; // лидирующие единицы и первый ноль
|
||||
|
||||
bool changeit = false; |
||||
int bigbyte = 0; |
||||
|
||||
for(int j = 0; j < lErase; ++j) // побитовое смещение
|
||||
{ |
||||
for(int i = 63; i >= 0; --i) |
||||
{ |
||||
if(bigbyte == i+1) // предыдущий байт требует переноса
|
||||
changeit = true; |
||||
|
||||
if(HashValue[i] & 0x80) |
||||
bigbyte = i; |
||||
|
||||
HashValue[i] <<= 1; |
||||
|
||||
if(changeit) |
||||
{ |
||||
HashValue[i] |= 0x01; |
||||
changeit = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
std::string address; |
||||
bool shortadd = false; |
||||
std::stringstream ss(address); |
||||
ss << 0x02 << std::setw(2) << std::setfill('0') << std::hex << lErase - 1 << ":"; |
||||
// 2 - константа подсети Yggdrasil, второй байт - кол-во лидирующих единиц в хешэ
|
||||
|
||||
for(int i = 0; i < 14; ++i) |
||||
{ |
||||
if(i % 2 == 0) // если работаем с первым байтом секции
|
||||
{ |
||||
if(HashValue[i] == 0) // если байт нулевой
|
||||
{ |
||||
if(HashValue[i+1] == 0) // если следующий байт нулевой
|
||||
{ |
||||
if(HashValue[i+2] == 0 && i+2 < 13 && HashValue[i+3] == 0 && i+3 <= 13 && !shortadd) |
||||
{ |
||||
ss << ":"; |
||||
i += 3; |
||||
shortadd = true; |
||||
continue; |
||||
} else { |
||||
ss << "0"; |
||||
++i; |
||||
} |
||||
} |
||||
} else { |
||||
ss << std::hex << (int)HashValue[i]; |
||||
} |
||||
} else { // если работаем со вторым байтом секции
|
||||
if(HashValue[i-1] == 0) // если предыдущий первый байт был нулевой, нули сокращаем
|
||||
ss << std::hex << (int)HashValue[i]; |
||||
else |
||||
ss << std::setw(2) << std::setfill('0') << std::hex << (int)HashValue[i]; |
||||
} |
||||
if(i != 13 && i % 2 != 0) // не выводим двоеточие в конце адреса и после первого байта секции
|
||||
ss << ":"; |
||||
} |
||||
return ss.str(); |
||||
} |
||||
|
||||
void getConsoleLog() |
||||
{ |
||||
mtx.lock(); |
||||
++totalcount; |
||||
if(totalcount % 250000 == 0) |
||||
{ |
||||
if(newline) |
||||
{ |
||||
std::cout << std::endl; |
||||
newline = false; |
||||
} |
||||
std::time_t realtime = std::time(NULL); |
||||
|
||||
std::cout << " # count [ " << std::dec << std::setfill('.') << std::setw(19) << totalcount << " ] [ " |
||||
<< std::setw(15) << totalcountfortune << " ] " << std::asctime(std::localtime(&realtime)); |
||||
std::cout.flush(); |
||||
} |
||||
mtx.unlock(); |
||||
} |
||||
|
||||
void highminer() |
||||
{ |
||||
unsigned char HashValue[SHA512_DIGEST_LENGTH]; |
||||
|
||||
uint8_t PublicKeyBest[KEYSIZE]; |
||||
uint8_t PrivateKeyBest[KEYSIZE]; |
||||
|
||||
while(true) |
||||
{ |
||||
BoxKeys myKeys = getKeyPair(); |
||||
SHA512(myKeys.PublicKey, KEYSIZE, HashValue); |
||||
int newones = getOnes(HashValue); |
||||
|
||||
if(newones > conf_high) // сохранение лучших ключей
|
||||
{ |
||||
conf_high = newones; |
||||
for(int i = 0; i < KEYSIZE; ++i) |
||||
{ |
||||
PublicKeyBest[i] = myKeys.PublicKey[i]; |
||||
PrivateKeyBest[i] = myKeys.PrivateKey[i]; |
||||
} |
||||
|
||||
std::string address = getAddress(HashValue); |
||||
mtx.lock(); |
||||
std::cout << "\n Address: " << address << std::endl; |
||||
std::cout << " PublicKey: "; |
||||
for(int i = 0; i < 32; ++i) |
||||
{ |
||||
std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)PublicKeyBest[i]; |
||||
} |
||||
std::cout << std::endl; |
||||
|
||||
std::cout << " PrivateKey: "; |
||||
for(int i = 0; i < 32; ++i) |
||||
{ |
||||
std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)PrivateKeyBest[i]; |
||||
} |
||||
std::cout << std::endl; |
||||
|
||||
if(conf_log) // запись в файл
|
||||
{ |
||||
std::ofstream output(log_file, std::ios::app); |
||||
output << "\nAddress: " << address << std::endl; |
||||
output << "EncryptionPublicKey: "; |
||||
for(int i = 0; i < 32; ++i) |
||||
{ |
||||
output << std::setw(2) << std::setfill('0') << std::hex << (int)PublicKeyBest[i]; |
||||
} |
||||
output << std::endl; |
||||
|
||||
output << "EncryptionPrivateKey: "; |
||||
for(int i = 0; i < 32; ++i) |
||||
{ |
||||
output << std::setw(2) << std::setfill('0') << std::hex << (int)PrivateKeyBest[i]; |
||||
} |
||||
output << std::endl; |
||||
output.close(); |
||||
} |
||||
++totalcountfortune; |
||||
newline = true; |
||||
mtx.unlock(); |
||||
} |
||||
getConsoleLog(); |
||||
} // while(true)
|
||||
} |
||||
|
||||
void nameminer() |
||||
{ |
||||
unsigned char HashValue[SHA512_DIGEST_LENGTH]; |
||||
|
||||
uint8_t PublicKeyBest[KEYSIZE]; |
||||
uint8_t PrivateKeyBest[KEYSIZE]; |
||||
|
||||
while(true) |
||||
{ |
||||
BoxKeys myKeys = getKeyPair(); |
||||
SHA512(myKeys.PublicKey, KEYSIZE, HashValue); |
||||
std::string tempstr = getAddress(HashValue); |
||||
|
||||
if(tempstr.find(conf_search.c_str()) != std::string::npos) // сохранение найденных ключей
|
||||
{ |
||||
for(int i = 0; i < KEYSIZE; ++i) |
||||
{ |
||||
PublicKeyBest[i] = myKeys.PublicKey[i]; |
||||
PrivateKeyBest[i] = myKeys.PrivateKey[i]; |
||||
} |
||||
mtx.lock(); |
||||
std::cout << "\n Address: " << tempstr << std::endl; |
||||
std::cout << " PublicKey: "; |
||||
for(int i = 0; i < 32; ++i) |
||||
{ |
||||
std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)PublicKeyBest[i]; |
||||
} |
||||
std::cout << std::endl; |
||||
|
||||
std::cout << " PrivateKey: "; |
||||
for(int i = 0; i < 32; ++i) |
||||
{ |
||||
std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)PrivateKeyBest[i]; |
||||
} |
||||
std::cout << std::endl; |
||||
|
||||
if(conf_log) // запись в файл
|
||||
{ |
||||
std::ofstream output(log_file, std::ios::app); |
||||
output << "\nAddress: " << tempstr << std::endl; |
||||
output << "EncryptionPublicKey: "; |
||||
for(int i = 0; i < 32; ++i) |
||||
{ |
||||
output << std::setw(2) << std::setfill('0') << std::hex << (int)PublicKeyBest[i]; |
||||
} |
||||
output << std::endl; |
||||
output << "EncryptionPrivateKey: "; |
||||
for(int i = 0; i < 32; ++i) |
||||
{ |
||||
output << std::setw(2) << std::setfill('0') << std::hex << (int)PrivateKeyBest[i]; |
||||
} |
||||
output << std::endl; |
||||
output.close(); |
||||
} |
||||
++totalcountfortune; |
||||
newline = true; |
||||
mtx.unlock(); |
||||
} |
||||
getConsoleLog(); |
||||
} |
||||
} |
||||
|
||||
// ------------------------------------------------------
|
||||
int main() |
||||
{ |
||||
intro(); |
||||
|
||||
int configcheck = config(); |
||||
if(configcheck < 0) // функция получения конфигурации
|
||||
{ |
||||
std::cerr << "Error code: " << configcheck << std::endl; |
||||
system("PAUSE"); |
||||
return configcheck; |
||||
} |
||||
|
||||
testoutput(); |
||||
if(conf_mode) // запуск соответствующего режима майнинга
|
||||
{ |
||||
std::thread * threads[conf_proc]; |
||||
for(int i = 0; i < conf_proc; ++i) |
||||
threads[i] = new std::thread(highminer); |
||||
|
||||
for(int i = 0; i < conf_proc - 1; ++i) |
||||
threads[i]->detach(); |
||||
|
||||
threads[conf_proc-1]->join(); // "ждем" последний трэд, бесконечное ожидание
|
||||
} |
||||
else |
||||
{ |
||||
std::thread * threads[conf_proc]; |
||||
for(int i = 0; i < conf_proc; ++i) |
||||
threads[i] = new std::thread(nameminer); |
||||
|
||||
for(int i = 0; i < conf_proc - 1; ++i) |
||||
threads[i]->detach(); |
||||
|
||||
threads[conf_proc-1]->join(); |
||||
} |
||||
|
||||
std::cerr << "SYG has stopped working unexpectedly! Please, report about this." << std::endl; |
||||
system("PAUSE"); |
||||
return -420; |
||||
} |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
#include <winresrc.h> |
||||
|
||||
#define MAINICON 101 |
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US |
||||
#pragma code_page(1252) |
||||
|
||||
MAINICON ICON "syg-cpp-logo.ico" |
||||
|
||||
VS_VERSION_INFO VERSIONINFO |
||||
FILEVERSION 1,1,0,0 |
||||
PRODUCTVERSION 1,1,0,0 |
||||
|
||||
FILEOS 0x40004L |
||||
FILETYPE 0x1L |
||||
FILESUBTYPE 0x0L |
||||
|
||||
BEGIN |
||||
BLOCK "StringFileInfo" |
||||
BEGIN |
||||
BLOCK "040904b0" |
||||
BEGIN |
||||
VALUE "CompanyName", "acetone" |
||||
VALUE "FileDescription", "SimpleYggGen" |
||||
VALUE "FileVersion", "1.1.0.0" |
||||
VALUE "LegalCopyright", "Copyright (C) 2020, acetone" |
||||
VALUE "OriginalFilename", "sygcpp" |
||||
VALUE "ProductName", "SimpleYggGen" |
||||
VALUE "ProductVersion", "1.1-train" |
||||
END |
||||
END |
||||
BLOCK "VarFileInfo" |
||||
BEGIN |
||||
VALUE "Translation", 0x409, 1252 |
||||
END |
||||
END |
After Width: | Height: | Size: 15 KiB |
Loading…
Reference in new issue