News

Stratum V2 deja de olvidarse las claves por ahí

El 19 de agosto de 2026 la implementación de referencia de Stratum V2 integró 27 commits en el crate que cifra la conexión de un minero con su pool y en el códec que lo rodea. Ninguno arregla el cifrado. Todos tratan de lo que el código hace con claves y contadores alrededor de él.

5 min de lecturaStratum V2
Stratum V2 deja de olvidarse las claves por ahí

Qué pasó

El 19 de agosto de 2026 la implementación de referencia de Stratum V2 integró la pull request 2283, 27 commits en noise_sv2, el crate que cifra el enlace entre un minero y su pool, y en el códec que enmarca sus mensajes. La pull request cierra seis issues del propio repositorio y doce hallazgos de un repositorio de auditoría, project-loupe/audit-stratum, que no es legible públicamente. Nada de esto repara un cifrado roto. Todo trata de lo que la implementación hace con el material criptográfico y con los contadores a ambos lados del cifrado.

Qué cambia

Stratum V2 envuelve el enlace entre minero y pool en una sesión cifrada y autenticada, y la especificación es clara sobre el motivo: "Cualquier información sobre los shares enviados puede convertirse directamente en estimaciones de los ingresos de un minero y asociarse a un nombre de usuario concreto". La sesión usa ChaCha20-Poly1305, con una clave de 32 bytes y un nonce de 8 bytes que empieza en cero y se incrementa tras cada mensaje.

Cuatro de los cambios merecen seguirse.

Un contador que podía dar la vuelta. Con este tipo de cifrado autenticado, una misma clave nunca debe cifrar dos mensajes con el mismo nonce. El código incrementaba el contador sin comprobación, así que en su valor máximo la suma daba la vuelta y la misma clave volvía a empezar en el nonce cero. Ahora el cifrado y el descifrado fallan, con un test que fija el contador en su último valor y comprueba que ambos se niegan (commit 02630c9c).

Copiar un cifrador es copiar un nonce. Initiator, Responder y el códec derivaban Clone, de modo que una copia llevaba la misma clave y el mismo contador y podía cifrar mensajes distintos con ambos. Esas derivaciones ya no están. El issue que lo pedía resume el motivo en una línea: "Esto lleva a reutilización de nonce, lo cual es particularmente indeseable".

Secretos que sobrevivían al handshake. Cuando el handshake termina, sus pares de claves efímero, estático y de autoridad, la chaining key y el hash del handshake se borran en lugar de quedarse en el objeto (commit 25194461), y los búferes intermedios usados para derivar las claves de sesión, antes construidos con .concat() en el heap y nunca limpiados, son ahora un búfer fijo en la pila que se borra. Las escrituras volátiles a cero escritas a mano se sustituyeron por el crate zeroize (commit caf81de8). Una clave que ya se ha borrado no se puede recuperar de un volcado tras un fallo, de una página en disco ni de un proceso que alguien lea después, que es todo el argumento para borrarla.

Un campo firmado que nadie leía. Un pool demuestra su identidad con un certificado firmado por una clave de autoridad, y el mensaje firmado es SHA-256(version || valid_from || not_valid_after || server_public_key). La versión estaba cubierta por la firma y nunca se comparaba, así que un certificado escrito para un formato posterior verificaba y luego se leía con la disposición actual. La verificación ahora rechaza cualquier versión distinta de la que implementa el crate (commit 15e5969c).

Qué no cambia

Nadie robó hashrate y no consta que se haya leído ninguna sesión cifrada. El caso del contador necesita en particular que una sola sesión envíe más de dieciocho trillones de mensajes, cosa que ninguna conexión de minería hará. Lo que se corrige es la forma del error, un incremento sin nada que lo comprobara, no una pérdida que alguien haya sufrido.

El borrado tampoco es absoluto. zeroize impide que el compilador elimine una escritura que en apariencia nadie lee; no puede seguir una copia que el asignador de memoria, el sistema operativo o el archivo de intercambio hayan hecho antes. El cambio estrecha la ventana en la que el material criptográfico está en memoria. No promete que la ventana esté cerrada.

Nada de esto trata de quién controla la minería. El cifrado impide que la red entre un minero y un pool lea o reescriba el trabajo, y según la especificación es "opcional en la red local" y "obligatorio para el acceso remoto a los nodos superiores". Qué transacciones entran en el bloque es otro protocolo distinto, el que puso una plantilla construida por el minero en el bloque 955.318 en junio.

Y nada de esto está instalado. La versión etiquetada más reciente, la v1.11.1, es del 22 de julio de 2026, anterior a todo este trabajo; estos commits están en la rama principal.

Contexto

Lo interesante es de dónde salieron los hallazgos. Las implementaciones de Bitcoin se están leyendo este año a un ritmo al que no se habían leído antes, con auditorías que abren issues concretos, pequeños y bien descritos en lugar de anunciar un incidente. Seis issues numerados en el repositorio del propio proyecto, doce hallazgos en un repositorio de auditoría y una pull request que los cierra a la vez es el aspecto que tiene ese proceso desde dentro.

Conviene ser preciso sobre lo que produce una auditoría así. No un agujero espectacular, sino una lista de puntos donde el código era correcto en el caso que ocurre e indefinido en el que no: el contador que nadie esperaba que llegara a su límite, el campo que nadie esperaba que cambiara, el búfer que nadie esperaba que se leyera. La distancia entre "no puede pasar" y "está comprobado" es todo el asunto, y es la misma distancia en la que confía un minero cuando apunta una máquina a un pool cuyo interior no puede ver.

Boletín

Bitcoin, sin ruido

Qué ha pasado en Bitcoin, qué cambia de verdad, y las fuentes para que puedas comprobarnos. Un número cada vez, directo a tu correo.

  • Un correo por número, nunca una secuencia automática
  • Sin píxeles de seguimiento y sin compartir direcciones
  • Baja desde cualquier número con un clic

Recibe el próximo número

Un correo por número, sin píxeles de seguimiento, y te puedes dar de baja desde cualquiera de ellos. No compartimos tu dirección. Política de privacidad