]> git.codecow.com Git - libnemo.git/commitdiff
Fix wallet signing to work with arbitrary strings like Tools. Update test vectors...
authorChris Duncan <chris@zoso.dev>
Fri, 24 Apr 2026 06:51:05 +0000 (23:51 -0700)
committerChris Duncan <chris@zoso.dev>
Fri, 24 Apr 2026 06:51:05 +0000 (23:51 -0700)
src/lib/wallet/index.ts
src/lib/wallet/sign.ts
test/test.tools.mjs

index 0f716f2d357a1f8965204386c9c03ca380f3c70d..4df8ff65d6a97a868343b941867619061e6f419c 100644 (file)
@@ -330,8 +330,8 @@ export class Wallet {
        /**\r
        * Signs arbitrary strings using the private key of the account at the wallet\r
        * index specified and returns a detached signature as a hexadecimal string.\r
-       * For compatibility with other Nano tools, the data is first hashed to a\r
-       * 32-byte value using BLAKE2b. The wallet must be unlocked prior to signing.\r
+       * The data is treated as UTF-8 strings and is internally encoded as bytes\r
+       * accordingly. The wallet must be unlocked prior to signing.\r
        *\r
        * Special note: This method can be used to sign a 16-byte nonce with a Ledger\r
        * device. The actual message signed is a string which can be expressed as the\r
@@ -346,7 +346,7 @@ export class Wallet {
        * Plan for this eventuality if you implement this method to sign nonces.\r
        *\r
        * @param {number} index - Account to use for signing\r
-       * @param {(string|string[])} data - Arbitrary data to be hashed and signed\r
+       * @param {(string|string[])} data - Arbitrary data to be signed\r
        */\r
        async sign (index: number, data: string | string[]): Promise<string>\r
        /**\r
index 5254605fdc201ee3e8ccdf2152becebfcb9bbc84..35f6609d78526374e4f7604e5b45e0b311c4f9bc 100644 (file)
@@ -3,7 +3,6 @@
 
 import { Block } from '../block'
 import { bytes, hex, utf8 } from '../convert'
-import { Blake2b } from '../crypto'
 import { Ledger } from '../ledger'
 import { Vault } from '../vault'
 import { Wallet } from '../wallet'
@@ -21,12 +20,10 @@ export async function _signData (wallet: Wallet, vault: Vault, index: unknown, d
                if (wallet.type === 'Ledger') {
                        return await Ledger.sign(index, message[0])
                }
-               const hash = new Blake2b(32)
-               message.forEach(s => hash.update(utf8.toBytes(s)))
                const { signature } = await vault.request<ArrayBuffer>({
                        action: 'sign',
                        index,
-                       message: hash.digest().buffer
+                       message: utf8.toBuffer(message.join(''))
                })
                return bytes.toHex(new Uint8Array(signature))
        } catch (err) {
index efef90f1a6cc7c060c5d4f6301eeb74b57600b79..eb04b12012c95949caa62009288597c921cc31f3 100644 (file)
@@ -99,26 +99,31 @@ await Promise.all([
        }),\r
 \r
        suite('signature tests', async () => {\r
+               const m = 'bug-libnemo@'\r
+               const n = 'codecow.com'\r
 \r
                await test('should sign data with a single parameter', async () => {\r
-                       const result = Tools.sign(NANO_TEST_VECTORS.PRIVATE_0 + NANO_TEST_VECTORS.PUBLIC_0, 'miro@metsanheimo.fi')\r
-                       assert.equal(result, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C')\r
+                       const result = Tools.sign(NANO_TEST_VECTORS.PRIVATE_0 + NANO_TEST_VECTORS.PUBLIC_0, n)\r
+                       assert.equal(result.toLowerCase(), '176469a6bea176bc060889225e2d35c484bee7bcfbe32658645de446236121fa2d2dd90e4c895c5fc3e7e9328752fb1e15195cea54964ef5cfe81a6a56dadb02')\r
                })\r
 \r
                await test('should sign data with multiple parameters', async () => {\r
-                       const result = Tools.sign(NANO_TEST_VECTORS.PRIVATE_0 + NANO_TEST_VECTORS.PUBLIC_0, 'miro@metsanheimo.fi', 'somePassword')\r
-                       assert.equal(result, 'BB534F9B469AF451B1941FFEF8EE461FC5D284B5D393140900C6E13A65EF08D0AE2BC77131EE182922F66C250C7237A83878160457D5C39A70E55F7FCE925804')\r
+                       const result = Tools.sign(NANO_TEST_VECTORS.PRIVATE_0 + NANO_TEST_VECTORS.PUBLIC_0, m, n)\r
+                       assert.equal(result.toLowerCase(), '0ceebbc0b9b3a270a30bad1eef4eddc0931effd8d5c0b7cab007fcc61f30d3ee9760cd93d7eeb5b654ecc0d9d17bc7a6d53bee54aa163a8272f425fb1184e30e')\r
                })\r
 \r
                await test('should verify a signature using the public key', async () => {\r
-                       const result = Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C', 'miro@metsanheimo.fi')\r
+                       const result = Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, '176469a6bea176bc060889225e2d35c484bee7bcfbe32658645de446236121fa2d2dd90e4c895c5fc3e7e9328752fb1e15195cea54964ef5cfe81a6a56dadb02', n)\r
                        assert.equal(result, true)\r
 \r
-                       const result2 = Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C', 'mir@metsanheimo.fi')\r
+                       const result2 = Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, '176469a6bea176bc060889225e2d35c484bee7bcfbe32658645de446236121fa2d2dd90e4c895c5fc3e7e9328752fb1e15195cea54964ef5cfe81a6a56dadb02', m)\r
                        assert.equal(result2, false)\r
 \r
-                       const result3 = Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, 'AECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C', 'miro@metsanheimo.fi')\r
+                       const result3 = Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, '076469a6bea176bc060889225e2d35c484bee7bcfbe32658645de446236121fa2d2dd90e4c895c5fc3e7e9328752fb1e15195cea54964ef5cfe81a6a56dadb02', n)\r
                        assert.equal(result3, false)\r
+\r
+                       const result4 = Tools.verify(NANO_TEST_VECTORS.PUBLIC_1, '176469a6bea176bc060889225e2d35c484bee7bcfbe32658645de446236121fa2d2dd90e4c895c5fc3e7e9328752fb1e15195cea54964ef5cfe81a6a56dadb02', n)\r
+                       assert.equal(result4, false)\r
                })\r
 \r
                await test('sweeper throws without required parameters', async () => {\r