/** * SPDX-License-Identifier: CC0-1.0 * * Copyright (C) 2025-2026 Woj. Kosior */ /* #+begin_src manifest-jq .matches = [""] #+end_src */ /* This PoW code is used by multiple content scripts. */ function byteArray2Hex(arrayLike) { const byte2Hex = byte => ("0" + byte.toString(16)).slice(-2); return [...arrayLike].map(byte2Hex).join(""); } async function genericSolvePow(randomData, zeroesNeeded, countingSchemes) { const zeroBytesNeeded = zeroesNeeded >> 3; const finalZeroesNeeded = (zeroesNeeded & 7); const finalBitsMask = 255 << (8 - finalZeroesNeeded); let solution = null; async function powLoop(scheme) { const stepArray = Function.bind.call(scheme.stepArray, scheme); let inputArray = scheme.makeArray(randomData); inputArray = typeof inputArray === 'string' ? new TextEncoder().encode(inputArray) : inputArray; while (!solution) { const digest = new Uint8Array( await crypto.subtle.digest("SHA-256", inputArray) ); let success = true; for (let idx = 0; success && idx < zeroBytesNeeded; idx++) success &&= digest[idx] === 0; success &&= (digest[zeroBytesNeeded] & finalBitsMask) === 0; if (success) { const suffixArray = inputArray.slice(-scheme.suffixLength()); return solution = [digest, inputArray, suffixArray]; } /* Mutation (side-effects) or new array creation — allow both. */ inputArray = stepArray(inputArray) || inputArray; } return solution; } const startMillis = Date.now(); /* * Under both IceCat 140.3.1-gnu1 and ungoogled-chromium 140.0.7339.207-1 * (both from Guix) on a Core 2 CPU the best hash/s result was observed when * running 2 async loops. TODO: use workers to leverage hw concurrency. */ const promises = countingSchemes.map(scheme => powLoop(scheme)); const [digest, inputArray, suffixArray] = await Promise.any(promises); return { hash: byteArray2Hex(digest), inputArray, suffixArray, elapsedTime: Date.now() - startMillis }; }