Esta es una traducción a título informativo. La versión en inglés es la normativa y es la que prevalece. Leer la versión en inglés

Verificación

Los tres roles de verificador de Label 309, los estados del veredicto, la profundidad de finalidad y el catálogo de errores tipados: cómo cualquiera llega a la misma respuesta usando solo infraestructura pública.

Label 309 se verifica, nunca se da por sentado. Quien publica ancla un hash del contenido en Cardano bajo la etiqueta de metadatos 309; a partir de ese momento la afirmación se sostiene por sí sola sobre sus propios bytes, y cualquiera que tenga la referencia de la transacción puede comprobarla. Esta página define cómo se ejecuta esa comprobación: los tres roles de verificador, qué toca y qué no toca cada uno, los estados de veredicto que emiten, la profundidad de confirmación por debajo de la cual un veredicto sigue siendo provisional, y el catálogo de errores tipados que hace que dos implementaciones independientes coincidan en el mismo fallo ante la misma entrada.

La propiedad que lo define es la independencia del servicio. Un verificador conforme alcanza su veredicto usando únicamente la cadena pública, un explorador o gateway de Cardano elegido por el propio verificador y, para las afirmaciones de contenido y los registros sellados, los gateways de almacenamiento direccionado por contenido que el verificador también elige. Nunca contacta con el emisor. El estándar no nombra a ningún proveedor concreto: el gateway es una entrada que aporta el operador.

Tres roles, cada uno una extensión estricta

La verificación está organizada por capas. Cada rol hace todo lo que hace el rol anterior y, además, añade una capacidad. Un rol inferior es por sí mismo un verificador completo y útil: simplemente prueba menos.

RolAñadeToca
Validador estructuralconformidad de esquema y de dominio sobre los bytes del registronada: es una función pura
Verificador públicoresolución de cadena, inclusión en cadena, comprobación de firmasun explorador de Cardano + gateways de contenido
Verificador destinatariodescifrado de prueba de una carga útil sellada, recálculo del hash del texto planola propia clave privada del verificador

Validador estructural: una función pura sobre los bytes

El validador estructural es una única función que va de una cadena de bytes a un resultado. No realiza E/S, ni comprobaciones de firma criptográfica, ni descifrado. Nunca accede a una red, una transacción ni una clave. Dada la misma entrada devuelve la misma salida, siempre y en cualquier lugar, que es justo lo que le permite ejecutarse antes del envío dentro de las herramientas de quien publica, dentro de un indexador de terceros o dentro de una herramienta de archivo que confirma que un registro sigue bien formado a largo plazo, todo ello sin un servidor.

Su flujo es fijo:

1. resource bounds   — a local, non-normative guard on input size; never a
                       Label 309 conformance error.
2. canonical decode  — decode with a canonical-CBOR decoder (RFC 8949 §4.2.1):
                       definite lengths, sorted map keys, no duplicate keys,
                       valid UTF-8. Any malformed or non-canonical input →
                       a single MALFORMED_CBOR.
3. schema parse      — type, length, and the chunk/length bounds; a strict
                       object mode that rejects unknown fields.
4. domain rules      — cross-field constraints the schema cannot express:
                       registry membership, the items-or-merkle rule, COSE
                       structural shape, URI reconstruction, envelope shape.
5. result            — { valid, record } with optional warnings/info, or a
                       sorted list of typed issues.

El validador es independiente del perfil: analiza el esquema v1 completo, sea cual sea el subconjunto sobre el que un verificador posterior pretenda actuar. Los errores invalidan el registro; las advertencias y las entradas informativas se muestran, pero lo dejan válido. Y, lo más importante, confirma la forma de un COSE_Sign1 (un arreglo de cuatro elementos, una carga útil separada (null) y un encabezado protegido bien formado), pero nunca verifica la firma, y nunca rechaza un registro por el simple hecho de que el algoritmo de firma sea uno que no reconoce (ese caso se etiqueta como SIGNATURE_UNSUPPORTED, con severidad info, y el registro sigue siendo válido). Verificar la firma es tarea del verificador público. Consulte El registro para conocer el esquema que esta fase impone.

Verificador público: cadena, inclusión y firmas

El verificador público añade la cadena sobre el validador estructural. Dada una referencia de transacción de Cardano:

  1. Resuelve un explorador elegido por el verificador. La cadena de exploradores es una entrada; el verificador los prueba en orden, obteniendo el CBOR en bruto de la transacción en cadena, nunca la proyección JSON de metadatos del explorador. La vista JSON colapsa los tipos mayores de CBOR en una unión JSON y descarta el orden de las claves del mapa, el marco de longitud definida y la distinción entre bytes y texto, de modo que un verificador que recodificara a partir de ella no podría reproducir la entrada de firma exacta byte a byte y toda firma sobre un registro conforme fallaría. La respuesta negativa de un único proveedor no es autoritativa sobre la cadena (la transacción puede estar en cadena y ser simplemente desconocida para ese proveedor), así que el verificador consulta a todos los proveedores restantes antes de emitir TX_NOT_FOUND; si todos los proveedores son inalcanzables, emite PROVIDER_UNAVAILABLE.
  2. Vincula los bytes obtenidos a la referencia de la transacción. Antes de leer nada de una transacción obtenida, el verificador recalcula blake2b-256 sobre los bytes del cuerpo de la transacción obtenida (que, por definición del ledger, es el id de la transacción) y rechaza la respuesta ante cualquier discordancia con el hash solicitado. Luego recalcula blake2b-256 sobre los bytes de los datos auxiliares obtenidos y rechaza ante cualquier discordancia con el auxiliary_data_hash del cuerpo ya verificado. Ambos resúmenes se calculan sobre los bytes exactamente como se obtuvieron, nunca sobre una recodificación. Una respuesta que falle cualquiera de las dos comprobaciones lleva bytes demostrablemente erróneos y se descarta; si ningún proveedor produce una respuesta que sobreviva a la vinculación, el informe lleva TX_INTEGRITY_MISMATCH. Tras este paso, cada byte del registro y de la transacción circundante queda criptográficamente comprometido con el hash que suministró el llamante: ningún explorador puede sustituir, enmendar ni truncar el registro sin producir una segunda preimagen de blake2b-256.
  3. Desenvuelve los datos auxiliares. El ledger de la era Conway admite tres codificaciones de datos auxiliares, las tres válidas: un mapa de metadatos pelado y sin etiqueta, un arreglo de dos elementos [ metadata, scripts ] y un mapa con etiqueta 259 que lleva los metadatos bajo la clave 0. El verificador DEBE aceptar las tres y discriminar únicamente por el tipo y la etiqueta de CBOR de nivel superior: un valor con etiqueta 259 es la forma de mapa con clave, un arreglo sin etiqueta es la forma de dos elementos, y un mapa sin etiqueta es siempre el propio mapa de metadatos. NO DEBE inspeccionar las claves de un mapa para adivinar la forma; cualquier otra forma de nivel superior, o cualquier etiqueta distinta de 259, es MALFORMED_CBOR. Si la transacción vinculada no lleva metadatos bajo la etiqueta 309, el verificador emite METADATA_NOT_FOUND, un resultado atribuible al registro, porque la propia transacción vinculada demuestra la ausencia: ningún proveedor podría haber retirado los metadatos sin fallar la vinculación.
  4. Reensambla el array de fragmentos del cuerpo completo. El valor de la etiqueta 309 es el cuerpo del registro en CBOR canónico dividido en un arreglo de cadenas de bytes de ≤ 64 bytes. El verificador concatena los elementos byte a byte y en orden (devolviendo los bytes en bruto, sin una pasada de recodificación) para que la comprobación de CBOR canónico aún pueda detectar una codificación en cadena no conforme.
  5. Valida estructuralmente el cuerpo reensamblado (el rol anterior). Un rechazo del validador interrumpe el informe con el veredicto failed.
  6. Comprueba la profundidad de confirmación (más abajo). Una transacción por debajo del umbral se detiene aquí con el veredicto pending.
  7. Verifica cada firma a nivel de registro bajo Ed25519 estricto. No descifra. La resolución de la firma, la carga útil con separación de dominio y las reglas de verificación estricta se especifican en Firmas.
  8. Obtiene y comprueba el hash del contenido, exigiendo cuentas al registro solo por los bytes que puede atribuir a la propia dirección de contenido de un URI (más abajo). No descifra.

Por qué CBOR en bruto y no JSON

Una firma se calcula sobre el CBOR canónico, byte a byte, del cuerpo del registro. Una proyección JSON de los metadatos tiene pérdida por construcción: no puede volver a esos bytes en un viaje de ida y vuelta. Recodificar a partir de JSON rompe toda firma sobre un registro conforme. El CBOR en bruto de la transacción es la única entrada autoritativa para cualquier comprobación criptográfica; una vista JSON sirve para mostrarlo a las personas, una vez que la verificación ya ha pasado.

Verificador destinatario: descifrar y recalcular

El verificador destinatario es un verificador público que, además, posee una clave privada. Para un registro sellado dirigido a él, descifra de prueba las ranuras de clave en cadena con su clave, recupera la clave de contenido cuando lo consigue, descifra el texto cifrado y, a continuación, recalcula los hashes del texto plano contra el compromiso en cadena, cerrando así el círculo entre los bytes cifrados y la afirmación de existencia del contenido. Como todo registro sellado lleva al menos una entrada de hash del contenido, ese recálculo siempre tiene algo concreto con qué compararse. El sobre sellado, las ranuras de clave y la construcción de desenvolvimiento se especifican en PoE sellada.

Antes de que el destinatario toque ninguna primitiva KEM o AEAD, vuelve a aplicar las mismas comprobaciones de forma y de recursos del sobre que ya ejecutó el validador estructural, rechazando primero un sobre estructuralmente inválido o sobredimensionado. Dos de esas guardas previas a las primitivas son cotas de recursos fijadas por despliegue, no campos de transmisión: los límites de referencia son MAX_SLOTS = 1024 ranuras y 65536 bytes para el sobre enc decodificado, ambos muy por encima del techo de ~16 KiB de los metadatos de transacción de Cardano que acota cualquier registro honesto, de modo que un registro que supere cualquiera de ellos está mal formado y se rechaza con ENC_SLOTS_TOO_MANY o ENC_ENVELOPE_TOO_LARGE antes de ejecutar una sola primitiva. Los despliegues PUEDEN endurecerlos.

Una comprobación de forma es determinante para la seguridad: el material de encapsulamiento DEBE ser distinto dentro de un mismo slots[] (todos los valores epk para x25519, o todos los valores kem_ct reensamblados para mlkem768x25519). Un duplicado dentro del registro se rechaza con ENC_SLOTS_DUPLICATE_KEM_MATERIAL antes de ejecutar ninguna primitiva KEM o AEAD, porque un epk/kem_ct repetido rompería la unicidad de clave por ranura de la que depende el envoltorio con nonce a cero. La reutilización de claves entre registros o entre claves es una obligación del productor y no la puede detectar el verificador; solo el duplicado dentro del registro sí. Las tres comprobaciones son estructurales: el validador las impone en todo registro (los códigos de material duplicado, recuento de ranuras y sobre decodificado son códigos de la Parte A); el destinatario simplemente las vuelve a ejecutar como defensa en profundidad.

El desenvolvimiento en sí son dos pasos criptográficos que el destinatario reproduce a partir del sobre, nunca de ninguna entrada externa. Primero recalcula el hash de la transcripción de ranuras slots_hash una vez, antes del bucle, y lo mantiene constante en cada ranura: slots_hash = SHA-256("cardano-poe-slots-transcript-v1" || canonicalEncode(SLOTS_TRANSCRIPT)), donde la transcripción fija los campos de cabecera, el conjunto de ranuras en el cable (cada campo de ranura es una única cadena de bytes, así que no hay fragmentación por campo que normalizar) y la afirmación de hash del ítem mediante hashes_hash. Vincular hashes_hash es lo que permite al destinatario confirmar que el sobre se selló para esta afirmación de hash exacta solo a partir de los bytes en cadena, antes de recuperar ningún texto cifrado: un sobre empalmado en un ítem con un mapa hashes distinto falla el MAC. Itera todas las ranuras sin salida anticipada; una ranura se acepta solo cuando la clave de contenido que produce también reproduce el slots_mac en el cable sobre ese slots_hash constante. La aceptación también pliega un bit de validez independiente del secreto: en la ruta clásica, una ranura diseñada para llevar el secreto compartido X25519 al valor todo a cero pone ese bit en falso (una comparación en tiempo constante contra 0^32), la KEK se selecciona en tiempo constante hacia una falsa derivada de 0^32 para que el bucle realice un trabajo idéntico, y el bit gobierna la aceptación de la ranura: una ranura con ECDH inválido nunca puede abrir, sea cual sea su envoltorio o MAC. Tanto la apertura del envoltorio como la posterior apertura del contenido son atómicas: ante un fallo del tag AEAD no devuelven texto plano, y el candidato que entregan (la clave envuelta o el texto plano del contenido) es un valor de relleno fijo o pseudoaleatorio independiente del texto cifrado que falló: nunca se libera texto plano sin verificar.

Una clave de destinatario PUEDE coincidir legítimamente con más de una ranura: un productor puede sellar la misma clave de contenido para el mismo destinatario en varias ranuras, cada una con material KEM fresco por ranura, para acolchar el recuento de destinatarios; es una técnica de privacidad válida, y distinta del rechazo de material de encapsulamiento duplicado, que se dispara solo ante un epk/kem_ct idéntico. El verificador selecciona la clave de la primera coincidencia y NO DEBE rechazar solo porque coincidieran varias ranuras. La única anomalía que DEBE rechazar son dos ranuras coincidentes que recuperan claves de contenido distintas (comparadas en tiempo constante): el bucle arrastra un bit cek_conflict y aflora el único fallo genérico si cualquier coincidencia posterior produce una clave que difiera de la seleccionada. Esto es defensa en profundidad: bajo el compromiso del conjunto de ranuras, una coincidencia con clave distinta ya es inviable, así que la comprobación simplemente falla de forma segura.

Luego, sobre la clave de cifrado del contenido recuperada, deriva la clave de contenido (una hoja HKDF de esa clave con salt del enc.nonce) y abre el texto cifrado en STREAM segmentado segmento a segmento, verificando la etiqueta de cada segmento antes de liberar el texto plano de ese segmento. El AAD por segmento es vacío: todo el contexto de cabecera ya está vinculado a la clave de forma transitiva a través de slots_mac, así que alterar cualquier campo de cabecera cambia lo que el destinatario deriva y el flujo no consigue abrir. El truncamiento se detecta con la marca final: un segmento final ausente, datos a continuación de él, una marca final en un segmento no final, o un segmento no final corto fallan todos como TAMPERED_CIPHERTEXT. El formato segmentado no impone ningún techo criptográfico a la carga útil (el contador de segmento de 88 bits admite 2^88 segmentos); un máximo práctico es una política de denegación de servicio del despliegue, impuesta de forma incremental a medida que se lee el flujo. En la ruta de frase de contraseña, el destinatario lee primero la cabecera de compromiso inicial de 32 bytes y la compara en tiempo constante antes de abrir ningún segmento.

La ruta del destinatario es donde el catálogo de errores demuestra su precisión: distingue el caso en que ninguna ranura aceptó esta clave (destinatario equivocado) del caso en que una ranura aceptó la clave pero el conjunto de ranuras o el texto cifrado fue manipulado. Son afirmaciones de seguridad distintas y llevan códigos diferentes (más abajo). Un llamante no confiable, sin embargo, recibe exactamente una forma de fallo genérico sea cual sea la causa (ninguna ranura abrió, el conjunto de ranuras fue manipulado o el tag de contenido falló), y la respuesta nunca revela qué caso ocurrió ni qué ranura coincidió; los códigos tipados son un diagnóstico interno solo para un llamante local de confianza.

El tiempo sigue un modelo explícito. El verificador PUEDE retornar en la comprobación de no-coincidencia, antes del descifrado del contenido, de modo que un no destinatario y un destinatario tomen un tiempo medible distinto. Esa diferencia revela solo destinatario frente a no destinatario, nunca qué ranura coincidió ni material de clave alguno. No se exige un tiempo uniforme entre un no destinatario y un destinatario cuyo texto cifrado no consigue abrir, y NO DEBE imponerse una apertura de contenido ficticia: cargaría el coste del descifrado del contenido sobre todo transeúnte. La garantía de tiempo constante que se mantiene es la de entre ranuras: dentro de la pasada de una sola clave privada, el bucle recorre todas las ranuras con comparaciones en tiempo constante, de modo que nada filtra qué ranura, si alguna, desenvuelve esa clave.

Finalidad: profundidad de confirmación

La liquidación en Cardano es probabilística. Una transacción con un bloque de profundidad todavía puede quedar huérfana por una reorganización corta; una transacción con muchos bloques de profundidad ha quedado liquidada con probabilidad abrumadora. Un verificador que calificara como valid un registro de un solo bloque de profundidad permitiría que un atacante reanclara un registro contradictorio en una bifurcación competidora y obtuviera un veredicto «válido» en ambas, rompiendo en silencio la suposición de solo-anexar sobre la que descansa toda la prueba.

Por eso un verificador reporta el registro como pending, no failed, mientras se sitúa por debajo de un umbral de profundidad de confirmación. El umbral de uso general RECOMENDADO es de ≥ 15 bloques (unos cinco minutos). El umbral es una política del verificador, no una constante del formato: los despliegues que manejan registros de alto valor o de carácter probatorio DEBERÍAN elevarlo hacia la finalidad firme, y un verificador DEBE exponer el umbral que usó para que los consumidores puedan superponer una política más estricta. Un registro pending está bien formado y en cadena; simplemente todavía no ha liquidado a suficiente profundidad, y puede resolverse a valid en un reintento posterior.

Estados del veredicto

Un verificador concluye en uno de cuatro veredictos legibles por máquina, cada uno emparejado uno a uno con un código de salida del proceso, de modo que quien lo invoca (una puerta de CI, un monitor, un script) pueda distinguir un fallo atribuible al registro de uno operativo transitorio sin necesidad de analizar el informe estructurado. La línea rectora es la atribución: condenar un registro exige evidencia que los propios bytes del registro (o bytes vinculados de forma atribuible a sus referencias) realmente aporten. Ningún mal comportamiento de un proveedor puede fabricar un failed.

VeredictoSalidaSignificado
valid0toda comprobación que ejecutó el verificador devolvió ok; no hay ningún problema con severidad error.
failed1un fallo atribuible al registro: el validador estructural rechazó los bytes, una firma no verificó, un hash atribuible no coincidió, la transacción vinculada no lleva metadatos bajo la etiqueta 309 (METADATA_NOT_FOUND), o se disparó una regla de host denegado.
unverifiable2sin error atribuible al registro, pero una comprobación requerida no pudo ejecutarse o no pudo atribuirse: la transacción no se resolvió, ninguna respuesta de proveedor sobrevivió a la vinculación (TX_INTEGRITY_MISMATCH), o no se pudo obtener ni atribuir el contenido o el texto cifrado comprometidos. El mismo registro puede verificarse como valid en un reintento o bajo un gateway distinto.
pending3estructuralmente bien formado y en cadena, pero por debajo del umbral de profundidad de confirmación (INSUFFICIENT_CONFIRMATIONS); puede liquidar. Ningún resultado de un registro pendiente puede presentarse como definitivo.

Los fallos en tiempo de ejecución del anfitrión del verificador que no son atribuibles al registro usan códigos de salida 4 y superiores y no se corresponden con ningún veredicto.

Un veredicto valid NO DEBE reportarse cuando haya presente algún problema con severidad error; un registro PUEDE ser valid con una lista warnings o info no vacía. Ninguna capa puede «suavizar» un error y convertirlo en advertencia para hacer pasar un registro. Cada veredicto se reserva para su propio caso: pending nunca sustituye a valid ni a failed, y un fallo atribuible a un proveedor es unverifiable, nunca failed.

Un suelo de compromiso gobierna la disponibilidad: cuando la comprobación de contenido se ejecutó pero los fallos de disponibilidad dejaron sin verificar ningún compromiso de contenido del registro, el veredicto es unverifiable, nunca valid; un veredicto valid significa que se comprobó al menos un compromiso de contenido. Los resultados de integridad quedan al margen del suelo: unos bytes atribuibles que fallan un compromiso producen failed, sea cual sea lo demás que estuviera disponible.

Vinculación a la dirección de contenido y atribución

El paso 8 (y, para el verificador destinatario, el descifrado) obtiene bytes de gateways de almacenamiento direccionado por contenido que el verificador eligió, y los gateways no son de confianza. La línea de veredicto de más arriba gira en torno a una única pregunta que el verificador DEBE poder responder sobre cada flujo de bytes obtenido: ¿se pueden atribuir estos bytes al propio URI? Ambos esquemas están direccionados por contenido, así que sí se puede:

  • ipfs://: recalcular el CID sobre el contenido obtenido (el multihash directamente para un CID de códec en bruto; los resúmenes bloque a bloque a lo largo de la ruta resuelta para un CID en forma de DAG).
  • ar://: validar la transacción de Arweave firmada y recalcular el árbol de Merkle de fragmentos contra su data_root; para un elemento de datos ANS-104, recalcular el deep-hash, verificar la firma del propietario y comprobar que el SHA-256 de la firma sea igual al id del URI.

Los bytes que satisfacen los propios resúmenes del registro no necesitan comprobación de vinculación: el compromiso del registro es al menos tan fuerte como el de la capa de almacenamiento. Allí donde la vinculación se aplica, la atribución decide qué significa una discordancia:

  • Bytes atribuibles (vinculación verificada, o suministrados fuera de banda por el llamante) se imputan al registro cuando fallan un compromiso: URI_INTEGRITY_MISMATCH para el contenido de un ítem (un fallo de integridad duro, sea cual sea lo que contenga cualquier URI hermano), la familia MERKLE_* para una lista de hojas, TAMPERED_CIPHERTEXT para un blob de texto cifrado atribuible. Veredicto failed.
  • Bytes no atribuibles (vinculación no verificada, o verificada y fallida) incriminan al proveedor que los sirve, nunca al registro: URI_PROVIDER_INTEGRITY_MISMATCH (advertencia). El verificador continúa con los URI y gateways restantes; una afirmación que se queda sin bytes atribuibles termina en un resultado de disponibilidad (CONTENT_UNAVAILABLE, MERKLE_LEAVES_UNAVAILABLE, CIPHERTEXT_UNAVAILABLE), veredicto unverifiable, exactamente como si no se hubiera obtenido nada.

Esta es la contraparte, del lado del almacenamiento, de la vinculación a la referencia de la transacción: un gateway que se comporta mal solo puede degradar la disponibilidad, nunca el veredicto. URI_INTEGRITY_MISMATCH y URI_PROVIDER_INTEGRITY_MISMATCH son, por tanto, códigos distintos (el primero condena el registro, el segundo condena un proveedor), y un verificador que los confundiera dejaría que un gateway hostil forjara un failed. La recomprobación del hash del texto plano posterior al descifrado no necesita calificador de atribución: un texto cifrado que abre bajo el sobre autenticado queda atribuido por el propio AEAD, así que una discordancia del hash del texto plano allí (URI_INTEGRITY_MISMATCH) es siempre atribuible al registro y fuerza failed.

El catálogo de errores tipados

Cada modo de fallo se resuelve a un código de un único catálogo cerrado. Los códigos van en SCREAMING_SNAKE_CASE, y una implementación conforme DEBE emitir exactamente esas cadenas: nunca un código interno en minúsculas de un analizador, nunca un mensaje de formato libre. Dos implementaciones en dos lenguajes que reciben la misma entrada emiten el mismo código; la lista normativa completa queda fijada byte a byte por la suite de pruebas de conformidad, y el catálogo está cerrado (los códigos solo se añaden mediante enmienda).

Modelo de severidad

Cada problema lleva una de tres severidades, y la distinción es determinante:

  • error: invalida el veredicto. Un resultado valid no puede coexistir con ningún error.
  • warning: una anomalía no fatal en tiempo de ejecución (falló un único gateway, una lista de hojas estaba solo parcialmente disponible) que no impide valid.
  • info: una no-comprobación deliberada: un aspecto que el verificador eligió no evaluar (un campo fuera de su perfil, un algoritmo opcional no reconocido). Una entrada informativa no es un error suavizado y nunca se usa como tal.

Un código queda aparte: INSUFFICIENT_CONFIRMATIONS se corresponde con el veredicto pending en lugar de con una severidad, porque el registro está bien formado y solo aguarda la liquidación.

Familias de errores

El catálogo se agrupa en familias. Un conjunto representativo, no exhaustivo, de códigos:

FamiliaSeveridadCódigos representativos
CBOR malformado / no canónicoerrorMALFORMED_CBOR, CHUNK_TOO_LARGE
EsquemaerrorSCHEMA_TYPE_MISMATCH, SCHEMA_MISSING_REQUIRED, SCHEMA_UNKNOWN_FIELD, SCHEMA_EMPTY_RECORD
Algoritmo no admitidoerrorUNSUPPORTED_HASH_ALG, UNSUPPORTED_AEAD_ALG, UNSUPPORTED_KEM_ALG, UNSUPPORTED_MERKLE_COMMIT_ALG
Explorador / metadatoserror / pendingTX_NOT_FOUND, PROVIDER_UNAVAILABLE, TX_INTEGRITY_MISMATCH (→ unverifiable), METADATA_NOT_FOUND (→ failed); INSUFFICIENT_CONFIRMATIONS (→ pending)
Firmaerror / infoMALFORMED_SIG_COSE_SIGN1, SIGNER_KEY_UNRESOLVED, SIGNATURE_INVALID, WALLET_ADDRESS_MISMATCH; SIGNATURE_UNSUPPORTED (info)
Cifrado / KEM / envolturaerrorKEM_EPK_LENGTH_MISMATCH, KEM_CT_LENGTH_MISMATCH, WRAP_LENGTH_MISMATCH, ENC_SLOTS_DUPLICATE_KEM_MATERIAL, ENC_SLOTS_TOO_MANY, ENC_ENVELOPE_TOO_LARGE, ENC_REQUIRES_CONTENT_HASH
Resultado del descifradoerrorWRONG_DECRYPTION_INPUT_SHAPE, WRONG_RECIPIENT_KEY, TAMPERED_HEADER, TAMPERED_CIPHERTEXT, KDF_DERIVATION_FAILED
URI / contenidoerror / warningINVALID_URI, URI_TARGET_FORBIDDEN, URI_INTEGRITY_MISMATCH, CONTENT_UNAVAILABLE (→ unverifiable), CIPHERTEXT_UNAVAILABLE (→ unverifiable); URI_PROVIDER_INTEGRITY_MISMATCH, URI_FETCH_FAILED (advertencias)
Compromiso de lista Merkleerror / warning / infoMERKLE_ROOT_MISMATCH, SCHEMA_MERKLE_LEAF_COUNT_MISMATCH; MERKLE_LEAVES_UNAVAILABLE (dual); MERKLE_UNSUPPORTED (dual)
Independencia del servicioerrorSERVICE_INDEPENDENCE_VIOLATION

Los códigos de red/política (TX_NOT_FOUND, PROVIDER_UNAVAILABLE, CONTENT_UNAVAILABLE, CIPHERTEXT_UNAVAILABLE) —y TX_INTEGRITY_MISMATCH, cuya discordancia es demostrable contra los proveedores y no contra el registro— son de severidad error en la lista de problemas (bloquean un veredicto valid) pero no son atribuibles al registro, así que se asignan a unverifiable, nunca a failed. URI_PROVIDER_INTEGRITY_MISMATCH es la advertencia por recuperación bajo el mismo principio. Unos pocos códigos llevan severidad dual (ENC_UNSUPPORTED, MERKLE_UNSUPPORTED, OUT_OF_PROFILE_SKIPPED y MERKLE_LEAVES_UNAVAILABLE): se leen como info/warning por defecto y se promueven a error en un contexto estricto (el rol del destinatario, la escalada de solo-merkle, el modo estricto de extremo a extremo o el suelo de compromiso).

La ruta del destinatario es la familia más precisa en términos de diagnóstico. Para un llamante local de confianza, un descifrado fallido se resuelve a uno de tres códigos internos: WRONG_RECIPIENT_KEY significa que ninguna ranura aceptó la clave suministrada (nunca se recuperó ninguna clave de contenido); TAMPERED_HEADER significa que se recuperó una clave pero la clave de contenido candidata no reprodujo slots_mac sobre slots_hash (se alteró una ranura, un campo de cabecera o el propio slots_mac); TAMPERED_CIPHERTEXT significa que el conjunto de ranuras estaba intacto pero falló el tag del AEAD de contenido tras recuperar la clave. Los tres son estructuralmente distinguibles para ese llamante local, y la frontera entre ellos no filtra material de clave alguno. Para un llamante externo no confiable, los tres colapsan en el único fallo genérico descrito más arriba, indistinguibles por la forma de la respuesta. Bajo el modelo de tiempo, un retorno anticipado permitido en la no-coincidencia separa WRONG_RECIPIENT_KEY (un no destinatario) de los dos resultados de manipulación del lado del destinatario, que entre sí no llevan ninguna distinción adicional, de modo que la precisión diagnóstica nunca se convierte en un oráculo selectivo por ranura o por clave.

Cómo los códigos se asignan a los cuatro veredictos

Un código emitido por el validador estructural significa que los bytes del registro no son conformes. El verificador público interrumpe el informe con el veredicto failed (salida 1) y con la lista de problemas del validador, sin ejecutar más trabajo de cadena ni de criptografía. Un código emitido solo después de que la validación estructural haya pasado (una firma que no verificó, un hash atribuible que no coincidió, METADATA_NOT_FOUND en la transacción vinculada) también es failed: cada uno es atribuible al registro, evidencia que los propios bytes del registro aportan.

Un fallo transitorio o atribuible a un proveedor es un veredicto distinto: un contenido que no se pudo obtener ni atribuir, un explorador inalcanzable o un proveedor que sirvió bytes que fallan la vinculación a la referencia de la transacción se asignan todos a unverifiable (salida 2), porque ninguno es culpa del registro y el mismo registro puede verificarse como valid en un reintento. La distinción que preserva el código de salida es, por tanto, triple entre los estados de fallo: failed atribuible al registro (1), unverifiable operativo o atribuible a un proveedor (2), y pending por debajo del umbral (3).

Algunos códigos llevan una severidad que depende del contexto. Un verificador que lee un registro más rico que el perfil que declara (por ejemplo, un verificador de solo hash que se topa con un registro sellado) reporta el campo adicional como info en un contexto de visualización, y aun así valida la afirmación de hash, o como error en un contexto de auditoría estricta de extremo a extremo. Del mismo modo, un algoritmo de firma opcional no reconocido es info: la afirmación de existencia del contenido no depende de él, de modo que una prueba pública de solo hash sigue siendo valid incluso cuando una firma de carácter consultivo no se puede verificar.

La independencia del servicio no es opcional

La verificación nunca recurre de vuelta al emisor. Toda llamada saliente que realiza un verificador conforme se dirige a infraestructura que eligió el operador: un explorador de Cardano para la transacción, y gateways de almacenamiento direccionado por contenido para cualesquiera bytes ar:// o ipfs://. Esto se impone estructuralmente, no es una promesa en un comentario de código:

  • Toda llamada de red pasa por una única envoltura de salida que registra url, method, status, el recuento de bytes y el propósito de cada llamada (éxito, fallo y reintento por igual) en un rastro de auditoría obligatorio dentro del informe. Un verificador que no puede producir ese rastro no puede demostrar su independencia.
  • Esa envoltura acepta una lista de hosts denegados que aporta el despliegue y falla de forma tajante cualquier llamada a un host coincidente con SERVICE_INDEPENDENCE_VIOLATION. La lista es una entrada del operador (una suite de conformidad la rellena con los propios dominios de quien implementa), no una constante del formato de Label 309.
  • Un arnés de conformidad ejecuta el verificador contra transacciones de fixture congeladas en una red donde los propios dominios del operador no resuelven a ningún lado, y afirma que el verificador aun así devuelve valid. La afirmación se hace en la capa de red del sistema operativo, no rastreando el código fuente: un verificador que alcanzara un host prohibido mediante una IP codificada a mano pasaría un escaneo del fuente, pero fallaría esta prueba.

El verificador necesita un explorador de Cardano alcanzable y nada específico de quien implementa. Los gateways de contenido, una clave privada de destinatario y una lista de hojas fuera de cadena son entradas opcionales que desbloquean, respectivamente, las comprobaciones de contenido, de destinatario y de Merkle. Ninguna de ellas es un servicio que el estándar nombre, y ninguna de ellas es el emisor.

Páginas relacionadas

  • El registro: el formato del que parte el validador estructural para sus comprobaciones: la etiqueta 309, la forma del mapa, el reensamblaje de fragmentos y el esquema CDDL.
  • Firmas: la construcción COSE_Sign1 a nivel de registro, la carga útil con separación de dominio y las reglas de verificación estricta de Ed25519.
  • PoE sellada: el sobre de cifrado, las ranuras de clave del destinatario y el desenvolvimiento que realiza el verificador destinatario.