]> zoso.dev Git - libnemo.git/commitdiff
Convert BIP44 ckd to class and update imports in worker.
authorChris Duncan <chris@zoso.dev>
Mon, 16 Dec 2024 19:30:55 +0000 (11:30 -0800)
committerChris Duncan <chris@zoso.dev>
Mon, 16 Dec 2024 19:30:55 +0000 (11:30 -0800)
src/lib/workers.ts
src/lib/workers/bip44-ckd.ts

index d6d03a7af1c736f15f3a3e3744a21222ed28a8cb..61a1b6d97f13ae6b6733d16e8c57dbab326dcd21 100644 (file)
@@ -1,4 +1,4 @@
-import { Bip44Ckd, worker as Bip44CkdWorker } from './workers/bip44-ckd.js'
+import { Bip44Ckd } from './workers/bip44-ckd.js'
 import { NanoNaCl, worker as NanoNaClWorker } from './workers/nano-nacl.js'
 // import './workers/passkey.js'
 import { Pow } from './workers/pow.js'
@@ -81,9 +81,9 @@ const w = () => {
        }
 }
 
-const bip44ckd = `const Bip44Ckd = () => {\n${Bip44CkdWorker}\n}\n`
+const bip44ckd = `const Bip44Ckd = ${Bip44Ckd}\n`
 const nanonacl = `const NanoNaCl = () => {\n${NanoNaClWorker}\n}\n`
-const pow = `const Pow = ${Pow}`
+const pow = `const Pow = ${Pow}\n`
 const start = w.toString().indexOf('{') + 1
 const end = w.toString().lastIndexOf('}')
 const body = w.toString().substring(start, end)
index aca7869a5de106892920a537028d4baa69d6dc5d..300cb8ac2763396f810e606bd3a2038ed82412e9 100644 (file)
@@ -6,20 +6,19 @@ type ExtendedKey = {
        chainCode: DataView
 }
 
-const b = () => {
+export class Bip44Ckd {
 
-       const BIP44_COIN_NANO = 165
-       const BIP44_PURPOSE = 44
-       const HARDENED_OFFSET = 0x80000000
-       const SLIP10_ED25519 = 'ed25519 seed'
+       static BIP44_COIN_NANO = 165
+       static BIP44_PURPOSE = 44
+       static HARDENED_OFFSET = 0x80000000
+       static SLIP10_ED25519 = 'ed25519 seed'
 
-
-       async function calculate (data: any[]): Promise<any[]> {
+       static async calculate (data: any[]): Promise<any[]> {
                for (const d of data) {
-                       if (d.coin != null && d.coin !== BIP44_PURPOSE) {
-                               d.privateKey = await ckd(d.seed, d.coin, d.index)
+                       if (d.coin != null && d.coin !== this.BIP44_PURPOSE) {
+                               d.privateKey = await this.ckd(d.seed, d.coin, d.index)
                        } else {
-                               d.privateKey = await nanoCKD(d.seed, d.index)
+                               d.privateKey = await this.nanoCKD(d.seed, d.index)
                        }
                }
                return data
@@ -33,11 +32,11 @@ const b = () => {
        * @param {number} index - Account number between 0 and 2^31-1
        * @returns {Promise<string>} Private child key for the account
        */
-       async function nanoCKD (seed: string, index: number): Promise<string> {
+       static async nanoCKD (seed: string, index: number): Promise<string> {
                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)
+               return await this.ckd(seed, this.BIP44_COIN_NANO, index)
        }
 
        /**
@@ -50,17 +49,17 @@ const b = () => {
        * @param {number} index - Account number between 0 and 2^31-1
        * @returns {Promise<string>} Private child key for the account
        */
-       async function ckd (seed: string, coin: number, index: number): Promise<string> {
+       static async ckd (seed: string, coin: number, index: number): Promise<string> {
                if (seed.length < 32 || seed.length > 128) {
                        throw new RangeError(`Invalid seed length`)
                }
                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)
+               const masterKey = await this.slip10(this.SLIP10_ED25519, seed)
+               const purposeKey = await this.CKDpriv(masterKey, this.BIP44_PURPOSE + this.HARDENED_OFFSET)
+               const coinKey = await this.CKDpriv(purposeKey, coin + this.HARDENED_OFFSET)
+               const accountKey = await this.CKDpriv(coinKey, index + this.HARDENED_OFFSET)
                const privateKey = new Uint8Array(accountKey.privateKey.buffer)
                let hex = ''
                for (let i = 0; i < privateKey.length; i++) {
@@ -69,29 +68,29 @@ const b = () => {
                return hex
        }
 
-       async function slip10 (curve: string, S: string): Promise<ExtendedKey> {
+       static async slip10 (curve: string, S: string): Promise<ExtendedKey> {
                const key = new TextEncoder().encode(curve)
                const data = new Uint8Array(64)
                data.set(S.match(/.{1,2}/g)!.map(byte => parseInt(byte, 16)))
-               const I = await hmac(key, data)
+               const I = await this.hmac(key, data)
                const IL = new DataView(I.buffer.slice(0, I.length / 2))
                const IR = new DataView(I.buffer.slice(I.length / 2))
                return ({ privateKey: IL, chainCode: IR })
        }
 
-       async function CKDpriv ({ privateKey, chainCode }: ExtendedKey, index: number): Promise<ExtendedKey> {
+       static async CKDpriv ({ privateKey, chainCode }: ExtendedKey, index: number): Promise<ExtendedKey> {
                const key = new Uint8Array(chainCode.buffer)
                const data = new Uint8Array(37)
                data.set([0])
-               data.set(ser256(privateKey), 1)
-               data.set(ser32(index), 33)
-               const I = await hmac(key, data)
+               data.set(this.ser256(privateKey), 1)
+               data.set(this.ser32(index), 33)
+               const I = await this.hmac(key, data)
                const IL = new DataView(I.buffer.slice(0, I.length / 2))
                const IR = new DataView(I.buffer.slice(I.length / 2))
                return ({ privateKey: IL, chainCode: IR })
        }
 
-       function ser32 (integer: number): Uint8Array {
+       static ser32 (integer: number): Uint8Array {
                if (typeof integer !== 'number') {
                        throw new TypeError(`Expected a number, received ${typeof integer}`)
                }
@@ -103,7 +102,7 @@ const b = () => {
                return new Uint8Array(view.buffer)
        }
 
-       function ser256 (integer: DataView): Uint8Array {
+       static ser256 (integer: DataView): Uint8Array {
                if (integer.constructor !== DataView) {
                        throw new TypeError(`Expected DataView, received ${typeof integer}`)
                }
@@ -113,18 +112,12 @@ const b = () => {
                return new Uint8Array(integer.buffer)
        }
 
-       async function hmac (key: Uint8Array, data: Uint8Array): Promise<Uint8Array> {
+       static async hmac (key: Uint8Array, data: Uint8Array): Promise<Uint8Array> {
                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 new Uint8Array(signature)
        }
-
-       return { ckd, nanoCKD }
 }
 
-export const Bip44Ckd = b()
-
-const start = b.toString().indexOf('{') + 1
-const end = b.toString().lastIndexOf('return')
-export const worker = b.toString().substring(start, end)
+export default Bip44Ckd.toString()