return new Promise(async (resolve, reject) => {
try {
if (typeof input === 'string' && /^[A-F0-9]{64}$/i.test(input)) {
- const signature = await nano25519.sign(hex.toBytes(this.hash), hex.toBytes(input))
+ const prv = hex.toBytes(input)
+ const pub = nano25519.derive(prv)
+ const signature = nano25519.sign(hex.toBytes(this.hash), new Uint8Array([...prv, ...pub]))
this.signature = bytes.toHex(signature)
} else if (input instanceof Wallet && typeof index === 'number'
&& (frontier === undefined || frontier instanceof (this.constructor as typeof Block))
* 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 private key to use for signing
+ * @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 verify (key: string | Uint8Array<ArrayBuffer>, signature: string, ...input: string[]): Promise<boolean> {
if (typeof key === 'string') key = hex.toBytes(key)
try {
- return await nano25519.verify(this.hash(input), hex.toBytes(signature), key)
+ return await nano25519.verify(hex.toBytes(signature), this.hash(input), key)
} catch (err) {
throw new Error('Failed to verify signature', { cause: err })
} finally {
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
-import * as nano25519 from 'nano25519'
import { Worker as NodeWorker } from 'node:worker_threads'
import { default as CONSTANTS } from '../constants'
import { Bip39, Bip44, Blake2b, Secp256k1, WalletAesGcm } from '../crypto'
import { Data } from '../database'
+import { vaultDependencies } from './dependencies'
import { Passkey } from './passkey'
import { VaultTimer } from './vault-timer'
import { VaultWorker } from './vault-worker'
}
}
-const nano25519Url = URL.createObjectURL(new Blob([`${nano25519}`], { type: 'text/javascript' }))
-
const blob = `
- const nano25519 = await import(${nano25519Url})
+ ;${vaultDependencies};
${CONSTANTS}
const ${Secp256k1.name} = ${Secp256k1}
const ${Bip39.name} = ${Bip39}
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 = nano25519.sign(new Uint8Array(data), new Uint8Array(prv))
+ return derive.then(buf => {
+ const prv = new Uint8Array(buf)
+ 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 }
})
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