From acd267877b63df4a9f8902d206d00f4d1a097f64 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Mon, 9 Dec 2024 04:09:24 -0800 Subject: [PATCH] Organize worker files into workers directory and update imports. Delete unused duplicate BIP-32 ckd file. --- src/lib/bip32-key-derivation.ts | 93 ---------------------------- src/lib/workers.ts | 6 +- src/lib/{ => workers}/bip44-ckd.ts | 0 src/lib/{ => workers}/nano-nacl.d.ts | 0 src/lib/{ => workers}/nano-nacl.ts | 0 src/lib/{ => workers}/pow.ts | 0 src/main.ts | 2 +- 7 files changed, 4 insertions(+), 97 deletions(-) delete mode 100644 src/lib/bip32-key-derivation.ts rename src/lib/{ => workers}/bip44-ckd.ts (100%) rename src/lib/{ => workers}/nano-nacl.d.ts (100%) rename src/lib/{ => workers}/nano-nacl.ts (100%) rename src/lib/{ => workers}/pow.ts (100%) diff --git a/src/lib/bip32-key-derivation.ts b/src/lib/bip32-key-derivation.ts deleted file mode 100644 index 886b623..0000000 --- a/src/lib/bip32-key-derivation.ts +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Chris Duncan -// SPDX-License-Identifier: GPL-3.0-or-later - -import { BIP44_COIN_NANO, BIP44_PURPOSE, HARDENED_OFFSET, SLIP10_ED25519 } from './constants.js' -import { bytes, dec, hex, utf8 } from './convert.js' - -type ExtendedKey = { - privateKey: string - chainCode: string -} - -/** -* Derives a private child key following the BIP-32 and BIP-44 derivation path -* registered to the Nano block lattice. Only hardened child keys are defined. -* -* @param {string} seed - Hexadecimal seed derived from mnemonic phrase -* @param {number} index - Account number between 0 and 2^31-1 -* @returns {Promise} Private child key for the account -*/ -export async function nanoCKD (seed: string, index: number): Promise { - if (!Number.isSafeInteger(index) || index < 0 || index > 0x7fffffff) { - throw new RangeError(`Invalid child key index 0x${index.toString(16)}`) - } - return await ckd(seed, BIP44_COIN_NANO, index) -} - -/** -* Derives a private child key for a coin by following the specified BIP-32 and -* BIP-44 derivation path. Purpose is always 44'. Only hardened child keys are -* defined. -* -* @param {string} seed - Hexadecimal seed derived from mnemonic phrase -* @param {number} coin - Number registered to a specific coin in SLIP-044 -* @param {number} index - Account number between 0 and 2^31-1 -* @returns {Promise} Private child key for the account -*/ -export async function ckd (seed: string, coin: number, index: number): Promise { - if (!Number.isSafeInteger(index) || index < 0 || index > 0x7fffffff) { - throw new RangeError(`Invalid child key index 0x${index.toString(16)}`) - } - const masterKey = await slip10(SLIP10_ED25519, seed) - const purposeKey = await CKDpriv(masterKey, BIP44_PURPOSE + HARDENED_OFFSET) - const coinKey = await CKDpriv(purposeKey, coin + HARDENED_OFFSET) - const accountKey = await CKDpriv(coinKey, index + HARDENED_OFFSET) - return accountKey.privateKey -} - -async function slip10 (curve: string, S: string): Promise { - const key = utf8.toBytes(curve) - const data = hex.toBytes(S) - const I = await hmac(key, data) - const IL = I.slice(0, I.length / 2) - const IR = I.slice(I.length / 2) - return ({ privateKey: IL, chainCode: IR }) -} - -async function CKDpriv ({ privateKey, chainCode }: ExtendedKey, index: number): Promise { - const key = hex.toBytes(chainCode) - const data = hex.toBytes(`00${bytes.toHex(ser256(privateKey))}${bytes.toHex(ser32(index))}`) - const I = await hmac(key, data) - const IL = I.slice(0, I.length / 2) - const IR = I.slice(I.length / 2) - return ({ privateKey: IL, chainCode: IR }) -} - -function ser32 (integer: number): Uint8Array { - if (typeof integer !== 'number') { - throw new TypeError(`Expected a number, received ${typeof integer}`) - } - const bits = dec.toBin(integer) - if (bits.length > 32) { - throw new RangeError(`Expected 32-bit integer, received ${bits.length}-bit value: ${integer}`) - } - return dec.toBytes(integer, 4) -} - -function ser256 (integer: string): Uint8Array { - if (typeof integer !== 'string') { - throw new TypeError(`Expected string, received ${typeof integer}`) - } - const bits = hex.toBin(integer) - if (bits.length > 256) { - throw new RangeError(`Expected 256-bit integer, received ${bits.length}-bit value: ${integer}`) - } - return hex.toBytes(integer, 32) -} - -async function hmac (key: Uint8Array, data: Uint8Array): Promise { - const { subtle } = globalThis.crypto - const pk = await subtle.importKey('raw', key, { name: 'HMAC', hash: 'SHA-512' }, false, ['sign']) - const signature = await subtle.sign('HMAC', pk, data) - return bytes.toHex(new Uint8Array(signature)) -} diff --git a/src/lib/workers.ts b/src/lib/workers.ts index bfe19fa..631a4f7 100644 --- a/src/lib/workers.ts +++ b/src/lib/workers.ts @@ -1,6 +1,6 @@ -import { worker as Bip44Ckd } from './bip44-ckd.js' -import { worker as NanoNaCl } from './nano-nacl.js' +import { worker as Bip44Ckd } from './workers/bip44-ckd.js' +import { worker as NanoNaCl } from './workers/nano-nacl.js' // import './workers/passkey.js' -import { worker as Pow } from './pow.js' +import { worker as Pow } from './workers/pow.js' export { Bip44Ckd, NanoNaCl, Pow } diff --git a/src/lib/bip44-ckd.ts b/src/lib/workers/bip44-ckd.ts similarity index 100% rename from src/lib/bip44-ckd.ts rename to src/lib/workers/bip44-ckd.ts diff --git a/src/lib/nano-nacl.d.ts b/src/lib/workers/nano-nacl.d.ts similarity index 100% rename from src/lib/nano-nacl.d.ts rename to src/lib/workers/nano-nacl.d.ts diff --git a/src/lib/nano-nacl.ts b/src/lib/workers/nano-nacl.ts similarity index 100% rename from src/lib/nano-nacl.ts rename to src/lib/workers/nano-nacl.ts diff --git a/src/lib/pow.ts b/src/lib/workers/pow.ts similarity index 100% rename from src/lib/pow.ts rename to src/lib/workers/pow.ts diff --git a/src/main.ts b/src/main.ts index a5f6c25..8ac28a2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import { Account } from './lib/account.js' import { Blake2b } from './lib/blake2b.js' import { SendBlock, ReceiveBlock, ChangeBlock } from './lib/block.js' -import { Pow } from './lib/pow.js' +import { Pow } from './lib/workers/pow.js' import { Rpc } from './lib/rpc.js' import { Rolodex } from './lib/rolodex.js' import { Safe } from './lib/safe.js' -- 2.34.1