]> git.codecow.com Git - libnemo.git/commitdiff
Swtich from internal NanoNaCl to nano25519 package.
authorChris Duncan <chris@zoso.dev>
Fri, 27 Mar 2026 18:14:49 +0000 (11:14 -0700)
committerChris Duncan <chris@zoso.dev>
Fri, 27 Mar 2026 18:14:49 +0000 (11:14 -0700)
src/lib/account/index.ts
src/lib/block.ts
src/lib/crypto/index.ts
src/lib/tools.ts
src/lib/vault/vault-worker.ts
test/test.tools.mjs

index 7c780a962e0655540c521a1f003491d6080b360e..cedc7539e36a8ff85263fddb1497db313100391f 100644 (file)
@@ -1,10 +1,10 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>\r
 //! SPDX-License-Identifier: GPL-3.0-or-later\r
 \r
+import * as nano25519 from 'nano25519'\r
 import { Block } from '../block'\r
 import { ACCOUNT_KEY_BYTE_LENGTH, ACCOUNT_KEY_HEX_LENGTH } from '../constants'\r
 import { bytes, hex } from '../convert'\r
-import { NanoNaCl } from '../crypto'\r
 import { Rpc } from '../rpc'\r
 import { Address } from './address'\r
 import { _refresh } from './refresh'\r
@@ -302,7 +302,7 @@ export class Account {
                                if (privateKey.byteLength !== ACCOUNT_KEY_BYTE_LENGTH) {\r
                                        throw new TypeError(`Private key must be ${ACCOUNT_KEY_BYTE_LENGTH} bytes`)\r
                                }\r
-                               const publicKey = await NanoNaCl.convert(privateKey)\r
+                               const publicKey = nano25519.derive(privateKey)\r
                                const address = new Address(publicKey)\r
                                this.#isInternal = true\r
                                const account = new this(address, publicKey, index)\r
index e5cd617b9d0677b7dc3cc5d47b8d7aaef9fbe9f7..4fa64f727451490a44223fb5e8a5497c63e7b0f2 100644 (file)
@@ -2,10 +2,11 @@
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
 import { NanoPow } from 'nano-pow'
+import * as nano25519 from 'nano25519'
 import { Account } from './account'
-import { BURN_PUBLIC_KEY, PREAMBLE, DIFFICULTY_RECEIVE, DIFFICULTY_SEND, UNITS } from './constants'
+import { BURN_PUBLIC_KEY, DIFFICULTY_RECEIVE, DIFFICULTY_SEND, PREAMBLE, UNITS } from './constants'
 import { bytes, dec, hex } from './convert'
-import { Blake2b, NanoNaCl } from './crypto'
+import { Blake2b } from './crypto'
 import { Rpc } from './rpc'
 import { Tools } from './tools'
 import { Wallet } from './wallet'
@@ -411,7 +412,7 @@ export class Block {
                return new Promise(async (resolve, reject) => {
                        try {
                                if (typeof input === 'string' && /^[A-F0-9]{64}$/i.test(input)) {
-                                       const signature = await NanoNaCl.detached(hex.toBytes(this.hash), hex.toBytes(input))
+                                       const signature = nano25519.sign(hex.toBytes(this.hash), hex.toBytes(input))
                                        this.signature = bytes.toHex(signature)
                                } else if (input instanceof Wallet && typeof index === 'number'
                                        && (frontier === undefined || frontier instanceof (this.constructor as typeof Block))
@@ -443,7 +444,7 @@ export class Block {
                        if (typeof key !== 'string') {
                                throw new Error('Invalid key')
                        }
-                       return await NanoNaCl.verify(hex.toBytes(this.hash), hex.toBytes(this.signature ?? ''), hex.toBytes(key))
+                       return await nano25519.verify(hex.toBytes(this.signature ?? ''), hex.toBytes(this.hash), hex.toBytes(key))
                } catch (err) {
                        throw new Error('Failed to verify block signature', { cause: err })
                }
index c0f3d8c73b8863b2ae7c056cc01c601de7d641ca..127f95281ff7dabc76c5c244c88954fa84506bc6 100644 (file)
@@ -4,8 +4,8 @@
 import { Bip39 } from './bip39'
 import { Bip44 } from './bip44'
 import { Blake2b } from './blake2b'
-import { NanoNaCl } from './nano-nacl'
 import { Secp256k1 } from './secp256k1'
 import { WalletAesGcm } from './wallet-aes-gcm'
 
-export { Bip39, Bip44, Blake2b, NanoNaCl, Secp256k1, WalletAesGcm }
+export { Bip39, Bip44, Blake2b, Secp256k1, WalletAesGcm }
+
index 59ca5d4659dc728c17bc0afd8f07d27e2895e2d6..d93cbe231dc42727a92be6c5c58e78917bb76c2b 100644 (file)
@@ -1,11 +1,12 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
+import * as nano25519 from 'nano25519'
 import { Account } from './account'
 import { Block } from './block'
 import { MAX_SUPPLY, UNITS } from './constants'
 import { bytes, hex } from './convert'
-import { Blake2b, NanoNaCl } from './crypto'
+import { Blake2b } from './crypto'
 import { Rpc } from './rpc'
 import { Wallet } from './wallet'
 
@@ -140,7 +141,7 @@ export class Tools {
        static async sign (key: string | Uint8Array<ArrayBuffer>, ...input: string[]): Promise<string> {
                if (typeof key === 'string') key = hex.toBytes(key)
                try {
-                       const signature = await NanoNaCl.detached(this.hash(input), key)
+                       const signature = nano25519.sign(this.hash(input), key)
                        return bytes.toHex(signature)
                } catch (err) {
                        throw new Error(`Failed to sign message with private key`, { cause: err })
@@ -218,7 +219,7 @@ export class Tools {
        static async verify (key: string | Uint8Array<ArrayBuffer>, signature: string, ...input: string[]): Promise<boolean> {
                if (typeof key === 'string') key = hex.toBytes(key)
                try {
-                       return await NanoNaCl.verify(this.hash(input), hex.toBytes(signature), key)
+                       return nano25519.verify(hex.toBytes(signature), this.hash(input), key)
                } catch (err) {
                        throw new Error('Failed to verify signature', { cause: err })
                } finally {
index 88a9b2582fcd4ea10d4306ab2dbe88e77794f209..e813cd61edf13d519dfb25fe8a9a288e84c7d161 100644 (file)
@@ -1,8 +1,9 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
+import * as nano25519 from 'nano25519'
 import { BIP44_COIN_NANO } from '../constants'
-import { Bip39, Bip44, Blake2b, NanoNaCl, WalletAesGcm } from '../crypto'
+import { Bip39, Bip44, Blake2b, WalletAesGcm } from '../crypto'
 import { WalletType } from '../wallet'
 import { Passkey } from './passkey'
 import { VaultTimer } from './vault-timer'
@@ -192,8 +193,9 @@ export class VaultWorker {
                                : this.#type === 'Exodus'
                                        ? Bip44.ckd('Bitcoin seed', this.#seed, 0x100, index, 0, 0)
                                        : Blake2b.ckd(this.#seed, index)
-                       return derive.then(prv => {
-                               const pub = NanoNaCl.convert(new Uint8Array(prv))
+                       return derive.then(result => {
+                               const prv = new Uint8Array(result)
+                               const pub = nano25519.derive(prv)
                                this.#timer = new VaultTimer(() => this.lock(), this.#timeout)
                                return { index, publicKey: pub.buffer }
                        })
@@ -258,8 +260,10 @@ export class VaultWorker {
                        const derive = this.#type === 'BLAKE2b'
                                ? Blake2b.ckd(this.#seed, index)
                                : Bip44.ckd(this.#type === 'Exodus' ? 'Bitcoin seed' : 'ed25519 seed', this.#seed, BIP44_COIN_NANO, index)
-                       return derive.then(prv => {
-                               const sig = NanoNaCl.detached(new Uint8Array(data), new Uint8Array(prv))
+                       return derive.then(result => {
+                               const prv = new Uint8Array(result)
+                               const pub = nano25519.derive(prv)
+                               const sig = nano25519.sign(new Uint8Array(data), new Uint8Array([...prv, ...pub]))
                                this.#timer = new VaultTimer(() => this.lock(), this.#timeout)
                                return { signature: sig.buffer }
                        })
index 81ba67da6ae437751537fe8af41aff8c53a52a79..2965c1cdcd3edc072d088b139fbb086b0e36b0b9 100644 (file)
@@ -101,12 +101,12 @@ await Promise.all([
        suite('signature tests', async () => {\r
 \r
                await test('should sign data with a single parameter', async () => {\r
-                       const result = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, 'miro@metsanheimo.fi')\r
+                       const result = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0 + NANO_TEST_VECTORS.PUBLIC_0, 'miro@metsanheimo.fi')\r
                        assert.equal(result, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C')\r
                })\r
 \r
                await test('should sign data with multiple parameters', async () => {\r
-                       const result = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, 'miro@metsanheimo.fi', 'somePassword')\r
+                       const result = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0 + NANO_TEST_VECTORS.PUBLIC_0, 'miro@metsanheimo.fi', 'somePassword')\r
                        assert.equal(result, 'BB534F9B469AF451B1941FFEF8EE461FC5D284B5D393140900C6E13A65EF08D0AE2BC77131EE182922F66C250C7237A83878160457D5C39A70E55F7FCE925804')\r
                })\r
 \r