Saltar al contenido
El bit perdido
Newsletter

McEliece: esconde un mensaje entre errores

En 1978, Robert McEliece propuso cifrar con un código corrector de errores: el mensaje se codifica y se le añaden errores a propósito. Solo quien conoce el código secreto sabe quitarlos. Genera tus claves, cifra, descifra y después ponte en la piel del atacante.

Borrador: pendiente de que lo revise el autor. Esta página no aparece en Google.

Claves de juguete: esta demo implementa el McEliece de 1978 con claves pequeñas y un generador pseudoaleatorio con semilla (para poder repetirlas y compartirlas). No la uses para proteger nada. Todo se calcula en tu navegador.

Parámetros y semilla

GF(16) entero como soporte; k = 8: se cifra un byte por bloque.

Cuánto detalle quieres ver

1 Genera las claves

La clave privada es un código de Goppa: un código corrector de errores que sabes decodificar deprisa. La pública es ese mismo código disfrazado para que parezca uno cualquiera, que es difícil de decodificar. Cada paso se despliega.

1.1 El cuerpo \mathrm{GF}(2^{4}) y su polinomio primitivo

Los números con los que trabajamos son los de \mathrm{GF}(2^{4}): polinomios en x con coeficientes 0 o 1, módulo el polinomio primitivo f(x) = x^{4} + x + 1. Tiene 2^{4} = 16 elementos: el 0 y las potencias \alpha^0, \dots, \alpha^{14}, donde \alpha es una raíz de f.

0 = 0000 α⁰ = 0001α = 0010α^2 = 0100α^3 = 1000α^4 = 0011α^5 = 0110α^6 = 1100α^7 = 1011α^8 = 0101α^9 = 1010α^10 = 0111α^11 = 1110α^12 = 1111α^13 = 1101α^14 = 1001

Cada elemento se escribe con 4 bits (los coeficientes de 1, x, x², …). Eso permite convertir una matriz sobre el cuerpo en una matriz binaria.

1.2 El polinomio de Goppa g(z), irreducible de grado t = 2

g(z) = z^{2} + \alpha^{9}\,z + 1. Se prueban polinomios mónicos de grado 2 al azar hasta encontrar uno irreducible (sin factores): han hecho falta 6 intentos. Irreducible garantiza que el código corrige 2 errores y que el algoritmo de Patterson funciona.

1.3 El soporte L: 16 elementos del cuerpo

L = (\alpha_0, \dots, \alpha_{15}): elementos distintos del cuerpo que no son raíces de g. Cada uno es el «nombre» de una posición del mensaje.

0 01 12 α3 α^24 α^35 α^46 α^57 α^68 α^79 α^810 α^911 α^1012 α^1113 α^1214 α^1315 α^14
1.4 La matriz de control H y su versión binaria

H = \left( \alpha_j^{\,i} / g(\alpha_j) \right)_{0 \le i < t,\quad 0 \le j < n}, de 2 filas y 16 columnas, sobre \mathrm{GF}(2^{4}). Un vector binario c está en el código si y solo si H c^{T} = 0. Cada elemento se desdobla en sus 4 bits y sale una matriz binaria H_{\text{bin}} de 8 × 16 (rango 8).

1α^6α^14α^9α^14αα^3α^3α^6α^51α^13α^9α^5α^13α
0α^61α^11α^2α^5α^8α^9α^13α^13α^9α^8α^5α^2α^111
1.5 La matriz generadora G (8 × 16)

Sus 8 filas son una base del código: k = n - \operatorname{rango}(H_{\text{bin}}) = 16 - 8 = 8 . Las columnas en verde forman un conjunto de información: ahí G es la identidad, así que el mensaje se lee directamente. Comprobación: H_{\text{bin}}\, G^{T} = 0 ✓.

1.6 El disfraz: S (invertible, 8 × 8) y P (permutación, 16 × 16)

S mezcla las filas de G (cambia de base el mismo código) y P reordena las columnas. S se elige al azar entre las matrices binarias hasta que sea invertible: 1 intento.

S

P (un 1 por fila y por columna): la fila i tiene su 1 en la columna π(i), con π = (15, 8, 14, 0, 10, 3, 12, 9, 4, 6, 1, 5, 11, 7, 2, 13)

1.7 La clave pública G′ = S · G · P

G' = S\,G\,P: sigue generando un código equivalente al de Goppa, pero ya no se ve su estructura; parece una matriz aleatoria. Es la clave pública, junto con t = 2. Ocupa 8 × 16 = 128 bits (16 bytes). La privada es (g, L, S, P).

2 Cifra un mensaje

Qué cifrar

El texto pasa a bytes (UTF-8) y se corta en bloques de 8 bits: un byte (una letra) por bloque. Cada bloque m se cifra por separado.

Bloquem (8 bits)e (peso 2)c = mG′ + e (16 bits)
010010002, 121011100100001100
011011118, 101100101010101010
011011008, 151001111111110101
011000017, 140000000011110011

Pulsa un bloque de la tabla para ver su detalle (aquí, el bloque 1 de 4) en los pasos de cifrado, descifrado y ataque.

Detalle del bloque 1

  1. El mensaje m 01001000
  2. m\,G': una palabra de tu código público 1001100100000100
  3. El error e: exactamente 2 bits a 1, en posiciones al azar (numeradas desde 0) 0010000000001000
  4. c = m\,G' + e: el texto cifrado (en rojo, los bits que el error ha cambiado) 1011100100001100

3 Descifra (con la clave privada)

Sigue el bloque 1. Solo el dueño de la clave conoce P, S y el código de Goppa.

  1. Deshaz la permutación: y = c\,P^{-1} = (m S)\,G + e P^{-1}. El error cambia de sitio pero sigue pesando 2. 0001011010000111
3.2 El algoritmo de Patterson, paso a paso

Hay que averiguar dónde está e P^{-1}. Se calcula el síndrome de y, y con él un polinomio localizador de errores \sigma cuyas raíces (en el soporte) son las posiciones del error.

  1. Síndrome S(z) = \sum_{y_j = 1} \frac{1}{z - \alpha_j} \bmod g S(z) = \alpha^{8}\,z + \alpha^{12}
  2. Inverso T(z) = S(z)^{-1} \bmod g T(z) = \alpha^{8}\,z + \alpha^{7}
  3. T(z) + z \alpha^{2}\,z + \alpha^{7}
  4. Se escribe T + z = Q_0^2 + z\,Q_1^2 y se toma la raíz cuadrada R = Q_0 + \sqrt{z}\,Q_1 \bmod g (en característica 2 siempre existe): Q_0 = \alpha^{11},\quad Q_1 = \alpha,\quad \sqrt z = \alpha^{3}\,z + \alpha^{3}
    R(z) = \alpha^{4}\,z + \alpha^{13}
  5. Euclides extendido sobre (g, R), hasta un resto de grado ≤ ⌊t/2⌋ = 1: aparecen a y b con a \equiv b R \pmod g.
    cocienteresto ruv
    z^2 + α^9·z + 110
    α^4·z + α^1301
  6. a = \alpha^{4}\,z + \alpha^{13},\quad b = 1
  7. El localizador \sigma(z) = a(z)^2 + z\,b(z)^2 \sigma(z) = \alpha^{8}\,z^{2} + z + \alpha^{11}
  8. Raíces de \sigma entre los elementos del soporte → posiciones del error: \sigma(\alpha^{5}) = 0 → posición 6\sigma(\alpha^{13}) = 0 → posición 14
  1. Se quita el error: y + e P^{-1} = (m S)\,G, una palabra del código de Goppa. 0001010010000101
  2. Como G es la identidad en el conjunto de información J, las coordenadas de la palabra en J son m S (8 bits): 00010001
  3. Y se multiplica por la inversa de S: m = (m S)\,S^{-1}. 01001000
Mensaje descifrado: Hola ✓ coincide con el original

4 Sé el atacante

Eres el atacante: solo tienes la clave pública G′ y el texto cifrado del bloque 1. El ataque de Prange elige 8 columnas al azar (un «conjunto de información»); si el error no cae en ninguna de ellas, con esas 8 columnas puedes despejar el mensaje con álgebra lineal y comprobar que lo que sobra pesa 2. Cada intento acierta con probabilidad baja; se repite hasta que sale.

Intentos esperados con estos parámetros: ≈ 15.

De juguete a real: la tabla de extrapolación

Costes estimados de los ataques de Prange y Stern y tamaños de clave, desde el juguete hasta los parámetros reales
Parámetrosn, t, kPrange: iteraciones (log₂)Prange: operaciones (log₂)Prange: tiempoStern: operaciones (log₂)Stern: tiempoClave pública, forma de 1978 (G′, k × n bits)Clave pública de Classic McEliece (T)Texto cifrado (Classic)
De juguete (el de arriba)16, 2, 82,111,7menos de 1 ms12,6 (p = 1, ℓ = 5)menos de 1 ms16 B——
McEliece 19781024, 50, 52453,681,110⁷ años63,5 (p = 3, ℓ = 27)42,4 años65,5 KiB——
mceliece3488643488, 64, 2720142,8173,610³⁵ años147,4 (p = 3, ℓ = 36)10²⁷ años1,13 MiB255 KiB96 B
mceliece4608964608, 96, 3360184,9217,410⁴⁸ años189,2 (p = 3, ℓ = 37)10³⁹ años1,85 MiB511,9 KiB156 B
mceliece66881286688, 128, 5024262,4296,310⁷² años264,8 (p = 5, ℓ = 57)10⁶² años4,01 MiB1020,5 KiB208 B
mceliece69601196960, 119, 5413263,4297,210⁷² años265,3 (p = 6, ℓ = 66)10⁶² años4,49 MiB1022,8 KiB194 B
mceliece81921288192, 128, 6528300,1334,410⁸³ años300,4 (p = 8, ℓ = 85)10⁷³ años6,38 MiB1,29 MiB208 B
  • Prange es el ataque genérico básico, no el mejor. Stern (1989) y sus sucesores lo mejoran mucho; por eso hay una columna con Stern, en un modelo sencillo y sin sus mejoras posteriores. Los parámetros reales se eligen frente a ataques todavía mejores y con modelos de coste más finos (memoria incluida), así que estas cifras son órdenes de magnitud y no el nivel de seguridad que declara Classic McEliece.
  • La lección: con parámetros de juguete, el ataque acaba al instante (pruébalo arriba). Pasar a n = 3488 o más convierte el mismo ataque en un cálculo fuera de alcance. La seguridad de McEliece es esa distancia, no un secreto del algoritmo.
  • El precio es el tamaño: la clave pública de Classic McEliece ocupa de cientos de kilobytes a más de un megabyte (en 1978 bastaban unos 65 KiB con n = 1024), pero el texto cifrado es muy corto.
  • «Clave pública de Classic McEliece» es la matriz T de la versión de Niederreiter con clave sistemática: no es exactamente la G′ de esta demo (columna anterior), que se da para comparar.

¿Y los ataques de 2025-2026?

En 2025 y 2026 se han publicado trabajos nuevos contra los códigos de Goppa binarios de Classic McEliece. Lo demostrado es un distinguidor: permite reconocer que una clave pública no es una matriz aleatoria, pero no descifra nada. Las recuperaciones de clave son heurísticas, con estimaciones de coste por debajo del nivel de seguridad declarado en el modelo de operaciones de bit (que no cobra la memoria): se ha estrechado el margen, pero no hay ningún ataque práctico. El BSI alemán desaconseja Classic McEliece para desarrollos nuevos desde el 1 de octubre de 2026.

Esta demo es el McEliece original de 1978, no Classic McEliece. Léelo con calma en el artículo, con las fuentes.

Incrusta esta demo en tu web

Copia este código y pégalo en tu web, tu blog o tu aula virtual. Es gratis; solo te pedimos que dejes el pie con el enlace.

Ver cómo queda ↗

Qué mirar

Con el tamaño «De juguete» (cuerpo de 16 elementos, 2 errores), cifra «Hola»: cada letra es un bloque de 8 bits. Pasa a «Mediano» y ataca: Prange tarda unos cientos de intentos. Prueba «Muy grande» y fíjate en cuánto más cuesta. Y con «McEliece 1978» comprueba que la clave pública es una matriz de más de medio megabit, y que el mismo ataque ya no termina.

Las matemáticas que hay debajo (síndrome, cuerpos finitos, códigos de Reed-Solomon, de los que los de Goppa son parientes) están en el curso:decodificación por síndrome ycódigos de Reed-Solomon. El artículo completo, con el estado de la seguridad y sus fuentes: cómo funciona el cifrado de McEliece. Para comparar con el cifrado de clave pública más usado: RSA paso a paso.

Preguntas frecuentes

¿Cómo funciona el cifrado de McEliece, en una frase?

Se elige un código corrector de errores que sabes decodificar (un código de Goppa), se disfraza multiplicando su matriz por otras dos (S y P) para que parezca uno cualquiera, y se publica el disfraz. Cifrar es codificar el mensaje con el código público y añadir a propósito exactamente t errores; descifrar es quitarlos con el código secreto, que es el único que sabe corregirlos.

¿Por qué no se puede descifrar sin la clave privada?

Quien solo tiene la clave pública necesita decodificar un código lineal sin estructura visible, y ese problema es difícil en general: los mejores algoritmos genéricos (Prange, Stern y sus sucesores) tardan un tiempo exponencial en n. En la demo, con parámetros de juguete, lo ves acabar al instante; con los parámetros reales, no.

¿Por qué hay que añadir exactamente t errores?

Un código de Goppa de grado t corrige hasta t errores. Con menos, el cifrado seguiría siendo descifrable, pero un ataque tendría menos que buscar; con más de t, ni siquiera el dueño de la clave podría decodificar. La demo te deja comprobarlo: elige a mano más de t errores y el descifrado falla (o, peor, se equivoca sin avisar).

¿Es esto Classic McEliece, el de los estándares?

No exactamente. Esta demo es el esquema original de McEliece (1978). Classic McEliece usa la versión dual de Niederreiter (1986), como mecanismo de encapsulación de claves, con la clave pública en forma sistemática. Comparten el mismo código de Goppa y por eso los tamaños y costes de la tabla son los suyos.

¿Se ha roto McEliece?

No: no se conoce ningún ataque práctico contra los parámetros reales. En 2025 y 2026 se han publicado trabajos nuevos (un distinguidor demostrado y recuperaciones de clave heurísticas con estimaciones por debajo del nivel declarado en el modelo de operaciones de bit), de modo que se ha estrechado el margen de seguridad, y el BSI alemán lo desaconseja para desarrollos nuevos desde el 1 de octubre de 2026. Las fuentes, en el artículo.

¿Mis claves o mensajes se envían a algún sitio?

No. Todo se calcula en tu navegador. El enlace de «Copiar enlace» lleva solo el tamaño del código, la semilla y el mensaje, nada más.

Cómo citar esta página

Fernando Hernando (2026). Cifrado de McEliece paso a paso [Herramienta web], versión del 22 de octubre de 2026. El bit perdido. https://elbitperdido.com/herramientas/mceliece

@misc{hernando2026mceliece,
  author = {Fernando Hernando},
  title = {Cifrado de McEliece paso a paso},
  year = {2026},
  howpublished = {El bit perdido},
  url = {https://elbitperdido.com/herramientas/mceliece},
  note = {Herramienta web, versión del 22 de octubre de 2026}
}