sygcpp.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /**
  2. *
  3. * IRC: irc.ilita.i2p port 6667 || 303:60d4:3d32:a2b9::3 port 16667
  4. * general channels: #ru and #howtoygg
  5. *
  6. * acetone (default) git: notabug.org/acetone/SimpleYggGen-CPP
  7. * Vort (member) git: notabug.org/Vort/SimpleYggGen-CPP
  8. *
  9. * developers: acetone, lialh4, orignal, R4SAS, Vort
  10. * developers team, 2020 (c) GPLv3
  11. *
  12. */
  13. #include <x86intrin.h>
  14. #include <string.h> // memcmp
  15. #include <sodium.h> // библиотека libsodium
  16. #include <iostream> // вывод на экран
  17. #include <string>
  18. #include <sstream>
  19. #include <fstream> // файловые потоки
  20. #include <iomanip> // форматированный вывод строк
  21. #include <bitset> // побитовое чтение
  22. #include <vector>
  23. #include <thread> // многопоточность
  24. #include <mutex> // блокирование данных при многопоточности
  25. #include <chrono> // для вычисления скорости
  26. #include <ctime>
  27. #include <regex> // регулярные выражения
  28. #ifdef _WIN32 // преобразование в IPv6
  29. #include <ws2tcpip.h>
  30. #else
  31. #include <arpa/inet.h>
  32. #endif
  33. #include "x25519.h"
  34. #include "sha512.h"
  35. #define BLOCKSIZE 10000
  36. //#define SELF_CHECK // debug
  37. ////////////////////////////////////////////////// Заставка
  38. void Intro()
  39. {
  40. std::cout <<
  41. std::endl <<
  42. " +--------------------------------------------------------------------------+" << std::endl <<
  43. " | SimpleYggGen C++ 3.2.1-legend |" << std::endl <<
  44. " | X25519 -> SHA512 -> IPv6 |" << std::endl <<
  45. " | notabug.org/acetone/SimpleYggGen-CPP |" << std::endl <<
  46. " | |" << std::endl <<
  47. " | developers: Vort, acetone, R4SAS, lialh4, orignal |" << std::endl <<
  48. " | GPLv3 (c) 2020 |" << std::endl <<
  49. " +--------------------------------------------------------------------------+" << std::endl <<
  50. std::endl;
  51. }
  52. ////////////////////////////////////////////////// Суть вопроса
  53. std::mutex mtx;
  54. std::time_t sygstartedin = std::time(NULL); // для вывода времени работы
  55. int countsize = 0; // определяет периодичность вывода счетчика
  56. uint64_t block_count = 0; // количество вычисленных блоков
  57. uint64_t totalcountfortune = 0; // счетчик нахождений
  58. bool newline = false; // форматирует вывод после нахождения адреса
  59. std::chrono::steady_clock::duration blocks_duration(0);
  60. #include "basefiles.cpp"
  61. int getOnes(const unsigned char HashValue[crypto_hash_sha512_BYTES])
  62. {
  63. int lOnes = 0; // кол-во лидирующих единиц
  64. for (int i = 0; i < 32; ++i) // всего 32 байта, т.к. лидирующих единиц больше быть не может (32*8 = 256 бит, а ff = 255)
  65. {
  66. std::bitset<8> bits(HashValue[i]);
  67. for (int i = 7; i >= 0; --i)
  68. {
  69. if (bits[i] == 1) // обращение к i-тому элементу битсета
  70. ++lOnes;
  71. else
  72. return lOnes;
  73. }
  74. }
  75. return -421; // это никогда не случится
  76. }
  77. std::string getAddress(unsigned char HashValue[crypto_hash_sha512_BYTES])
  78. {
  79. // функция "портит" массив хэша, т.к. копирование массива не происходит
  80. int lErase = getOnes(HashValue) + 1; // лидирующие единицы и первый ноль
  81. bool changeit = false;
  82. int bigbyte = 0;
  83. for(int j = 0; j < lErase; ++j) // побитовое смещение
  84. {
  85. for(int i = 63; i >= 0; --i)
  86. {
  87. if(bigbyte == i+1) // предыдущий байт требует переноса
  88. changeit = true;
  89. if(HashValue[i] & 0x80)
  90. bigbyte = i;
  91. HashValue[i] <<= 1;
  92. if(changeit)
  93. {
  94. HashValue[i] |= 0x01;
  95. changeit = false;
  96. }
  97. }
  98. }
  99. uint8_t ipAddr[16];
  100. ipAddr[0] = 0x02;
  101. ipAddr[1] = lErase - 1;
  102. for (int i = 0; i < 14; ++i)
  103. ipAddr[i + 2] = HashValue[i];
  104. char ipStrBuf[46];
  105. inet_ntop(AF_INET6, ipAddr, ipStrBuf, 46);
  106. return std::string(ipStrBuf);
  107. }
  108. void logStatistics()
  109. {
  110. if (++block_count % countsize == 0)
  111. {
  112. auto timedays = (std::time(NULL) - sygstartedin) / 86400;
  113. auto timehours = ((std::time(NULL) - sygstartedin) - (timedays * 86400)) / 3600;
  114. auto timeminutes = ((std::time(NULL) - sygstartedin) - (timedays * 86400) - (timehours * 3600)) / 60;
  115. auto timeseconds = (std::time(NULL) - sygstartedin) - (timedays * 86400) - (timehours * 3600) - (timeminutes * 60);
  116. std::chrono::duration<double, std::milli> df = blocks_duration;
  117. blocks_duration = std::chrono::steady_clock::duration::zero();
  118. int khs = conf.proc * countsize * BLOCKSIZE / df.count();
  119. std::cout <<
  120. " kH/s: [" << std::setw(7) << std::setfill('_') << khs <<
  121. "] Total: [" << std::setw(19) << block_count * BLOCKSIZE <<
  122. "] Found: [" << std::setw(3) << totalcountfortune <<
  123. "] Time: [" << timedays << ":" << std::setw(2) << std::setfill('0') <<
  124. timehours << ":" << std::setw(2) << timeminutes << ":" << std::setw(2) << timeseconds << "]" << std::endl;
  125. newline = true;
  126. }
  127. }
  128. std::string hexArrayToString(const uint8_t* bytes, int length)
  129. {
  130. std::stringstream ss;
  131. for (int i = 0; i < length; i++)
  132. ss << std::setw(2) << std::setfill('0') << std::hex << (int)bytes[i];
  133. return ss.str();
  134. }
  135. std::string keyToString(const key25519 key)
  136. {
  137. return hexArrayToString(key, KEYSIZE);
  138. }
  139. std::string hashToString(const uint8_t hash[crypto_hash_sha512_BYTES])
  140. {
  141. return hexArrayToString(hash, crypto_hash_sha512_BYTES);
  142. }
  143. void logKeys(std::string address, const key25519 publicKey, const key25519 privateKey)
  144. {
  145. if(newline) // добавляем пустую строку на экране между счетчиком и новым адресом
  146. {
  147. std::cout << std::endl;
  148. newline = false;
  149. }
  150. std::cout << " Address: " << address << std::endl;
  151. std::cout << " PublicKey: " << keyToString(publicKey) << std::endl;
  152. std::cout << " PrivateKey: " << keyToString(privateKey) << std::endl;
  153. std::cout << std::endl;
  154. if (conf.log) // запись в файл
  155. {
  156. std::ofstream output(conf.outputfile, std::ios::app);
  157. output << std::endl;
  158. output << "Address: " << address << std::endl;
  159. output << "EncryptionPublicKey: " << keyToString(publicKey) << std::endl;
  160. output << "EncryptionPrivateKey: " << keyToString(privateKey) << std::endl;
  161. output.close();
  162. }
  163. }
  164. void process_fortune_key(const keys_block& block, int index)
  165. {
  166. if (index == -1)
  167. return;
  168. key25519 public_key;
  169. key25519 private_key;
  170. block.get_public_key(public_key, index);
  171. block.get_private_key(private_key, index);
  172. uint8_t sha512_hash[crypto_hash_sha512_BYTES];
  173. crypto_hash_sha512(sha512_hash, public_key);
  174. std::string address = getAddress(sha512_hash);
  175. logKeys(address, public_key, private_key);
  176. ++totalcountfortune;
  177. }
  178. template <int T>
  179. void miner_thread()
  180. {
  181. key25519 public_key;
  182. keys_block block(BLOCKSIZE);
  183. uint8_t random_bytes[KEYSIZE];
  184. uint8_t sha512_hash[crypto_hash_sha512_BYTES];
  185. std::regex regx(conf.rgx_search, std::regex_constants::egrep);
  186. for (;;)
  187. {
  188. auto start_time = std::chrono::steady_clock::now();
  189. int fortune_key_index = -1;
  190. randombytes(random_bytes, KEYSIZE);
  191. block.calculate_public_keys(random_bytes);
  192. for (int i = 0; i < BLOCKSIZE; i++)
  193. {
  194. block.get_public_key(public_key, i);
  195. crypto_hash_sha512(sha512_hash, public_key);
  196. if (T == 0) // pattern mining
  197. {
  198. if (getAddress(sha512_hash).find(
  199. conf.str_search.c_str()) != std::string::npos)
  200. {
  201. fortune_key_index = i;
  202. break; // можно использовать только один ключ из блока
  203. }
  204. }
  205. if (T == 1) // high mining
  206. {
  207. int newones = getOnes(sha512_hash);
  208. if (newones > conf.high)
  209. {
  210. conf.high = newones;
  211. fortune_key_index = i;
  212. }
  213. }
  214. if (T == 2) // pattern & high mining
  215. {
  216. int newones = getOnes(sha512_hash);
  217. if (getAddress(sha512_hash).find(
  218. conf.str_search.c_str()) != std::string::npos &&
  219. newones > conf.high)
  220. {
  221. conf.high = newones;
  222. fortune_key_index = i;
  223. break;
  224. }
  225. }
  226. if (T == 3) // regexp mining
  227. {
  228. if (std::regex_search((getAddress(sha512_hash)), regx))
  229. {
  230. fortune_key_index = i;
  231. break;
  232. }
  233. }
  234. if (T == 4) // regexp & high mining
  235. {
  236. int newones = getOnes(sha512_hash);
  237. if (std::regex_search((getAddress(sha512_hash)), regx) &&
  238. newones > conf.high)
  239. {
  240. conf.high = newones;
  241. fortune_key_index = i;
  242. break;
  243. }
  244. }
  245. }
  246. auto stop_time = std::chrono::steady_clock::now();
  247. mtx.lock();
  248. blocks_duration += stop_time - start_time;
  249. process_fortune_key(block, fortune_key_index);
  250. logStatistics();
  251. mtx.unlock();
  252. }
  253. }
  254. #ifdef SELF_CHECK // debug
  255. void selfCheck()
  256. {
  257. std::cout << "Self-check started." << std::endl;
  258. for (int i = 0; i < 16; i++)
  259. {
  260. int block_size = 1 << i;
  261. keys_block block(block_size);
  262. uint8_t random_bytes[KEYSIZE];
  263. randombytes(random_bytes, KEYSIZE);
  264. block.calculate_public_keys(random_bytes);
  265. key25519 public_key1;
  266. key25519 public_key2;
  267. key25519 private_key;
  268. uint8_t sha512_hash1[crypto_hash_sha512_BYTES];
  269. uint8_t sha512_hash2[crypto_hash_sha512_BYTES];
  270. for (int j = 0; j < block_size; j++)
  271. {
  272. block.get_public_key(public_key1, j);
  273. block.get_private_key(private_key, j);
  274. crypto_scalarmult_curve25519_base(public_key2, private_key);
  275. crypto_hash_sha512(sha512_hash1, public_key2);
  276. crypto_hash_sha512(sha512_hash2, public_key2, KEYSIZE);
  277. if (memcmp(public_key1, public_key2, KEYSIZE) != 0 ||
  278. memcmp(sha512_hash1, sha512_hash2, crypto_hash_sha512_BYTES))
  279. {
  280. std::cout << "!!! Self-check failed !!!" << std::endl;
  281. std::cout << " PrivateKey: " << keyToString(private_key) << std::endl;
  282. std::cout << " PublicKey1: " << keyToString(public_key1) << std::endl;
  283. std::cout << " PublicKey2: " << keyToString(public_key2) << std::endl;
  284. std::cout << " SHA512Hash1: " << hashToString(sha512_hash1) << std::endl;
  285. std::cout << " SHA512Hash2: " << hashToString(sha512_hash2) << std::endl;
  286. std::cout << "!!! Self-check failed !!!" << std::endl;
  287. return;
  288. }
  289. else
  290. {
  291. //std::cout << " Self-check ok" << std::endl;
  292. //std::cout << " PrivateKey: " << keyToString(private_key) << std::endl;
  293. }
  294. }
  295. }
  296. std::cout << "Self-check finished." << std::endl;
  297. }
  298. #endif // debug
  299. // ------------------------------------------------------
  300. int main()
  301. {
  302. Intro();
  303. #ifdef SELF_CHECK
  304. selfCheck();
  305. return 0;
  306. #endif
  307. int configcheck = config(); // функция получения конфигурации
  308. if(configcheck < 0)
  309. {
  310. std::cerr << " Error code: " << configcheck;
  311. std::this_thread::sleep_for(std::chrono::seconds(15));
  312. return configcheck;
  313. }
  314. DisplayConfig();
  315. testoutput();
  316. std::thread* lastThread;
  317. for (int i = 0; i < conf.proc; i++)
  318. {
  319. lastThread = new std::thread(
  320. conf.mode == 0 ? miner_thread<0> :
  321. conf.mode == 1 ? miner_thread<1> :
  322. conf.mode == 2 ? miner_thread<2> :
  323. conf.mode == 3 ? miner_thread<3> :
  324. miner_thread<4>
  325. );
  326. }
  327. lastThread->join();
  328. std::cerr << "SYG has stopped working unexpectedly! Please, report about this.";
  329. std::this_thread::sleep_for(std::chrono::seconds(15));
  330. return -420;
  331. }