31 de julio de 2026
Verificamos una prueba Zero-Knowledge del AV app oficial: cómo funciona, y lo que todavía le falta a nuestro verifier
Por Jorge
La pieza de privacidad del blueprint
El EU Age Verification Blueprint tiene una pieza de privacidad que está por encima de las demás: las Zero-Knowledge Proofs. Con el esquema longfellow-zk —diseñado por ingenieros de Google, con paper revisado y borrador en el IETF— una cartera puede demostrar que su titular es mayor de 18 años sin enseñar la credencial, sin una firma del emisor rastreable en claro, y sin que dos verificaciones distintas sean vinculables entre sí. El Annex A del blueprint lo dice explícitamente: la app de verificación de edad debería generar estas pruebas, y el relying party debería verificarlas.
Google Wallet las genera desde 2025; el AV app oficial europeo, desde principios de 2026. Nosotros queríamos entender la otra mitad —la del relying party, el negocio que tiene que comprobar la prueba— construyéndola. Así que construimos un verifier ZK independiente y lo probamos contra el artículo real.
Qué hicimos, y con qué se prueba
En un teléfono Android con el AV app oficial de referencia y una credencial de edad emitida por el emisor de test del propio blueprint, abrimos nuestra demo, pulsamos "Con tu teléfono", elegimos el AV app y confirmamos la presentación.
El resultado:
✓ aceptada · verify 317 ms · 353 KB
emisor: CN=Age Verification DS - 001,
O=Age Verification Reference Implementation, C=EU
Ese emisor es lo que hace la prueba creíble. No es nuestro emisor de demo —el nuestro firma como "espuni demo AV issuer"—. Es el Document Signer de la implementación de referencia: la credencial era genuina, la cartera era la oficial, y la prueba criptográfica la comprobó nuestro código. 353 KB de proof, verificada en algo más de tres décimas de segundo. Y como cada ejecución de nuestra demo publica la proof, cualquiera puede descargarla y re-verificarla con el binario open-source, fuera de nuestra infraestructura.
La parte difícil, para un relying party, no es la cartera
Que quede claro: criptográficamente, generar la prueba es lo más costoso — el proving de un sistema Zero-Knowledge es órdenes de magnitud más pesado que verificarlo (por eso la cartera tarda ~1 s en generarla y nosotros ~300 ms en comprobarla). Pero esa parte ya está construida y desplegada: las carteras —Google, el AV app de referencia— ya generan las pruebas; nadie que integre verificación reimplementa el prover.
Lo que nadie te da hecho —y lo que tuvimos que construir— es el lado del relying party: pedir la prueba en el formato correcto, recibir la respuesta cifrada, descifrarla y verificarla contra el circuito y la clave correctos. Ahí está el trabajo de integración.
Cada paso tiene su trampa. La petición viaja como un deviceRequest de ISO 18013-7 con un bloque zkRequest que anuncia qué circuitos aceptamos. La respuesta vuelve cifrada con HPKE (RFC 9180) a una clave efímera que generamos nosotros —así que implementamos y validamos HPKE contra los vectores de prueba oficiales del CFRG antes de confiar en un solo byte—. El "transcript" que liga la prueba a esta sesión concreta hay que reconstruirlo idéntico, byte a byte, o la verificación falla sin decirte por qué. Todo eso lo sacamos leyendo el código de la cartera de referencia y comprobando cada suposición contra el artículo real. Es trabajo de integración de verdad, y funciona.
Lo que ya cerramos, y lo que todavía no
Aquí es donde queremos ser precisos, porque en verificación de identidad la mitad honesta de una demo importa tanto como la que sale bien.
- La Trusted List ya la validamos en el camino ZK — y para AV eso es toda la cadena. Cuando publicamos la primera versión de este artículo aún no lo hacíamos; desde entonces lo cerramos. AV no tiene una "lista de listas": hay una única lista europea de emisores de AV, publicada y firmada por la Comisión. El veredicto ZK exige ahora las tres capas: que la prueba sea criptográficamente correcta, que sea fresca, y que el Document Signer de la credencial esté entre los emisores reconocidos de esa lista —cuya firma XAdES verificamos contra el operador de esquema cuyo certificado tenemos pineado—. No hay un nivel superior al que encadenar: anclar a esa lista es anclar a la raíz. Es la misma validación que hace nuestro flujo clásico.
- La frescura también. El "ahora" contra el que el circuito valida el periodo de la credencial va firmado dentro de la prueba, así que no podemos sustituirlo por nuestro reloj — pero sí exigimos que ese instante esté dentro de una ventana de nuestra hora real, lo que rechaza una prueba con timestamp viejo (una credencial caducada afirmada como vigente) o futuro.
- Lo que queda es confirmarlo y endurecerlo, no completar la cadena. Falta cotejar el match byte-a-byte del DS real contra la lista en un test con teléfono (la interop criptográfica ya está verificada); comprobar el
NextUpdatepara rechazar explícitamente una copia rancia de la lista (hoy la descargamos en vivo cada pocas horas, así que el riesgo práctico es bajo); y, si la lista no se pudiera cargar, el chequeo cae a report-only en vez de bloquear. La cadena de confianza en sí, para AV, está completa. - No somos los únicos. El propio ecosistema de referencia tiene un verifier ZK (el backend DC API construido sobre Multipaz), que además valida trust anchors. Otros actores del ecosistema también verifican ZK. Lo que aportamos no es ser los primeros, sino hacerlo como una capa gestionada para el relying party.
Por qué esto le importa a una plataforma
La dirección del ecosistema es unívoca: ZKP está en el Annex A del blueprint, en las especificaciones del EUDI, en el borrador de la segunda edición de ISO 18013-5, y Google ya lo despliega. Cuando las carteras empiecen a enviar pruebas ZK en volumen, cada plataforma tendrá que decidir: montar toda la infraestructura —circuitos archivados y versionados, validación de Trusted List, un servicio de verificación nativo, y seguir un esquema que ha roto compatibilidad tres veces en un año— o llamar a una API que absorbe esa complejidad.
Esa es la apuesta de espuni: una integración, todas las apps. La verificación clásica lleva tiempo en producción con validación de confianza completa; el verifier ZK está probado contra la cartera oficial y ya valida Trusted List y frescura, con la cadena de confianza completa para AV — lo que queda es confirmarlo en campo (el match del DS real en teléfono) y un endurecimiento operativo menor. Si estás construyendo verificación de edad, hablemos.
Nota técnica: el esquema longfellow-zk está bajo dos revisiones de seguridad independientes cuyos informes aún no se han publicado; no lo describimos como "auditado". El verifier es real y reproducible —cada ejecución de la demo publica la prueba para que cualquiera pueda re-verificarla con el binario open-source—, con los límites que hemos detallado arriba.
Las fuentes de este artículo están enlazadas en el propio texto. Para el listado completo de fuentes primarias en las que se basa espuni, consulta referencias.