commit 7b64aba9dad147a68a437280503d26bf7c22c5ce Author: R4SAS Date: Mon Aug 17 11:38:24 2020 +0300 init restructured 1.1 release Signed-off-by: R4SAS diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eae497d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/obj +/sygcpp* +/syg-*.txt +/sygcpp.conf \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..212153e --- /dev/null +++ b/Makefile @@ -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 diff --git a/Makefile.mingw b/Makefile.mingw new file mode 100644 index 0000000..3cedfc1 --- /dev/null +++ b/Makefile.mingw @@ -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 $@ diff --git a/README.md b/README.md new file mode 100644 index 0000000..aad236b --- /dev/null +++ b/README.md @@ -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` diff --git a/sygcpp.cpp b/sygcpp.cpp new file mode 100644 index 0000000..fe9fe61 --- /dev/null +++ b/sygcpp.cpp @@ -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 +#include +#include +#include // вывод на экран +#include +#include +#include // файловые потоки +#include // форматированный вывод строк +#include // побитовое чтение +#include +#include // многопоточность +#include +#include // для паузы в заставке +#include + +////////////////////////////////////////////////// Заставка + +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> 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; +} diff --git a/windows/resource.rc b/windows/resource.rc new file mode 100644 index 0000000..5fe1680 --- /dev/null +++ b/windows/resource.rc @@ -0,0 +1,36 @@ +#include + +#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 diff --git a/windows/syg-cpp-logo.ico b/windows/syg-cpp-logo.ico new file mode 100644 index 0000000..56f16a5 Binary files /dev/null and b/windows/syg-cpp-logo.ico differ