blob: 2b9131044493ec16a6b7ea51741bf0da6ddafb54 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
/**
* SPDX-License-Identifier: CC0-1.0
*
* Copyright (C) 2025-2026 Woj. Kosior <koszko@koszko.org>
*/
/*
#+begin_src manifest-jq
.matches = ["<all_urls>"]
#+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
};
}
|