]> git.codecow.com Git - libnemo.git/commitdiff
Update tests.
authorChris Duncan <chris@zoso.dev>
Fri, 18 Jul 2025 13:44:39 +0000 (06:44 -0700)
committerChris Duncan <chris@zoso.dev>
Fri, 18 Jul 2025 13:44:39 +0000 (06:44 -0700)
test/VECTORS.js
test/test.blocks.mjs [moved from test/test.sign-blocks.mjs with 82% similarity]
test/test.derive-accounts.mjs
test/test.import-wallet.mjs
test/test.main.mjs
test/test.refresh-accounts.mjs

index fad2f9e407aee71b82c242c2d5556248614fad0e..a0066b196a376dbacc34479a5cc506210fe9a00d 100644 (file)
@@ -7,16 +7,24 @@
 * Do not send any funds to the test vectors below!
 *
 * Sources:
+*      https://docs.nano.org/integration-guides/the-basics/#seed
 *      https://docs.nano.org/integration-guides/key-management/#test-vectors
 *      https://docs.nano.org/integration-guides/key-management/#creating-transactions
 *      https://github.com/trezor/python-mnemonic/blob/master/vectors.json
 *      https://tools.nanos.cc/?tool=seed
+*      https://github.com/BLAKE2/BLAKE2/blob/master/testvectors/blake2b-kat.txt
+*      https://github.com/emilbayes/blake2b/blob/master/test-vectors.json#L514-L577
 */
 export const GENESIS_ADDRESS = 'nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3'
 export const RAW_MAX = '340282366920938463463374607431768211455'
 export const SUPPLY_MAX = '133248297920938463463374607431768211455'
 
 export const NANO_TEST_VECTORS = Object.freeze({
+       // from nano.org python sample code
+       BLAKE2B_SEED: '0000000000000000000000000000000000000000000000000000000000000001',
+       BLAKE2B_PRIVATE_1: '1495F2D49159CC2EAAAA97EBB42346418E1268AFF16D7FCA90E6BAD6D0965520',
+
+       // from nano.org test vectors
        MNEMONIC: 'edge defense waste choose enrich upon flee junk siren film clown finish luggage leader kid quick brick print evidence swap drill paddle truly occur',
        PASSWORD: 'some password',
        BIP39_SEED: '0DC285FDE768F7FF29B66CE7252D56ED92FE003B605907F7A4F683C3DC8586D34A914D3C71FC099BB38EE4A59E5B081A3497B7A323E90CC68F67B5837690310C',
@@ -33,6 +41,7 @@ export const NANO_TEST_VECTORS = Object.freeze({
        PUBLIC_2: 'A46DA51986E25A14D82E32D765DCEE69B9EECCD4405411430D91DDB61B717566',
        ADDRESS_2: 'nano_3b5fnnerfrkt4me4wepqeqggwtfsxu8fai4n473iu6gxprfq4xd8pk9gh1dg',
 
+       // from nano.org transaction examples
        SEND_BLOCK: {
                account: "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx",
                previous: "92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D",
@@ -209,6 +218,7 @@ export const CUSTOM_TEST_VECTORS = Object.freeze({
        ADDRESS_3: "nano_1ddgc1m71fpyef9wg8jhmhnc8fodm6frgng3dp65om8s3hymqufp8jefijxu",
 })
 
+// from blake2b by Emil Bay who derived them using libsodium
 export const BLAKE2B_TEST_VECTORS = Object.freeze({
        LIBSODIUM: [
                { "outlen": 1, "out": "ba", "in": "", "key": "00", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
@@ -276,6 +286,8 @@ export const BLAKE2B_TEST_VECTORS = Object.freeze({
                { "outlen": 63, "out": "19c14de35fe19c92cc0e624280e4136355d4cfa9a0a98b090c4b06f5665021920725852ff1f566b0c8c37157b25fb9f947a2e70b40577a17860a0732c170ac", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
                { "outlen": 64, "out": "5fcdcc02be7714a0dbc77df498bf999ea9225d564adca1c121c9af03af92cac8177b9b4a86bcc47c79aa32aac58a3fef967b2132e9352d4613fe890beed2571b", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" }
        ],
+
+       // from BLAKE2 reference C implementation
        REFERENCE: [
                {
                        "in": "",
similarity index 82%
rename from test/test.sign-blocks.mjs
rename to test/test.blocks.mjs
index 6997be33468a1f02cda52a5dd99da6f149b29975..157400ef50287dd6974d452aa6bfa7267c73e868 100644 (file)
@@ -7,9 +7,9 @@ import { assert, suite, test } from './GLOBALS.mjs'
 import { NANO_TEST_VECTORS } from './VECTORS.js'\r
 import { SendBlock, ReceiveBlock, ChangeBlock } from '../dist/main.min.js'\r
 \r
-await suite('Valid blocks', async () => {\r
+await suite('Block format', async () => {\r
 \r
-       await test('should not allow negative balances', async () => {\r
+       await test('throw on negative balances', async () => {\r
                assert.throws(() => {\r
                        new SendBlock(\r
                                NANO_TEST_VECTORS.ADDRESS_0,\r
@@ -22,7 +22,7 @@ await suite('Valid blocks', async () => {
                }, { message: 'Negative balance' })\r
        })\r
 \r
-       await test('should allow zero balances', async () => {\r
+       await test('allow zero balances', async () => {\r
                const block = new SendBlock(\r
                        NANO_TEST_VECTORS.ADDRESS_0,\r
                        '9007199254740991',\r
@@ -35,7 +35,7 @@ await suite('Valid blocks', async () => {
                assert.equals(block.balance, BigInt(0))\r
        })\r
 \r
-       await test('should subtract balance from SendBlock correctly', async () => {\r
+       await test('subtract balance from SendBlock correctly', async () => {\r
                const block = new SendBlock(\r
                        NANO_TEST_VECTORS.ADDRESS_0,\r
                        '3000000000000000000000000000000',\r
@@ -47,7 +47,7 @@ await suite('Valid blocks', async () => {
                assert.equals(block.balance, 1000000000000000000000000000000n)\r
        })\r
 \r
-       await test('should add balance from ReceiveBlock correctly', async () => {\r
+       await test('add balance from ReceiveBlock correctly', async () => {\r
                const block = new ReceiveBlock(\r
                        NANO_TEST_VECTORS.ADDRESS_0,\r
                        '2000000000000000000000000000000',\r
@@ -60,9 +60,9 @@ await suite('Valid blocks', async () => {
        })\r
 })\r
 \r
-await suite('Block signing tests using official test vectors', async () => {\r
+await suite('Block signing using official test vectors', async () => {\r
 \r
-       await test('should create a valid signature for an open block', async () => {\r
+       await test('sign open block', async () => {\r
                const block = new ReceiveBlock(\r
                        NANO_TEST_VECTORS.OPEN_BLOCK.account,\r
                        '0',\r
@@ -77,7 +77,7 @@ await suite('Block signing tests using official test vectors', async () => {
                assert.equals(block.signature, NANO_TEST_VECTORS.OPEN_BLOCK.signature)\r
        })\r
 \r
-       await test('should create a valid signature for a receive block', async () => {\r
+       await test('sign receive block', async () => {\r
                const block = new ReceiveBlock(\r
                        NANO_TEST_VECTORS.RECEIVE_BLOCK.account,\r
                        NANO_TEST_VECTORS.RECEIVE_BLOCK.balance,\r
@@ -92,7 +92,7 @@ await suite('Block signing tests using official test vectors', async () => {
                assert.equals(block.signature, NANO_TEST_VECTORS.RECEIVE_BLOCK.signature)\r
        })\r
 \r
-       await test('should create a valid signature for a receive block without work', async () => {\r
+       await test('sign receive block without work', async () => {\r
                const block = new ReceiveBlock(\r
                        NANO_TEST_VECTORS.RECEIVE_BLOCK.account,\r
                        NANO_TEST_VECTORS.RECEIVE_BLOCK.balance,\r
@@ -107,7 +107,7 @@ await suite('Block signing tests using official test vectors', async () => {
                assert.equals(block.work, '')\r
        })\r
 \r
-       await test('should create a valid signature for a send block', async () => {\r
+       await test('sign send block', async () => {\r
                const block = new SendBlock(\r
                        NANO_TEST_VECTORS.SEND_BLOCK.account,\r
                        NANO_TEST_VECTORS.SEND_BLOCK.balance,\r
@@ -122,7 +122,7 @@ await suite('Block signing tests using official test vectors', async () => {
                assert.equals(block.signature, NANO_TEST_VECTORS.SEND_BLOCK.signature)\r
        })\r
 \r
-       await test('should create a valid signature for a send block without work', async () => {\r
+       await test('sign send block without work', async () => {\r
                const block = new SendBlock(\r
                        NANO_TEST_VECTORS.SEND_BLOCK.account,\r
                        NANO_TEST_VECTORS.SEND_BLOCK.balance,\r
@@ -137,7 +137,7 @@ await suite('Block signing tests using official test vectors', async () => {
                assert.equals(block.work, '')\r
        })\r
 \r
-       await test('should create a valid signature for a change rep block', async () => {\r
+       await test('sign change rep block', async () => {\r
                const work = '0000000000000000'\r
                const block = new ChangeBlock(\r
                        'nano_3igf8hd4sjshoibbbkeitmgkp1o6ug4xads43j6e4gqkj5xk5o83j8ja9php',\r
@@ -151,7 +151,7 @@ await suite('Block signing tests using official test vectors', async () => {
                assert.equals(block.work, work)\r
        })\r
 \r
-       await test('should create a valid signature for a change rep block without work', async () => {\r
+       await test('sign change rep block without work', async () => {\r
                const block = new ChangeBlock(\r
                        NANO_TEST_VECTORS.ADDRESS_0,\r
                        '0',\r
index 56dad8b2d770a647f1bdb2ea78bab1c4a6a38bde..00cf66e1232e9f1a5927459ca616459e40f43793 100644 (file)
@@ -7,8 +7,9 @@ import { assert, suite, test } from './GLOBALS.mjs'
 import { NANO_TEST_VECTORS } from './VECTORS.js'\r
 import { Bip44Wallet, Blake2bWallet } from '../dist/main.min.js'\r
 \r
-await suite('BIP-44 account derivation', async () => {\r
-       await test('should derive the first account from the given BIP-44 seed', async () => {\r
+await suite('Derive accounts from BIP-44 wallet', async () => {\r
+\r
+       await test('derive the first account from the given BIP-44 seed', async () => {\r
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)\r
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
                const account = await wallet.account()\r
@@ -17,14 +18,16 @@ await suite('BIP-44 account derivation', async () => {
                assert.equals(privateKey, NANO_TEST_VECTORS.PRIVATE_0)\r
                assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_0)\r
                assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_0)\r
+               assert.equals(account.index, 0)\r
 \r
                const accounts = await wallet.accounts()\r
+               assert.exists(accounts[0])\r
                assert.equals(account, accounts[0])\r
 \r
                await wallet.destroy()\r
        })\r
 \r
-       await test('should derive low indexed accounts from the given BIP-44 seed', async () => {\r
+       await test('derive low indexed accounts from the given BIP-44 seed', async () => {\r
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)\r
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
                const accounts = await wallet.accounts(1, 2)\r
@@ -35,14 +38,16 @@ await suite('BIP-44 account derivation', async () => {
                assert.equals(privateKey1, NANO_TEST_VECTORS.PRIVATE_1)\r
                assert.equals(accounts[1].publicKey, NANO_TEST_VECTORS.PUBLIC_1)\r
                assert.equals(accounts[1].address, NANO_TEST_VECTORS.ADDRESS_1)\r
+               assert.equals(accounts[1].index, 1)\r
                assert.equals(privateKey2, NANO_TEST_VECTORS.PRIVATE_2)\r
                assert.equals(accounts[2].publicKey, NANO_TEST_VECTORS.PUBLIC_2)\r
                assert.equals(accounts[2].address, NANO_TEST_VECTORS.ADDRESS_2)\r
+               assert.equals(accounts[2].index, 2)\r
 \r
                await wallet.destroy()\r
        })\r
 \r
-       await test('should derive high indexed accounts from the given seed', async () => {\r
+       await test('derive high indexed accounts from the given seed', async () => {\r
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)\r
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
                const accounts = await wallet.accounts(0x70000000, 0x7000000f)\r
@@ -51,6 +56,7 @@ await suite('BIP-44 account derivation', async () => {
                for (let i = 0x70000000; i < 0x7000000f; i++) {\r
                        const a = accounts[i]\r
                        assert.exists(a)\r
+                       assert.equals(a.index, i)\r
                        assert.exists(a.address)\r
                        assert.exists(a.publicKey)\r
                        const privateKey = await a.exportPrivateKey(wallet.seed, 'hex')\r
@@ -61,26 +67,56 @@ await suite('BIP-44 account derivation', async () => {
        })\r
 })\r
 \r
-await suite('BLAKE2b account derivation', async () => {\r
-       await test('should derive accounts for a BLAKE2b wallet', async () => {\r
-               const wallet = await Blake2bWallet.create(NANO_TEST_VECTORS.PASSWORD)\r
+await suite('Derive accounts from BLAKE2b wallet', async () => {\r
+\r
+       await test('derive the second account from the given BLAKE2b seed', async () => {\r
+               const wallet = await Blake2bWallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BLAKE2B_SEED)\r
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
-               const lowAccounts = await wallet.accounts(0, 2)\r
+               const account = await wallet.account(1)\r
+               const privateKey = await account.exportPrivateKey(wallet.seed, 'hex')\r
 \r
-               assert.equals(lowAccounts.length, 3)\r
-               for (const a of lowAccounts) {\r
-                       assert.exists(a)\r
-                       assert.exists(a.address)\r
-                       assert.exists(a.publicKey)\r
-                       const privateKey = await a.exportPrivateKey(wallet.seed, 'hex')\r
-                       assert.exists(privateKey)\r
-               }\r
+               assert.equals(privateKey, NANO_TEST_VECTORS.BLAKE2B_PRIVATE_1)\r
+               // assert.equals(account.publicKey, NANO_TEST_VECTORS.BLAKE2B_PUBLIC_0)\r
+               // assert.equals(account.address, NANO_TEST_VECTORS.BLAKE2B_ADDRESS_0)\r
+               assert.equals(account.index, 1)\r
+\r
+               const accounts = await wallet.accounts(1)\r
+               assert.exists(accounts[1])\r
+               assert.equals(account, accounts[1])\r
+\r
+               await wallet.destroy()\r
+       })\r
 \r
-               const highAccounts = await wallet.accounts(0x70000000, 0x7000000f)\r
+       await test('derive low indexed accounts from the given BLAKE2B seed', async () => {\r
+               const wallet = await Blake2bWallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BLAKE2B_SEED)\r
+               await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
+               const accounts = await wallet.accounts(1, 2)\r
+               // const privateKey1 = await accounts[1].exportPrivateKey(wallet.seed, 'hex')\r
+               // const privateKey2 = await accounts[2].exportPrivateKey(wallet.seed, 'hex')\r
+\r
+               assert.equals(accounts.length, 2)\r
+               // assert.equals(privateKey1, NANO_TEST_VECTORS.BLAKE2B_PRIVATE_1)\r
+               // assert.equals(accounts[1].publicKey, NANO_TEST_VECTORS.BLAKE2B_PUBLIC_1)\r
+               // assert.equals(accounts[1].address, NANO_TEST_VECTORS.BLAKE2B_ADDRESS_1)\r
+               assert.equals(accounts[1].index, 1)\r
+               // assert.equals(privateKey2, NANO_TEST_VECTORS.BLAKE2B_PRIVATE_2)\r
+               // assert.equals(accounts[2].publicKey, NANO_TEST_VECTORS.BLAKE2B_PUBLIC_2)\r
+               // assert.equals(accounts[2].address, NANO_TEST_VECTORS.BLAKE2B_ADDRESS_2)\r
+               assert.equals(accounts[2].index, 2)\r
+\r
+               await wallet.destroy()\r
+       })\r
 \r
-               assert.equals(highAccounts.length, 0x10)\r
-               for (const a of highAccounts) {\r
+       await test('derive high indexed accounts from the given seed', async () => {\r
+               const wallet = await Blake2bWallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BLAKE2B_SEED)\r
+               await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
+               const accounts = await wallet.accounts(0x70000000, 0x7000000f)\r
+\r
+               assert.equals(accounts.length, 0x10)\r
+               for (let i = 0x70000000; i < 0x7000000f; i++) {\r
+                       const a = accounts[i]\r
                        assert.exists(a)\r
+                       assert.equals(a.index, i)\r
                        assert.exists(a.address)\r
                        assert.exists(a.publicKey)\r
                        const privateKey = await a.exportPrivateKey(wallet.seed, 'hex')\r
index 8c9b125a48076a4795609048a1e58dedede6b7e9..f43b86c666bbce1d4cbaa512d7b66367ed36c3f1 100644 (file)
@@ -242,11 +242,8 @@ await suite('Import wallets', async () => {
                await assert.rejects(Blake2bWallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_1.replace(/./, 'g')),\r
                        'Seed contains invalid hexadecimal characters.')\r
        })\r
-})\r
-\r
-await suite('Retrieve wallets from session storage using a wallet-generated ID', async () => {\r
 \r
-       await test('Bip44Wallet', async () => {\r
+       await test('Import BIP-44 wallet from session storage using a wallet-generated ID', async () => {\r
                const id = (await Bip44Wallet.fromMnemonic(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD)).id\r
                const wallet = await Bip44Wallet.restore(id)\r
 \r
@@ -266,7 +263,7 @@ await suite('Retrieve wallets from session storage using a wallet-generated ID',
                await wallet.destroy()\r
        })\r
 \r
-       await test('Blake2bWallet', async () => {\r
+       await test('Import BLAKE2B wallet from session storage using a wallet-generated ID', async () => {\r
                const id = (await Blake2bWallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_0)).id\r
                const wallet = await Blake2bWallet.restore(id)\r
 \r
index 90f764482ce76a841260bac3a6225b97f7470dc4..ff503202de899736914565d6c56b3bd015398803 100644 (file)
@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: GPL-3.0-or-later
 
 import './test.blake2b.mjs'
+import './test.blocks.mjs'
 import './test.calculate-pow.mjs'
 import './test.create-wallet.mjs'
 import './test.derive-accounts.mjs'
@@ -10,7 +11,6 @@ import './test.ledger.mjs'
 import './test.lock-unlock.mjs'
 import './test.manage-rolodex.mjs'
 import './test.refresh-accounts.mjs'
-import './test.sign-blocks.mjs'
 import './test.tools.mjs'
 
 console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
index 4118d306fcd1b631d180700eb73ae1883875917f..79cd170fbddc8923ff13e174477c880ae361dd3f 100644 (file)
@@ -9,7 +9,7 @@ import { Account, Bip44Wallet, Rpc } from '../dist/main.min.js'
 
 const rpc = new Rpc(process.env.NODE_URL ?? '', process.env.API_KEY_NAME)
 
-await suite('refreshing account info', { skip: true }, async () => {
+await suite('Refreshing account info', { skip: true }, async () => {
 
        await test('fetch balance, frontier, and representative', async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)