sygcpp.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /**
  2. * Thanks PurpleI2P Project for support to writing that code.
  3. *
  4. * IRC: irc.ilita.i2p port 6667 || 303:60d4:3d32:a2b9::3 port 16667
  5. * general channels: #ru and #howtoygg
  6. *
  7. * git: notabug.org/acetone/SimpleYggGen-CPP
  8. *
  9. * developers: acetone, lialh4, orignal, R4SAS, Vort
  10. * developers team, 2020 (c) GPLv3
  11. *
  12. */
  13. #include <sodium.h> // библиотека libsodium
  14. #include <iostream> // вывод на экран
  15. #include <string>
  16. #include <sstream>
  17. #include <fstream> // файловые потоки
  18. #include <iomanip> // форматированный вывод строк
  19. #include <bitset> // побитовое чтение
  20. #include <vector>
  21. #include <thread> // многопоточность
  22. #include <mutex>
  23. #include <chrono> // для паузы в заставке
  24. #include <ctime>
  25. #ifdef _WIN32 // преобразование в IPv6
  26. #include <ws2tcpip.h>
  27. #else
  28. #include <arpa/inet.h>
  29. #endif
  30. ////////////////////////////////////////////////// Заставка
  31. void intro()
  32. {
  33. std::cout << std::endl
  34. << " +--------------------------------------------------------------------------+" << std::endl
  35. << " | SimpleYggGen C++ 2.0-outrunning |" << std::endl
  36. << " | libsodium inside: x25519 -> sha512 |" << std::endl
  37. << " | notabug.org/acetone/SimpleYggGen-CPP |" << std::endl
  38. << " | |" << std::endl
  39. << " | developers: acetone, lialh4, orignal, R4SAS, Vort |" << std::endl
  40. << " | GPLv3 (c) 2020 |" << std::endl
  41. << " +";
  42. for(int i = 0; i < 74; ++i)
  43. {
  44. std::cout << "-";
  45. std::cout.flush();
  46. std::this_thread::sleep_for(std::chrono::milliseconds(3));
  47. }
  48. std::cout << "+\n" << std::endl;
  49. }
  50. ////////////////////////////////////////////////// Суть вопроса
  51. #define SODIUM_STATIC
  52. #define KEYSIZE 32
  53. std::mutex mtx;
  54. int conf_proc = 0;
  55. int conf_mode = 0;
  56. int conf_log = 0;
  57. int conf_high = 0;
  58. std::string conf_search;
  59. std::string log_file;
  60. std::chrono::time_point<std::chrono::high_resolution_clock> startTime; // для вывода kH/s
  61. std::time_t sygstartedin = std::time(NULL); // для вывода времени работы
  62. uint64_t totalcount = 0; // счетчик основного цикла
  63. uint64_t totalcountfortune = 0; // счетчик нахождений
  64. int countsize = 0; // определяет периодичность вывода счетчика
  65. double khstemp = 0.0; // для подсчета килохешей
  66. bool newline = true; // используется для вывода счетчика: пустая строка после найденного адреса
  67. int config()
  68. {
  69. std::ifstream conffile ("sygcpp.conf");
  70. if(!conffile) // проверка наличия конфига
  71. {
  72. std::cout << " Configuration file not found..." << std::endl;
  73. conffile.close();
  74. std::ofstream newconf ("sygcpp.conf"); // создание конфига
  75. if(!newconf)
  76. {
  77. std::cerr << " Config (sygcpp.conf) creation failed :(" << std::endl;
  78. return -1;
  79. }
  80. newconf << "1 0 1 9 ::\n"
  81. << "| | | | ^Pattern for search by name.\n"
  82. << "| | | ^Start position for high addresses search.\n"
  83. << "| | ^Logging mode (0 - console output only, 1 - log to file).\n"
  84. << "| ^Mining mode (0 - by name, 1 - high address).\n"
  85. << "^Count of thread (mining streams).\n\n"
  86. << "Parameters are separated by spaces.";
  87. newconf.close();
  88. std::ifstream conffile ("sygcpp.conf");
  89. if(conffile)
  90. std::cout << " Config successfully created :)" << std::endl;
  91. config();
  92. return 0;
  93. } else {
  94. conffile >> conf_proc >> conf_mode >> conf_log >> conf_high >> conf_search;
  95. conffile.close();
  96. if(conf_mode > 1 || conf_mode < 0 || conf_log > 1 || conf_log < 0 || conf_high < 0) // проверка полученных значений
  97. {
  98. std::cerr << " Invalid config found! Check it:\n";
  99. if(conf_mode > 1 || conf_mode < 0)
  100. std::cerr << " - field #2 - mining mode: 0 or 1 only\n";
  101. if(conf_log > 1 || conf_log < 0)
  102. std::cerr << " - field #3 - logging mode: 0 or 1 only\n";
  103. if(conf_high < 0)
  104. std::cerr << " - field #4 - start position for high address search (default 9)\n";
  105. std::cerr << " Remove or correct sygcpp.conf and run SYG again."<< std::endl;
  106. return -2;
  107. }
  108. unsigned int processor_count = std::thread::hardware_concurrency(); // кол-во процессоров
  109. if(conf_proc > (int)processor_count)
  110. conf_proc = (int)processor_count;
  111. if(conf_proc <= 2)
  112. {
  113. countsize = 250000;
  114. khstemp = 250000000.0;
  115. } else {
  116. countsize = 500000;
  117. khstemp = 500000000.0;
  118. }
  119. }
  120. // вывод конфигурации на экран
  121. std::cout << " Threads: " << conf_proc << ", ";
  122. if(conf_mode)
  123. std::cout << "search high addresses (" << conf_high << "), ";
  124. else
  125. std::cout << "search by name (" << conf_search << "), ";
  126. if(conf_log)
  127. std::cout << "logging to text file." << std::endl;
  128. else
  129. std::cout << "console log only." << std::endl;
  130. return 0;
  131. }
  132. void testoutput()
  133. {
  134. if(conf_log) // проверка включено ли логирование
  135. {
  136. if(conf_mode)
  137. log_file = "syg-high.txt";
  138. else
  139. log_file = "syg-byname.txt";
  140. std::ifstream test(log_file);
  141. if(!test) // проверка наличия выходного файла
  142. {
  143. test.close();
  144. std::ofstream output(log_file);
  145. output << "**************************************************************************\n"
  146. << "Change EncryptionPublicKey and EncryptionPrivateKey to your yggdrasil.conf\n"
  147. << "Windows: C:\\ProgramData\\Yggdrasil\\yggdrasil.conf\n"
  148. << "Debian: /etc/yggdrasil.conf\n\n"
  149. << "Visit HowTo.Ygg wiki for more information (russian language page):\n"
  150. << "http://[300:529f:150c:eafe::6]/doku.php?id=yggdrasil:simpleygggen_cpp\n"
  151. << "**************************************************************************\n";
  152. output.close();
  153. } else test.close();
  154. }
  155. }
  156. struct BoxKeys
  157. {
  158. uint8_t PublicKey[KEYSIZE];
  159. uint8_t PrivateKey[KEYSIZE];
  160. };
  161. BoxKeys getKeyPair()
  162. {
  163. BoxKeys keys;
  164. randombytes(keys.PrivateKey, KEYSIZE);
  165. keys.PrivateKey[0] &= 248;
  166. keys.PrivateKey[KEYSIZE - 1] &= 127;
  167. keys.PrivateKey[KEYSIZE - 1] |= 64;
  168. crypto_scalarmult_curve25519_base(keys.PublicKey, keys.PrivateKey);
  169. return keys;
  170. }
  171. int getOnes(const unsigned char HashValue[crypto_hash_sha512_BYTES])
  172. {
  173. bool done = false;
  174. int lOnes = 0; // кол-во лидирующих единиц
  175. std::vector<std::bitset<8>> bytes; // вектор с однобайтовыми битсетами (двумерный массив)
  176. for(int i = 0; i < 32; ++i) // всего 32 байта, т.к. лидирующих единиц больше быть не может (32*8 = 256 бит, а ff = 255)
  177. bytes.push_back(HashValue[i]); // вставка в вектор с битсетами одного i-того байта хэша
  178. for(auto vector_count = bytes.begin(); vector_count != bytes.end() && !done; vector_count++)
  179. {
  180. for(int i = 7; i >= 0 && !done; --i)
  181. {
  182. if((*vector_count)[i] == 1) // обращение к i-тому элементу битсета
  183. ++lOnes;
  184. if((*vector_count)[i] == 0)
  185. done = true;
  186. }
  187. }
  188. return lOnes;
  189. }
  190. std::string getAddress(unsigned char HashValue[crypto_hash_sha512_BYTES])
  191. {
  192. // функция "портит" массив хэша, т.к. копирование массива не происходит
  193. int lErase = getOnes(HashValue) + 1; // лидирующие единицы и первый ноль
  194. bool changeit = false;
  195. int bigbyte = 0;
  196. for(int j = 0; j < lErase; ++j) // побитовое смещение
  197. {
  198. for(int i = 63; i >= 0; --i)
  199. {
  200. if(bigbyte == i+1) // предыдущий байт требует переноса
  201. changeit = true;
  202. if(HashValue[i] & 0x80)
  203. bigbyte = i;
  204. HashValue[i] <<= 1;
  205. if(changeit)
  206. {
  207. HashValue[i] |= 0x01;
  208. changeit = false;
  209. }
  210. }
  211. }
  212. uint8_t ipAddr[16];
  213. ipAddr[0] = 0x02;
  214. ipAddr[1] = lErase - 1;
  215. for (int i = 0; i < 14; ++i)
  216. ipAddr[i + 2] = HashValue[i];
  217. char ipStrBuf[46];
  218. inet_ntop(AF_INET6, ipAddr, ipStrBuf, 46);
  219. return std::string(ipStrBuf);
  220. }
  221. void getConsoleLog()
  222. {
  223. mtx.lock();
  224. ++totalcount;
  225. if(totalcount % countsize == 0)
  226. {
  227. if(newline)
  228. {
  229. std::cout << std::endl;
  230. newline = false;
  231. }
  232. auto stopTime = std::chrono::high_resolution_clock::now();
  233. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stopTime - startTime);
  234. startTime = stopTime;
  235. float khs = khstemp / duration.count();
  236. auto timedays = (std::time(NULL) - sygstartedin) / 86400;
  237. auto timehours = ((std::time(NULL) - sygstartedin) - (timedays * 86400)) / 3600;
  238. auto timeminutes = ((std::time(NULL) - sygstartedin) - (timedays * 86400) - (timehours * 3600)) / 60;
  239. auto timeseconds = (std::time(NULL) - sygstartedin) - (timedays * 86400) - (timehours * 3600) - (timeminutes * 60);
  240. std::cout << " kH/s: [" << std::setw(7) << std::dec << std::fixed << std::setprecision(3)
  241. << std::setfill('_') << khs << "] Total: [" << std::setw(19) << totalcount << "] Found: ["
  242. << std::setw(3) << totalcountfortune << "] Uptime: " << timedays << ":" << std::setw(2) << std::setfill('0')
  243. << timehours << ":" << std::setw(2) << timeminutes << ":" << std::setw(2) << timeseconds << std::endl;
  244. }
  245. mtx.unlock();
  246. }
  247. void highminer()
  248. {
  249. unsigned char HashValue[crypto_hash_sha512_BYTES];
  250. uint8_t PublicKeyBest[KEYSIZE];
  251. uint8_t PrivateKeyBest[KEYSIZE];
  252. startTime = std::chrono::high_resolution_clock::now();
  253. while(true)
  254. {
  255. BoxKeys myKeys = getKeyPair();
  256. crypto_hash_sha512(HashValue, myKeys.PublicKey, KEYSIZE);
  257. int newones = getOnes(HashValue);
  258. if(newones > conf_high) // сохранение лучших ключей
  259. {
  260. std::right;
  261. conf_high = newones;
  262. for(int i = 0; i < KEYSIZE; ++i)
  263. {
  264. PublicKeyBest[i] = myKeys.PublicKey[i];
  265. PrivateKeyBest[i] = myKeys.PrivateKey[i];
  266. }
  267. std::string address = getAddress(HashValue);
  268. mtx.lock();
  269. std::cout << "\n Address: " << address << std::endl;
  270. std::cout << " PublicKey: ";
  271. for(int i = 0; i < 32; ++i)
  272. {
  273. std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)PublicKeyBest[i];
  274. }
  275. std::cout << std::endl;
  276. std::cout << " PrivateKey: ";
  277. for(int i = 0; i < 32; ++i)
  278. {
  279. std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)PrivateKeyBest[i];
  280. }
  281. std::cout << std::endl;
  282. if(conf_log) // запись в файл
  283. {
  284. std::ofstream output(log_file, std::ios::app);
  285. output << "\nAddress: " << address << std::endl;
  286. output << "EncryptionPublicKey: ";
  287. for(int i = 0; i < 32; ++i)
  288. {
  289. output << std::setw(2) << std::setfill('0') << std::hex << (int)PublicKeyBest[i];
  290. }
  291. output << std::endl;
  292. output << "EncryptionPrivateKey: ";
  293. for(int i = 0; i < 32; ++i)
  294. {
  295. output << std::setw(2) << std::setfill('0') << std::hex << (int)PrivateKeyBest[i];
  296. }
  297. output << std::endl;
  298. output.close();
  299. }
  300. ++totalcountfortune;
  301. newline = true;
  302. mtx.unlock();
  303. }
  304. getConsoleLog();
  305. } // while(true)
  306. }
  307. void nameminer()
  308. {
  309. unsigned char HashValue[crypto_hash_sha512_BYTES];
  310. uint8_t PublicKeyBest[KEYSIZE];
  311. uint8_t PrivateKeyBest[KEYSIZE];
  312. startTime = std::chrono::high_resolution_clock::now();
  313. while(true)
  314. {
  315. BoxKeys myKeys = getKeyPair();
  316. crypto_hash_sha512(HashValue, myKeys.PublicKey, KEYSIZE);
  317. std::string tempstr = getAddress(HashValue);
  318. if(tempstr.find(conf_search.c_str()) != std::string::npos) // сохранение найденных ключей
  319. {
  320. std::right;
  321. for(int i = 0; i < KEYSIZE; ++i)
  322. {
  323. PublicKeyBest[i] = myKeys.PublicKey[i];
  324. PrivateKeyBest[i] = myKeys.PrivateKey[i];
  325. }
  326. mtx.lock();
  327. std::cout << "\n Address: " << tempstr << std::endl;
  328. std::cout << " PublicKey: ";
  329. for(int i = 0; i < 32; ++i)
  330. {
  331. std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)PublicKeyBest[i];
  332. }
  333. std::cout << std::endl;
  334. std::cout << " PrivateKey: ";
  335. for(int i = 0; i < 32; ++i)
  336. {
  337. std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)PrivateKeyBest[i];
  338. }
  339. std::cout << std::endl;
  340. if(conf_log) // запись в файл
  341. {
  342. std::ofstream output(log_file, std::ios::app);
  343. output << "\nAddress: " << tempstr << std::endl;
  344. output << "EncryptionPublicKey: ";
  345. for(int i = 0; i < 32; ++i)
  346. {
  347. output << std::setw(2) << std::setfill('0') << std::hex << (int)PublicKeyBest[i];
  348. }
  349. output << std::endl;
  350. output << "EncryptionPrivateKey: ";
  351. for(int i = 0; i < 32; ++i)
  352. {
  353. output << std::setw(2) << std::setfill('0') << std::hex << (int)PrivateKeyBest[i];
  354. }
  355. output << std::endl;
  356. output.close();
  357. }
  358. ++totalcountfortune;
  359. newline = true;
  360. mtx.unlock();
  361. }
  362. getConsoleLog();
  363. }
  364. }
  365. // ------------------------------------------------------
  366. int main()
  367. {
  368. intro();
  369. int configcheck = config();
  370. if(configcheck < 0) // функция получения конфигурации
  371. {
  372. std::cerr << " Error code: " << configcheck << std::endl << std::endl;
  373. system("PAUSE");
  374. return configcheck;
  375. }
  376. testoutput();
  377. if(conf_mode) // запуск соответствующего режима майнинга
  378. {
  379. std::thread * threads[conf_proc];
  380. for(int i = 0; i < conf_proc; ++i)
  381. threads[i] = new std::thread(highminer);
  382. for(int i = 0; i < conf_proc - 1; ++i)
  383. threads[i]->detach();
  384. threads[conf_proc-1]->join(); // "ждем" последний трэд, бесконечное ожидание
  385. } else {
  386. std::thread * threads[conf_proc];
  387. for(int i = 0; i < conf_proc; ++i)
  388. threads[i] = new std::thread(nameminer);
  389. for(int i = 0; i < conf_proc - 1; ++i)
  390. threads[i]->detach();
  391. threads[conf_proc-1]->join();
  392. }
  393. std::cerr << "SYG has stopped working unexpectedly! Please, report about this." << std::endl;
  394. system("PAUSE");
  395. return -420;
  396. }