/// <summary> /// Устанавливает первичные настройки для блоков текста и ключа /// </summary> /// <param name="blockSize"></param> /// <param name="keySize"></param> /// <param name="key"></param> public void SetSettings(BlockSize blockSize, KeySize keySize, byte[] key) { var keyLengthInBytes = RijndaelSizesConverter.KeySizeToInt(keySize) / 8; if (key.Length != keyLengthInBytes) { throw new Exception("Неверная длина ключа"); } _blockSize = blockSize; _keySize = keySize; _key = key; GenerateKeyExpansion(); }
/// <summary> /// Генерирует набор ключей для шифрования и дешифрования /// </summary> private void GenerateKeyExpansion() { var blockSize = _blockSize; var keySize = _keySize; var key = _key; var blockSizeBits = RijndaelSizesConverter.BlockSizeToInt(blockSize); var nb = blockSizeBits / 32; var nr = GetAmountRounds(blockSize, keySize); // amount rounds var nk = RijndaelSizesConverter.KeySizeToInt(keySize) / 32; // amount of columns switch (blockSizeBits > key.Length * 8 ? blockSizeBits : key.Length * 8) { case 128: nr = 10; break; case 192: nr = 12; break; case 256: nr = 14; break; default: throw new Exception("InvalidKeySize"); } _encryptKeyExpansion = new int[nb * (nr + 1)]; _decryptKeyExpansion = new int[nb * (nr + 1)]; int iTemp; var index = 0; for (var i = 0; i < nk; ++i) { int i0 = key[index++]; int i1 = key[index++]; int i2 = key[index++]; int i3 = key[index++]; _encryptKeyExpansion[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0; } if (nk <= 6) { for (var i = nk; i < nb * (nr + 1); ++i) { iTemp = _encryptKeyExpansion[i - 1]; if (i % nk == 0) { iTemp = SubWord(Rot3(iTemp)); iTemp ^= RijndaelTables.Rcon[(i / nk) - 1]; } _encryptKeyExpansion[i] = _encryptKeyExpansion[i - nk] ^ iTemp; } } else { for (var i = nk; i < nb * (nr + 1); ++i) { iTemp = _encryptKeyExpansion[i - 1]; if (i % nk == 0) { iTemp = SubWord(Rot3(iTemp)); iTemp ^= RijndaelTables.Rcon[(i / nk) - 1]; } else if (i % nk == 4) { iTemp = SubWord(iTemp); } _encryptKeyExpansion[i] = _encryptKeyExpansion[i - nk] ^ iTemp; } } for (var i = 0; i < nb; ++i) { _decryptKeyExpansion[i] = _encryptKeyExpansion[i]; _decryptKeyExpansion[nb * nr + i] = _encryptKeyExpansion[nb * nr + i]; } for (var i = nb; i < nb * nr; ++i) { var tmpKey = _encryptKeyExpansion[i]; var mul02 = MulX(tmpKey); var mul04 = MulX(mul02); var mul08 = MulX(mul04); var mul09 = tmpKey ^ mul08; _decryptKeyExpansion[i] = mul02 ^ mul04 ^ mul08 ^ Rot3(mul02 ^ mul09) ^ Rot2(mul04 ^ mul09) ^ Rot1(mul09); } for (var i = 0; i < nr + 1; i++) { for (var k = 0; k < nb; k++) { _decryptKeyExpansion[i * nb + k] = _encryptKeyExpansion[(nr - i) * nb + k]; } } }