From: Chris Duncan Date: Fri, 1 May 2026 03:59:32 +0000 (-0700) Subject: Replace redundant sign overload that just set the property with support for 64-byte... X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=c2393b0a0c3d62e8ed41e92b6a833220a25c9af5;p=libnemo.git Replace redundant sign overload that just set the property with support for 64-byte secret key signing. Simplify return construction of sign method. Add block signature verification using address. --- diff --git a/src/lib/block.ts b/src/lib/block.ts index 69b59e3..83194a4 100644 --- a/src/lib/block.ts +++ b/src/lib/block.ts @@ -369,20 +369,24 @@ export class Block { } /** - * Sets the `signature` property of the block to a precalculated value. + * Sign the block with a 32-byte private key by deriving the matching public + * key, concatenating to create the full 64-byte secret key, and signing. * - * @param {string} signature - 64-byte hexadecimal signature - * @returns Block with `signature` value set + * Saves the result to the `signature` property of the block. + * + * @param {string} [key] - 32-byte hexadecimal private key to use for signing + * @returns {Block} this with `signature` value set */ - sign (signature: string): Block + sign (key: string): Block /** - * Signs the block using a private key. If successful, the result is stored in - * the `signature` property of the block. + * Sign the block using a 64-byte secret key. * - * @param {string} [key] - 32-byte hexadecimal private key to use for signing - * @returns Block with `signature` value set + * Saves the result to the `signature` property of the block. + * + * @param {string} [key] - 64-byte hexadecimal secret key to use for signing + * @returns {Block} this with `signature` value set */ - async sign (key: string): Promise + sign (key: string): Block /** * Signs the block using a Wallet. If successful, the result is stored in * the `signature` property of the block. The wallet must be unlocked prior to @@ -414,52 +418,51 @@ export class Block { if (this.signature !== undefined) { throw new TypeError('Block signature already exists', { cause: this.signature }) } - if (typeof input === 'string' && /^[A-F0-9]{128}$/i.test(input)) { - this.signature = input - return this - } - return new Promise(async (resolve, reject) => { - try { - if (typeof input === 'string' && /^[A-F0-9]{64}$/i.test(input)) { - const prv = hex.toBytes(input) - try { - const pub = nano25519_derive(prv) - const signature = nano25519_sign(hex.toBytes(this.hash), new Uint8Array([...prv, ...pub])) - this.signature = bytes.toHex(signature) - } finally { - prv.fill(0) - } - } else if (input instanceof Wallet && typeof index === 'number' - && (frontier === undefined || frontier instanceof (this.constructor as typeof Block)) - ) { - const wallet = input - await wallet.sign(index, this, frontier) - } else { - throw new TypeError('Invalid input for block signature') - } - resolve(this) - } catch (err) { - console.error(err) - reject(new Error('Failed to sign block', { cause: err })) + try { + if (typeof input === 'string' && /^[A-F0-9]{64}$/i.test(input)) { + const pub = nano25519_derive(input) + input += pub + } + if (typeof input === 'string' && /^[A-F0-9]{128}$/i.test(input)) { + this.signature = nano25519_sign(this.hash, input) + return this + } else if (input instanceof Wallet && typeof index === 'number' + && (frontier === undefined || frontier instanceof (this.constructor as typeof Block)) + ) { + return input.sign(index, this, frontier) + } else { + throw new TypeError('Invalid input for block signature') } - }) + } catch (err) { + console.error(err) + throw new Error('Failed to sign block', { cause: err }) + } } /** - * Verifies the signature of the block. If a key is not provided, the public - * key of the block's account will be used if it exists. + * Verifies the signature of the block with a Nano address. Defaults to the + * block's account, if it exists. * - * @param {string} [key] - Hexadecimal-formatted public key to use for verification + * @param {string} [address] - Nano account address to use for verification * @returns {boolean} True if block was signed by the matching private key */ - async verify (key?: string): Promise - async verify (key: unknown): Promise { + verify (address?: string): boolean + /** + * Verifies the signature of the block with a public key. Defaults to the + * block's account, if it exists. + * + * @param {string} [publicKey] - 32-byte hexadecimal public key to use for verification + * @returns {boolean} True if block was signed by the matching private key + */ + verify (publicKey?: string): boolean + verify (input: unknown): boolean { + input ??= this.account.publicKey + if (typeof input !== 'string') { + throw new Error('Invalid input') + } try { - key ??= this.account.publicKey - if (typeof key !== 'string') { - throw new Error('Invalid key') - } - return await nano25519_verify(hex.toBytes(this.signature ?? ''), hex.toBytes(this.hash), hex.toBytes(key)) + const account = new Account(input) + return nano25519_verify(this.signature ?? '', this.hash, account.publicKey) } catch (err) { throw new Error('Failed to verify block signature', { cause: err }) }