const key = chainCode
const data = t.buffer
return hmac(key, data)
- .then(I => childKey(curve, pk, I))
+ .then(I => childKey(curve, pk, chainCode, index, I))
}
-function childKey (curve: Curve, pk: Bytes, I: ArrayBuffer): Promise<ExtendedKey> {
+function childKey (curve: Curve, pk: Bytes, chainCode: ArrayBuffer, index: number, I: ArrayBuffer): Promise<ExtendedKey> {
const IL = I.slice(0, I.byteLength / 2)
const IR = I.slice(I.byteLength / 2)
if (curve === 'ed25519 seed') {
return Promise.resolve({ privateKey: IL, chainCode: IR })
}
const ILparsed = parse256(new Uint8Array(IL))
- if (ILparsed >= Point.CURVE().n) {
- throw new Error('Invalid child key is greater than the order of the curve')
+ if (ILparsed < Point.CURVE().n) {
+ const pkParsed = parse256(pk)
+ const ck = (ILparsed + pkParsed) % Point.CURVE().n
+ if (ck !== 0n) {
+ return Promise.resolve({ privateKey: ser256(ck).buffer, chainCode: IR })
+ }
}
- const pkParsed = parse256(pk)
- const ck = (ILparsed + pkParsed) % Point.CURVE().n
- if (ck === 0n) {
- throw new Error('Invalid child key is zero')
- }
- return Promise.resolve({ privateKey: ser256(ck).buffer, chainCode: IR })
+ const t = new Uint8Array(37)
+ t.set([1])
+ t.set(new Uint8Array(IR), 1)
+ t.set(ser32(index), 33)
+ const key = chainCode
+ const data = t.buffer
+ return hmac(key, data)
+ .then(I => childKey(curve, pk, chainCode, index, I))
}
function ser32 (integer: number): Bytes {