import { BIP44_PURPOSE, HARDENED_OFFSET, SLIP10_ED25519 } from './constants'
type ExtendedKey = {
- privateKey: DataView<ArrayBuffer>
- chainCode: DataView
+ privateKey: ArrayBuffer
+ chainCode: ArrayBuffer
}
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}`)
}
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)
}
}