mac static method

String mac(
  1. String macData,
  2. String oneTimeKey
)

Implementation

static String mac(String macData, String oneTimeKey) {
  String clamp(List rList) {
    /// Decimal numbers are derived from the list of hexadecimal values, from the first part of the password (r), so that they can be calculated
    /// with AND. At the end these are converted back to hexadecimal, with an even number, then these are connected to a hexadecimal value
    /// and then rotated.
    List r = [for (int a = 0; a < 16; a++) int.parse(rList[a], radix: 16)];
    List rTemp = [];

    r[3] &= 15;
    r[7] &= 15;
    r[11] &= 15;
    r[15] &= 15;
    r[4] &= 252;
    r[8] &= 252;
    r[12] &= 252;

    rTemp = [for (int a = 0; a < 16; a++) isNotEven(r[a].toRadixString(16))];

    return serialize(rTemp.join());
  }

  String tag = "";
  List messageBlock = [];

  /// It splits the hexadecimal text into 32 bytes elements, rotates it, adds a "01" and then adds it to the list.
  for (int a = 0; a < macData.length; a += 32) {
    String string = "";
    if (a + 16 > macData.length) {
      string = "01${serialize(macData.substring(a, macData.length))}";
    } else {
      string = "01${serialize(macData.substring(a, a + 32))}";
    }
    messageBlock.add(string);
  }

  /// The first part of the key (32 bytes) is split into two groups in hexadecimal and then a BigInt is created with the clamp function.
  List rList = [
    for (int a = 0; a < 32; a += 2) oneTimeKey.substring(a, a + 2)
  ];
  BigInt r = BigInt.parse(clamp(rList), radix: 16);

  /// The second part of the key (32 bytes) is rotated and then also converted to BigInt.
  BigInt s = BigInt.parse(serialize(oneTimeKey.substring(32)), radix: 16);
  BigInt p = BigInt.parse("3fffffffffffffffffffffffffffffffb", radix: 16);
  BigInt accumulator = BigInt.from(0);

  /// The accumulator is then created here.
  for (int a = 0; a < messageBlock.length; a++) {
    /// The accumulator is added to the block element of the text. In the second step the accumulator is multiplied by r (first part of the key) and
    /// modulo is applied to it by p. At the first round the accumulator is still zero, but if there are more elements, then at the next round of
    /// calculation the accumulator will have the last value and so on.
    accumulator += BigInt.parse(messageBlock[a], radix: 16);
    accumulator = (accumulator * r) % p;
  }

  /// Now the accumulator must be added with s (second part of the key). If the result in hexadecimal has more than 32 digits, then the first ones
  /// are removed until there are only 32 characters left. The result is the tag.
  accumulator += s;

  if (accumulator.toRadixString(16).length > 32) {
    tag = accumulator.toRadixString(16);
    tag = serialize(tag.substring(tag.length - 32, tag.length));
  } else {
    tag = serialize(accumulator.toRadixString(16));
  }

  return tag;
}