throw new RangeError('Must pass at least one block', { cause: data })
}
if (OUT_BUF_LEN < count) {
- throw new RangeError('Bulk Nano block verification must be no more than 256 blocks', { cause: data })
+ throw new RangeError('Bulk Nano block verification must be no more than 256 blocks', { cause: count })
}
const verified = new Uint8Array(count)
let buffer = new Uint8Array(exports.memory.buffer)
}
for (let b = 0, p = MSG_PTR; b < count; b++) {
const block = blocks[b]
- if (!(block != null && typeof block === 'object' && 'hash' in block && 'signature' in block)) {
- throw new TypeError('invalid block', { cause: block })
+ if (block == null || typeof block !== 'object') {
+ throw new TypeError('Invalid block', { cause: block })
+ }
+ if (!('hash' in block)) {
+ throw new TypeError('Block hash is required to verify', { cause: block })
+ }
+ if (!('signature' in block)) {
+ throw new TypeError('Block signature is required to verify', { cause: block })
}
const hash = normalize('hash', BLK_LEN, BLK_LEN, block.hash)
const signature = normalize('signature', SIG_LEN, SIG_LEN, block.signature)
//! SPDX-FileCopyrightText: 2026 Chris Duncan <chris@codecow.com>
//! SPDX-License-Identifier: GPL-3.0-or-later
-import { derive, sign, verify } from 'nano25519'
+import { derive, sign, verify, verify_blocks } from 'nano25519'
import { NANO_ORG_VECTOR, PROBLEM_VECTOR, PYTHON_ED25519_BLAKE2B_VECTORS } from './vectors.mjs'
/**
result = false
} catch (err) {
if (err != null && typeof err === 'object' && 'message' in err && typeof err.message === 'string') {
- console.log(err.message.substring(0, 38))
result = err.message.includes('Nano25519WasmError') && err.message.includes('Invalid public key')
} else {
result = false
failures += +!test
}
+// Check bulk verification of Nano blocks
+try {
+ result = verify_blocks(NANO_ORG_VECTOR.publicKeyBytes, [{ hash: NANO_ORG_VECTOR.blockHashBytes, signature: NANO_ORG_VECTOR.signatureBytes }])[0]
+} catch (err) {
+ console.log(err)
+ result = false
+}
+test = result === true
+check(`verify_blocks single hash bytes ${NANO_ORG_VECTOR.blockHash} with signature bytes ${NANO_ORG_VECTOR.signature}`, test)
+passes += +test
+failures += +!test
+
+try {
+ const blocks = []
+ for (let i = 0; i < 256; i++) {
+ blocks[i] = { hash: NANO_ORG_VECTOR.blockHashBytes, signature: NANO_ORG_VECTOR.signatureBytes }
+ }
+ const verified = verify_blocks(NANO_ORG_VECTOR.publicKeyBytes, blocks)
+ result = verified.every(v => v === true)
+} catch (err) {
+ console.log(err)
+ result = false
+}
+test = result === true
+check(`verify_blocks 256 max`, test)
+passes += +test
+failures += +!test
+
+// Check min and max ranges of bulk verification
+try {
+ //@ts-expect-error
+ const blocks = []
+ //@ts-expect-error
+ verify_blocks(NANO_ORG_VECTOR.publicKeyBytes, blocks)
+ result = false
+} catch (err) {
+ if (err != null && typeof err === 'object' && 'message' in err) {
+ result = err.message === 'Must pass at least one block'
+ } else {
+ result = false
+ }
+}
+test = result === true
+check(`verify_blocks empty blocks`, test)
+passes += +test
+failures += +!test
+
+try {
+ const blocks = []
+ for (let i = 0; i < 257; i++) {
+ blocks[i] = { hash: NANO_ORG_VECTOR.blockHashBytes, signature: NANO_ORG_VECTOR.signatureBytes }
+ }
+ verify_blocks(NANO_ORG_VECTOR.publicKeyBytes, blocks)
+ result = false
+} catch (err) {
+ if (err != null && typeof err === 'object' && 'message' in err) {
+ result = err.message === 'Bulk Nano block verification must be no more than 256 blocks'
+ } else {
+ result = false
+ }
+}
+test = result === true
+check(`verify_blocks too many blocks`, test)
+passes += +test
+failures += +!test
+
+// Check proper format of bulk block verification
+try {
+ //@ts-expect-error
+ verify_blocks(NANO_ORG_VECTOR.publicKeyBytes, [null])
+ result = false
+} catch (err) {
+ if (err != null && typeof err === 'object' && 'message' in err) {
+ result = err.message === 'Invalid block'
+ } else {
+ result = false
+ }
+}
+test = result === true
+check(`verify_blocks null block`, test)
+passes += +test
+failures += +!test
+
+try {
+ //@ts-expect-error
+ verify_blocks(NANO_ORG_VECTOR.publicKeyBytes, [{ signature: NANO_ORG_VECTOR.signatureBytes }])
+ result = false
+} catch (err) {
+ if (err != null && typeof err === 'object' && 'message' in err) {
+ result = err.message === 'Block hash is required to verify'
+ } else {
+ result = false
+ }
+}
+test = result === true
+check(`verify_blocks missing hash`, test)
+passes += +test
+failures += +!test
+
+try {
+ //@ts-expect-error
+ verify_blocks(NANO_ORG_VECTOR.publicKeyBytes, [{ hash: NANO_ORG_VECTOR.blockHashBytes }])
+ result = false
+} catch (err) {
+ if (err != null && typeof err === 'object' && 'message' in err) {
+ result = err.message === 'Block signature is required to verify'
+ } else {
+ result = false
+ }
+}
+test = result === true
+check(`verify_blocks missing signature`, test)
+passes += +test
+failures += +!test
+
console.log(`${passes} \x1b[32mPASSED\x1b[0m`)
console.log(`${failures} \x1b[31mFAILED\x1b[0m`)