/**
   * From the Lucky13 paper: An individual record R (viewed as a byte sequence of length at least
   * zero) is processed as follows. The sender maintains an 8-byte sequence number SQN which is
   * incremented for each record sent, and forms a 5-byte field HDR consisting of a 1-byte type
   * field, a 2-byte version field, and a 2-byte length field. It then calculates a MAC over the
   * bytes SQN || HDR || R.
   *
   * @param protocolVersion
   * @param contentType
   * @param data
   * @return
   */
  public byte[] calculateMac(
      ProtocolVersion protocolVersion, ProtocolMessageType contentType, byte[] data) {

    byte[] SQN = ArrayConverter.longToUint64Bytes(sequenceNumber);
    byte[] HDR =
        ArrayConverter.concatenate(
            contentType.getArrayValue(),
            protocolVersion.getValue(),
            ArrayConverter.intToBytes(data.length, 2));

    writeMac.update(SQN);
    writeMac.update(HDR);
    writeMac.update(data);

    LOGGER.debug(
        "The MAC was caluculated over the following data: {}",
        ArrayConverter.bytesToHexString(ArrayConverter.concatenate(SQN, HDR, data)));

    byte[] result = writeMac.doFinal();

    LOGGER.debug("MAC result: {}", ArrayConverter.bytesToHexString(result));

    // we increment sequence number for the sent records
    sequenceNumber++;

    return result;
  }