Procedimientos de firma

Ed25519 explicado matemáticamente

La firma que acompaña a cada valoración de McGesund — desde la curva y la clave hasta la ecuación que recalcula el navegador del lector.

Actualizado: 2026-09-07

1. De qué trata esto

Una valoración en McGesund no es un campo de texto de una base de datos en el que haya que creer sin más. Al enviarla se firma digitalmente, y cualquier visitante puede recalcular esa firma más tarde en su propio navegador.

Para esta firma utilizamos Ed25519. A diferencia de FALCON y ML-DSA, que pueden añadirse al lado como sellos adicionales, Ed25519 no es opcional: toda valoración firmada la lleva, con independencia de la tarifa y de la vía de envío.

Una precisión previa:

Ed25519 no es un cifrado. El texto de la valoración está justamente para leerse. La firma no demuestra confidencialidad, sino origen e integridad.


2. Qué se firma exactamente

No se firma el texto corrido, sino un objeto de datos compacto que fija de forma inequívoca el texto y todo lo demás:

{
  "v":   1,
  "typ": "rev-comment",
  "f":   "<ID de la empresa>",
  "c":   "<ID de la valoración>",
  "h":   "<SHA-256 del texto de la valoración>",
  "rh":  "<SHA-256 del registro de envío completo>",
  "rv":  1,
  "qh":  "<SHA-256 del envelope QR, solo en valoraciones por QR>",
  "kid": "<ID de la clave>",
  "iat": 1757203200
}

Este objeto se codifica en CBOR. Esa secuencia de bytes — y no su representación cuidada de arriba — es nuestro mensaje mm. Firma y mensaje viajan juntos dentro de un sobre:

Envelope=MCG1:    base64url(CBOR[3,  m,  σ])\text{Envelope} = \texttt{MCG1:} \;\|\; \mathrm{base64url}\bigl(\mathrm{CBOR}[\,3,\; m,\; \sigma\,]\bigr)

El 33 es la versión del formato. No hay nada más ahí dentro — en particular, ninguna firma post-cuántica: esa se encuentra, si existe, junto al registro y no dentro del sobre.


3. Qué debe lograr la firma

Un lector que llega a un perfil de empresa se plantea dos preguntas:

  1. ¿Procede esta valoración realmente del sistema de McGesund?
  2. ¿Se ha modificado posteriormente?

Para eso existe un par de claves:

  • una clave privada — permanece en el servicio de firma
  • una clave pública — puede tenerla cualquiera; se direcciona mediante el identificador de clave (kid) del payload

Se firma con la clave privada. Se verifica con la pública — y además en el navegador del lector, no en nuestro servidor. Ese es el punto: una verificación que realizásemos nosotros mismos y cuyo resultado comunicásemos no sería una verificación, sino una afirmación.


4. ¿Por qué una curva elíptica?

Toda firma necesita un cálculo que sea fácil en un sentido y prácticamente imposible en el otro. En Ed25519 ese cálculo es la multiplicación escalar sobre una curva elíptica:

a    A=aB.a \;\longmapsto\; A = a\cdot B.

Calcular el punto público AA a partir del número secreto aa cuesta microsegundos. Deducir aa a partir de AA es el problema del logaritmo discreto — y para él no se conoce ningún método que termine en plazos humanos con este tamaño.

La ventaja práctica frente a procedimientos más antiguos como RSA está en el tamaño:

clave públicafirma
RSA-3072384 B384 B
Ed2551932 B64 B

Con un nivel de seguridad comparable. 64 bytes por valoración no son, ni siquiera con millones de valoraciones, una magnitud sobre la que haya que reflexionar.


5. La curva edwards25519

Se calcula módulo un número primo:

p=225519.p = 2^{255}-19.

De ahí el nombre. La curva es una curva de Edwards retorcida:

x2+y2  =  1+dx2y2,d=121665121666modp.-x^2+y^2 \;=\; 1 + d\,x^2y^2, \qquad d = -\frac{121665}{121666} \bmod p.

Un «punto» es un par de números (x,y)(x,y) de {0,,p1}\{0,\dots,p-1\} que cumple esta ecuación. No hay ninguna curva que ver — el dibujo de la sección siguiente es una ayuda visual sobre los números reales, no una imagen del espacio de cálculo real.

Faltan aún dos magnitudes:

  • un punto base BB fijado por convenio,
  • el orden \ell del subgrupo generado por BB:
=2252+27742317777372353535851937790883648493.\ell = 2^{252} + 27742317777372353535851937790883648493.

\ell es primo. Eso significa: si se suma BB una y otra vez consigo mismo, se recorren exactamente \ell puntos distintos y después se vuelve al principio. Por eso todos los cálculos con escalares se hacen módulo \ell y todos los cálculos con coordenadas módulo pp. Confundir estos dos números es el error clásico de principiante.


6. Sumar puntos

Dos puntos se combinan en un tercero según una fórmula fija:

x3=x1y2+y1x21+dx1x2y1y2,y3=y1y2x1x21dx1x2y1y2.x_3=\frac{x_1y_2+y_1x_2}{1+d\,x_1x_2y_1y_2}, \qquad y_3=\frac{y_1y_2-x_1x_2}{1-d\,x_1x_2y_1y_2}.

El elemento neutro es (0,1)(0,1) — el punto en el que empieza el cálculo.

Esta fórmula tiene una propiedad que no se aprecia a simple vista y que para la seguridad importa más que cualquier constante: es completa. Funciona para todas las entradas, sin casos especiales para «ambos puntos iguales» o «el resultado es el elemento neutro». En las curvas de Weierstrass, más antiguas, esos casos especiales existen, y cada uno de ellos es una rama en el programa — una rama cuyo tiempo de ejecución se puede medir. Quien mide cuánto tarda una firma averigua, en esos procedimientos, algo sobre la clave secreta.

Fórmulas completas significan: siempre el mismo camino de cálculo, siempre el mismo tiempo, nada que medir.


7. Multiplicación escalar — la calle de sentido único

nBn\cdot B significa sumar BB exactamente nn veces consigo mismo. Con un nn de 253 bits eso sería una cantidad de trabajo absurda — por eso se duplica:

B2B4B8BB \to 2B \to 4B \to 8B \to \dots

y con esos resultados intermedios se compone el nn deseado. Unas 253 duplicaciones bastan para cualquier nn. Ese es el camino de ida.

Hacia atrás no existe ese atajo. Determinar el número aa a partir del punto AA significa resolver el problema del logaritmo discreto.

(0,1) — elemento neutroB2B3B4B5B6B
Una curva de Edwards con los primeros múltiplos del punto base, calculados con la ley de adición real. Sobre los números reales se desplazan aún de forma visiblemente ordenada por la curva — se podría reconstruir el camino de vuelta. Módulo p desaparece precisamente ese orden, y en ello se basa la seguridad.

En el procedimiento real se calcula módulo pp. Allí no hay «izquierda», ni «derecha», ni proximidad: 17B17\,B y 18B18\,B se convierten en dos pares de números sin parentesco reconocible alguno.


8. El par de claves del servicio de firma

Al principio hay 32 bytes aleatorios, la semilla. Todo lo demás se deriva de ahí:

h=SHA-512(semilla),h=h0..31  a    h32..63prefijo.h = \mathrm{SHA\text{-}512}(\text{semilla}), \qquad h = \underbrace{h_{0..31}}_{\to\;a}\;\|\;\underbrace{h_{32..63}}_{\text{prefijo}}.

De la primera mitad surge el escalar secreto aa, aunque no sin cambios. Tres bits se ponen a uno o a cero — el llamado clamping:

  • los tres bits inferiores se ponen a cero: con ello aa pasa a ser un múltiplo de 8. La razón es el cofactor 8 de la curva — el grupo de puntos completo es ocho veces mayor que el subgrupo de orden \ell. Un aa divisible por 8 acaba con seguridad en el subgrupo correcto y no revela nada sobre puntos de orden pequeño.
  • el bit superior se pone a cero y el segundo por arriba a uno: así aa tiene siempre la misma longitud en bits. Un aa más corto necesitaría menos duplicaciones — y de nuevo el tiempo de ejecución dejaría algo que leer.

La clave pública es entonces, simplemente,

A=aB,A = a\cdot B,

almacenada en 32 bytes: la coordenada yy y, en el bit más alto, el signo de xx. La xx la recalcula el propio verificador a partir de la ecuación de la curva — las dos soluciones se diferencian solo en el signo, y cuál es la correcta lo dice ese único bit.

La segunda mitad del valor hash, el prefijo, no hace falta para la clave. Entra en juego en la sección siguiente.


9. Por qué aquí el azar no es azar

Toda firma de este tipo necesita un valor único rr, llamado a menudo nonce. Nunca puede repetirse: quien disponga de dos firmas con el mismo rr puede despejar la clave secreta con álgebra elemental.

Precisamente en eso han fracasado sistemas reales. El caso más conocido es la verificación de firmas de una videoconsola cuyo fabricante utilizó en 2010 siempre el mismo nonce — la clave privada quedó así reconstruible públicamente.

Ed25519 lo resuelve no utilizando azar en absoluto:

r=SHA-512(prefijo    m)mod.r = \mathrm{SHA\text{-}512}(\text{prefijo}\;\|\;m) \bmod \ell.

El nonce depende del prefijo secreto y del mensaje. De ahí se siguen dos cosas:

  • Dos valoraciones distintas dan, con probabilidad abrumadora, valores rr distintos — el caso de repetición no se produce.
  • La misma valoración da siempre la misma firma. Un proceso de firma se puede así reproducir, y un mal generador de números aleatorios en el servidor no puede estropear nada, porque no se necesita ninguno.

Para un portal de valoraciones con muchas firmas al día esa no es una ventaja académica. Es la diferencia entre «un fallo en la fuente de aleatoriedad sería fatal» y «no hay ninguna fuente de aleatoriedad que pueda fallar».


10. Firmar

Tres líneas, nada más:

r=H(prefijo    m)mod,R=rB,r = H(\text{prefijo}\;\|\;m) \bmod \ell, \qquad R = r\cdot B,
k=H(R    A    m)mod,k = H(R \;\|\; A \;\|\; m) \bmod \ell,
S=(r+ka)mod.S = (r + k\,a) \bmod \ell.

La firma es el par

σ=(R,S),\sigma = (R,\,S),

32 bytes para el punto RR, 32 bytes para el número SS — 64 bytes en total.

Merece atención la segunda línea: en kk entran RR, la clave pública AA y el mensaje. Que AA se incluya en el hash no es un adorno — evita ataques en los que una firma se reinterpreta como perteneciente a otra clave.


11. Verificar

El navegador del lector conoce: la valoración mm, la firma (R,S)(R,S) y la clave pública AA. Recalcula kk y comprueba una única ecuación:

SB  =  R+kA\boxed{S\cdot B \;=\; R + k\cdot A}

Si se cumple, la firma es válida. RFC 8032 permite además la variante multiplicada por el cofactor, 8SB=8R+8kA8S\cdot B = 8R + 8k\cdot A, que trata algunos casos límite con mayor tolerancia.

No se pregunta a ningún servidor, no hace falta que ningún servicio esté disponible. Basta con la clave pública.


12. Por qué la ecuación cuadra

Basta con sustituir:

SB=(r+ka)B=rB+k(aB)=R+kA.S\cdot B = (r + k\,a)\cdot B = r\cdot B + k\,(a\cdot B) = R + k\cdot A.

Todo el truco está en la transformación intermedia: la multiplicación escalar es compatible con la adición. Quien conoce aa puede calcular un SS que satisfaga la ecuación. Quien no conoce aa tendría que encontrar, para un kk elegido por él mismo, un SS adecuado — y eso significa resolver el logaritmo discreto.


13. Un miniejemplo calculado por completo

Con los números reales no hay nada que recalcular — valores de 253 bits no se comprueban mentalmente. Por eso, el mismo procedimiento en un grupo diminuto, en el que cada paso se puede seguir con la calculadora.

Paso 1: El grupo

Calculamos con los restos módulo 2323 y tomamos g=2g = 2. Se cumple

211=2048=8923+11(mod23),2^{11} = 2048 = 89\cdot 23 + 1 \equiv 1 \pmod{23},

es decir, gg genera un subgrupo de orden =11\ell = 11. Las potencias son:

nn1234567891011
gng^n248169181336121

gg asume el papel del punto base BB, y la multiplicación el de la adición de puntos. Los escalares se calculan módulo 1111; los valores, módulo 2323.

Paso 2: El par de claves

Sea el secreto a=6a = 6. Entonces

A=ga=26=6418(mod23).A = g^a = 2^6 = 64 \equiv 18 \pmod{23}.

A=18A = 18 puede saberlo cualquiera.

Paso 3: Nonce y commitment

Supongamos que del prefijo y la valoración resulta r=4r = 4. De ahí:

R=gr=24=16.R = g^r = 2^4 = 16.

Paso 4: El desafío

Supongamos que el hash sobre RR, AA y la valoración da

k=5.k = 5.

Paso 5: La firma

S=(r+ka)mod11=(4+56)mod11=34mod11=1.S = (r + k\,a) \bmod 11 = (4 + 5\cdot 6) \bmod 11 = 34 \bmod 11 = 1.

La firma es el par (R,S)=(16,1)(R,S) = (16,\,1).

Paso 6: El navegador verifica

Calcula ambos lados. A la izquierda:

gS=21=2.g^S = 2^1 = 2.

A la derecha, con 1853(mod23)18^5 \equiv 3 \pmod{23}:

RAk=163=482(mod23).R\cdot A^{k} = 16\cdot 3 = 48 \equiv 2 \pmod{23}.

Ambos lados dan 22:

Firma vaˊlida\boxed{\text{Firma válida}}

Paso 7: Alguien modifica el texto de la valoración

El texto entra en el hash, así que cambia el desafío — digamos que a k=7k' = 7. La firma sigue siendo (16,1)(16,1), pero el lado derecho no. Con 1876(mod23)18^7 \equiv 6 \pmod{23}:

RAk=166=964(mod23)    2=gSR\cdot A^{k'} = 16\cdot 6 = 96 \equiv 4 \pmod{23} \;\neq\; 2 = g^S
Firma no vaˊlida\boxed{\text{Firma no válida}}

Podemos borrar una valoración. Lo que no podemos es modificarla sin que se note.

Nota de honestidad sobre el ejemplo

Aquí se ha calculado en el grupo multiplicativo módulo 2323, no sobre una curva: gSg^S representa SBS\cdot B, y el producto RAkR\cdot A^k representa la adición de puntos R+kAR + k\cdot A. La estructura es la misma, y de eso se trata precisamente. Lo que difiere son los órdenes de magnitud: =11\ell = 11 frente a 2252\ell \approx 2^{252}, y allí la clave no se encuentra probando once posibilidades.


14. Qué ocurre si alguien modifica la valoración

Supongamos que alguien con acceso a la base de datos — también alguien de nuestra casa — modifica el texto de la valoración o uno de los corazones. Entonces cambia el registro y con él, al menos, uno de los dos valores hash h y rh del payload. Con ello cambia mm, con ello el desafío kk, y con ello el lado derecho de la ecuación de verificación. La firma antigua ya no encaja.

La frase decisiva al respecto: podemos borrar una valoración, pero no podemos modificarla sin que se note. En McGesund esa misma verificación se ejecuta además cada noche del lado del servidor sobre todo el fondo — una valoración que no la supera deja de contar en la media de la empresa.


15. Por qué fracasa un atacante

Conoce la clave pública AA, el punto base BB, la curva y todas las firmas emitidas hasta ahora. Lo que le falta es aa.

El mejor ataque clásico conocido contra el problema del logaritmo discreto en un grupo de orden \ell necesita aproximadamente \sqrt{\ell} pasos. Con 2252\ell \approx 2^{252} eso equivale a unas

21262^{126}

operaciones. Para comparar: incluso una máquina capaz de mil millones de miles de millones (101810^{18}) de pasos por segundo necesitaría para ello un múltiplo de la edad del universo.

Falsificar sin la clave significaría encontrar, para un kk elegido por uno mismo, un SS adecuado — la misma tarea con otro disfraz.


16. Por qué Ed25519 y no ECDSA

Ambos se basan en el mismo problema. La diferencia está en todo lo que ocurre alrededor:

ECDSA (curvas NIST)Ed25519
Noncerequiere azar frescodeterminista, a partir del prefijo y el mensaje
Fórmulascasos especiales, ramas dependientes de los datoscompletas, un único camino de cálculo
Parámetros de la curvaorigen de las constantes nunca explicado del todoelegidos con criterios verificables
Tamaño de la firma64–72 B, codificación variablefijo, 64 B
En el navegadordisponible desde hace muchonativo desde 2023/2024; si no, como biblioteca JS

Para nosotros el nonce fue el argumento decisivo. Un portal de valoraciones firma con frecuencia y de forma automatizada; un procedimiento en el que un único valor aleatorio débil revela la clave es, para eso, la elección equivocada.


17. Lo que Ed25519 no ofrece

Ed25519 se basa en el logaritmo discreto — y precisamente ese problema lo resuelve de forma eficiente un ordenador cuántico suficientemente grande con el algoritmo de Shor. Si esas máquinas llegarán a existir, y cuándo, es una cuestión abierta. Para una valoración que debe seguir siendo verificable dentro de diez años es, aun así, una pregunta que hay que responder hoy.

Por eso, junto a la firma Ed25519 puede colocarse un sello resistente a la computación cuántica:

Ninguno de los dos sustituye a Ed25519; se colocan a su lado. Si uno de los procedimientos se rompe, el otro sigue sosteniendo.


18. El proceso en imagen

SERVICIO DE FIRMA (MCGESUND)NAVEGADOR DEL VISITANTEescalar privado a + prefijo (de la semilla)payload m = {empresa, valoración, h, rh, iat}r = H(prefijo ‖ m) mod ℓR = r · Bk = H(R ‖ A ‖ m) mod ℓS = (r + k · a) mod ℓfirma σ = (R, S) + kidvaloración + σ + clave pública Arecalcular k a partir de R, A y mS · B = R + k · A ?válidano válida
Del payload a la marca de verificación en el navegador. Por encima de la línea divisoria todo ocurre una sola vez, al enviar; por debajo, de nuevo en cada lector — en su dispositivo, únicamente con la clave pública.

19. Qué hace McGesund concretamente con esto

El envelope. Cada valoración firmada lleva un sobre MCG1: con la versión de formato, el payload y la firma Ed25519. El kid del payload indica de qué clave se trata; la clave pública correspondiente la entrega el servidor cuando se le solicita — es pública, ahí no hay nada que proteger.

La verificación en el navegador. Chrome y Firefox soportan Ed25519 de forma nativa desde 2023/2024 a través de la interfaz WebCrypto. Safari no — allí la llamada lanza un error en lugar de verificar. Por eso nuestro código de verificación recurre a una implementación puramente en JavaScript, que solo se carga donde hace falta. La verificación de firma se completa así en cualquier navegador, y además en el dispositivo del lector.

El ancla temporal. La huella de la clave de firma se ancla mediante OpenTimestamps en un bloque de Bitcoin. Con ello no solo se puede acreditar que la firma es auténtica, sino también que la clave ya existía en un momento determinado — sin que nadie tenga que creerse nuestra marca de tiempo.

La vinculación al contenido. El payload lleva rh, el hash sobre el registro de envío completo: texto, corazones, estado de geolocalización, datos del motivo y procedencia. La firma Ed25519 no vincula así solo el texto, sino todo lo que se muestra junto a la valoración.


20. Una frase para llevarse

Ed25519 convierte un nuˊmero secreto en una ecuacioˊnque cualquiera puede recalcular y nadie inventar.\boxed{ \begin{array}{c} \text{Ed25519 convierte un número secreto en una ecuación}\\ \text{que cualquiera puede recalcular y nadie inventar.} \end{array}}

Quien posee el escalar secreto firma en microsegundos. Quien no lo posee tendría que resolver un logaritmo discreto en un grupo con unos 22522^{252} elementos.

Para el lector de una valoración eso significa, simplemente: no tiene que creernos. Puede recalcularlo.