From fa06494b59b1af6e5cb7be581477deb28c0ccab9 Mon Sep 17 00:00:00 2001 From: Tiago Garcia Date: Sun, 16 Nov 2025 19:41:51 +0000 Subject: [PATCH] WebAssembly Signed-off-by: Tiago Garcia --- aad_coin_miner_wasm.c | 268 ++++++++++++++++++++++++++++++++++++++++++ aad_sha1_wasm.h | 35 ++++++ index.html | 137 +++++++++++++++++++++ makefile | 14 ++- 4 files changed, 452 insertions(+), 2 deletions(-) create mode 100644 aad_coin_miner_wasm.c create mode 100644 aad_sha1_wasm.h create mode 100644 index.html diff --git a/aad_coin_miner_wasm.c b/aad_coin_miner_wasm.c new file mode 100644 index 0000000..58d33d6 --- /dev/null +++ b/aad_coin_miner_wasm.c @@ -0,0 +1,268 @@ +// +// Arquiteturas de Alto Desempenho 2025/2026 +// +// DETI Coin Miner - WebAssembly implementation +// + +#include +#include +#include +#include +#include "aad_data_types.h" + +#ifdef __EMSCRIPTEN__ +#include +#include "aad_sha1_wasm.h" +#else +#include "aad_sha1_cpu.h" +#include "aad_utilities.h" +#include "aad_vault.h" +#endif + +// Global mining state +static volatile int keep_running = 1; +static u64_t total_attempts = 0; +static u32_t coins_found = 0; +static double mining_start_time = 0; +static u32_t found_coins[1024][14]; // Store up to 1024 found coins +static u32_t found_coins_count = 0; + +// +// Check if a hash starts with aad20250 +// +static int is_valid_coin(u32_t *hash) +{ + return hash[0] == 0xAAD20250u; +} + +// +// Increment coin variable part (positions 12-53) +// +static int increment_coin(u32_t coin[14]) +{ + int pos = 53; + while(pos >= 12) + { + u08_t *byte = &((u08_t *)coin)[pos ^ 3]; + if(*byte == '\n' || *byte == 0x80) + *byte = 32; + + (*byte)++; + + if(*byte == '\n') + (*byte)++; + + if(*byte >= 127) + { + *byte = 32; + pos--; + } + else + { + break; + } + } + + return (pos >= 12); +} + +// +// Get current time in seconds +// +static double get_time() +{ +#ifdef __EMSCRIPTEN__ + return emscripten_get_now() / 1000.0; +#else + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + return (double)ts.tv_sec + (double)ts.tv_nsec / 1e9; +#endif +} + +// +// Main mining iteration (called from JavaScript) +// +#ifdef __EMSCRIPTEN__ +EMSCRIPTEN_KEEPALIVE +#endif +int mine_coins_wasm(u32_t iterations_per_call) +{ + static u32_t coin[14]; + static int initialized = 0; + u32_t hash[5]; + + // Initialize coin template on first call + if(!initialized) + { + memset(coin, 0, sizeof(coin)); + ((u08_t *)coin)[0x0 ^ 3] = 'D'; + ((u08_t *)coin)[0x1 ^ 3] = 'E'; + ((u08_t *)coin)[0x2 ^ 3] = 'T'; + ((u08_t *)coin)[0x3 ^ 3] = 'I'; + ((u08_t *)coin)[0x4 ^ 3] = ' '; + ((u08_t *)coin)[0x5 ^ 3] = 'c'; + ((u08_t *)coin)[0x6 ^ 3] = 'o'; + ((u08_t *)coin)[0x7 ^ 3] = 'i'; + ((u08_t *)coin)[0x8 ^ 3] = 'n'; + ((u08_t *)coin)[0x9 ^ 3] = ' '; + ((u08_t *)coin)[0xa ^ 3] = '2'; + ((u08_t *)coin)[0xb ^ 3] = ' '; + ((u08_t *)coin)[0x36 ^ 3] = '\n'; + ((u08_t *)coin)[0x37 ^ 3] = 0x80; + + for(int i = 12; i < 54; i++) + ((u08_t *)coin)[i ^ 3] = 'A' + (i - 12) % 26; + + mining_start_time = get_time(); + initialized = 1; + } + + if(!keep_running) + return 0; + + // Mine for the specified number of iterations + for(u32_t i = 0; i < iterations_per_call && keep_running; i++) + { + sha1(coin, hash); + total_attempts++; + + if(is_valid_coin(hash)) + { + if(found_coins_count < 1024) + { + memcpy(found_coins[found_coins_count], coin, sizeof(coin)); + found_coins_count++; + } + coins_found++; + +#ifndef __EMSCRIPTEN__ + printf("COIN FOUND! (attempt %llu)\n", (unsigned long long)total_attempts); + save_coin(coin); +#endif + } + + increment_coin(coin); + } + + return keep_running; +} + +// +// Get mining statistics +// +#ifdef __EMSCRIPTEN__ +EMSCRIPTEN_KEEPALIVE +#endif +void get_statistics(u64_t *attempts, u32_t *coins, double *hash_rate, double *elapsed_time) +{ + *attempts = total_attempts; + *coins = coins_found; + *elapsed_time = get_time() - mining_start_time; + *hash_rate = (*elapsed_time > 0) ? (total_attempts / *elapsed_time) : 0; +} + +// +// Stop mining +// +#ifdef __EMSCRIPTEN__ +EMSCRIPTEN_KEEPALIVE +#endif +void stop_mining() +{ + keep_running = 0; +} + +// +// Get found coin data (returns pointer to coin array) +// +#ifdef __EMSCRIPTEN__ +EMSCRIPTEN_KEEPALIVE +#endif +u32_t* get_found_coin(u32_t index) +{ + if(index < found_coins_count) + return found_coins[index]; + return NULL; +} + +// +// Get number of found coins +// +#ifdef __EMSCRIPTEN__ +EMSCRIPTEN_KEEPALIVE +#endif +u32_t get_found_coins_count() +{ + return found_coins_count; +} + +// +// Reset mining state +// +#ifdef __EMSCRIPTEN__ +EMSCRIPTEN_KEEPALIVE +#endif +void reset_mining() +{ + keep_running = 1; + total_attempts = 0; + coins_found = 0; + found_coins_count = 0; + mining_start_time = get_time(); +} + +// +// Main function (for standalone compilation/testing) +// +#ifndef __EMSCRIPTEN__ +int main(int argc, char *argv[]) +{ + u64_t max_attempts = 0; + + if(argc > 1) + max_attempts = strtoull(argv[1], NULL, 10); + + printf("Mining DETI coins using WebAssembly implementation (standalone mode)...\n"); + printf("Press Ctrl+C to stop\n\n"); + + time_measurement(); + time_measurement(); + double start_time = wall_time_delta(); + double last_report = start_time; + + while(keep_running && (max_attempts == 0 || total_attempts < max_attempts)) + { + mine_coins_wasm(100000); + + time_measurement(); + double current_time = wall_time_delta() - start_time; + + if(current_time - last_report >= 1.0) + { + u64_t attempts; + u32_t coins; + double hash_rate, elapsed; + get_statistics(&attempts, &coins, &hash_rate, &elapsed); + + printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u\n", + (unsigned long long)attempts, hash_rate / 1e6, coins); + + last_report = current_time; + } + } + + time_measurement(); + double total_time = wall_time_delta() - start_time; + + printf("\n=== Mining Statistics ===\n"); + printf("Total attempts: %llu\n", (unsigned long long)total_attempts); + printf("Total time: %.2f seconds\n", total_time); + printf("Average rate: %.2f attempts/second\n", total_attempts / total_time); + printf("Coins found: %u\n", coins_found); + + save_coin(NULL); + + return 0; +} +#endif diff --git a/aad_sha1_wasm.h b/aad_sha1_wasm.h new file mode 100644 index 0000000..30c5503 --- /dev/null +++ b/aad_sha1_wasm.h @@ -0,0 +1,35 @@ +#ifndef AAD_SHA1_WASM +#define AAD_SHA1_WASM + +#include "aad_data_types.h" +#include "aad_sha1.h" + +// +// SHA1 hash computation for WebAssembly (scalar implementation) +// + +static inline u32_t rotate_left(u32_t x, int n) +{ + return (x << n) | (x >> (32 - n)); +} + +static void sha1(u32_t *coin, u32_t *hash) +{ + // Define the macros needed by CUSTOM_SHA1_CODE + #define T u32_t + #define C(c) (c) + #define ROTATE(x,n) rotate_left(x,n) + #define DATA(idx) coin[idx] + #define HASH(idx) hash[idx] + + // Use the standard SHA1 template from aad_sha1.h + CUSTOM_SHA1_CODE(); + + #undef T + #undef C + #undef ROTATE + #undef DATA + #undef HASH +} + +#endif diff --git a/index.html b/index.html new file mode 100644 index 0000000..fcc9b9a --- /dev/null +++ b/index.html @@ -0,0 +1,137 @@ + + + + DETI Coin Miner - WebAssembly + + + +

DETI Coin Miner (WebAssembly)

+
+ + +
+
+ + +
+ + + +
+ Waiting to start... +
+ + + + + diff --git a/makefile b/makefile index f945203..28bbdad 100644 --- a/makefile +++ b/makefile @@ -84,11 +84,21 @@ coin_miner_cuda_kernel.cubin: aad_coin_miner_cuda_kernel.cu aad_sha1.h makefile coin_miner_cuda: aad_coin_miner_cuda.c coin_miner_cuda_kernel.cubin aad_sha1.h aad_sha1_cpu.h aad_data_types.h aad_utilities.h aad_vault.h aad_cuda_utilities.h makefile cc -march=native -Wall -Wshadow -Werror -O3 -I$(CUDA_DIR)/include $< -o $@ -lcuda +coin_miner_wasm: aad_coin_miner_wasm.c aad_sha1.h aad_sha1_cpu.h aad_sha1_wasm.h aad_data_types.h aad_utilities.h aad_vault.h makefile + emcc -O3 -flto -o aad_coin_miner_wasm.js aad_coin_miner_wasm.c \ + -s WASM=1 \ + -s EXPORTED_FUNCTIONS='["_mine_coins_wasm","_get_statistics","_stop_mining","_reset_mining","_get_found_coin","_get_found_coins_count","_malloc","_free"]' \ + -s EXPORTED_RUNTIME_METHODS='["cwrap","ccall","getValue","setValue"]' \ + -s ALLOW_MEMORY_GROWTH=1 \ + -s MODULARIZE=1 \ + -s EXPORT_NAME='CoinMinerModule' \ + -s INITIAL_MEMORY=67108864 + benchmark: aad_benchmark.c aad_sha1.h aad_sha1_cpu.h aad_data_types.h aad_utilities.h makefile cc -march=native -Wall -Wshadow -Werror -O3 $< -o $@ -miners: coin_miner_cpu coin_miner_simd coin_miner_cuda benchmark +miners: coin_miner_cpu coin_miner_simd coin_miner_wasm coin_miner_cuda benchmark all: sha1_tests sha1_cuda_test sha1_cuda_kernel.cubin \ - coin_miner_cpu coin_miner_simd coin_miner_cuda coin_miner_cuda_kernel.cubin \ + coin_miner_cpu coin_miner_simd coin_miner_wasm coin_miner_cuda coin_miner_cuda_kernel.cubin \ benchmark