Por dentro del fallo de Coldcard: qué salió mal y por qué una semilla débil no se puede reparar
Esta traducción se ha realizado con asistencia de IA.
Esto es un análisis. Interpreta los hechos y su contexto y no constituye asesoramiento financiero.
La cobertura del robo de Coldcard, tratada en nuestra noticia complementaria, responde a qué ocurrió. Este artículo responde a la pregunta más difícil, el porqué, y a lo que esa respuesta cambia sobre cómo debería leer cualquiera la promesa de seguridad de un hardware wallet.
La versión corta resulta incómoda por lo ordinaria que es. Nada en Bitcoin se rompió. No se resolvió ninguna curva elíptica, no se vulneró ningún secure element, ningún atacante tocó un dispositivo físico. Un único ajuste de compilación envió en silencio una de las operaciones más sensibles que realiza un monedero a través del fragmento de código equivocado, y allí se quedó durante años.
Empecemos por qué es realmente una semilla
Cuando se crea un monedero Bitcoin, este extrae un número aleatorio muy grande. Cada clave privada, dirección y firma que el monedero llegue a producir desciende de ese único número, llamado semilla. La seguridad de todo el monedero descansa sobre una sola propiedad de ese número: que nadie más pudiera haberlo adivinado.
La medida de lo difícil que es adivinar un número se llama entropía y se cuenta en bits. Una semilla de doce palabras debería aportar 128 bits de entropía. Ese número no es marketing. Describe un espacio de semillas posibles tan grande que recorrerlo no es solo caro, está físicamente fuera de alcance, más cerca de contar átomos que de ejecutar un programa.
Esta es la razón entera por la que existe un hardware wallet. Su tarea central, por encima de la pantalla, del air-gap y del chip seguro, es elegir ese número del espacio completo e imposible de recorrer. Si lo elige de un espacio más pequeño, todo lo construido encima hereda la debilidad, y ninguna de las demás funciones puede compensarlo.
El fallo: un ajuste, la rama equivocada
Coinkite diseñó la Coldcard para usar un generador de números aleatorios por hardware, una fuente física de ruido en el chip. En 2021 la empresa trasladó su criptografía Bitcoin a la biblioteca libsecp256k1 de Bitcoin Core, una elección sólida usada por el propio Bitcoin Core. Esa migración introdujo una biblioteca de apoyo, libngu, y redirigió la generación de semillas del antiguo camino por hardware a una nueva llamada, ngu.random.bytes().
Aquí es donde el cableado salió mal. Para decidir qué fuente aleatoria compilar, el código comprobaba un ajuste llamado MICROPY_HW_ENABLE_RNG. Coinkite había puesto ese valor a cero, con la intención de desactivar el generador integrado de MicroPython y usar el suyo. La comprobación usaba una forma que solo verifica si el ajuste existe, no si está activado. Como el ajuste existía, aun estando a cero, la compilación vinculó en silencio la generación de semillas al recurso de reserva por software de MicroPython en lugar de a la fuente por hardware.
Ese recurso de reserva es un generador pseudoaleatorio, una fórmula que produce una salida de apariencia aleatoria a partir de un valor inicial. En la Mk2 y la Mk3, ese valor inicial provenía en su mayor parte del identificador único del chip y de sus registros de temporización. Esas entradas parecen aleatorias pero son fijas o están estrechamente acotadas, y por eso Coinkite estima ahora el espacio de búsqueda efectivo en unos 40 bits en lugar de 128.
Para un atacante, 40 bits no son un muro, son una lista de tareas. El espacio es lo bastante pequeño como para recorrerlo con potencia de cálculo corriente, derivando semillas candidatas, comparando cada una con direcciones conocidas y quedándose con las que contienen fondos. Una dirección pública o una clave pública extendida le dice al atacante al instante si un intento fue correcto, y es exactamente por eso que una entropía débil en un monedero es mucho más peligrosa que una entropía débil en la mayoría del resto del software.
Por qué los modelos más nuevos también se vieron afectados, solo que menos
Durante el desarrollo de la Mk4, Coinkite mezcló aleatoriedad adicional de dos secure elements en el estado del generador, como respaldo de un respaldo. Por eso la Mk4, la Mk5 y la Q están menos expuestas que la Mk3. Y también por eso no son seguras.
Según el análisis de Block, el reseed sustituía solo una palabra de 32 bits del estado interno del generador, de modo que, para un estado de reserva y un historial de llamadas fijos, el dispositivo producía como mucho unos cuatro mil millones de flujos de salida distinguibles. Coinkite sitúa el espacio de búsqueda resultante en torno a 72 bits. Mejor que 40, todavía muy por debajo del objetivo de 128 bits, y todavía al alcance de un atacante motivado. La entropía adicional elevó el muro sin llegar a cerrar la brecha.
Por qué años de revisión no lo detectaron
El detalle que debería quedarse con cualquiera que construya estos dispositivos o confíe en ellos es lo silencioso que fue el fallo. Tanto el generador por hardware correcto como el recurso de reserva por software equivocado tenían la misma firma de función, así que la compilación terminó sin quejas. Los revisores podían confirmar que el código por hardware previsto estaba presente en el binario del firmware, y tener razón, sin advertir que el camino de la semilla nunca lo alcanzaba de verdad.
El fallo no era una línea de criptografía defectuosa que un lector atento pudiera detectar. Era una cuestión de cuál de dos funciones de apariencia idéntica conectaba el enlazador, dos capas más abajo en un submódulo. Eso es algo realmente difícil de captar leyendo el código, y es una advertencia contra tratar una auditoría como un único sello de aprobado o suspenso.
La subtrama de la licencia, y cuánto peso puede soportar
Hay una segunda historia en torno a este fallo, y merece contarse con cuidado en lugar de como un veredicto. El consejero delegado de Foundation Devices, Zach Herbert, expuso una cronología. En julio de 2020, Foundation anunció su monedero Passport, construido sobre el firmware de Coldcard que entonces estaba bajo la licencia de software libre GPLv3. El fundador de Coinkite objetó públicamente. Coinkite pasó después a una licencia más restrictiva de tipo source available y, en marzo de 2021, publicó un gran commit que eliminaba el último código GPL.
Ese mismo commit de unos 120 archivos es donde cambió la generación de semillas y entró el camino aleatorio defectuoso. Herbert enmarca el fallo como posible daño colateral de esa reescritura.
Leído como interpretación del autor, la coincidencia temporal es difícil de ignorar: la disputa por la licencia fue el desencadenante visible de la reescritura, y la reescritura es donde nació el fallo. La lectura contraria y honesta importa igual. Coinkite ha dicho que la misma migración perseguía objetivos técnicos reales, sobre todo adoptar libsecp256k1 de Bitcoin Core, y no hay pruebas de que el cambio de licencia por sí solo causara el fallo. Una reescritura de ese tamaño puede introducir un defecto sutil por razones que nada tienen que ver con por qué se inició. Esta lectura se debilitaría bastante si resultara que la comprobación defectuosa concreta era anterior al commit de marzo de 2021, o aparecía en un cambio sin conexión con el trabajo de licencia.
Lo que el fallo cuesta de verdad al usuario
La consecuencia más importante es también la menos intuitiva. Una semilla generada por firmware afectado no se puede reparar.
Actualizar el firmware no ayuda, porque la actualización solo cambia cómo se crean las semillas futuras. Reimportar la misma semilla en una nueva Coldcard, una BitBox o un Trezor tampoco ayuda, porque la debilidad está dentro de la propia semilla y viaja con ella. Resetear el dispositivo y restaurar las mismas palabras no hace nada. El único camino que describe Coinkite es generar una semilla realmente nueva en firmware corregido y mover los fondos a direcciones nuevas derivadas de ella.
Dos mitigaciones suavizan el cuadro sin arreglarlo. Coinkite dice que una semilla creada con al menos cincuenta tiradas de dados independientes y privadas no está en riesgo solo por este problema, porque el usuario aportó entropía que el firmware no podía socavar. Y una frase de contraseña fuerte y única, el secreto opcional que se combina con las palabras de la semilla para producir un monedero separado, obliga al atacante a adivinar ese secreto además de la semilla débil. Ambas compran seguridad o tiempo. Ninguna restaura la aleatoriedad que falta, y por eso la semilla subyacente aún debe reemplazarse.
La narrativa que se llevó el daño real
Durante años, la Coldcard se vendió en parte por ser air-gapped, es decir, nunca se conecta a un ordenador por USB y mueve los datos a través de una tarjeta MicroSD o de códigos QR. En partes de la comunidad Bitcoin eso se endureció en una afirmación más simple, la de que los monederos air-gapped son la opción segura y, en la práctica, imposibles de hackear.
Este caso es una demostración clara de por qué ese atajo siempre fue demasiado fuerte. El air-gap hizo su trabajo. Ningún dato se filtró por un cable, y el atacante nunca necesitó el dispositivo en absoluto, porque la debilidad quedó grabada en la semilla en el momento de su creación. Un hueco en el cableado no vale nada cuando el número que hay debajo era predecible desde el principio.
Un monedero tiene que hacer muchas cosas bien a la vez: generar una semilla verdaderamente aleatoria, almacenar las claves de forma segura, mostrar los detalles de la transacción con honestidad, verificar sus propias actualizaciones, implementar la criptografía con limpieza, resistir ataques físicos y proteger su cadena de suministro. "Sin USB" o "secure element" describe una propiedad de esa lista, no toda la lista. Hay incluso una pequeña ironía aquí, señalada por la propia Coinkite: el air-gap es parte de por qué el dispositivo no podía extraer entropía adicional de un host conectado, una fuente en la que se apoyan otros diseños.
Aquí es donde un punto estructural se gana su sitio, ofrecido como razonamiento y no como instrucción. Los diseños que combinan varias fuentes de entropía independientes, de modo que un solo componente defectuoso no pueda decidir por sí solo el resultado, son más robustos precisamente frente a esta clase de fallo de punto único. Es un argumento sobre la arquitectura, no sobre qué producto debería comprar nadie, y solo vale tanto como de limpia sea, en la práctica, la combinación de esas fuentes.
La parte que no va a desaparecer
Dos hilos hacen de esto algo más que un fallo corregido. Coinkite ha dicho que asume que un atacante usó un modelo de IA para revisar su firmware abierto y sacar a la luz el fallo, y que su propia revisión asistida por IA de unas semanas antes lo había pasado por alto. Las mismas herramientas se sientan ahora a ambos lados de la mesa. Y el uso por parte del operador de una cuenta de pago en un proveedor de datos blockchain, que Block rastreó a través de los propios registros del proveedor, es el tipo de rastro operativo corriente que un atacante cuidadoso habría evitado, y la pista más fuerte por ahora para los investigadores.
La lección que perdura no es que una empresa suspendiera un examen. Es que la seguridad de la autocustodia es una cadena que va desde el primerísimo número aleatorio hasta la última línea en la pantalla, y que un monedero merece ser juzgado por la cadena entera, no por la única palabra impresa más grande en la caja.
Fuentes
- 1.Block Engineering: Predictable RNG Fallback and 32-Bit Reseed in Coldcard Firmware
- 2.Coinkite: Technical Deep Dive into the Entropy Issue
- 3.Zach Herbert (Foundation Devices) on the firmware and licensing timeline
- 4.CryptoSlate: A flaw in Coldcard seed generation lets attackers recreate private keys
- 5.Bitcoin Magazine: Coinkite releases fixed firmware after Coldcard bug; AI likely involved
- 6.CoinDesk: How bitcoin cold wallets lost $70 million in an attack that never touched the devices