computeKeys method

MoneroComputeKey computeKeys(
  1. int minorIndex,
  2. int majorIndex
)

Compute the subaddress keys based on minor and major indexes.

Implementation

MoneroComputeKey computeKeys(int minorIndex, int majorIndex) {
  if (minorIndex < 0 || minorIndex > MoneroSubaddressConst.subaddrMaxIdx) {
    throw ArgumentException.invalidOperationArguments(
      "computeKeys",
      name: "minorIndex",
      reason: "Invalid minor index.",
    );
  }
  if (majorIndex < 0 || majorIndex > MoneroSubaddressConst.subaddrMaxIdx) {
    throw ArgumentException.invalidOperationArguments(
      "computeKeys",
      name: "majorIndex",
      reason: "Invalid major index.",
    );
  }

  if (minorIndex == 0 && majorIndex == 0) {
    return MoneroComputeKey(
      pubSKey: pubSKey,
      pubVKey: pubVKey,
      privateKey: privVKey,
    );
  }

  final List<int> majorIdxBytes = IntUtils.toBytes(
    majorIndex,
    length: MoneroSubaddressConst.subaddrIdxByteLen,
    byteOrder: Endian.little,
  );
  final List<int> minorIdxBytes = IntUtils.toBytes(
    minorIndex,
    length: MoneroSubaddressConst.subaddrIdxByteLen,
    byteOrder: Endian.little,
  );

  final List<int> privVKeyBytes = privVKey.raw;

  final List<int> mBytes = QuickCrypto.keccack256Hash([
    ...MoneroSubaddressConst.subaddrPrefix,
    ...privVKeyBytes,
    ...majorIdxBytes,
    ...minorIdxBytes,
  ]);
  final List<int> secretKey =
      Ed25519Utils.scalarReduceConst(mBytes).asImmutableBytes;
  final mult = Ed25519Utils.scalarMultBase(secretKey);
  final newPoint = Ed25519Utils.pointAdd(mult, pubSKey.point.toBytes());
  final MoneroPublicKey subaddrPubSKey = MoneroPublicKey.fromBytes(newPoint);
  final subaddrPubVKeyPoint = Ed25519Utils.pointScalarMult(
    newPoint,
    privVKey.raw,
  );
  final MoneroPublicKey subaddrPubVKey = MoneroPublicKey.fromBytes(
    subaddrPubVKeyPoint,
  );

  final sKey = MoneroPrivateKey.fromBytes(secretKey);
  return MoneroComputeKey(
    pubSKey: subaddrPubSKey,
    pubVKey: subaddrPubVKey,
    privateKey: sKey,
  );
}