#include #include #include #include #include #include #include "../libs/sha512.cuh" #include #include "../libs/ed25519.cuh" #include "../libs/edsign.cuh" __device__ __constant__ char hexDigitsConst[17] = "0123456789abcdef"; using Address = unsigned char[16]; using Key = unsigned char[32]; struct KeysBox { Key PublicKey; Key PrivateKey; }; struct option { unsigned high = 0x10; }; __device__ static option conf; struct ds64 { char data[65]; }; struct ds46 { char data[46]; }; __device__ ds64 KeyToString(const unsigned char* key) noexcept { ds64 str; const char* hexDigits = hexDigitsConst; for (unsigned char i = 0; i < 32; i++) { str.data[2 * i] = hexDigits[key[i] >> 4]; str.data[2 * i + 1] = hexDigits[key[i] & 0x0F]; } str.data[64] = '\0'; return str; } __device__ ds46 getAddress(const unsigned char rawAddr[16]) noexcept { ds46 addrStr; #ifdef __CUDA_ARCH__ const char* hexDigits = hexDigitsConst; #else const char* hexDigits = "0123456789abcdef"; #endif int pos = 0; for (int group = 0; group < 8; group++) { int idx = group * 2; addrStr.data[pos++] = hexDigits[rawAddr[idx] >> 4]; addrStr.data[pos++] = hexDigits[rawAddr[idx] & 0x0F]; addrStr.data[pos++] = hexDigits[rawAddr[idx + 1] >> 4]; addrStr.data[pos++] = hexDigits[rawAddr[idx + 1] & 0x0F]; if (group < 7) { addrStr.data[pos++] = ':'; } } addrStr.data[pos] = '\0'; return addrStr; } __device__ 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] = static_cast((InvertedPublicKey[i] << bitsToShift) | (InvertedPublicKey[i + 1] >> (8 - bitsToShift))); } } rawAddr[0] = 0x02; rawAddr[1] = static_cast(lErase - 1); memcpy(&rawAddr[2], &InvertedPublicKey[start], 14); } __device__ unsigned long long xorshift128plus(unsigned long long* state) { unsigned long long x = state[0]; const unsigned long long y = state[1]; state[0] = y; x ^= x << 23; x ^= x >> 17; x ^= y ^ (y >> 26); state[1] = x; return x + y; } __device__ unsigned char zeroCounter(unsigned int x) { if (x == 0) return 32; #ifdef __CUDA_ARCH__ return static_cast(__clz(x)); #else return static_cast(__builtin_clz(x)); #endif } __device__ unsigned char getZeros(const unsigned char* v) { unsigned char leadZeros = 0; for (int i = 0; i < 32; i += 4) { unsigned word = (static_cast(v[i]) << 24) | (static_cast(v[i + 1]) << 16) | (static_cast(v[i + 2]) << 8) | (static_cast(v[i + 3])); if (word == 0) leadZeros += 32; else { leadZeros += zeroCounter(word); break; } } return leadZeros; } __global__ void initRandStates(curandState* randStates) { int id = blockIdx.x * blockDim.x + threadIdx.x; curand_init((unsigned long long)clock64() + id, id, 0, &randStates[id]); } __device__ void generateRandomBytes(unsigned char* buf, unsigned long size, curandState* state) { for (unsigned long i = 0; i < size; i++) { buf[i] = curand(state) & 0xFF; } } __device__ void invertKey(const unsigned char* key, unsigned char* inverted) { for (int i = 0; i < 32; i++) inverted[i] = key[i] ^ 0xFF; } __device__ void compact_wipe(void* data, unsigned long length) { volatile unsigned char* p = (volatile unsigned char*)data; while (length--) { *p++ = 0; } } __device__ void ed25519_keygen(unsigned char private_key[64], unsigned char public_key[32], unsigned char random_seed[32]) { edsign_sec_to_pub(public_key, random_seed); memcpy(private_key, random_seed, 32); memcpy(private_key + 32, public_key, 32); compact_wipe(random_seed, 32); } __global__ __launch_bounds__(256) void minerKernel(curandState* randStates) { int thid = blockIdx.x * blockDim.x + threadIdx.x; curandState localState = randStates[thid]; Key seed; generateRandomBytes(seed, sizeof(seed), &localState); while (true) { generateRandomBytes(seed, sizeof(seed), &localState); KeysBox keys; ed25519_keygen(keys.PrivateKey, keys.PublicKey, seed); if (unsigned zeros = getZeros(keys.PublicKey); zeros > atomicMax(&conf.high, (unsigned)zeros)) { Key inv; Address raw; invertKey(keys.PublicKey, inv); getRawAddress(zeros, inv, raw); printf("\nIPv6:\t%s\nPK:\t%s\nSK:\t%s\n", getAddress(raw).data, KeyToString(keys.PublicKey).data, KeyToString(keys.PrivateKey).data); } __syncthreads(); } //randStates[thid] = localState; } int main() { curandState* d_randStates; cudaMalloc(&d_randStates, 1024 * sizeof(curandState)); initRandStates << <4, 256 >> > (d_randStates); cudaDeviceSynchronize(); minerKernel << <4, 256 >> > (d_randStates); cudaDeviceSynchronize(); cudaFree(d_randStates); return 0; }