processBlock method

int processBlock(
  1. List<int?> M,
  2. int offset
)
override

Implementation

int processBlock(List<int?> M, int offset) {
  List<List<int?>> invSubKeys = List.generate(16, (_) => []);
  if (!forEncryption) {
    for (var i = 0; i < 16; i++) {
      invSubKeys[i] = _subKeys[15 - i];
    }
  }

  List<List<int?>> subKeys = forEncryption ? _subKeys : invSubKeys;

  this._lBlock = M[offset]!.toSigned(32);
  this._rBlock = M[offset + 1]!.toSigned(32);
  // Initial permutation
  exchangeLR(4, 0x0f0f0f0f);
  exchangeLR(16, 0x0000ffff);
  exchangeRL(2, 0x33333333);
  exchangeRL(8, 0x00ff00ff);
  exchangeLR(1, 0x55555555);

  // Rounds
  for (var round = 0; round < 16; round++) {
    // Shortcuts
    var subKey = subKeys[round];
    var lBlock = this._lBlock;
    var rBlock = this._rBlock;

    // Feistel function
    var f = 0.toSigned(32);
    for (var i = 0; i < 8; i++) {
      (f |= (SBOX_P[i][((rBlock ^ subKey[i]!).toSigned(32) & SBOX_MASK[i])
                  .toUnsigned(32)])!
              .toSigned(32))
          .toSigned(32);
    }
    this._lBlock = rBlock.toSigned(32);
    this._rBlock = (lBlock ^ f).toSigned(32);
  }

  // Undo swap from last round
  var t = this._lBlock;
  this._lBlock = this._rBlock;
  this._rBlock = t;

  // Final permutation
  exchangeLR(1, 0x55555555);
  exchangeRL(8, 0x00ff00ff);
  exchangeRL(2, 0x33333333);
  exchangeLR(16, 0x0000ffff);
  exchangeLR(4, 0x0f0f0f0f);

  // Set output
  M[offset] = this._lBlock;
  M[offset + 1] = this._rBlock;
  return blockSize;
}