]> git.codecow.com Git - libnemo.git/commitdiff
Eliminate redundant DataViews from BIP-44 ckd.
authorChris Duncan <chris@zoso.dev>
Wed, 6 Aug 2025 18:52:35 +0000 (11:52 -0700)
committerChris Duncan <chris@zoso.dev>
Wed, 6 Aug 2025 18:52:35 +0000 (11:52 -0700)
src/lib/bip44-ckd.ts

index 82bfdc342d189d245f44889ff7c7fb4a543bea3e..a7c82ec82e2dae5ff7dcca1284c3a39e2eebc68c 100644 (file)
@@ -4,8 +4,8 @@
 import { BIP44_PURPOSE, HARDENED_OFFSET, SLIP10_ED25519 } from './constants'
 
 type ExtendedKey = {
-       privateKey: DataView<ArrayBuffer>
-       chainCode: DataView
+       privateKey: ArrayBuffer
+       chainCode: ArrayBuffer
 }
 
 export class Bip44Ckd {
@@ -30,35 +30,35 @@ export class Bip44Ckd {
                const purposeKey = await this.CKDpriv(masterKey, BIP44_PURPOSE + HARDENED_OFFSET)
                const coinKey = await this.CKDpriv(purposeKey, coin + HARDENED_OFFSET)
                const accountKey = await this.CKDpriv(coinKey, account + HARDENED_OFFSET)
-               if (chain == null) return accountKey.privateKey.buffer
+               if (chain == null) return accountKey.privateKey
                const chainKey = await this.CKDpriv(accountKey, chain)
-               if (address == null) return chainKey.privateKey.buffer
+               if (address == null) return chainKey.privateKey
                const addressKey = await this.CKDpriv(chainKey, address)
-               return addressKey.privateKey.buffer
+               return addressKey.privateKey
        }
 
        static async slip10 (curve: string, S: ArrayBuffer): Promise<ExtendedKey> {
-               const key = new TextEncoder().encode(curve)
+               const key = new Uint8Array(new TextEncoder().encode(curve))
                const data = new Uint8Array(S)
                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))
+               const IL = I.buffer.slice(0, I.length / 2)
+               const IR = I.buffer.slice(I.length / 2)
                return ({ privateKey: IL, chainCode: IR })
        }
 
        static async CKDpriv ({ privateKey, chainCode }: ExtendedKey, index: number): Promise<ExtendedKey> {
-               const key = new Uint8Array(chainCode.buffer)
+               const key = new Uint8Array(chainCode)
                const data = new Uint8Array(37)
                data.set([0])
                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))
+               const IL = I.buffer.slice(0, I.length / 2)
+               const IR = I.buffer.slice(I.length / 2)
                return ({ privateKey: IL, chainCode: IR })
        }
 
-       static ser32 (integer: number): Uint8Array {
+       static ser32 (integer: number): Uint8Array<ArrayBuffer> {
                if (typeof integer !== 'number') {
                        throw new TypeError(`Expected a number, received ${typeof integer}`)
                }
@@ -70,20 +70,19 @@ export class Bip44Ckd {
                return new Uint8Array(view.buffer)
        }
 
-       static ser256 (integer: DataView): Uint8Array {
-               if (!(integer instanceof DataView)) {
-                       throw new TypeError(`Expected DataView, received ${typeof integer}`)
+       static ser256 (integer: ArrayBuffer): Uint8Array<ArrayBuffer> {
+               if (!(integer instanceof ArrayBuffer)) {
+                       throw new TypeError(`Expected ArrayBuffer, received ${typeof integer}`)
                }
                if (integer.byteLength > 32) {
                        throw new RangeError(`Expected 32-byte integer, received ${integer.byteLength}-byte value: ${integer}`)
                }
-               return new Uint8Array(integer.buffer)
+               return new Uint8Array(integer)
        }
 
-       static async hmac (key: Uint8Array, data: Uint8Array): Promise<Uint8Array<ArrayBuffer>> {
-               const { subtle } = crypto
-               const pk = await subtle.importKey('raw', key, { name: 'HMAC', hash: 'SHA-512' }, false, ['sign'])
-               const signature = await subtle.sign('HMAC', pk, data)
+       static async hmac (key: Uint8Array<ArrayBuffer>, data: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>> {
+               const pk = await crypto.subtle.importKey('raw', key, { name: 'HMAC', hash: 'SHA-512' }, false, ['sign'])
+               const signature = await crypto.subtle.sign('HMAC', pk, data)
                return new Uint8Array(signature)
        }
 }