deriveChild method
Implementation
HDKey deriveChild(int index) {
bool isHardened = index >= HARDENED_OFFSET;
ByteData indexByteData = ByteData(4);
indexByteData.setUint32(0, index);
ByteData data;
if (isHardened) {
// Hardened child
trueOrThrow(
this.privateKey != null,
FormatException(
'Could not derive hardened child key', this.privateKey));
ByteData zb = ByteData(1);
List<int> tmpPk = Uint8List.view(zb.buffer).toList();
tmpPk.addAll(this.privateKey!.toList());
List<int> tmpData = [];
tmpData.addAll(tmpPk); // or we can use tmpData.addAll(pk);
tmpData.addAll(Uint8List.view(indexByteData.buffer).toList());
data = ByteData.view(Uint8List.fromList(tmpData).buffer);
} else {
// Normal child
// data = serP(point(kpar)) || ser32(index)
// = serP(Kpar) || ser32(index)
List<int> pk = this.publicKey!.toList(growable: true);
pk.addAll(Uint8List.view(indexByteData.buffer));
data = ByteData.view(Uint8List.fromList(pk).buffer);
}
Uint8List I = sha512(Uint8List.view(data.buffer), this.chainCode);
Uint8List IL = I.sublist(0, 32);
Uint8List IR = I.sublist(32);
HDKey hd = new HDKey(this.versions);
// Private parent key -> private child key
if (this.privateKey != null) {
// ki = parse256(IL) + kpar (mod n)
try {
hd.privateKey = privateKeyTweakAdd(this.privateKey!, IL);
// throw if IL >= n || (privateKey + IL) === 0
} catch (err) {
print("privateKeyTweakAdd error: ${err.toString()}");
// In case parse256(IL) >= n or ki == 0, one should proceed with the next value for i
return this.deriveChild(index + 1);
}
// Public parent key -> public child key
} else {
// Ki = point(parse256(IL)) + Kpar
// = G*IL + Kpar
try {
hd.publicKey = publicKeyTweakAdd(this.publicKey!, IL, true);
// throw if IL >= n || (g**IL + publicKey) is infinity
} catch (err) {
print("publicKeyTweakAdd error: ${err.toString()}");
// In case parse256(IL) >= n or Ki is the point at infinity, one should proceed with the next value for i
return this.deriveChild(index + 1);
}
}
hd.chainCode = IR;
hd.depth = this.depth + 1;
hd.parentFingerprint = this.fingerprint;
hd.index = index;
return hd;
}