Saltar al contenido
El bit perdido
Newsletter

Lección 12 de 13

La expansión de clave y el descifrado de AES

Genera las 11 claves de ronda de AES-128 a partir de 16 bytes, descifra deshaciendo cada operación en orden inverso y repasa los ataques conocidos.

Al terminar sabrás:

  • Calcular palabras de la expansión de clave con RotWord, SubWord y Rcon
  • Explicar por qué las constantes Rcon son potencias de x en el cuerpo de 256 elementos
  • Descifrar con InvShiftRows, InvSubBytes e InvMixColumns en orden inverso
  • Saber qué ataques se conocen contra AES-128 y qué significan

Si sabes qué es un número en binario y sumar módulo 2 (sin llevadas), puedes seguirlo. Lo demás (hexadecimal, XOR, permutaciones, polinomios módulo 2 y cuerpos finitos) se explica sobre la marcha.

En la lección anterior desmontamos una ronda de AES, y en la última cuenta usamos «la clave de ronda 1» sin decir de dónde sale. Hoy cerramos el diseño de AES: cómo se fabrican las once claves de ronda a partir de los 16 bytes de la clave, cómo se descifra, y qué se sabe de los intentos de romperlo. Seguimos en el punto del relato en que AES ya ha sustituido a DES, y quedan por delante los modos de operación.

La idea

AES-128 hace un AddRoundKey antes de la primera ronda y uno al final de cada una de las diez rondas: necesita 11 claves de ronda de 16 bytes, 176 bytes en total. Alicia y Bernardo comparten solo 16. La expansión de clave estira esos 16 bytes hasta 176 con un procedimiento público y sin secretos: lo único secreto es la clave.

Para que la expansión sirva, debe cumplir dos cosas. Cada byte de la clave debe influir en muchas claves de ronda, y las claves de ronda no deben ser fáciles de relacionar entre sí. Lo primero se consigue encadenando las palabras; lo segundo, metiendo de vez en cuando una caja S y una constante distinta en cada ronda.

Descifrar es la otra mitad: como cada operación de AES es invertible, se deshace una a una en orden inverso, y las claves de ronda se usan al revés. La diferencia con DES es que aquí no hay truco de Feistel: hay que construir de verdad las operaciones inversas.

La expansión de clave

Una palabra es una cadena de 4 bytes. La clave de 16 bytes son las cuatro primeras palabras w0,w1,w2,w3w_0, w_1, w_2, w_3 (los bytes 00 a 33 forman w0w_0, y así sucesivamente). Las demás, hasta w43w_{43}, se calculan con la regla

wi=wi−4⊕temp,temp={SubWord(RotWord(wi−1))⊕Rconi/4si i es muˊltiplo de 4,wi−1en otro caso.w_i = w_{i-4} \oplus \text{temp}, \qquad \text{temp} = \begin{cases} \mathrm{SubWord}(\mathrm{RotWord}(w_{i-1})) \oplus \mathrm{Rcon}_{i/4} & \text{si } i \text{ es múltiplo de } 4,\\ w_{i-1} & \text{en otro caso.} \end{cases}
  • RotWord\mathrm{RotWord} rota la palabra un byte a la izquierda: (a0,a1,a2,a3)↦(a1,a2,a3,a0)(a_0,a_1,a_2,a_3)\mapsto(a_1,a_2,a_3,a_0).
  • SubWord\mathrm{SubWord} aplica la caja S de SubBytes a cada uno de los cuatro bytes.
  • Rconj\mathrm{Rcon}_j es la palabra (rcj,00,00,00)(\texttt{rc}_j, \texttt{00}, \texttt{00}, \texttt{00}), con rcj\texttt{rc}_j la constante de la ronda jj.

La clave de ronda rr son las palabras w4r,w4r+1,w4r+2,w4r+3w_{4r}, w_{4r+1}, w_{4r+2}, w_{4r+3}, colocadas como columnas de una matriz 4×44\times 4, igual que el estado.

Las constantes. Los bytes rc1,…,rc10\texttt{rc}_1,\dots,\texttt{rc}_{10} son las potencias x0,x1,…,x9x^0, x^1, \dots, x^9 en F28\mathbb{F}_{2^8}. Se obtienen multiplicando por 02\texttt{02} (xtime) cada vez:

jj12345678910
rcj\texttt{rc}_j01\texttt{01}02\texttt{02}04\texttt{04}08\texttt{08}10\texttt{10}20\texttt{20}40\texttt{40}80\texttt{80}1b\texttt{1b}36\texttt{36}

Hasta 80\texttt{80} es solo desplazar. Luego, x8=x4+x3+x+1=1bx^8 = x^4+x^3+x+1 = \texttt{1b} por el polinomio con el que se construye el cuerpo, y x9=1b⋅02=36x^9 = \texttt{1b}\cdot\texttt{02} = \texttt{36}. Para qué sirven: sin ellas, las cuatro palabras de cada bloque se calcularían de la misma forma en todas las rondas, y la expansión tendría simetrías que un atacante podría aprovechar. Con una constante distinta por ronda se rompe esa simetría.

Ejemplo resuelto: de w0,…,w3w_0,\dots,w_3 a la clave de la ronda 1

Usamos la clave del ejemplo de FIPS 197:

w0=2b7e1516,w1=28aed2a6,w2=abf71588,w3=09cf4f3c.\begin{gathered} w_0 = \texttt{2b7e1516},\quad w_1 = \texttt{28aed2a6},\\ w_2 = \texttt{abf71588},\quad w_3 = \texttt{09cf4f3c}. \end{gathered}

w4w_4 (i=4i=4 es múltiplo de 4). Partimos de w3=09cf4f3cw_3 = \texttt{09cf4f3c}.

  1. RotWord\mathrm{RotWord}: cf4f3c09\texttt{cf4f3c09}.
  2. SubWord\mathrm{SubWord} (con la tabla de la caja S de FIPS 197, §5.1.1): S(cf)=8aS(\texttt{cf})=\texttt{8a}, S(4f)=84S(\texttt{4f})=\texttt{84}, S(3c)=ebS(\texttt{3c})=\texttt{eb}, S(09)=01S(\texttt{09})=\texttt{01}, luego 8a84eb01\texttt{8a84eb01}.
  3. XOR con Rcon1=01000000\mathrm{Rcon}_1 = \texttt{01000000}: 8b84eb01\texttt{8b84eb01}.
  4. w4=w0⊕8b84eb01=2b7e1516⊕8b84eb01=a0fafe17w_4 = w_0 \oplus \texttt{8b84eb01} = \texttt{2b7e1516}\oplus\texttt{8b84eb01} = \texttt{a0fafe17}.

w5,w6,w7w_5, w_6, w_7. Ya no hay caja S, solo XOR con la palabra anterior:

  • w5=w1⊕w4=28aed2a6⊕a0fafe17=88542cb1w_5 = w_1 \oplus w_4 = \texttt{28aed2a6}\oplus\texttt{a0fafe17} = \texttt{88542cb1}.
  • w6=w2⊕w5=abf71588⊕88542cb1=23a33939w_6 = w_2 \oplus w_5 = \texttt{abf71588}\oplus\texttt{88542cb1} = \texttt{23a33939}.
  • w7=w3⊕w6=09cf4f3c⊕23a33939=2a6c7605w_7 = w_3 \oplus w_6 = \texttt{09cf4f3c}\oplus\texttt{23a33939} = \texttt{2a6c7605}.

La clave de la ronda 1 es w4w5w6w7w_4w_5w_6w_7, la matriz con esas palabras como columnas, que ya usamos en la lección anterior:

(a088232afa54a36cfe2c397617b13905).\begin{pmatrix} \texttt{a0}&\texttt{88}&\texttt{23}&\texttt{2a}\\ \texttt{fa}&\texttt{54}&\texttt{a3}&\texttt{6c}\\ \texttt{fe}&\texttt{2c}&\texttt{39}&\texttt{76}\\ \texttt{17}&\texttt{b1}&\texttt{39}&\texttt{05} \end{pmatrix}.

Siguiendo igual hasta w43=b6630ca6w_{43} = \texttt{b6630ca6} se llega a la clave de la ronda 10, w40w41w42w43w_{40}w_{41}w_{42}w_{43}:

d014f9a8 c9ee2589 e13f0cc8 b6630ca6.\texttt{d014f9a8}\ \texttt{c9ee2589}\ \texttt{e13f0cc8}\ \texttt{b6630ca6}.

Las diez rondas del ejemplo

Con las claves de ronda, cifrar el bloque del ejemplo de FIPS 197,

3243f6a8 885a308d 313198a2 e0370734,\texttt{3243f6a8}\ \texttt{885a308d}\ \texttt{313198a2}\ \texttt{e0370734},

es repetir lo que ya sabes. Esta tabla da el estado al inicio de cada ronda (el de la ronda 1 es el bloque más la clave de la ronda 0). Cada estado se lista como los 16 bytes en el orden del bloque, es decir, columna a columna (cada grupo de 8 dígitos es una columna).

RondaEstado al inicio de la ronda
1193de3be a0f4e22b 9ac68d2a e9f84808\texttt{193de3be}\ \texttt{a0f4e22b}\ \texttt{9ac68d2a}\ \texttt{e9f84808}
2a49c7ff2 689f352b 6b5bea43 026a5049\texttt{a49c7ff2}\ \texttt{689f352b}\ \texttt{6b5bea43}\ \texttt{026a5049}
3aa8f5f03 61dde3ef 82d24ad2 6832469a\texttt{aa8f5f03}\ \texttt{61dde3ef}\ \texttt{82d24ad2}\ \texttt{6832469a}
4486c4eee 671d9d0d 4de3b138 d65f58e7\texttt{486c4eee}\ \texttt{671d9d0d}\ \texttt{4de3b138}\ \texttt{d65f58e7}
5e0927fe8 c86363c0 d9b13550 85b8be01\texttt{e0927fe8}\ \texttt{c86363c0}\ \texttt{d9b13550}\ \texttt{85b8be01}
6f1006f55 c1924cef 7cc88b32 5db5d50c\texttt{f1006f55}\ \texttt{c1924cef}\ \texttt{7cc88b32}\ \texttt{5db5d50c}
7260e2e17 3d41b77d e86472a9 fdd28b25\texttt{260e2e17}\ \texttt{3d41b77d}\ \texttt{e86472a9}\ \texttt{fdd28b25}
85a4142b1 1949dc1f a3e01965 7a8c040c\texttt{5a4142b1}\ \texttt{1949dc1f}\ \texttt{a3e01965}\ \texttt{7a8c040c}
9ea835cf0 0445332d 655d98ad 8596b0c5\texttt{ea835cf0}\ \texttt{0445332d}\ \texttt{655d98ad}\ \texttt{8596b0c5}
10eb40f21e 592e3884 8ba113e7 1bc342d2\texttt{eb40f21e}\ \texttt{592e3884}\ \texttt{8ba113e7}\ \texttt{1bc342d2}

La ronda 10 no tiene MixColumns, y su salida es el criptograma:

c=3925841d 02dc09fb dc118597 196a0b32.c = \texttt{3925841d}\ \texttt{02dc09fb}\ \texttt{dc118597}\ \texttt{196a0b32}.

Descifrar: deshacer en orden inverso

Cada operación de la ronda tiene inversa.

  • AddRoundKey es su propia inversa: el XOR con la misma clave deshace el XOR.
  • InvShiftRows rota la fila rr del estado rr posiciones a la derecha.
  • InvSubBytes aplica la tabla inversa de SS (que existe porque SS es biyectiva): S−1(ed)=53S^{-1}(\texttt{ed}) = \texttt{53}. A mano no se calcula: se lee en la tabla 6 de FIPS 197 (§5.3.2), igual que SS se lee en su tabla 4.
  • InvMixColumns multiplica cada columna por la matriz inversa de MM en F28\mathbb{F}_{2^8}:
M−1=(0e0b0d09090e0b0d0d090e0b0b0d090e).M^{-1} = \begin{pmatrix} \texttt{0e}&\texttt{0b}&\texttt{0d}&\texttt{09}\\ \texttt{09}&\texttt{0e}&\texttt{0b}&\texttt{0d}\\ \texttt{0d}&\texttt{09}&\texttt{0e}&\texttt{0b}\\ \texttt{0b}&\texttt{0d}&\texttt{09}&\texttt{0e} \end{pmatrix}.

Hemos comprobado con un programa que M M−1=IM\,M^{-1}=I en F28\mathbb{F}_{2^8}. Los coeficientes son más «pesados» que 01,02,03\texttt{01},\texttt{02},\texttt{03} (cada uno necesita hasta tres xtime), y por eso el descifrado de AES es algo más costoso que el cifrado.

El descifrado hace, en este orden:

  1. AddRoundKey con la clave de la ronda 10.
  2. Para r=9,8,…,1r = 9, 8, \dots, 1: InvShiftRows, InvSubBytes, AddRoundKey con la clave de la ronda rr e InvMixColumns.
  3. Última ronda: InvShiftRows, InvSubBytes y AddRoundKey con la clave de la ronda 0.

Las claves de ronda se usan de la 10 a la 0. A diferencia de DES, no basta con invertir el orden de las subclaves: hay que invertir también las operaciones.

Ejemplo resuelto: el primer paso del descifrado

Descifremos cc con la clave del ejemplo de FIPS 197. Sumamos la clave de la ronda 10:

(3902dc1925dc116a8409850b1dfb9732)⊕(d0c9e1b614ee3f63f9250c0ca889c8a6)=(e9cb3daf31322e097d2c8907b5725f94).\begin{pmatrix} \texttt{39}&\texttt{02}&\texttt{dc}&\texttt{19}\\ \texttt{25}&\texttt{dc}&\texttt{11}&\texttt{6a}\\ \texttt{84}&\texttt{09}&\texttt{85}&\texttt{0b}\\ \texttt{1d}&\texttt{fb}&\texttt{97}&\texttt{32} \end{pmatrix} \oplus \begin{pmatrix} \texttt{d0}&\texttt{c9}&\texttt{e1}&\texttt{b6}\\ \texttt{14}&\texttt{ee}&\texttt{3f}&\texttt{63}\\ \texttt{f9}&\texttt{25}&\texttt{0c}&\texttt{0c}\\ \texttt{a8}&\texttt{89}&\texttt{c8}&\texttt{a6} \end{pmatrix} = \begin{pmatrix} \texttt{e9}&\texttt{cb}&\texttt{3d}&\texttt{af}\\ \texttt{31}&\texttt{32}&\texttt{2e}&\texttt{09}\\ \texttt{7d}&\texttt{2c}&\texttt{89}&\texttt{07}\\ \texttt{b5}&\texttt{72}&\texttt{5f}&\texttt{94} \end{pmatrix}.

Es el estado tras el ShiftRows de la ronda 10. Ahora InvShiftRows (fila 1 una posición a la derecha, fila 2 dos, fila 3 tres):

(e9cb3daf0931322e89077d2c725f94b5),\begin{pmatrix} \texttt{e9}&\texttt{cb}&\texttt{3d}&\texttt{af}\\ \texttt{09}&\texttt{31}&\texttt{32}&\texttt{2e}\\ \texttt{89}&\texttt{07}&\texttt{7d}&\texttt{2c}\\ \texttt{72}&\texttt{5f}&\texttt{94}&\texttt{b5} \end{pmatrix},

y InvSubBytes. Estos son los 16 valores de la tabla inversa que hacen falta, columna a columna:

columna 1columna 2columna 3columna 4
e9↦eb\texttt{e9}\mapsto\texttt{eb}cb↦59\texttt{cb}\mapsto\texttt{59}3d↦8b\texttt{3d}\mapsto\texttt{8b}af↦1b\texttt{af}\mapsto\texttt{1b}
09↦40\texttt{09}\mapsto\texttt{40}31↦2e\texttt{31}\mapsto\texttt{2e}32↦a1\texttt{32}\mapsto\texttt{a1}2e↦c3\texttt{2e}\mapsto\texttt{c3}
89↦f2\texttt{89}\mapsto\texttt{f2}07↦38\texttt{07}\mapsto\texttt{38}7d↦13\texttt{7d}\mapsto\texttt{13}2c↦42\texttt{2c}\mapsto\texttt{42}
72↦1e\texttt{72}\mapsto\texttt{1e}5f↦84\texttt{5f}\mapsto\texttt{84}94↦e7\texttt{94}\mapsto\texttt{e7}b5↦d2\texttt{b5}\mapsto\texttt{d2}

Queda

(eb598b1b402ea1c3f23813421e84e7d2).\begin{pmatrix} \texttt{eb}&\texttt{59}&\texttt{8b}&\texttt{1b}\\ \texttt{40}&\texttt{2e}&\texttt{a1}&\texttt{c3}\\ \texttt{f2}&\texttt{38}&\texttt{13}&\texttt{42}\\ \texttt{1e}&\texttt{84}&\texttt{e7}&\texttt{d2} \end{pmatrix}.

Es el estado de la fila 10 de la tabla, eb40f21e 592e3884…\texttt{eb40f21e}\ \texttt{592e3884}\dots: la entrada de la ronda 10, recuperada. Seguimos: AddRoundKey con la clave de la ronda 9, w36w37w38w39w_{36}w_{37}w_{38}w_{39},

ac7766f3 19fadc21 28d12941 575c006e\texttt{ac7766f3}\ \texttt{19fadc21}\ \texttt{28d12941}\ \texttt{575c006e}

(en el ejercicio 2 recuperarás dos de esas palabras), da

(4740a34c37d4709f94e43a42eda5a6bc),\begin{pmatrix} \texttt{47}&\texttt{40}&\texttt{a3}&\texttt{4c}\\ \texttt{37}&\texttt{d4}&\texttt{70}&\texttt{9f}\\ \texttt{94}&\texttt{e4}&\texttt{3a}&\texttt{42}\\ \texttt{ed}&\texttt{a5}&\texttt{a6}&\texttt{bc} \end{pmatrix},

y falta InvMixColumns. La primera columna (47,37,94,ed)(\texttt{47},\texttt{37},\texttt{94},\texttt{ed}) da, en su primer byte,

0e⋅47⊕0b⋅37⊕0d⋅94⊕09⋅ed=87⊕fa⊕3e⊕c4=87.\begin{aligned} &\texttt{0e}\cdot\texttt{47}\oplus\texttt{0b}\cdot\texttt{37}\oplus\texttt{0d}\cdot\texttt{94}\oplus\texttt{09}\cdot\texttt{ed}\\ &= \texttt{87}\oplus\texttt{fa}\oplus\texttt{3e}\oplus\texttt{c4} = \texttt{87}. \end{aligned}

La columna completa es (87,6e,46,a6)(\texttt{87},\texttt{6e},\texttt{46},\texttt{a6}) y el estado resultante,

(87f24d976e4c90ec46e74ac3a68cd895),\begin{pmatrix} \texttt{87}&\texttt{f2}&\texttt{4d}&\texttt{97}\\ \texttt{6e}&\texttt{4c}&\texttt{90}&\texttt{ec}\\ \texttt{46}&\texttt{e7}&\texttt{4a}&\texttt{c3}\\ \texttt{a6}&\texttt{8c}&\texttt{d8}&\texttt{95} \end{pmatrix},

es exactamente el que salió de ShiftRows en la ronda 9. Repitiendo el proceso otras ocho veces se llega al bloque original, 3243f6a8…\texttt{3243f6a8}\dots (lo hemos comprobado con un programa).

¿Se puede romper AES?

Ningún ataque práctico se conoce contra AES completo: nadie ha encontrado una forma de recuperar la clave sustancialmente más rápida que probarlas todas con un coste que se pueda ejecutar. En 2011, Bogdanov, Khovratovich y Rechberger publicaron, según el resumen de su artículo, el primer ataque de recuperación de clave contra AES-128 completo: un ataque de biclique con una complejidad de 2126,12^{126{,}1} operaciones. La fuerza bruta cuesta 21282^{128}, así que el ataque es unas 2128/2126,1≈3,72^{128}/2^{126{,}1}\approx 3{,}7 veces más rápido: menos de cuatro veces. Pero 2126,12^{126{,}1} es todavía del orden de 103810^{38} operaciones: un ahorro de factor pequeño sobre un número inalcanzable. Es un resultado teórico que mide el margen de seguridad de AES, no una amenaza.

Ejercicios

Ejercicio 1

Comprueba que rc9=1b\texttt{rc}_9 = \texttt{1b} y rc10=36\texttt{rc}_{10} = \texttt{36} partiendo de rc8=80\texttt{rc}_8 = \texttt{80}, y calcula la constante siguiente, x10x^{10}.

Ver la solución

Multiplicar por 02\texttt{02} es xtime. Con 80=10000000\texttt{80} = 10000000, el desplazamiento a la izquierda se sale del byte (queda 00\texttt{00} con un bit de desbordamiento), y se hace XOR con 1b\texttt{1b}: rc9=1b\texttt{rc}_9 = \texttt{1b}. Ahora 1b=00011011\texttt{1b} = 00011011 se desplaza a 00110110=3600110110 = \texttt{36} sin desbordar, así que rc10=36\texttt{rc}_{10} = \texttt{36}. Una vez más, 36=00110110\texttt{36} = 00110110 pasa a 01101100=6c01101100 = \texttt{6c}, sin desbordar. La constante siguiente es 6c\texttt{6c} (AES-128 no la usa).

Ejercicio 2

La expansión de clave se puede recorrer hacia atrás. Sabiendo w42=e13f0cc8w_{42} = \texttt{e13f0cc8}, w43=b6630ca6w_{43} = \texttt{b6630ca6} y w40=d014f9a8w_{40} = \texttt{d014f9a8}, calcula w39w_{39} y w36w_{36}. Usa S(5c)=4aS(\texttt{5c}) = \texttt{4a}, S(00)=63S(\texttt{00}) = \texttt{63}, S(6e)=9fS(\texttt{6e}) = \texttt{9f}, S(57)=5bS(\texttt{57}) = \texttt{5b}.

Ver la solución

Como 4343 no es múltiplo de 4, w43=w39⊕w42w_{43} = w_{39}\oplus w_{42}, y despejamos: w39=w43⊕w42=b6630ca6⊕e13f0cc8=575c006ew_{39} = w_{43}\oplus w_{42} = \texttt{b6630ca6}\oplus\texttt{e13f0cc8} = \texttt{575c006e}.

Para w40w_{40} sí hay caja S: w40=w36⊕SubWord(RotWord(w39))⊕Rcon10w_{40} = w_{36}\oplus\mathrm{SubWord}(\mathrm{RotWord}(w_{39}))\oplus\mathrm{Rcon}_{10}. Calculamos RotWord(575c006e)=5c006e57\mathrm{RotWord}(\texttt{575c006e}) = \texttt{5c006e57}, SubWord=4a639f5b\mathrm{SubWord} = \texttt{4a639f5b} y, con Rcon10=36000000\mathrm{Rcon}_{10} = \texttt{36000000}, el XOR da 7c639f5b\texttt{7c639f5b}. Despejamos: w36=w40⊕7c639f5b=d014f9a8⊕7c639f5b=ac7766f3w_{36} = w_{40}\oplus\texttt{7c639f5b} = \texttt{d014f9a8}\oplus\texttt{7c639f5b} = \texttt{ac7766f3}.

Conclusión: conocida la clave de la ronda 10, se recupera la clave de cifrado entera. La expansión es invertible, así que robar una clave de ronda equivale a robar la clave.

Ejercicio 3

Calcula el primer byte de InvMixColumns de la columna (47,37,94,ed)(\texttt{47},\texttt{37},\texttt{94},\texttt{ed}) con todas las cuentas.

Ver la solución

Primer byte: 0e⋅47⊕0b⋅37⊕0d⋅94⊕09⋅ed\texttt{0e}\cdot\texttt{47}\oplus\texttt{0b}\cdot\texttt{37}\oplus\texttt{0d}\cdot\texttt{94}\oplus\texttt{09}\cdot\texttt{ed}. Como 0e=8+4+2\texttt{0e}=8+4+2, 0b=8+2+1\texttt{0b}=8+2+1, 0d=8+4+1\texttt{0d}=8+4+1 y 09=8+1\texttt{09}=8+1 (en el sentido de potencias de xx), calculamos para cada byte ss los valores 02s\texttt{02}s, 04s\texttt{04}s y 08s\texttt{08}s con xtime:

ss02s\texttt{02}s04s\texttt{04}s08s\texttt{08}s
47\texttt{47}8e\texttt{8e}07\texttt{07}0e\texttt{0e}
37\texttt{37}6e\texttt{6e}dc\texttt{dc}a3\texttt{a3}
94\texttt{94}33\texttt{33}66\texttt{66}cc\texttt{cc}
ed\texttt{ed}c1\texttt{c1}99\texttt{99}29\texttt{29}

Entonces:

  • 0e⋅47=0e⊕07⊕8e=87\texttt{0e}\cdot\texttt{47} = \texttt{0e}\oplus\texttt{07}\oplus\texttt{8e} = \texttt{87}.
  • 0b⋅37=a3⊕6e⊕37=fa\texttt{0b}\cdot\texttt{37} = \texttt{a3}\oplus\texttt{6e}\oplus\texttt{37} = \texttt{fa}.
  • 0d⋅94=cc⊕66⊕94=3e\texttt{0d}\cdot\texttt{94} = \texttt{cc}\oplus\texttt{66}\oplus\texttt{94} = \texttt{3e}.
  • 09⋅ed=29⊕ed=c4\texttt{09}\cdot\texttt{ed} = \texttt{29}\oplus\texttt{ed} = \texttt{c4}.

Suma: 87⊕fa⊕3e⊕c4=87\texttt{87}\oplus\texttt{fa}\oplus\texttt{3e}\oplus\texttt{c4} = \texttt{87}.

En resumen

  • La expansión de clave produce w0,…,w43w_0,\dots,w_{43}: cada palabra es wi−4⊕wi−1w_{i-4}\oplus w_{i-1}, salvo cada cuarta, donde wi−1w_{i-1} pasa antes por RotWord, SubWord y un XOR con Rcon\mathrm{Rcon}.
  • Las constantes Rcon\mathrm{Rcon} son las potencias x0,…,x9x^0,\dots,x^9 de F28\mathbb{F}_{2^8} y hacen distinta cada ronda.
  • Descifrar es deshacer cada operación en orden inverso con las claves de la 10 a la 0: InvShiftRows, InvSubBytes e InvMixColumns (con 0e,0b,0d,09\texttt{0e},\texttt{0b},\texttt{0d},\texttt{09}).
  • Para el ejemplo de FIPS 197, las diez rondas llevan el bloque 3243f6a8…\texttt{3243f6a8…} al criptograma 3925841d…\texttt{3925841d…}, y el descifrado hace el camino inverso.
  • No se conoce ataque práctico contra AES; el primer ataque teórico de recuperación de clave contra AES-128 completo, un biclique (2011), cuesta 2126,12^{126{,}1} frente a 21282^{128}.

Siguiente lección: Modos de operación

Para profundizar