-export const NanoPowCpuHasher = `
-const blake2b_sigma = [
- [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]
-]
+// SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
-function G (v, a, b, c, d, m, x, y) {
- 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)
-}
+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]
+ ]
+
+ 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<bigint> {
+ return new Promise(async (resolve, reject): Promise<void> => {
+ 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 hash (m, v) {
- 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])
+ /**
+ * 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])
}
- return (0x6a09e667f3bcc908 ^ v[0] ^ v[8])
}
+
+export default `
+const NanoPowCpuHasher = ${NanoPowCpuHasher}
`