]> git.codecow.com Git - libnemo.git/commitdiff
Update arbitrary data signing tool.
authorChris Duncan <chris@zoso.dev>
Wed, 15 Apr 2026 06:18:28 +0000 (23:18 -0700)
committerChris Duncan <chris@zoso.dev>
Wed, 15 Apr 2026 06:18:28 +0000 (23:18 -0700)
src/lib/tools.ts

index b629365d918973038b3e64209c46b6c35226ef42..9c0db6f9e4e26c2df8d2e7eafab7700b3bc645bd 100644 (file)
@@ -1,7 +1,7 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
-import { sign as nano25519_sign, verify as nano25519_verify } from 'nano25519'
+import { sign as nano25519_sign, verify as nano25519_verify } from 'nano25519/sync'
 import { Account } from './account'
 import { Block } from './block'
 import { MAX_SUPPLY, UNITS } from './constants'
@@ -18,13 +18,13 @@ type SweepResult = {
 
 export class Tools {
        /**
-       * Converts a decimal amount of nano from one unit divider to another.
-       *
-       * @param {(bigint|number|string)} amount - Decimal amount to convert
-       * @param {string} inputUnit - Current denomination
-       * @param {string} outputUnit - Desired denomination
-       * @param {string} [format] - Data type of output
-       */
+        * Converts a decimal amount of nano from one unit divider to another.
+        *
+        * @param {(bigint|number|string)} amount - Decimal amount to convert
+        * @param {string} inputUnit - Current denomination
+        * @param {string} outputUnit - Desired denomination
+        * @param {string} [format] - Data type of output
+        */
        static convert (amount: bigint | number | string, inputUnit: string, outputUnit: string): string
        static convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format: 'bigint'): bigint
        static convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format: 'number'): number
@@ -103,19 +103,19 @@ export class Tools {
        }
 
        /**
-       * Hashes one or more arbitrary strings to a 32-byte value using BLAKE2b.
-       *
-       * @param {(string|string[])} data String(s) to hash
-       * @param {string} [encoding] Interprets input strings as hexadecimal values if 'hex' is passed, else UTF-8
-       */
+        * Hashes one or more arbitrary strings to a 32-byte value using BLAKE2b.
+        *
+        * @param {(string|string[])} data String(s) to hash
+        * @param {string} [encoding] Interprets input strings as hexadecimal values if 'hex' is passed, else UTF-8
+        */
        static hash (data: string | string[], encoding?: 'hex'): Uint8Array<ArrayBuffer>
        /**
-       * Hashes one or more arbitrary strings to a 32-byte value using BLAKE2b.
-       *
-       * @param {(string|string[])} data String(s) to hash
-       * @param {string} [encoding] Interprets input strings as hexadecimal values if 'hex' is passed, else UTF-8
-       * @param {string} [format] Formats output as a hexadecimal value if 'hex' is passed, else Uint8Array<ArrayBuffer>
-       */
+        * Hashes one or more arbitrary strings to a 32-byte value using BLAKE2b.
+        *
+        * @param {(string|string[])} data String(s) to hash
+        * @param {string} [encoding] Interprets input strings as hexadecimal values if 'hex' is passed, else UTF-8
+        * @param {string} [format] Formats output as a hexadecimal value if 'hex' is passed, else Uint8Array<ArrayBuffer>
+        */
        static hash (data: string | string[], encoding?: 'hex', format?: 'hex'): string | Uint8Array<ArrayBuffer> {
                if (!Array.isArray(data)) data = [data]
                const hash = new Blake2b(32)
@@ -131,35 +131,32 @@ export class Tools {
        }
 
        /**
-       * Signs arbitrary strings with a private key using the Ed25519 signature scheme.
-       * The strings are first hashed to a 32-byte value using BLAKE2b.
-       *
-       * @param {string | Uint8Array<ArrayBuffer>} key - Hexadecimal-formatted secret key to use for signing
-       * @param {...string} input - Data to be signed
-       * @returns {Promise<string>} Hexadecimal-formatted signature
-       */
-       static async sign (key: string | Uint8Array<ArrayBuffer>, ...input: string[]): Promise<string> {
-               if (typeof key === 'string') key = hex.toBytes(key)
+        * Concatenates and signs an arbitrary set of strings with a secret key using
+        * nano25519. The input data can be up to 32 KiB in total.
+        *
+        * @param {string} secretKey - 64-byte hexadecimal secret key
+        * @param {...string[]} input - Data to be concatenated and then signed
+        * @returns {string} 64-byte hexadecimal signature
+        */
+       static sign (secretKey: string, ...input: string[]): string {
                try {
-                       const signature = nano25519_sign(this.hash(input), key)
-                       return bytes.toHex(signature)
+                       const signature = nano25519_sign(input.join(''), secretKey)
+                       return signature
                } catch (err) {
-                       throw new Error(`Failed to sign message with private key`, { cause: err })
-               } finally {
-                       bytes.erase(key)
+                       throw new Error(`Failed to sign message`, { cause: err })
                }
        }
 
        /**
-       * Collects the funds from a specified range of accounts in a wallet and sends
-       * them all to a single recipient address. Hardware wallets are unsupported.
-       *
-       * @param {(Rpc | string | URL)} rpc - RPC node information required to refresh accounts, calculate PoW, and process blocks
-       * @param {Wallet} wallet - Wallet from which to sweep funds
-       * @param {string} recipient - Destination address for all swept funds
-       * @param {number} [from=0] - Starting account index to sweep
-       * @param {number} [to=from] - Ending account index to sweep
-       * @returns An array of results including both successes and failures
+        * Collects the funds from a specified range of accounts in a wallet and sends
+        * them all to a single recipient address. Hardware wallets are unsupported.
+        *
+        * @param {(Rpc | string | URL)} rpc - RPC node information required to refresh accounts, calculate PoW, and process blocks
+        * @param {Wallet} wallet - Wallet from which to sweep funds
+        * @param {string} recipient - Destination address for all swept funds
+        * @param {number} [from=0] - Starting account index to sweep
+        * @param {number} [to=from] - Ending account index to sweep
+        * @returns An array of results including both successes and failures
         */
        static async sweep (
                rpc: Rpc | string | URL,
@@ -209,21 +206,18 @@ export class Tools {
        }
 
        /**
-       * Verifies the signature of arbitrary strings using a public key.
-       *
-       * @param {string | Uint8Array<ArrayBuffer>} key - Hexadecimal-formatted public key to use for verification
-       * @param {string} signature - Hexadcimal-formatted signature
-       * @param {...string} input - Data to be verified
-       * @returns {Promise<boolean>} True if the data was signed by the public key's matching private key
-       */
-       static async verify (key: string | Uint8Array<ArrayBuffer>, signature: string, ...input: string[]): Promise<boolean> {
-               if (typeof key === 'string') key = hex.toBytes(key)
+        * Verifies the signature of arbitrary strings using a public key.
+        *
+        * @param {string} publicKey - 64-character hexadecimal public key
+        * @param {string} signature - 128-character hexadcimal signature
+        * @param {...string} input - Data to be verified
+        * @returns {boolean} True if the data was signed by the public key's matching private key
+        */
+       static verify (publicKey: string, signature: string, ...input: string[]): boolean {
                try {
-                       return nano25519_verify(hex.toBytes(signature), this.hash(input), key)
+                       return nano25519_verify(signature, input.join(''), publicKey)
                } catch (err) {
                        throw new Error('Failed to verify signature', { cause: err })
-               } finally {
-                       bytes.erase(key)
                }
        }
 }