From 4411262c1ede7aead83a50ad3e1e5fc278306412 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Wed, 6 Aug 2025 11:52:35 -0700 Subject: [PATCH] Eliminate redundant DataViews from BIP-44 ckd. --- src/lib/bip44-ckd.ts | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/lib/bip44-ckd.ts b/src/lib/bip44-ckd.ts index 82bfdc3..a7c82ec 100644 --- a/src/lib/bip44-ckd.ts +++ b/src/lib/bip44-ckd.ts @@ -4,8 +4,8 @@ import { BIP44_PURPOSE, HARDENED_OFFSET, SLIP10_ED25519 } from './constants' type ExtendedKey = { - privateKey: DataView - 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 { - 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 { - 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 { 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 { + 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> { - 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, data: Uint8Array): Promise> { + 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) } } -- 2.47.3