diff --git a/sources/main.cpp b/sources/main.cpp index 6219751..98dc326 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -1,20 +1,18 @@ #include #include -#include +//#include #include #include -#include #include #include #include #include -#include #include #include #include struct option { unsigned proc = 0; - unsigned high = 10; + std::atomic high; //std::string outputfile; }; static option conf; @@ -47,35 +45,32 @@ void displayConfig() { std::cout << " Threads: " << conf.proc << ", " << "high addresses (2" << std::setw(2) << std::setfill('0') << std::hex << conf.high << "+)" << std::dec << std::endl; } using Address = unsigned char[16]; -const char* getAddress(const Address& rawAddr) noexcept { - char* ipStrBuf = new char[46]; +using Key = unsigned char[32]; +inline std::string getAddress(const Address& rawAddr) noexcept { + char ipStrBuf[46]; inet_ntop(AF_INET6, rawAddr, ipStrBuf, 46); - return ipStrBuf; + return std::string(ipStrBuf); } inline std::string keyToString(const unsigned char* key) noexcept { - std::string result; - result.resize(64); + char result[65]; const char* hexDigits = "0123456789abcdef"; - for (unsigned char i = 0; i < 32; i++) { + for (size_t i = 0; i < 32; ++i) { result[2 * i] = hexDigits[key[i] >> 4]; result[2 * i + 1] = hexDigits[key[i] & 0x0F]; } - return result; + result[64] = '\0'; + return std::string(result); } -using Key = unsigned char[32]; -struct KeysBox { +typedef struct alignas(32) { Key PublicKey; Key PrivateKey; -}; -void getRawAddress(int lErase, Key& InvertedPublicKey, Address& rawAddr) { +} KeysBox; +void getRawAddress(int lErase, Key& InvertedPublicKey, Address& rawAddr) noexcept { lErase++; const int bitsToShift = lErase % 8; const int start = lErase / 8; - if (bitsToShift == 0) { - for (int i = start; i < start + 15; ++i) - InvertedPublicKey[i] = InvertedPublicKey[i]; - } else { - for (int i = start; i < start + 15; ++i) { + if (bitsToShift != 0) { + for (int i = start; i < start + 15; i++) { InvertedPublicKey[i] = static_cast((InvertedPublicKey[i] << bitsToShift) | (InvertedPublicKey[i + 1] >> (8 - bitsToShift))); } } @@ -108,41 +103,54 @@ inline void bitwiseInverse(const unsigned char* key, Key& inverted) noexcept { } return leadZeros; } -[[nodiscard]] inline long long xorshift64(unsigned long& state) { +[[nodiscard]] inline long long xorshift64(unsigned long& state) noexcept { state ^= state << 21; state ^= state >> 35; state ^= state << 4; return static_cast(state * 2685821657736338717); } -inline void randombytesavx2(unsigned char* buf, unsigned char size, unsigned long& state) noexcept { - for (unsigned char x = 0; x < size; x += 32) { - _mm256_storeu_si256((__m256i*) & buf[x], _mm256_set_epi64x(xorshift64(state), xorshift64(state), xorshift64(state), xorshift64(state))); +inline void rmbytes(unsigned char* buf, unsigned char size, unsigned long& state) noexcept { + for (unsigned char x = 0; x < size / 32; x++) { + _mm256_storeu_si256((__m256i*) & buf[x * 32], _mm256_set_epi64x(xorshift64(state), xorshift64(state), xorshift64(state), xorshift64(state))); + } + for (unsigned char x = 0; x < (size % 32); x++) { + buf[(size / 32) * 32 + x] = static_cast(xorshift64(state) & 0xFF); } } +inline void sign_keypair(unsigned char* pk, unsigned char* sk, const unsigned char* seed) noexcept { + alignas(32) unsigned char h[64]; + crypto_hash_sha512(h, seed, 32); + h[31] = (h[31] & 0xF8) | (0x40 | (h[31] & 0x7F)); + crypto_scalarmult_ed25519_base(pk, h); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(sk), _mm256_loadu_si256(reinterpret_cast(seed))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(sk + 32), _mm256_loadu_si256(reinterpret_cast(pk))); +} void miner_thread() noexcept { - Key inv; + alignas(32) Key inv; + alignas(32) Key seed; KeysBox keys; Address rawAddr; unsigned char ones = 0; - unsigned char seed[32]; std::random_device rd; unsigned long state = static_cast(rd()); + printf("Using seed: %lu\n", state); while (true) { - randombytesavx2(seed, sizeof(seed) / sizeof(seed[0]), state); - crypto_sign_ed25519_seed_keypair(keys.PublicKey, keys.PrivateKey, seed); + rmbytes(seed, sizeof(seed), state); + sign_keypair(keys.PublicKey, keys.PrivateKey, seed); + //crypto_sign_ed25519_seed_keypair(keys.PublicKey, keys.PrivateKey, seed); ones = getZeros(keys.PublicKey); - if (ones > conf.high) { - conf.high = ones; + if (ones > conf.high.load()) { + conf.high.store(ones); bitwiseInverse(keys.PublicKey, inv); getRawAddress(ones, inv, rawAddr); - printf("\nIPv6:\t%s\nPK:\t%s\nSK:\t%s\n", getAddress(rawAddr), keyToString(keys.PublicKey).c_str(), keyToString(keys.PrivateKey).c_str()); + printf("\nIPv6:\t%s\nPK:\t%s\nSK:\t%s\n", getAddress(rawAddr).c_str(), keyToString(keys.PublicKey).c_str(), keyToString(keys.PrivateKey).c_str()); } } } void startThreads() noexcept { std::vector threads; threads.reserve(conf.proc); - for (unsigned char i = 0; i < conf.proc; i++) { + for (unsigned char x = 0; x < conf.proc; x++) { threads.emplace_back(miner_thread); } for (auto& thread : threads) { @@ -173,22 +181,4 @@ int main(int argc, char* argv[]) noexcept { displayConfig(); startThreads(); return 0; -} -/* -void logKeys(const Address& raw, const KeysBox& keys) { - std::cout << std::endl; - std::cout << " Address: " << getAddress(raw) << std::endl; - std::cout << " PublicKey: " << keyToString(keys.PublicKey) << std::endl; - std::cout << " PrivateKey: " << keyToString(keys.PrivateKey); - if (!conf.log || conf.fullkeys) std::cout << keyToString(keys.PublicKey); - std::cout << std::endl << std::endl; - if (conf.log) { - std::ofstream output(conf.outputfile, std::ios::app); - output << std::endl; - output << "Address: " << getAddress(raw) << std::endl; - output << "PublicKey: " << keyToString(keys.PublicKey) << std::endl; - output << "PrivateKey: " << keyToString(keys.PrivateKey) << keyToString(keys.PublicKey) << std::endl; - output.close(); - } -} -*/ \ No newline at end of file +} \ No newline at end of file