derive method

Bip32 derive(
  1. int index, {
  2. Bip32EccCurve? ecc,
})

Implementation

Bip32 derive(int index, {Bip32EccCurve? ecc}) {
  ecc ??= Bip32EccCurve();

  if (index > _UINT32_MAX || index < 0) {
    throw ArgumentError('Expected UInt32');
  }

  final isHardened = index >= _HIGHEST_BIT;
  final data = Uint8List(37);

  if (isHardened) {
    if (isNeutered()) {
      throw ArgumentError('Missing private key for hardened child key');
    }

    data[0] = 0x00;
    data.setRange(1, 33, privateKey!);
    data.buffer.asByteData().setUint32(33, index);
  } else {
    data.setRange(0, 33, publicKey);
    data.buffer.asByteData().setUint32(33, index);
  }

  final hmac = HMac(SHA512Digest(), 128)..init(KeyParameter(chainCode));
  final i = hmac.process(data);

  final iL = i.sublist(0, 32);
  final iR = i.sublist(32);

  if (!ecc.isPrivate(iL)) {
    return derive(index + 1);
  }

  Bip32 hd;
  if (!isNeutered()) {
    final ki = ecc.privateAdd(privateKey!, iL);

    if (ki == null) {
      return derive(index + 1);
    }

    hd = Bip32.fromPrivateKey(privateKey: ki, chainCode: iR);
  } else {
    final ki = ecc.pointAddScalar(publicKey, iL);

    if (ki == null) {
      return derive(index + 1);
    }

    hd = Bip32.fromPublicKey(publicKey: ki, chainCode: iR);
  }

  hd.depth = depth + 1;
  hd.index = index;
  hd.parentFingerprint = fingerprint.buffer.asByteData().getUint32(0);

  return hd;
}