nano-pow 4.0.10 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -136,18 +136,16 @@ official Nano node software. The installed command will launch the server in a
136
136
  detached process, and it can also be started manually to customize behavior by
137
137
  executing the server script directly.
138
138
 
139
- `NANO_POW_PORT` can be passed as an environment variable and defaults to 3000 if
140
- not specified.
139
+ #### Environment Variables
140
+ `NANO_POW_PORT`: override the default port 5040
141
141
 
142
- `NANO_POW_EFFORT` can also be passed as an environment variable to increase
143
- or decrease the demand on the GPU.
142
+ `NANO_POW_EFFORT` increase or decrease demand on the GPU
144
143
 
145
- `NANO_POW_DEBUG` can be set to enable additional logging saved to the HOME
146
- directory.
144
+ `NANO_POW_DEBUG` enable additional logging saved to the HOME directory
147
145
 
148
146
  ```console
149
147
  $ # Launch the server and detach from the current session
150
- $ PORT=8080 nano-pow --server
148
+ $ NANO_POW_PORT=8080 nano-pow --server
151
149
  $ # View process ID for "NanoPow Server"
152
150
  $ cat ~/.nano-pow/server.pid
153
151
  $ # Display list of server logs
@@ -163,7 +161,7 @@ $ # Generate a work value
163
161
  $ curl -d '{
164
162
  "action": "work_generate",
165
163
  "hash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
166
- }' localhost:3000
164
+ }' localhost:5040
167
165
  ```
168
166
  ```console
169
167
  $ # Validate a work value
@@ -171,7 +169,7 @@ $ curl -d '{
171
169
  "action": "work_validate",
172
170
  "work": "e45835c3b291c3d1",
173
171
  "hash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
174
- }' localhost:3000
172
+ }' localhost:5040
175
173
  ```
176
174
 
177
175
  ## Notes
package/dist/bin/cli.js CHANGED
@@ -1,18 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
3
3
  //! SPDX-License-Identifier: GPL-3.0-or-later
4
- import * as readline from "node:readline/promises";
4
+ import { getRandomValues } from "node:crypto";
5
+ import { createInterface } from "node:readline/promises";
5
6
  process.title = "NanoPow CLI";
6
7
  process.env.NANO_POW_DEBUG = "";
7
8
  process.env.NANO_POW_EFFORT = "";
8
- process.env.NANO_POW_PORT = "3000";
9
+ process.env.NANO_POW_PORT = "5041";
9
10
  function log(...args2) {
10
11
  if (process.env.NANO_POW_DEBUG) console.log(new Date(Date.now()).toLocaleString(), "NanoPow", args2);
11
12
  }
12
13
  const hashes = [];
13
14
  const stdinErrors = [];
14
15
  if (!process.stdin.isTTY) {
15
- const stdin = readline.createInterface({
16
+ const stdin = createInterface({
16
17
  input: process.stdin
17
18
  });
18
19
  let i = 0;
@@ -37,11 +38,12 @@ If using --validate, results will also include validity properties.
37
38
 
38
39
  -h, --help show this dialog
39
40
  --debug enable additional logging output
41
+ --benchmark <value> generate work for specified number of random hashes
40
42
 
41
43
  -b, --batch process all data before returning final results as array
42
- -d, --difficulty=<value> override the minimum difficulty value
43
- -e, --effort=<value> increase demand on GPU processing
44
- -v, --validate=<value> check an existing work value instead of searching for one
44
+ -d, --difficulty <value> override the minimum difficulty value
45
+ -e, --effort <value> increase demand on GPU processing
46
+ -v, --validate <value> check an existing work value instead of searching for one
45
47
 
46
48
  If validating a nonce, it must be a 16-character hexadecimal value.
47
49
  Effort must be a decimal number between 1-32.
@@ -58,11 +60,8 @@ while (/^[0-9A-Fa-f]{64}$/.test(args[args.length - 1] ?? "")) {
58
60
  inArgs.unshift(args.pop());
59
61
  }
60
62
  hashes.push(...inArgs);
61
- if (hashes.length === 0) {
62
- console.error("Invalid block hash input");
63
- process.exit(1);
64
- }
65
63
  let isBatch = false;
64
+ let isBenchmark = false;
66
65
  const body = {
67
66
  action: "work_generate"
68
67
  };
@@ -90,6 +89,18 @@ for (let i = 0; i < args.length; i++) {
90
89
  process.env.NANO_POW_EFFORT = args[i + 1];
91
90
  break;
92
91
  }
92
+ case "--benchmark": {
93
+ if (args[i + 1] == null) throw new Error("Missing argument for benchmark");
94
+ if (!(+args[i + 1] > 0)) throw new Error("Invalid benchmark count");
95
+ const random = new Uint8Array(32);
96
+ while (hashes.length < +args[i + 1]) {
97
+ getRandomValues(random);
98
+ const byteArray = [...random].map((byte) => byte.toString(16).padStart(2, "0"));
99
+ hashes.push(byteArray.join(""));
100
+ }
101
+ isBenchmark = true;
102
+ break;
103
+ }
93
104
  case "--debug": {
94
105
  process.env.NANO_POW_DEBUG = "true";
95
106
  break;
@@ -101,6 +112,10 @@ for (let i = 0; i < args.length; i++) {
101
112
  }
102
113
  }
103
114
  }
115
+ if (hashes.length === 0) {
116
+ console.error("Invalid block hash input");
117
+ process.exit(1);
118
+ }
104
119
  log("CLI args:", ...args);
105
120
  for (const stdinErr of stdinErrors) {
106
121
  log(stdinErr);
@@ -108,8 +123,9 @@ for (const stdinErr of stdinErrors) {
108
123
  log("Starting NanoPow CLI");
109
124
  await import("./server.js");
110
125
  const results = [];
111
- const start = performance.now();
112
126
  const aborter = new AbortController();
127
+ if (isBenchmark) console.log("Starting benchmark...");
128
+ const start = performance.now();
113
129
  for (const hash of hashes) {
114
130
  try {
115
131
  body.hash = hash;
@@ -121,7 +137,7 @@ for (const hash of hashes) {
121
137
  });
122
138
  clearTimeout(kill);
123
139
  const result = await response.json();
124
- if (isBatch) {
140
+ if (isBatch || isBenchmark) {
125
141
  results.push(result);
126
142
  } else {
127
143
  console.log(result);
@@ -131,6 +147,8 @@ for (const hash of hashes) {
131
147
  }
132
148
  }
133
149
  const end = performance.now();
134
- if (isBatch) console.log(results);
135
- log(end - start, "ms total |", (end - start) / hashes.length, "ms avg");
150
+ if (isBatch && !isBenchmark) console.log(results);
151
+ if (process.env.NANO_POW_DEBUG || isBenchmark) {
152
+ console.log(end - start, "ms total |", (end - start) / hashes.length, "ms avg");
153
+ }
136
154
  process.exit(0);
@@ -10,7 +10,7 @@ NANO_POW_LOGS="$NANO_POW_HOME"/logs;
10
10
  mkdir -p "$NANO_POW_LOGS";
11
11
  if [ "$1" = '--server' ]; then
12
12
  shift;
13
- node "$SCRIPT_DIR"/server.js > "$NANO_POW_LOGS"/nano-pow-server-$(date +%s).log 2>&1 & echo "$!" > "$NANO_POW_HOME"/server.pid;
13
+ node "$SCRIPT_DIR"/server.js > "$NANO_POW_LOGS"/nano-pow-server-$(date -u -Iseconds).log 2>&1 & echo "$!" > "$NANO_POW_HOME"/server.pid;
14
14
  else
15
15
  node "$SCRIPT_DIR"/cli.js "$@";
16
16
  fi;
@@ -13,7 +13,7 @@ const MAX_REQUEST_SIZE = 1024;
13
13
  const MAX_BODY_SIZE = 158;
14
14
  const DEBUG = !!(process.env.NANO_POW_DEBUG || false);
15
15
  const EFFORT = +(process.env.NANO_POW_EFFORT || 8);
16
- const PORT = +(process.env.NANO_POW_PORT || 3e3);
16
+ const PORT = +(process.env.NANO_POW_PORT || 5040);
17
17
  let browser;
18
18
  let page;
19
19
  function log(...args) {
@@ -41,6 +41,7 @@ async function respond(res, data) {
41
41
  if (action === "work_validate" && !/^[0-9A-Fa-f]{16}$/.test(work ?? "")) {
42
42
  throw new Error("Invalid work. Must be a 16-character hex string.");
43
43
  }
44
+ response = `${action} failed`;
44
45
  const options = {
45
46
  debug: DEBUG,
46
47
  effort: EFFORT,
@@ -142,7 +143,7 @@ page.on("console", (msg) => log(msg.text()));
142
143
  const path = new URL(import.meta.url).pathname;
143
144
  const dir = path.slice(0, path.lastIndexOf("/"));
144
145
  const filename = join(dir, `${process.pid}.html`);
145
- await writeFile(filename, "");
146
+ await writeFile(filename, '<!DOCTYPE html><link rel="icon" href="data:,">');
146
147
  await page.goto(import.meta.resolve(filename));
147
148
  await page.waitForFunction(async () => {
148
149
  return await navigator["gpu"].requestAdapter();
@@ -152,11 +153,9 @@ const hash = await subtle.digest("SHA-256", Buffer.from(src));
152
153
  const enc = `sha256-${Buffer.from(hash).toString("base64")}`;
153
154
  await page.setContent(`
154
155
  <!DOCTYPE html>
155
- <head>
156
- <meta http-equiv="Content-Security-Policy" content="default-src 'none'; base-uri 'none'; form-action 'none'; script-src '${enc}';">
157
- <script type="module">${src}</script>
158
- </head>
159
- </html>
156
+ <link rel="icon" href="data:,">
157
+ <meta http-equiv="Content-Security-Policy" content="default-src 'none'; base-uri 'none'; form-action 'none'; script-src '${enc}';">
158
+ <script type="module">${src}</script>
160
159
  `);
161
160
  await unlink(filename);
162
161
  log("Puppeteer initialized");
package/dist/main.min.js CHANGED
@@ -505,7 +505,7 @@ var NanoPowGl = class _NanoPowGl {
505
505
  // src/lib/gpu/compute.wgsl
506
506
  var compute_default = `//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
507
507
  //! SPDX-License-Identifier: GPL-3.0-or-later
508
- struct UBO{blockhash:array<vec4<u32>,2>,seed:vec2<u32>,difficulty:vec2<u32>};@group(0)@binding(0)var<uniform> ubo:UBO;struct WORK{found:atomic<u32>,nonce:vec2<u32>,result:vec2<u32>};@group(0)@binding(1)var<storage,read_write>work:WORK;const BLAKE2B_IV=array<vec2<u32>,8>(vec2<u32>(0xF3BCC908u,0x6A09E667u),vec2<u32>(0x84CAA73Bu,0xBB67AE85u),vec2<u32>(0xFE94F82Bu,0x3C6EF372u),vec2<u32>(0x5F1D36F1u,0xA54FF53Au),vec2<u32>(0xADE682D1u,0x510E527Fu),vec2<u32>(0x2B3E6C1Fu,0x9B05688Cu),vec2<u32>(0xFB41BD6Bu,0x1F83D9ABu),vec2<u32>(0x137E2179u,0x5BE0CD19u));const BLAKE2B_PARAM=vec2<u32>(0x01010008u,0u);const BLAKE2B_INLEN=vec2<u32>(0x00000028u,0u);const BLAKE2B_FINAL=vec2<u32>(0xFFFFFFFFu,0xFFFFFFFFu);const BLAKE2B_INIT=array<vec2<u32>,16>(BLAKE2B_IV[0u]^ BLAKE2B_PARAM,BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u],BLAKE2B_IV[5u],BLAKE2B_IV[6u],BLAKE2B_IV[7u],BLAKE2B_IV[0u],BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u]^ BLAKE2B_INLEN,BLAKE2B_IV[5u],BLAKE2B_IV[6u]^ BLAKE2B_FINAL,BLAKE2B_IV[7u]);const Z=vec2(0u);const CARRY=vec4(1u,0u,1u,0u);const ROTATE_1=vec4(1u);const ROTATE_8=vec4(8u);const ROTATE_16=vec4(16u);const ROTATE_24=vec4(24u);const ROTATE_31=vec4(31u);var<workgroup> found:bool;@compute @workgroup_size(32)fn search(@builtin(global_invocation_id)global_id:vec3<u32>,@builtin(local_invocation_id)local_id:vec3<u32>){found=(local_id.x==0u&&atomicLoad(&work.found)!=0u);workgroupBarrier();if(found){return;}main(global_id,false);}@compute @workgroup_size(1)fn validate(@builtin(global_invocation_id)global_id:vec3<u32>){main(global_id,true);}fn main(id:vec3<u32>,validate:bool){let m0:vec2<u32>=ubo.seed ^ id.xy;let m1:vec2<u32>=ubo.blockhash[0u].xy;let m2:vec2<u32>=ubo.blockhash[0u].zw;let m3:vec2<u32>=ubo.blockhash[1u].xy;let m4:vec2<u32>=ubo.blockhash[1u].zw;var v01:vec4<u32>=vec4<u32>(BLAKE2B_INIT[0u],BLAKE2B_INIT[1u]);var v23:vec4<u32>=vec4<u32>(BLAKE2B_INIT[2u],BLAKE2B_INIT[3u]);var v45:vec4<u32>=vec4<u32>(BLAKE2B_INIT[4u],BLAKE2B_INIT[5u]);var v67:vec4<u32>=vec4<u32>(BLAKE2B_INIT[6u],BLAKE2B_INIT[7u]);var v89:vec4<u32>=vec4<u32>(BLAKE2B_INIT[8u],BLAKE2B_INIT[9u]);var vAB:vec4<u32>=vec4<u32>(BLAKE2B_INIT[10u],BLAKE2B_INIT[11u]);var vCD:vec4<u32>=vec4<u32>(BLAKE2B_INIT[12u],BLAKE2B_INIT[13u]);var vEF:vec4<u32>=vec4<u32>(BLAKE2B_INIT[14u],BLAKE2B_INIT[15u]);var v56:vec4<u32>;var vFC:vec4<u32>;var v74:vec4<u32>;var vDE:vec4<u32>;var s0:vec4<u32>;var s1:vec4<u32>;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m0,m2);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;v23+=vec4(m4,Z);v23.y+=u32(v23.x<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m3);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m4);v01.w+=u32(v01.z<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m0);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m2);v01.w+=u32(v01.z<m2.x);v23+=vec4(Z,m3);v23.w+=u32(v23.z<m3.x);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(Z,m0);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+vec4(m2,Z);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01.z+=m3.x;v01.w+=m3.y+u32(v01.z<m3.x);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m1,m4)+vec4(0u,u32(v23.x+vec4(m1,m4).x<v23.x),0u,u32(v23.z+vec4(m1,m4).z<v23.z));vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m3)+vec4(Z,0u,u32(v01.z+vec4(Z,m3).z<v01.z));vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m1)+vec4(Z,0u,u32(v01.z+vec4(Z,m1).z<v01.z));vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m2,Z)+vec4(0u,u32(v01.x+vec4(m2,Z).x<v01.x),Z);v23+=vec4(m4,Z)+vec4(0u,u32(v23.x+vec4(m4,Z).x<v23.x),Z);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m0,Z)+vec4(0u,u32(v23.x+vec4(m0,Z).x<v23.x),Z);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(m2,Z);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m0,Z)+vec4(0u,u32(v01.x+vec4(m0,Z).x<v01.x),Z);v23+=vec4(m4,Z)+vec4(0u,u32(v23.x+vec4(m4,Z).x<v23.x),Z);vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(Z,m3);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m1,Z)+vec4(0u,u32(v01.x+vec4(m1,Z).x<v01.x),Z);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m2,Z)+vec4(0u,u32(v01.x+vec4(m2,Z).x<v01.x),Z);v23+=vec4(m0,Z)+vec4(0u,u32(v23.x+vec4(m0,Z).x<v23.x),Z);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(Z,m3);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m4,Z)+vec4(0u,u32(v01.x+vec4(m4,Z).x<v01.x),Z);v23+=vec4(Z,m1)+vec4(Z,0u,u32(v23.z+vec4(Z,m1).z<v23.z));vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m1)+vec4(Z,0u,u32(v01.z+vec4(Z,m1).z<v01.z));v23+=vec4(Z,m4)+vec4(Z,0u,u32(v23.z+vec4(Z,m4).z<v23.z));vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m0,Z)+vec4(0u,u32(v01.x+vec4(m0,Z).x<v01.x),Z);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m3)+vec4(Z,0u,u32(v01.z+vec4(Z,m3).z<v01.z));s1=v23+vec4(m2,Z);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(Z,m3);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m1,Z)+vec4(0u,u32(v23.x+vec4(m1,Z).x<v23.x),Z);vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m2)+vec4(Z,0u,u32(v23.z+vec4(Z,m2).z<v23.z));vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m0,m4)+vec4(0u,u32(v01.x+vec4(m0,m4).x<v01.x),0u,u32(v01.z+vec4(m0,m4).z<v01.z));vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m0);v23.w+=u32(v23.z<m0.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m3,Z)+vec4(0u,u32(v23.x+vec4(m3,Z).x<v23.x),Z);vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m1,Z)+vec4(0u,u32(v23.x+vec4(m1,Z).x<v23.x),Z);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m2,Z)+vec4(0u,u32(v01.x+vec4(m2,Z).x<v01.x),Z);v23+=vec4(m4,Z)+vec4(0u,u32(v23.x+vec4(m4,Z).x<v23.x),Z);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m1);v23.w+=u32(v23.z<m1.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m2,m4);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m3,Z);v23.y+=u32(v23.x<m3.x);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m0);v23.w+=u32(v23.z<m0.x);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m0,m2);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;v23+=vec4(m4,Z);v23.y+=u32(v23.x<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m3);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m4);v01.w+=u32(v01.z<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m0);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m3);v23.w+=u32(v23.z<m3.x);vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;var result=BLAKE2B_INIT[0u]^ v01.xy ^ v89.xy;if(validate||((result.y>ubo.difficulty.y||(result.y==ubo.difficulty.y&&result.y>=ubo.difficulty.y))&&atomicLoad(&work.found)==0u)){atomicStore(&work.found,1u);work.nonce=m0;work.result=result;}return;}`;
508
+ struct UBO{blockhash:array<vec4<u32>,2>,seed:vec2<u32>,difficulty:vec2<u32>};@group(0)@binding(0)var<uniform> ubo:UBO;struct WORK{found:atomic<u32>,nonce:vec2<u32>,result:vec2<u32>};@group(0)@binding(1)var<storage,read_write>work:WORK;const BLAKE2B_IV=array<vec2<u32>,8>(vec2<u32>(0xF3BCC908u,0x6A09E667u),vec2<u32>(0x84CAA73Bu,0xBB67AE85u),vec2<u32>(0xFE94F82Bu,0x3C6EF372u),vec2<u32>(0x5F1D36F1u,0xA54FF53Au),vec2<u32>(0xADE682D1u,0x510E527Fu),vec2<u32>(0x2B3E6C1Fu,0x9B05688Cu),vec2<u32>(0xFB41BD6Bu,0x1F83D9ABu),vec2<u32>(0x137E2179u,0x5BE0CD19u));const BLAKE2B_PARAM=vec2<u32>(0x01010008u,0u);const BLAKE2B_INLEN=vec2<u32>(0x00000028u,0u);const BLAKE2B_FINAL=vec2<u32>(0xFFFFFFFFu,0xFFFFFFFFu);const BLAKE2B_INIT=array<vec2<u32>,16>(BLAKE2B_IV[0u]^ BLAKE2B_PARAM,BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u],BLAKE2B_IV[5u],BLAKE2B_IV[6u],BLAKE2B_IV[7u],BLAKE2B_IV[0u],BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u]^ BLAKE2B_INLEN,BLAKE2B_IV[5u],BLAKE2B_IV[6u]^ BLAKE2B_FINAL,BLAKE2B_IV[7u]);fn G(a:ptr<function,vec2<u32>>,b:ptr<function,vec2<u32>>,c:ptr<function,vec2<u32>>,d:ptr<function,vec2<u32>>,m0:vec2<u32>,m1:vec2<u32>){*a+=*b;(*a).y+=u32((*a).x<(*b).x);*a+=m0;(*a).y+=u32((*a).x<m0.x);*d=(*d ^*a).yx;*c+=*d;(*c).y+=u32((*c).x<(*d).x);*b ^=*c;*b=(*b>>vec2(24u))|(*b<<vec2(8u)).yx;*a+=*b;(*a).y+=u32((*a).x<(*b).x);*a+=m1;(*a).y+=u32((*a).x<m1.x);*d ^=*a;*d=(*d>>vec2(16u))|(*d<<vec2(16u)).yx;*c+=*d;(*c).y+=u32((*c).x<(*d).x);*b ^=*c;*b=(*b>>vec2(31u)).yx|(*b<<vec2(1u));}const Z=vec2(0u);var<workgroup> found:bool;var<workgroup> seed:vec2<u32>;var<workgroup> m1:vec2<u32>;var<workgroup> m2:vec2<u32>;var<workgroup> m3:vec2<u32>;var<workgroup> m4:vec2<u32>;@compute @workgroup_size(96)fn search(@builtin(global_invocation_id)global_id:vec3<u32>,@builtin(local_invocation_id)local_id:vec3<u32>){if(local_id.x==0u){found=atomicLoad(&work.found)!=0u;seed=ubo.seed;m1=ubo.blockhash[0u].xy;m2=ubo.blockhash[0u].zw;m3=ubo.blockhash[1u].xy;m4=ubo.blockhash[1u].zw;}workgroupBarrier();if(found){return;}main(global_id,false);}@compute @workgroup_size(1)fn validate(@builtin(global_invocation_id)global_id:vec3<u32>){seed=ubo.seed;m1=ubo.blockhash[0u].xy;m2=ubo.blockhash[0u].zw;m3=ubo.blockhash[1u].xy;m4=ubo.blockhash[1u].zw;main(global_id,true);}fn main(id:vec3<u32>,validate:bool){let m0:vec2<u32>=seed ^ id.xy;var v0:vec2<u32>=vec2<u32>(BLAKE2B_INIT[0u]);var v1:vec2<u32>=vec2<u32>(BLAKE2B_INIT[1u]);var v2:vec2<u32>=vec2<u32>(BLAKE2B_INIT[2u]);var v3:vec2<u32>=vec2<u32>(BLAKE2B_INIT[3u]);var v4:vec2<u32>=vec2<u32>(BLAKE2B_INIT[4u]);var v5:vec2<u32>=vec2<u32>(BLAKE2B_INIT[5u]);var v6:vec2<u32>=vec2<u32>(BLAKE2B_INIT[6u]);var v7:vec2<u32>=vec2<u32>(BLAKE2B_INIT[7u]);var v8:vec2<u32>=vec2<u32>(BLAKE2B_INIT[8u]);var v9:vec2<u32>=vec2<u32>(BLAKE2B_INIT[9u]);var vA:vec2<u32>=vec2<u32>(BLAKE2B_INIT[10u]);var vB:vec2<u32>=vec2<u32>(BLAKE2B_INIT[11u]);var vC:vec2<u32>=vec2<u32>(BLAKE2B_INIT[12u]);var vD:vec2<u32>=vec2<u32>(BLAKE2B_INIT[13u]);var vE:vec2<u32>=vec2<u32>(BLAKE2B_INIT[14u]);var vF:vec2<u32>=vec2<u32>(BLAKE2B_INIT[15u]);G(&v0,&v4,&v8,&vC,m0,m1);G(&v1,&v5,&v9,&vD,m2,m3);G(&v2,&v6,&vA,&vE,m4,Z);G(&v3,&v7,&vB,&vF,Z,Z);G(&v0,&v5,&vA,&vF,Z,Z);G(&v1,&v6,&vB,&vC,Z,Z);G(&v2,&v7,&v8,&vD,Z,Z);G(&v3,&v4,&v9,&vE,Z,Z);G(&v0,&v4,&v8,&vC,Z,Z);G(&v1,&v5,&v9,&vD,m4,Z);G(&v2,&v6,&vA,&vE,Z,Z);G(&v3,&v7,&vB,&vF,Z,Z);G(&v0,&v5,&vA,&vF,m1,Z);G(&v1,&v6,&vB,&vC,m0,m2);G(&v2,&v7,&v8,&vD,Z,Z);G(&v3,&v4,&v9,&vE,Z,m3);G(&v0,&v4,&v8,&vC,Z,Z);G(&v1,&v5,&v9,&vD,Z,m0);G(&v2,&v6,&vA,&vE,Z,m2);G(&v3,&v7,&vB,&vF,Z,Z);G(&v0,&v5,&vA,&vF,Z,Z);G(&v1,&v6,&vB,&vC,m3,Z);G(&v2,&v7,&v8,&vD,Z,m1);G(&v3,&v4,&v9,&vE,Z,m4);G(&v0,&v4,&v8,&vC,Z,Z);G(&v1,&v5,&v9,&vD,m3,m1);G(&v2,&v6,&vA,&vE,Z,Z);G(&v3,&v7,&vB,&vF,Z,Z);G(&v0,&v5,&vA,&vF,m2,Z);G(&v1,&v6,&vB,&vC,Z,Z);G(&v2,&v7,&v8,&vD,m4,m0);G(&v3,&v4,&v9,&vE,Z,Z);G(&v0,&v4,&v8,&vC,Z,m0);G(&v1,&v5,&v9,&vD,Z,Z);G(&v2,&v6,&vA,&vE,m2,m4);G(&v3,&v7,&vB,&vF,Z,Z);G(&v0,&v5,&vA,&vF,Z,m1);G(&v1,&v6,&vB,&vC,Z,Z);G(&v2,&v7,&v8,&vD,Z,Z);G(&v3,&v4,&v9,&vE,m3,Z);G(&v0,&v4,&v8,&vC,m2,Z);G(&v1,&v5,&v9,&vD,Z,Z);G(&v2,&v6,&vA,&vE,m0,Z);G(&v3,&v7,&vB,&vF,Z,m3);G(&v0,&v5,&vA,&vF,m4,Z);G(&v1,&v6,&vB,&vC,Z,Z);G(&v2,&v7,&v8,&vD,Z,Z);G(&v3,&v4,&v9,&vE,m1,Z);G(&v0,&v4,&v8,&vC,Z,Z);G(&v1,&v5,&v9,&vD,m1,Z);G(&v2,&v6,&vA,&vE,Z,Z);G(&v3,&v7,&vB,&vF,m4,Z);G(&v0,&v5,&vA,&vF,m0,Z);G(&v1,&v6,&vB,&vC,Z,m3);G(&v2,&v7,&v8,&vD,Z,m2);G(&v3,&v4,&v9,&vE,Z,Z);G(&v0,&v4,&v8,&vC,Z,Z);G(&v1,&v5,&v9,&vD,Z,Z);G(&v2,&v6,&vA,&vE,Z,m1);G(&v3,&v7,&vB,&vF,m3,Z);G(&v0,&v5,&vA,&vF,Z,m0);G(&v1,&v6,&vB,&vC,Z,m4);G(&v2,&v7,&v8,&vD,Z,Z);G(&v3,&v4,&v9,&vE,m2,Z);G(&v0,&v4,&v8,&vC,Z,Z);G(&v1,&v5,&v9,&vD,Z,Z);G(&v2,&v6,&vA,&vE,Z,m3);G(&v3,&v7,&vB,&vF,m0,Z);G(&v0,&v5,&vA,&vF,Z,m2);G(&v1,&v6,&vB,&vC,Z,Z);G(&v2,&v7,&v8,&vD,m1,m4);G(&v3,&v4,&v9,&vE,Z,Z);G(&v0,&v4,&v8,&vC,Z,m2);G(&v1,&v5,&v9,&vD,Z,m4);G(&v2,&v6,&vA,&vE,Z,Z);G(&v3,&v7,&vB,&vF,m1,Z);G(&v0,&v5,&vA,&vF,Z,Z);G(&v1,&v6,&vB,&vC,Z,Z);G(&v2,&v7,&v8,&vD,m3,Z);G(&v3,&v4,&v9,&vE,Z,m0);G(&v0,&v4,&v8,&vC,m0,m1);G(&v1,&v5,&v9,&vD,m2,m3);G(&v2,&v6,&vA,&vE,m4,Z);G(&v3,&v7,&vB,&vF,Z,Z);G(&v0,&v5,&vA,&vF,Z,Z);G(&v1,&v6,&vB,&vC,Z,Z);G(&v2,&v7,&v8,&vD,Z,Z);G(&v3,&v4,&v9,&vE,Z,Z);G(&v0,&v4,&v8,&vC,Z,Z);G(&v1,&v5,&v9,&vD,m4,Z);G(&v2,&v6,&vA,&vE,Z,Z);G(&v3,&v7,&vB,&vF,Z,Z);G(&v0,&v5,&vA,&vF,m1,Z);G(&v2,&v7,&v8,&vD,Z,Z);var result:vec2<u32>=BLAKE2B_INIT[0u]^ v0 ^ v8;if(validate||((result.y>ubo.difficulty.y||(result.y==ubo.difficulty.y&&result.y>=ubo.difficulty.y))&&atomicLoad(&work.found)==0u)){atomicStore(&work.found,1u);work.nonce=m0;work.result=result;}return;}`;
509
509
 
510
510
  // src/lib/gpu/index.ts
511
511
  //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
package/docs/nano-pow.1 CHANGED
@@ -28,19 +28,22 @@ Start work server (see SERVER below). Must be the first argument in order to be
28
28
  \fB\-h\fR, \fB\-\-help\fR
29
29
  Show this help dialog and exit.
30
30
  .TP
31
- \fB\-d\fR, \fB\-\-debug\fR
31
+ \fB\-\-debug\fR
32
32
  Enable additional logging output.
33
33
  .TP
34
- \fB\-j\fR, \fB\-\-json\fR
35
- Format final output of all hashes as a JSON array of stringified values instead of incrementally returning Javascript objects for each result.
34
+ \fB\-\-benchmark\fR \fICOUNT\fR
35
+ Generate work for the specified number of random hashes.
36
36
  .TP
37
- \fB\-e\fR, \fB\-\-effort\fR=\fIEFFORT\fR
38
- Increase demand on GPU processing. Must be between 1 and 32 inclusive.
37
+ \fB\-b\fR, \fB\-\-batch\fR
38
+ Format final output of all hashes as a JSON array instead of incrementally returning an object for each result as soon as it is calculated.
39
39
  .TP
40
- \fB\-t\fR, \fB\-\-difficulty\fR=\fIDIFFICULTY\fR
40
+ \fB\-t\fR, \fB\-\-difficulty\fR \fIDIFFICULTY\fR
41
41
  Override the minimum threshold value. Higher values increase difficulty. Must be a hexadecimal string between 1 and FFFFFFFFFFFFFFFF inclusive.
42
42
  .TP
43
- \fB\-v\fR, \fB\-\-validate\fR=\fIWORK\fR
43
+ \fB\-e\fR, \fB\-\-effort\fR \fIEFFORT\fR
44
+ Increase demand on GPU processing. Must be between 1 and 32 inclusive.
45
+ .TP
46
+ \fB\-v\fR, \fB\-\-validate\fR \fIWORK\fR
44
47
  Check an existing work value instead of searching for one. If you pass multiple blockhashes, the work value will be validated against each one.
45
48
 
46
49
  .SH SERVER
@@ -50,12 +53,18 @@ It provides work generation and validation via HTTP requests in a similar, but n
50
53
  .PP
51
54
  More specifically, it does not support the \fIuse_peers\fR, \fImultiplier\fR, \fIaccount\fR, \fIversion\fR, \fIblock\fR, and \fIjson_block\fR options.
52
55
  .PP
53
- By default, the server listens on port 3000. To use a different port, set the \fBPORT\fR environment variable before starting the server.
56
+ By default, the server listens on port 5040.
54
57
 
55
- .PP
56
- .EX
57
- $ PORT=8080 nano-pow --server
58
- .EE
58
+ .SS ENVIRONMENT VARIABLES
59
+ .TP
60
+ \fBNANO_POW_PORT\fR
61
+ Override the default port on which the NanoPow server listens for requests.
62
+ .TP
63
+ \fBNANO_POW_EFFORT\fR
64
+ Increase demand on GPU processing. Must be between 1 and 32 inclusive.
65
+ .TP
66
+ \fBNANO_POW_DEBUG\fR
67
+ Enable additional logging saved to the \fBHOME\fR directory.
59
68
 
60
69
  .PP
61
70
  The server process ID (PID) is saved to \fB~/.nano-pow/server.pid\fR. Log files are stored in \fB~/.nano-pow/logs/\fR.
@@ -89,7 +98,7 @@ Validate an existing work value against a blockhash. Requires \fBwork\fR field c
89
98
 
90
99
  .SH EXAMPLES - CLI
91
100
  .PP
92
- Search for a work nonce for a blockhash using the default difficulty 0xFFFFFFF800000000:
101
+ Search for a work nonce for a blockhash using the default difficulty FFFFFFF800000000:
93
102
  .EX
94
103
  $ nano-pow \fB0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\fR
95
104
  .EE
@@ -97,19 +106,25 @@ $ nano-pow \fB0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\f
97
106
  .PP
98
107
  Search for a work nonce using a custom difficulty and increased effort:
99
108
  .EX
100
- $ nano-pow \fB\-t fffffe0000000000 \-e 32 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\fR
109
+ $ nano-pow \fB\-d fffffe0000000000 \-e 32 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\fR
101
110
  .EE
102
111
 
103
112
  .PP
104
- Read one or more lines of blockhashes from a file and output to another file:
113
+ Read one or more lines of blockhashes from a file and output results to another file:
105
114
  .EX
106
- $ cat /path/to/file.txt | nano-pow --json > work.json
115
+ $ cat /path/to/file.txt | nano-pow \fB--batch\fR > work.json
107
116
  .EE
108
117
 
109
118
  .PP
110
119
  Validate an existing work nonce against a blockhash and show debugging output:
111
120
  .EX
112
- $ nano-pow \fB\-d \-v fedcba9876543210 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\fR
121
+ $ nano-pow \fB\--debug \-v fedcba9876543210 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\fR
122
+ .EE
123
+
124
+ .PP
125
+ Run a benchmark of generating work for 100 random sample blockhashes:
126
+ .EX
127
+ $ nano-pow \fB\--benchmark 100\fR
113
128
  .EE
114
129
 
115
130
  .SH EXAMPLES - SERVER
@@ -119,7 +134,7 @@ Generate a work value:
119
134
  $ curl -d '{
120
135
  "action": "work_generate",
121
136
  "hash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
122
- }' localhost:3000
137
+ }' localhost:5040
123
138
  .EE
124
139
 
125
140
  .PP
@@ -129,7 +144,7 @@ $ curl -d '{
129
144
  "action": "work_validate",
130
145
  "work": "e45835c3b291c3d1",
131
146
  "hash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
132
- }' localhost:3000
147
+ }' localhost:5040
133
148
  .EE
134
149
 
135
150
  .SH AUTHOR
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nano-pow",
3
- "version": "4.0.10",
3
+ "version": "4.1.0",
4
4
  "description": "Proof-of-work generation and validation with WebGPU/WebGL for Nano cryptocurrency.",
5
5
  "keywords": [
6
6
  "nemo",
@@ -45,6 +45,7 @@
45
45
  "url": "git+https://zoso.dev/nano-pow.git"
46
46
  },
47
47
  "scripts": {
48
+ "benchmark": "npm run build && ./dist/bin/nano-pow.sh --benchmark 1000",
48
49
  "build": "rm -rf {dist,types} && tsc && node esbuild.mjs && cp -p src/bin/nano-pow.sh dist/bin",
49
50
  "prepare": "npm run build",
50
51
  "start": "./dist/bin/nano-pow.sh --server",