yggm/sources/main.cu

199 lines
6.4 KiB
Plaintext
Raw Normal View History

2025-03-13 04:09:27 +05:00
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <cuda_runtime.h>
#include <curand_kernel.h>
#include <arpa/inet.h>
#include "../libs/sha512.cuh"
#include "../libs/ed25519.cuh"
#include "../libs/edsign.cuh"
#define MAX_RESULTS 1024
__constant__ char hexDigitsConst[17] = "0123456789abcdef";
using Address = unsigned char[16];
using Key = unsigned char[32];
struct KeysBox {
Key PublicKey;
Key PrivateKey;
};
struct option {
unsigned proc = 0;
__device__ __managed__ unsigned high = 0x10;
};
__device__ static option conf;
struct ds64 {
char data[65];
};
struct ds46 {
char data[46];
};
__host__ __device__ ds64 KeyToString(const unsigned char* key) noexcept {
ds64 str;
#ifdef __CUDA_ARCH__
const char* hexDigits = hexDigitsConst;
#else
const char* hexDigits = "0123456789abcdef";
#endif
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<unsigned char>(
(InvertedPublicKey[i] << bitsToShift) |
(InvertedPublicKey[i + 1] >> (8 - bitsToShift))
);
}
}
rawAddr[0] = 0x02;
rawAddr[1] = static_cast<unsigned char>(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<unsigned char>(__clz(x));
#else
return static_cast<unsigned char>(__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 int word = (static_cast<unsigned int>(v[i]) << 24) |
(static_cast<unsigned int>(v[i + 1]) << 16) |
(static_cast<unsigned int>(v[i + 2]) << 8) |
(static_cast<unsigned int>(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(uint8_t* buf, size_t size, curandState* state) {
for (size_t 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, size_t length) {
volatile uint8_t* p = (volatile uint8_t*)data;
while (length--) {
*p++ = 0;
}
}
__device__ void ed25519_keygen(uint8_t private_key[64], uint8_t public_key[32], uint8_t 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);
}
struct Result {
char ipv6[46];
char pk[65];
char sk[65];
};
__device__ __managed__ Result resultBuffer[MAX_RESULTS];
__device__ __managed__ int resultCount = 0;
__global__ __launch_bounds__(256) void minerKernel(curandState* randStates) {
int tid_global = blockIdx.x * blockDim.x + threadIdx.x;
curandState localState = randStates[tid_global];
uint8_t seed[32];
generateRandomBytes(seed, sizeof(seed), &localState);
if (tid_global == 0) {
printf("Seed: %s\n", KeyToString(seed).data);
}
while (true) {
generateRandomBytes(seed, sizeof(seed), &localState);
KeysBox keys;
ed25519_keygen(keys.PrivateKey, keys.PublicKey, seed);
int zeros = getZeros(keys.PublicKey);
unsigned oldHigh = atomicMax(&conf.high, (unsigned)zeros);
if (zeros > oldHigh) {
Key inv;
Address rawAddr_local;
invertKey(keys.PublicKey, inv);
getRawAddress(zeros, inv, rawAddr_local);
ds46 addrStr = getAddress(rawAddr_local);
ds64 pkStr = KeyToString(keys.PublicKey);
ds64 skStr = KeyToString(keys.PrivateKey);
int idx = atomicAdd(&resultCount, 1);
if (idx < MAX_RESULTS) {
memcpy(resultBuffer[idx].ipv6, addrStr.data, sizeof(addrStr.data));
memcpy(resultBuffer[idx].pk, pkStr.data, sizeof(pkStr.data));
memcpy(resultBuffer[idx].sk, skStr.data, sizeof(skStr.data));
}
}
if (tid_global == 0) {
if (resultCount > 0) {
for (int i = 0; i < resultCount; i++) {
printf("\nIPv6:\t%s\nPK:\t%s\nSK:\t%s\n", resultBuffer[i].ipv6, resultBuffer[i].pk, resultBuffer[i].sk);
}
resultCount = 0;
}
}
__syncthreads();
}
randStates[tid_global] = 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;
}