UNPKG

nano-pow

Version:

Proof-of-work generation and validation with WebGPU/WebGL/WASM for Nano cryptocurrency.

32 lines (25 loc) 1.73 kB
<!-- SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev> SPDX-License-Identifier: GPL-3.0-or-later --> Twelve rounds of G mixing as part of BLAKE2b compression step, each divided into eight subprocesses. Each subprocess applies transformations to `m` and `v` variables based on a defined set of index inputs. The algorithm for each subprocess is defined as ollows: * r is the current round * i is the current subprocess within that round * a, b, c, d are elements of `v` at specific indexes * sigma is a defined set of array indexes for `m` * rotr64 is a right-hand bit rotation function ``` a = a + b a = a + m[sigma[r][2*i+0]] d = rotr64(d ^ a, 32) c = c + d b = rotr64(b ^ c, 24) a = a + b a = a + m[sigma[r][2*i+1]] d = rotr64(d ^ a, 16) c = c + d b = rotr64(b ^ c, 63) ``` Each sum step has an extra carry addition. Note that the m[sigma] sum is skipped if m[sigma] is zero since it effectively does nothing. Also note that rotations must be applied differently from the reference implementation due to the lack of both a native rotate function and 64-bit support in WGSL. Subprocesses 1-4 are entirely independent of each other, as are subprocesses 5-8, and so an opportunity to compute in parallel presents itself. However, testing showed this to be ineffective at improving performance. These subprocesses could also be parallelized by pairing variables of two different hash processes and packing them into vectors (i.e. a uvec2 for high and low bits of a u64 into a uvec4). Think of it as a two lane highway where traffic in one lane has entirely different cars than the other, but they both are travelling toward the same destination. Once again, however, testing showed this to have a neglible effect.