From 9739b55b7c3bba5368156878562b38e2bfcf4d5c Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Wed, 15 Jan 2025 19:13:09 -0800 Subject: [PATCH] Fix validation in gl implementation which could return false positives. --- src/classes/gl.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/classes/gl.ts b/src/classes/gl.ts index 689bf99..17a3c1c 100644 --- a/src/classes/gl.ts +++ b/src/classes/gl.ts @@ -139,22 +139,23 @@ export class NanoPowGl { * byte, converts the subsequent 3 pixels with the nonce byte values to a hex * string, and returns the result. * - * @param work - Buffer with the original random nonce value + * @param workBytes - Buffer with the original random nonce value + * @param workHex - Original nonce if provided for a validation call * @returns Nonce as an 8-byte (16-char) hexadecimal string */ - static #readResult (work: Uint8Array): string { + static #readResult (workBytes: Uint8Array, workHex?: string): string { if (this.#gl == null) throw new Error('WebGL 2 is required to read pixels') this.#gl.readPixels(0, 0, this.#gl.drawingBufferWidth, this.#gl.drawingBufferHeight, this.#gl.RGBA, this.#gl.UNSIGNED_BYTE, this.#pixels) for (let i = 0; i < this.#pixels.length; i += 4) { if (this.#pixels[i] !== 0) { /** Return the work value with the custom bits */ - const hex = this.#hexify(work.subarray(4, 8)) + this.#hexify([ + const hex = this.#hexify(workBytes.subarray(4, 8)) + this.#hexify([ this.#pixels[i + 2], this.#pixels[i + 3], - work[2] ^ (this.#pixels[i] - 1), - work[3] ^ (this.#pixels[i + 1] - 1) + workBytes[2] ^ (this.#pixels[i] - 1), + workBytes[3] ^ (this.#pixels[i + 1] - 1) ]) - return hex + if (workHex == null || workHex == hex) return hex } } throw new Error('Query reported result but nonce value not found') @@ -239,9 +240,13 @@ export class NanoPowGl { data.setBigUint64(0, BigInt(`0x${work}`), true) const seed = new Uint8Array(data.buffer) this.#draw(seed) - const found = await this.#checkQueryResult() + let found = await this.#checkQueryResult() if (found) { - nonce = this.#readResult(seed) + try { + nonce = this.#readResult(seed, work) + } catch (err) { + found = false + } } if (found && nonce !== work) throw new Error(`Nonce found but does not match work`) return found -- 2.34.1