From 21abae8f47e298b058fac4d52c51dc5efa47e9a6 Mon Sep 17 00:00:00 2001
From: Chris Duncan <chris@zoso.dev>
Date: Sun, 1 Dec 2024 20:49:45 -0800
Subject: [PATCH] Implement initial PoW worker.

---
 src/lib/pow.ts         | 48 ++++++++++++++++++++++++++++++++++++++++++
 src/lib/workers.ts     |  6 ++----
 src/lib/workers/pow.ts |  8 -------
 3 files changed, 50 insertions(+), 12 deletions(-)
 create mode 100644 src/lib/pow.ts
 delete mode 100644 src/lib/workers/pow.ts

diff --git a/src/lib/pow.ts b/src/lib/pow.ts
new file mode 100644
index 0000000..38e9782
--- /dev/null
+++ b/src/lib/pow.ts
@@ -0,0 +1,48 @@
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import { Blake2b } from './blake2b.js'
+import { Entropy } from './entropy.js'
+
+const p = () => {
+  /**
+  * Listens for messages from a calling function.
+  */
+  addEventListener('message', (message) => {
+    const data = JSON.parse(new TextDecoder().decode(message.data ?? message))
+    for (const d of data) {
+      d.nonce = find(d.hash, d.threshold)
+    }
+    const buf = new TextEncoder().encode(JSON.stringify(data)).buffer
+    //@ts-expect-error
+    postMessage(buf, [buf])
+  })
+
+  function find (hash: string, threshold: string) {
+    let nonce = null
+    do {
+      const e: Entropy = new Entropy(16)
+      const bytes: Uint8Array = parseHex(`${e.hex}${hash}`)
+      const result: string = new Blake2b(16).update(bytes).digest('hex') as string
+      const delta = BigInt(`0x${result}`) - BigInt(`0x${threshold}`)
+      if (delta >= 0) {
+        nonce = result
+      }
+    } while (nonce == null)
+    return nonce
+  }
+
+  function parseHex (hex: string) {
+    if (hex.length % 2 === 1) hex = `0${hex}`
+    const arr = hex.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16))
+    return Uint8Array.from(arr ?? [])
+  }
+
+  return { find }
+}
+
+export const Pow = p()
+
+const start = p.toString().indexOf('{') + 1
+const end = p.toString().lastIndexOf('return')
+export const worker = p.toString().substring(start, end)
diff --git a/src/lib/workers.ts b/src/lib/workers.ts
index e75c766..bfe19fa 100644
--- a/src/lib/workers.ts
+++ b/src/lib/workers.ts
@@ -1,8 +1,6 @@
 import { worker as Bip44Ckd } from './bip44-ckd.js'
 import { worker as NanoNaCl } from './nano-nacl.js'
 // import './workers/passkey.js'
-import pow from './workers/pow.js'
+import { worker as Pow } from './pow.js'
 
-
-
-export { Bip44Ckd, NanoNaCl }
+export { Bip44Ckd, NanoNaCl, Pow }
diff --git a/src/lib/workers/pow.ts b/src/lib/workers/pow.ts
deleted file mode 100644
index f75adb4..0000000
--- a/src/lib/workers/pow.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-const pow = () => {
-
-}
-
-export default pow.toString().substring(pow.toString().indexOf('{') + 1, pow.toString().lastIndexOf('}'))
-- 
2.34.1