From dae74514b4b139621052a69d37307496e6ee0274 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Tue, 4 Mar 2025 12:57:17 -0800 Subject: [PATCH] Add assemblyscript and start converting CPU hash "shader". --- asconfig.json | 16 +++++ package-lock.json | 42 +++++++++++++ package.json | 4 +- src/shaders/cpu-hash.ts | 126 +++++++++++++------------------------- src/shaders/tsconfig.json | 13 ++++ 5 files changed, 116 insertions(+), 85 deletions(-) create mode 100644 asconfig.json create mode 100644 src/shaders/tsconfig.json diff --git a/asconfig.json b/asconfig.json new file mode 100644 index 0000000..a7f8290 --- /dev/null +++ b/asconfig.json @@ -0,0 +1,16 @@ +{ + "targets": { + "release": { + "outFile": "dist/nano-pow.wasm", + "textFile": "dist/nano-pow.wat", + "sourceMap": true, + "optimizeLevel": 3, + "shrinkLevel": 0, + "converge": false, + "noAssert": false + } + }, + "options": { + "bindings": "esm" + } +} diff --git a/package-lock.json b/package-lock.json index 9cf97c1..6f9d8ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "devDependencies": { "@types/node": "^22.13.8", "@webgpu/types": "^0.1.54", + "assemblyscript": "^0.27.34", "esbuild": "^0.25.0", "esbuild-plugin-glsl": "^1.2.2", "typescript": "^5.8.2" @@ -462,6 +463,40 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/assemblyscript": { + "version": "0.27.34", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.27.34.tgz", + "integrity": "sha512-7snWLfLjXhgPxC3xadAkRqWgpNxEvP4FR7TVqNhUtStzrXEOCZJe6zc5DzIUM0PSzDx7qCBmLY8qF1LzYfeRBQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "binaryen": "116.0.0-nightly.20240114", + "long": "^5.2.4" + }, + "bin": { + "asc": "bin/asc.js", + "asinit": "bin/asinit.js" + }, + "engines": { + "node": ">=18", + "npm": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/binaryen": { + "version": "116.0.0-nightly.20240114", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-116.0.0-nightly.20240114.tgz", + "integrity": "sha512-0GZrojJnuhoe+hiwji7QFaL3tBlJoA+KFUN7ouYSDGZLSo9CKM8swQX8n/UcbR0d1VuZKU+nhogNzv423JEu5A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "wasm-opt": "bin/wasm-opt", + "wasm2js": "bin/wasm2js" + } + }, "node_modules/esbuild": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", @@ -516,6 +551,13 @@ "esbuild": "0.x.x" } }, + "node_modules/long": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz", + "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/typescript": { "version": "5.8.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", diff --git a/package.json b/package.json index 15e7571..fc2b7e4 100644 --- a/package.json +++ b/package.json @@ -40,11 +40,13 @@ "url": "git+https://zoso.dev/nano-pow.git" }, "scripts": { - "build": "rm -rf types && tsc && node esbuild.mjs && cp types.d.ts dist" + "build": "rm -rf types && tsc && node esbuild.mjs && cp types.d.ts dist", + "asbuild": "asc src/shaders/cpu-hash.ts --target release" }, "devDependencies": { "@types/node": "^22.13.8", "@webgpu/types": "^0.1.54", + "assemblyscript": "^0.27.34", "esbuild": "^0.25.0", "esbuild-plugin-glsl": "^1.2.2", "typescript": "^5.8.2" diff --git a/src/shaders/cpu-hash.ts b/src/shaders/cpu-hash.ts index 5cf927c..a0b4195 100644 --- a/src/shaders/cpu-hash.ts +++ b/src/shaders/cpu-hash.ts @@ -1,91 +1,49 @@ // SPDX-FileCopyrightText: 2025 Chris Duncan // SPDX-License-Identifier: GPL-3.0-or-later -export class NanoPowCpuHasher { - static #blake2b_sigma: number[][] = [ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], - [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], - [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], - [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], - [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], - [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], - [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], - [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], - [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], - [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], - [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3] - ] +const blake2b_sigma: u8[][] = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], + [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], + [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], + [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], + [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], + [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], + [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], + [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], + [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3] +] - static #G (v: BigUint64Array, a: number, b: number, c: number, d: number, m: BigUint64Array, x: number, y: number): void { - v[a] += v[b] - v[a] += m[x] - v[d] ^= v[a] - v[d] = (v[d] >> 32n) | (v[d] << 32n) - v[c] += v[d] - v[b] ^= v[c] - v[b] = (v[b] >> 24n) | (v[b] << 40n) - v[a] += v[b] - v[a] += m[y] - v[d] ^= v[a] - v[d] = (v[d] >> 16n) | (v[d] << 48n) - v[c] += v[d] - v[b] ^= v[c] - v[b] = (v[b] >> 63n) | (v[b] << 1n) - } - - static async hash (v: BigUint64Array, m: BigUint64Array): Promise { - return new Promise(async (resolve, reject): Promise => { - try { - for (let r = 0; r < 12; r++) { - const s = this.#blake2b_sigma[r] - this.#G(v, 0, 4, 8, 12, m, s[0], s[1]) - this.#G(v, 1, 5, 9, 13, m, s[2], s[3]) - this.#G(v, 2, 6, 10, 14, m, s[4], s[5]) - this.#G(v, 3, 7, 11, 15, m, s[6], s[7]) - this.#G(v, 0, 5, 10, 15, m, s[8], s[9]) - this.#G(v, 1, 6, 11, 12, m, s[10], s[11]) - this.#G(v, 2, 7, 8, 13, m, s[12], s[13]) - this.#G(v, 3, 4, 9, 14, m, s[14], s[15]) - } - } catch (err) { - reject(err) - } - resolve(0x6a09e667f3bcc908n ^ v[0] ^ v[8]) - }) - } - - /** - * Listens for messages from the main thread. - */ - static { - addEventListener('message', (message: any): void => { - const { name, buffer } = message.data - if (name === 'STOP') { - close() - const buffer = new ArrayBuffer(0) - //@ts-expect-error - postMessage(buffer, [buffer]) - } else { - const data = JSON.parse(new TextDecoder().decode(buffer)) - this.hash(data).then(this.report) - } - }) - } +function G (v: Uint64Array, a: u8, b: u8, c: u8, d: u8, m: Uint64Array, x: u8, y: u8): void { + v[a] += v[b] + v[a] += m[x] + v[d] ^= v[a] + v[d] = (v[d] >> 32) | (v[d] << 32) + v[c] += v[d] + v[b] ^= v[c] + v[b] = (v[b] >> 24) | (v[b] << 40) + v[a] += v[b] + v[a] += m[y] + v[d] ^= v[a] + v[d] = (v[d] >> 16) | (v[d] << 48) + v[c] += v[d] + v[b] ^= v[c] + v[b] = (v[b] >> 63) | (v[b] << 1) +} - /** - * Encodes worker results as an ArrayBuffer so it can be transferred back to - * the main thread. - * - * @param {bigint} nonce - 64-bit nonce - */ - static report (nonce: bigint): void { - const buffer = new TextEncoder().encode(JSON.stringify(nonce)).buffer - //@ts-expect-error - postMessage(buffer, [buffer]) +export function hash (v: Uint64Array, m: Uint64Array): u64 { + for (let r = 0; r < 12; r++) { + const s = blake2b_sigma[r] + G(v, 0, 4, 8, 12, m, s[0], s[1]) + G(v, 1, 5, 9, 13, m, s[2], s[3]) + G(v, 2, 6, 10, 14, m, s[4], s[5]) + G(v, 3, 7, 11, 15, m, s[6], s[7]) + G(v, 0, 5, 10, 15, m, s[8], s[9]) + G(v, 1, 6, 11, 12, m, s[10], s[11]) + G(v, 2, 7, 8, 13, m, s[12], s[13]) + G(v, 3, 4, 9, 14, m, s[14], s[15]) } + return (0x6a09e667f3bcc908 ^ v[0] ^ v[8]) } - -export default ` -const NanoPowCpuHasher = ${NanoPowCpuHasher} -` diff --git a/src/shaders/tsconfig.json b/src/shaders/tsconfig.json new file mode 100644 index 0000000..999dc09 --- /dev/null +++ b/src/shaders/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "assemblyscript/std/assembly.json", + "include": [ + "./**/*.ts" + ], + "compilerOptions": { + "paths": { + "*": [ + "./*" + ] + } + } +} -- 2.34.1