**AES** (angl. *Advanced Encryption Standard* – pažangus šifravimo standartas) – šifravimo algoritmas, 2001 metais JAV paskelbtas standartu. Dar vadinamas **Rijndael** algoritmu, jo autoriai yra Joan Daemen ir Vincent Rijmen. Rijndael yra blokinis simetrinis algoritmas. Šifravimo raktai gali būti 128, 192, arba 256 bitų ilgio, o bloko ilgis 128 bitų.

Etapų raktų sudarymas
---------------------

Etapo rakto sudarymas iš šifro rakto susideda iš dviejų pagrindinių dalių: rakto plėtimas ir etapo rakto pasirinkimas.

**Etapų raktų sudarymo procesas:**  

* Žymėjimai:

Nb – Bloko ilgis.  

Nk – Šifro rakto stulpelių skaičius.  

Nr – Etapų skaičius  

* Etapo konstanta Rcon[i] yra nepriklausoma nuo Nk ir yra apibrėžta taip:

{\displaystyle Rcon[i]=(RC[i],00,00,00)}   

kur {\displaystyle RC[i]:}   

{\displaystyle RC[1]=01}   

{\displaystyle RC[i]=02\*RC[i-1]=2^{i-1}}   

* SubByte(W) – funkcija, naudodama gautą 4-baitų žodį ir Rijndeal S-box, suskaičiuoja ir grąžina 4-baitų žodį.
* RotByte(W) – funkcija grąžina žodį, kurio baitai yra cikliškai perstatyti, jei gautas žodis buvo (a, b, c, d), tai grąžinamas rezultatas bus (b, c, d, a).
* Šifro raktas yra išplečiamas iki išplėstinio rakto.
* Etapo raktas yra gaunamas iš išplėstinio rakto tokiu būdu: pirmas Etapo Raktas sudarytas iš pirmų Nb žodžių, antrasis iš sekančių Nb žodžių, ir t. t.
* Išplėstinis Raktas yra 4-baitų žodžių masyvas ir žymimas W, W yra {\displaystyle Nb\*(Nr+1)} ilgio. Pirmi Nk žodžiai yra tiesiog Šifro Raktas. Visi kiti žodžiai yra apibrėžti besikartojančiu skaičiavimu. Rakto išplėtimo funkcija priklauso nuo Nk.

kai Nk<6:

```
KeyExpansion(byte Key[4*Nk] word W[Nb*(Nr+1)])  

 {  

   for(i = 0; i < Nk; i++)  

     W[i] = (Key[4*i], Key[4*i+1], Key[4*i+2], Key[4*i+3]);  

     for(i = Nk; i < Nb * (Nr + 1); i++)  

       {  

           temp = W[i – 1];  

           if (i % Nk == 0)  

             temp = SubByte(RotByte(temp)) XOR Rcon[i / Nk];  

             W[i] = W[i – Nk] XOR temp;  

       }  

 }  

```

Pirmieji Nk žodžių yra užpildyti šifro raktu. Kiekvienas tolimesnis žodis {\displaystyle W[i]} yra lygus prieš tai buvusio žodžio W[i–1] ir Nk pozicijų anksčiau buvusio žodžio {\displaystyle W[i-Nk]} XOR sumai. Kai indeksas i dalinasi iš Nk {\displaystyle imodNk=0} prieš atliekant operacija XOR, žodžiui W[i – 1]> įvykdoma funkcija RotByte, gautam rezultatui įvykdoma SubByte, dar pridedama Etapo konstanta {\displaystyle Rcon[i/Nk]}, ir po šių veiksmų gauta reikšmė sudedama XOR su žodžio {\displaystyle W[i-Nk]}.   

Skirtumas tarp atvejo kai {\displaystyle Nk<=6} ir kai {\displaystyle Nk>6}, kuomet {\displaystyle Nk>6}, kai indeksas {\displaystyle i-4} dalinasi iš Nk {\displaystyle (i-4)modNk=0}, atliekam SubByte operaciją žodžiui {\displaystyle W[i-1]}

Šifravimas
----------

* Visas pradinis tekstas padalijamas į vienodo ilgio blokus, kurių ilgiai gali būti 128, 192, 256 bitų, atitinkamai 4x4, 4x6, 4x8 matricos, kurių elementas {\displaystyle a\_{ij},iin(0,3),jin(0,Nb-1)}yra 8 bitų žodis, ir kiekvienam blokui atskirai atliekami skaičiavimai.
* SubByte

kiekvienas baitas {\displaystyle X=[x\_{0},x\_{1},x\_{2},x\_{3},x\_{4},x\_{5},x\_{6},x\_{7}]} pakeičiamas Y,{\displaystyle Y=[y\_{0},y\_{1},y\_{2},y\_{3},y\_{4},y\_{5},y\_{6},y\_{7}]}. Kuris yra skaičiuojamas taip:
{\displaystyle {\begin{bmatrix}y\_{0}\\y\_{1}\\y\_{2}\\y\_{3}\\y\_{4}\\y\_{5}\\y\_{6}\\y\_{7}\end{bmatrix}}={\begin{bmatrix}1&0&0&0&1&1&1&1\\1&1&0&0&0&1&1&1\\1&1&1&0&0&0&1&1\\1&1&1&1&0&0&0&1\\1&1&1&1&1&0&0&0\\0&1&1&1&1&1&0&0\\0&0&1&1&1&1&1&0\\0&0&0&1&1&1&1&1\end{bmatrix}}\*{\begin{bmatrix}x\_{0}\\x\_{1}\\x\_{2}\\x\_{3}\\x\_{4}\\x\_{5}\\x\_{6}\\x\_{7}\end{bmatrix}}+{\begin{bmatrix}1\\1\\0\\0\\0\\1\\1\\0\end{bmatrix}}}

* ShiftRows

Eilutės pastumiamos cikliškai, nulinė eilutė nekeičiama, pirmoji eilutė pastumiama per viena baitą į kairę, antroje eilutėje per du, trečioje per tris baitus.

* MixColumns

Kiekvienas stulpelis {\displaystyle A=[a\_{0},a\_{1},a\_{2},a\_{3}]} padauginamas iš matricos.
{\displaystyle {\begin{bmatrix}b\_{0}\\b\_{1}\\b\_{2}\\b\_{3}\end{bmatrix}}={\begin{bmatrix}02&03&01&01\\01&02&03&01\\01&01&02&03\\03&01&01&02\end{bmatrix}}\*{\begin{bmatrix}a\_{0}\\a\_{1}\\a\_{2}\\a\_{3}\end{bmatrix}}}
  
 Gautą rezultatas padedamas atgal.

* AddRoundKey

Sudedama bloko matrica su etapo rakto (Round key) matrica.  

Šios operacijos kartojamos dešimt kartų, tik dešimta kartą neatliekama stulpelių maišymo operacija (MixColumns).