processBlock method
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;
}