//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
//! SPDX-License-Identifier: GPL-3.0-or-later
-import { WorkGenerateResponse } from 'nano-pow'
import { NanoPowValidate } from '#lib/validate'
-import { bigintRandom, Logger } from '#utils'
+import { Bytes, Logger } from '#utils'
+import { WorkGenerateResponse } from 'nano-pow'
const logger = new Logger()
const check = () => {
try {
LOG: logger.log('check 0x8000 nonces')
- let result = NanoPowValidate(bigintRandom(), hash, difficulty, false)
+ let result = NanoPowValidate(crypto.getRandomValues(new Uint8Array(8)), Bytes(hash, 32), difficulty, false)
for (let i = 0; i < 0x8000; i++) {
- result = NanoPowValidate(bigintRandom(), hash, difficulty, false)
+ result = NanoPowValidate(crypto.getRandomValues(new Uint8Array(8)), Bytes(hash, 32), difficulty, false)
if (result.valid === '1') break
}
if (result.valid === '1') {
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
//! SPDX-License-Identifier: GPL-3.0-or-later
-import { WorkGenerateResponse } from 'nano-pow'
import { NanoPowValidate } from '#lib/validate'
-import { bigintRandom, bigintToHex, Logger } from '#utils'
+import { bigintRandom, bigintToHex, Bytes, Logger } from '#utils'
+import { WorkGenerateResponse } from 'nano-pow'
import { NanoPowWasmWorker } from './worker.js'
const logger = new Logger()
let result = ''
try {
work = await dispatch()
- result = (await NanoPowValidate(work, hash, difficulty, debug)).difficulty
+ result = (await NanoPowValidate(Bytes(work, 8), Bytes(hash, 32), difficulty, debug)).difficulty
} catch (err) {
LOG: logger.log(err)
} finally {
import { NanoPowConfig } from '#lib/config'
import { NanoPowCpu, NanoPowWasm, NanoPowWebgl, NanoPowWebgpu } from '#lib/generate'
import { NanoPowValidate } from '#lib/validate'
-import { bigintFrom, Cache, Logger, Queue } from '#utils'
+import { bigintFrom, Bytes, Cache, Logger, Queue } from '#utils'
import { WorkErrorResponse, WorkGenerateResponse, WorkValidateResponse } from 'nano-pow'
const logger = new Logger()
const cached = Cache.search(bigintHash, difficulty)
if (cached) {
LOG: logger.log('found work in cache')
- const { valid } = NanoPowValidate(bigintFrom(cached.work, 'hex'), bigintFrom(cached.hash, 'hex'), bigintFrom(cached.difficulty, 'hex'), debug)
+ const { valid } = NanoPowValidate(Bytes(cached.work, 8), Bytes(cached.hash, 32), bigintFrom(cached.difficulty, 'hex'), debug)
if (valid === '1') {
return cached
} else {
export async function validate (work: unknown, hash: unknown, options?: unknown): Promise<WorkValidateResponse | WorkErrorResponse> {
try {
- const bigintHash = bigintFrom(hash, 'hex')
- const bigintWork = bigintFrom(work, 'hex')
+ const hashBytes = Bytes(hash, 32)
+ const workBytes = Bytes(work, 8)
const { debug, difficulty } = await NanoPowConfig(options)
- const result = await NanoPowValidate(bigintWork, bigintHash, difficulty, debug)
+ const result = await NanoPowValidate(workBytes, hashBytes, difficulty, debug)
return result
} catch (e: any) {
return { error: (typeof e === 'string' ? e : (e?.message ?? '')) }
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
//! SPDX-License-Identifier: GPL-3.0-or-later
+import { bigintToHex, BytesToHex, Logger, RECEIVE, SEND } from '#utils'
import { WorkValidateResponse } from 'nano-pow'
-import { bigintAsUintNArray, bigintToHex, Logger, RECEIVE, SEND } from '#utils'
const logger = new Logger()
G(3, 4, 9, 14, s[14], s[15])
}
-function init (seed: bigint, hash: BigUint64Array): void {
+function init (seed: BigUint64Array, hash: BigUint64Array): void {
// Reset buffers before each calculation
result = 0n
for (let i = 0; i < 8; i++) {
v[14] = ~v[14] // Compression
// Set up input buffers
- mView.setBigUint64(0, seed, true)
+ mView.setBigUint64(0, seed[0], true)
for (let i = 0; i < 4; i++) {
mView.setBigUint64(8 * (i + 1), hash[i])
}
}
-function blake2b (work: bigint, hash: bigint): void {
- init(work, bigintAsUintNArray(hash, 64, 4))
+function blake2b (work: Uint8Array, hash: Uint8Array): void {
+ init(new BigUint64Array(work.buffer), new BigUint64Array(hash.buffer))
for (let i = 0; i < 12; i++) {
ROUND(i)
}
result = (blake2b_IV[0] ^ 0x01010008n ^ v[0] ^ v[8])
}
-function log (work: bigint, hash: bigint, difficulty: bigint): void {
+function log (work: Uint8Array<ArrayBuffer>, hash: Uint8Array<ArrayBuffer>, difficulty: bigint): void {
LOG: logger.groupStart('NanoPow CPU work_validate')
- LOG: logger.log('NanoPow CPU work_validate', 'work', bigintToHex(work, 16))
- LOG: logger.log('NanoPow CPU work_validate', 'hash', bigintToHex(hash, 64))
+ LOG: logger.log('NanoPow CPU work_validate', 'work', BytesToHex(work.buffer))
+ LOG: logger.log('NanoPow CPU work_validate', 'hash', BytesToHex(hash.buffer))
LOG: logger.log('NanoPow CPU work_validate', 'difficulty', bigintToHex(difficulty, 16))
LOG: logger.log('NanoPow CPU work_validate', 'result', bigintToHex(result, 16))
LOG: logger.groupEnd('NanoPow CPU work_validate')
}
-function validate (work: bigint, hash: bigint, difficulty: bigint, debug: boolean): WorkValidateResponse {
+function validate (work: Uint8Array<ArrayBuffer>, hash: Uint8Array<ArrayBuffer>, difficulty: bigint, debug: boolean): WorkValidateResponse {
logger.isEnabled = debug
blake2b(work, hash)
log(work, hash, difficulty)
return {
- hash: bigintToHex(hash, 64),
- work: bigintToHex(work, 16),
+ hash: BytesToHex(hash.buffer, 64),
+ work: BytesToHex(work.buffer, 16),
difficulty: bigintToHex(result, 16),
valid: (result >= difficulty) ? '1' : '0',
valid_all: (result >= SEND) ? '1' : '0',
* @param {(bigint|number|string)} input
* @param {number} [length]
* @returns {Uint8Array<ArrayBuffer>}
- */
-export function Bytes (input: unknown, minLength?: number): Uint8Array<ArrayBuffer> {
+*/
+export function Bytes (input: unknown, minLength: unknown = 1): Uint8Array<ArrayBuffer> {
if (typeof input === 'number') {
input = BigInt(input | 0)
}
* @param {number} [length]
* @returns {string}
*/
-export function BytesToHex (input: unknown, length?: number): string {
+export function BytesToHex (input: ArrayBuffer, minLength?: number): string
+export function BytesToHex (input: unknown, minLength: unknown = 2): string {
if (!(input instanceof ArrayBuffer) || input.byteLength < 1) {
throw new TypeError('invalid buffer', { cause: input })
}
- if (typeof length !== 'number' || length < 1) {
- throw new TypeError('invalid length', { cause: length })
+ if (typeof minLength !== 'number' || minLength < 2 || minLength & 1) {
+ throw new TypeError('invalid length', { cause: minLength })
}
const bytes = new Uint8Array(input)
- return [...bytes].map(b => b.toString(16).padStart(2, '0')).join('').padStart(length, '0')
+ return [...bytes].map(b => b.toString(16).padStart(2, '0')).join('').padStart(minLength, '0')
}
export * from './api-support'
export * from './bigint'
+export * from './bytes'
export * from './cache'
export * from './logger'
export * from './queue'