예제 #1
0
        /// <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();
        }
예제 #2
0
        /// <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];
                }
            }
        }