L’enregistrement
Le format de sérialisation (wire format) de Label 309 : où réside l’enregistrement sous le label de métadonnées 309, la forme de sa map, les règles du CBOR canonique, le découpage en chunks pour le transport et le schéma CDDL.
Un enregistrement Label 309 est une unique map CBOR transportée dans les métadonnées d’une transaction Cardano sous le label 309. La map engage sur la chaîne une ou plusieurs empreintes de contenu ; l’heure du bloc de la transaction est le témoin que ces octets existaient au plus tard à cet instant. Tout le reste que l’enregistrement peut transporter — des URI de stockage, une enveloppe de chiffrement, des signatures de paternité, un pointeur de remplacement — constitue des métadonnées optionnelles à propos de cette affirmation centrale.
Cette page définit la forme sur le fil : où se situe l’enregistrement, comment il est encodé, comment les valeurs surdimensionnées sont transportées et le schéma fermé qu’un validateur structurel contrôle. Les constructions cryptographiques évoquées ici (algorithmes de hachage, l’enveloppe scellée, les signatures) ont leurs propres pages ; celle-ci porte sur le format de sérialisation.
Où réside l’enregistrement
Un enregistrement PoE DOIT être placé sous le label de métadonnées de
transaction 309, réservé comme « Proof of Existence record » dans le
registre des labels de métadonnées de CIP-10.
Les métadonnées de transaction sont une map d’un label entier vers une valeur, de
sorte qu’une transaction NE DOIT PAS transporter plus d’un enregistrement PoE —
exactement un enregistrement par transaction.
Une transaction PEUT transporter des métadonnées supplémentaires sous d’autres
labels (par exemple un message
CIP-20
674). Un vérificateur traitant une PoE DOIT ignorer tout label autre que
309.
Sur le ledger de l’ère Conway, les métadonnées de transaction sont le champ
metadata à l’intérieur de l’auxiliary_data de la transaction. Les valeurs
admises sous un label quelconque sont contraintes au type récursif metadatum du
ledger — entiers, chaînes d’octets, chaînes de texte, arrays et maps, les chaînes
d’octets comme les chaînes de texte étant toutes deux plafonnées à 64 octets
chacune :
metadatum =
{ * metadatum => metadatum }
/ [ * metadatum ]
/ int
/ bstr .size (0..64)
/ tstr .size (0..64)Une transaction transportant une quelconque bstr ou tstr isolée de plus de 64
octets est rejetée par les nœuds Cardano au moment de la soumission, avant qu’aucun
vérificateur ne la voie. Ce plafond est la raison pour laquelle Label 309 définit
une discipline de découpage en chunks pour le transport (ci-dessous) ; chaque champ
que l’enregistrement transporte — de base ou d’extension — doit se réduire à un
metadatum.
Transport : l’array de chunks du corps entier
Un corps d’enregistrement sérialisé dépasse couramment les 64 octets, il ne peut
donc pas être stocké sous le label 309 comme valeur nue. Le corps de
l’enregistrement est par conséquent transporté sous la forme d’un array opaque de
chunks du corps entier : un unique array CBOR de chaînes d’octets de ≤ 64 octets
(bstr .size (1..64)) dont la concaténation dans l’ordre est le corps de
l’enregistrement. Ce découpage de transport est le seul découpage en chunks
qu’effectue Label 309 — l’unique étape du format véritablement imposée par le
ledger.
Comme le ledger ne voit que cet array de transport et jamais les champs à
l’intérieur du corps réassemblé, ces champs sont des valeurs CBOR ordinaires sans
enveloppe de chunk par champ ni plafond de 64 octets au niveau du champ : une URI
de stockage est une unique chaîne de texte, un COSE_Sign1 est une unique chaîne
d’octets et un kem_ct X-Wing est une unique chaîne d’octets de 1120 octets. Un
champ de plus de 64 octets s’étend simplement par-delà les frontières de chunks de
l’array du corps entier, comme n’importe quel autre segment du corps.
Un producteur DOIT sérialiser le corps de l’enregistrement une seule fois en CBOR canonique, découper cette chaîne d’octets en chunks de 1 à 64 octets et stocker l’array de longueur définie de chaînes d’octets de longueur définie ainsi obtenu comme valeur du label 309. La forme d’array est toujours obligatoire, même pour un corps de 64 octets ou moins : un tel corps est un array de longueur 1, jamais une map ni une chaîne d’octets nue. Les producteurs DEVRAIENT utiliser le découpage minimal (chaque chunk sauf le dernier faisant exactement 64 octets) et NE DEVRAIENT PAS émettre de chunks de longueur nulle ; un découpage excessif gaspille des octets de transaction sans aucun bénéfice.
Un vérificateur DOIT concaténer octet à octet les éléments de l’array dans
l’ordre afin de réassembler le corps de l’enregistrement avant la validation
structurelle, et DOIT rejeter toute valeur du label 309 qui n’est pas un tel
array. Les frontières de chunks ne portent aucune signification sémantique : deux
arrays de transport dont les concaténations sont identiques octet à octet désignent
le même enregistrement. La taxonomie des erreurs de transport fixe les codes de
rejet — un chunk de plus de 64 octets est CHUNK_TOO_LARGE ; un élément d’array
qui n’est pas une chaîne d’octets, un array ou élément de longueur indéfinie, ou une
valeur du label 309 qui n’est pas un array (map nue, chaîne d’octets nue, entier)
est MALFORMED_CBOR. Un chunk de longueur nulle n’apporte aucun octet et il est
toléré, jamais rejeté à lui seul.
Le schéma décrit le corps réassemblé
Tout ce qui suit — la map de l’enregistrement, le CDDL, les règles des champs — décrit le corps de l’enregistrement après le réassemblage des chunks. L’array de chunks du corps entier ne fait pas partie du schéma ; il est d’abord défait, puis le corps est validé.
La map de l’enregistrement
Le corps réassemblé de l’enregistrement est une map CBOR. Les champs à valeur entière sont du major type CBOR 0/1 ; les champs de texte sont du major type 3 et DOIVENT être de l’UTF-8 valide ; les champs d’octets sont du major type 2 ; les arrays sont du major type 4 ; les maps imbriquées sont du major type 5. Un champ optionnel présent NE DOIT PAS porter de valeur vide.
La forme de premier niveau est la suivante :
| Clé | Type | Statut | Signification |
|---|---|---|---|
v | uint | REQUIS | Version du schéma ; ce document définit v = 1. |
items | array de maps d’item | OPTIONNEL | Engagements par contenu — voir Contenu et hachage. |
merkle | array d’engagements | OPTIONNEL | Engagements de liste reliant des listes de feuilles hors chaîne à une racine. |
supersedes | bytes (32) | OPTIONNEL | Hash de transaction d’un enregistrement antérieur que celui-ci remplace. |
sigs | array de maps de signature | OPTIONNEL | Signatures de paternité au niveau de l’enregistrement — voir Signatures. |
crit | array de chaînes de texte | OPTIONNEL | Clés d’extension qu’il est obligatoire de comprendre. |
Un enregistrement conforme DOIT s’engager sur au moins l’un des deux : items
(avec ≥ 1 entrée) ou merkle (avec ≥ 1 entrée). Un enregistrement qui ne transporte
ni l’un ni l’autre — ou qui transporte l’un d’eux comme array vide — est rejeté en
tant qu’enregistrement vide. Hormis cette règle, items et merkle sont
orthogonaux : un enregistrement peut transporter l’un ou l’autre seul, ou les deux
ensemble.
Label 309 n’impose aucun plafond numérique au nombre d’entrées. Le seul plafond est la taille maximale de transaction Cardano en vigueur, et les producteurs paient des frais par octet qui bornent naturellement la taille de l’enregistrement. Un validateur NE DOIT PAS rejeter un enregistrement au seul motif qu’il transporte de nombreuses entrées, dès lors qu’il tient sous la limite de taille du ledger.
Le champ de version
v est un entier non signé CBOR, et non une chaîne de version sémantique. Ce
document définit exactement v = 1. Un validateur DOIT rejeter avec une erreur
typée un enregistrement dont le v se situe hors de son ensemble pris en charge ;
il NE DOIT PAS entrer en panic, s’interrompre ni traiter silencieusement
l’enregistrement comme un schéma de métadonnées différent. L’entier v n’est
incrémenté que lorsqu’un changement amènerait un analyseur v1 à mal interpréter
l’enregistrement — les extensions additives et avec espace de noms propre ne
l’incrémentent pas.
Items
Chaque entrée d’items est une map CBOR comportant un champ requis et deux
optionnels :
hashes— REQUIS, une map non vide d’un identifiant d’algorithme de hachage vers un condensé brut de 32 octets. Au moins une entrée ; les algorithmes en double sont impossibles, car les clés d’une map CBOR sont uniques. Voir Contenu et hachage.uris— OPTIONNEL, une liste plurielle d’URI de découverte (règles ci-dessous).enc— OPTIONNEL, l’enveloppe de chiffrement d’un item scellé. Voir PoE scellée.
Il n’existe pas d’emplacement de signature par item. La paternité ne s’exprime qu’au
niveau de l’enregistrement, par une entrée sigs[] qui couvre uniformément chaque
item.
Engagements Merkle
Chaque entrée de merkle relie l’enregistrement à une liste ordonnée de feuilles de
32 octets via une construction canonique en arbre de hachage, de sorte qu’une unique
racine de 32 octets sur la chaîne puisse tenir lieu d’une liste de feuilles hors
chaîne arbitrairement grande. Un engagement est une map fermée :
| Champ | Type | Statut | Signification |
|---|---|---|---|
alg | tstr | REQUIS | Identifiant enregistré de l’algorithme d’engagement de liste. |
root | bytes (32) | REQUIS | Racine canonique sur la liste ordonnée de feuilles du producteur. |
leaf_count | uint | REQUIS | Nombre de feuilles engagées ; relie la racine à la taille de la liste. |
uris | liste d’URI | OPTIONNEL | URI adressée(s) par contenu du fichier de la liste de feuilles hors chaîne. |
Une racine Merkle s’engage sur une structure de liste de feuilles, tandis qu’une
entrée hashes s’engage sur des octets en clair ; les deux se vérifient
différemment (preuve d’inclusion contre recalcul du texte en clair), raison pour
laquelle les engagements de liste résident au niveau supérieur plutôt qu’à
l’intérieur d’un item. Le registre des engagements de liste est disjoint du registre
des hachages de contenu — voir Registres d’algorithmes.
Supersedes
supersedes est un hash de transaction Cardano optionnel de 32 octets qui pointe
vers un enregistrement Label 309 antérieur. C’est un lien indépendant du service et
en ajout seul : un enregistrement postérieur peut pointer vers un enregistrement
antérieur sans base de données hors chaîne ni identifiant d’enregistrement d’un
fournisseur.
Le remplacement ne supprime, ne révoque ni n’invalide l’enregistrement antérieur — la chaîne est en ajout seul, et les vérificateurs DOIVENT continuer à traiter l’enregistrement antérieur comme existant et vérifiable de façon indépendante. Le pointeur ne porte aucun champ de motif ni de texte libre ; tout sens humain (correction, remplacement, retrait) relève du nouveau contenu, non du label 309. Un vérificateur qui résout le pointeur DOIT le rechercher sur le même réseau Cardano que la transaction qui le contient ; le champ ne porte aucun discriminateur de réseau, car un hash de transaction n’est unique qu’au sein de son propre réseau.
Signatures
sigs est un array optionnel d’entrées de signature au niveau de l’enregistrement.
Chaque entrée porte une structure COSE_Sign1
détachée sur le corps de l’enregistrement — c’est-à-dire la map complète de
l’enregistrement avec sigs retiré — et, en option, la clé publique du signataire
pour la voie de signature par portefeuille. Une signature unique atteste du corps
entier : chaque item, chaque URI, chaque enveloppe, le pointeur de remplacement s’il
est présent et toute clé d’extension. Les signatures sont toujours optionnelles, et
un algorithme de signature non reconnu n’invalide jamais l’affirmation sur le
contenu. La charge utile signée, le préfixe de séparation de domaine, la résolution
de la clé du signataire et les règles strictes de vérification sont spécifiés dans
Signatures.
Règles des URI
Lorsqu’il est présent, uris est une liste non vide ; chaque entrée est une unique
chaîne de texte CBOR portant exactement une URI. Il n’existe ni plafond de longueur
par URI ni forme enveloppante : le transport du corps entier satisfait déjà le
plafond de 64 octets par chaîne du ledger, de sorte qu’une longue URI
ipfs://<CIDv1>/<path> est une chaîne de texte comme n’importe quelle autre. Chaque
URI DOIT être absolue, DOIT inclure un schéma et une partie hiérarchique, et
NE DOIT PAS contenir d’identifiant de fragment — une PoE est une affirmation sur
les octets d’un contenu, non sur un sous-composant d’un document.
L’ensemble de schémas de la v1 est fermé et adressé par contenu :
| Schéma | Notes |
|---|---|
ar:// | Id de transaction Arweave (base64url de 43 caractères). Forme ar://<txid>. |
ipfs:// | CID IPFS, CIDv1 de préférence. Forme ipfs://<cid> ou ipfs://<cid>/<path>. |
Les producteurs NE DOIVENT PAS émettre tout autre schéma — https://,
http://, file://, data: et les autres sont tous rejetés. La restriction est
délibérée, non temporaire : une URI adressée par contenu relie les octets récupérés
à l’URI elle-même à travers le modèle d’intégrité de la couche de stockage (un CID
IPFS est un multihash du contenu ; un id de transaction Arweave s’engage sur les
données sous le consensus d’Arweave), de sorte qu’un vérificateur peut confirmer
« les octets que j’ai récupérés sont les octets sur lesquels le producteur s’est
engagé » sans faire confiance au DNS, à TLS, aux passerelles ni aux autorités de
certification. Un schéma hors de l’ensemble rend un enregistrement structurellement
invalide ; il ne se valide jamais comme valid.
uris est optionnel en tout point. Un enregistrement à empreinte seule, avec uris
omis, est une affirmation complète — l’existence du contenu est affirmée sans
s’engager sur un canal de récupération. Le profil CID exact (préfixes multibase
acceptés, codecs et multihashes) fait partie des règles de vérification ; voir
Vérification.
CBOR canonique
Tout enregistrement Label 309 DOIT être encodé en CBOR canonique selon le RFC 8949 §4.2.1 (Core Deterministic Encoding). Concrètement :
- Sérialisation préférée (forme la plus courte) pour chaque entier.
- Encodage de longueur définie pour toutes les chaînes d’octets, chaînes de texte, arrays et maps.
- Aucun tag sémantique (ce document n’en requiert aucun — un tag bignum 2/3 NE DOIT PAS apparaître).
- Clés de map triées dans l’ordre lexicographique octet par octet de leur encodage CBOR.
- Chaînes de texte UTF-8 sans marque d’ordre des octets.
- Aucune clé en double dans aucune map.
- Aucune valeur à virgule flottante ni valeur simple non triviale — un enregistrement ne
transporte que des entiers, des chaînes d’octets, des chaînes de texte, des arrays, des
maps et (là où un schéma l’admet)
true/false/null. Les flottants de major type 7 (y compris un1.0entier), le zéro négatif etundefinedDOIVENT être rejetés, et non convertis.
Le déterminisme est ce qui rend le format interopérable : deux producteurs exprimant le même enregistrement logique émettent des octets identiques, de sorte qu’une signature calculée sur le corps par une implémentation se vérifie sous une autre. Un validateur DOIT rejeter un encodage non canonique. Les explorateurs et les portefeuilles peuvent exposer les métadonnées via une projection JSON, mais un vérificateur conforme DOIT valider le CBOR original de la transaction, jamais un réencodage JSON avec perte de celui-ci.
Compatibilité ascendante
Label 309 v1 réserve un ensemble fermé de clés de base : v, items, merkle,
supersedes, sigs, crit. Un enregistrement PEUT transporter en outre des
clés d’extension dont les noms correspondent à l’un de deux espaces de noms
réservés :
^x-.+— l’espace de noms fournisseur / expérimental.^[a-z]+-.+— l’espace de noms des spécifications complémentaires, où le préfixe nomme la spécification qui l’enregistre.
Un validateur DOIT décoder et préserver les clés d’extension, NE DOIT PAS
rejeter un enregistrement au seul motif qu’elles sont présentes, et DOIT les
exposer à titre informatif sans prétendre en avoir vérifié le contenu. Les clés
d’extension font partie du corps signé, de sorte qu’une signature au niveau de
l’enregistrement les couvre — un relais ne peut pas injecter une clé d’extension
après que la signature a été produite. Toute clé de premier niveau inconnue qui ne
correspond à aucun des deux motifs (une coquille telle que supersedess, ou une
variante de casse telle que Sigs) est rejetée en tant que champ inconnu. La
tolérance fondée sur des motifs préserve la détection des coquilles sur l’ensemble de
base, tout en maintenant ouvert un réservoir stable pour de futurs ajouts.
Un producteur qui exige d’un vérificateur qu’il comprenne un champ non de base
DOIT lister le nom de ce champ dans l’array crit de premier niveau. Un
vérificateur v1 qui rencontre une entrée crit qu’il n’implémente pas NE DOIT
PAS signaler l’enregistrement comme valide. Chaque entrée de crit DOIT
correspondre au motif des clés d’extension (les clés de base sont interdites dans
crit), DOIT nommer un champ effectivement présent dans l’enregistrement et
DOIT être unique — de sorte qu’une marque de criticité soit toujours traçable
jusqu’à un champ concret dont le vérificateur est tenu de comprendre la sémantique.
Ces règles suivent les précédents must-understand / must-ignore de
RFC 9052 §3.1
(crit de COSE) et RFC 7515 §4.1.11
(crit de JWS).
Budget d’octets
Le seul plafond absolu sur la taille de l’enregistrement est le paramètre de
protocole Cardano maxTxSize en vigueur — 16 384 octets à la version majeure 10 du
protocole sur mainnet, sous réserve des mises à jour des paramètres du ledger. Label
309 n’impose aucun plafond au niveau du schéma en deçà de cette valeur. Les
enregistrements qui dépassent la limite sont rejetés par les nœuds Cardano au moment
de la soumission, de sorte qu’aucun vérificateur n’en voit jamais ; un validateur
NE DOIT PAS inventer un plafond propre à Label 309 en deçà de maxTxSize.
En pratique, la structure non liée aux métadonnées d’une transaction (entrées, sorties, témoins, champs de frais et de validité) consomme environ 245 octets, laissant de l’ordre de 16 Ko pour l’enregistrement du label 309. Les producteurs DEVRAIENT viser quelques centaines d’octets sous la limite afin d’absorber la variabilité des frais et DEVRAIENT calculer la taille de l’enregistrement candidat avant la soumission, en échouant tôt s’il ne devait pas tenir. Les formes réalistes qui tiennent sont généreuses : bien plus d’une centaine d’items à empreinte unique, des dizaines de signatures au niveau de l’enregistrement ou de nombreux emplacements de destinataires classiques tiennent confortablement dans une seule transaction — et une unique racine Merkle s’engage sur une liste de feuilles hors chaîne non bornée pour un coût fixe sur la chaîne de 32 octets.
Schéma CDDL
Le CDDL suivant est le schéma structurel du corps réassemblé de l’enregistrement
— les octets CBOR canoniques obtenus après concaténation de l’array de chunks de
≤ 64 octets stocké sous le label 309. Le corps réassemblé est du CBOR déterministe
ordinaire : il n’est pas lui-même un metadatum du ledger, et ses champs ne sont
pas soumis au plafond de 64 octets par chaîne, que l’enveloppe de transport du
corps entier satisfait à elle seule. L’enveloppe n’est pas modélisée ici.
Le bloc décrit le sur-ensemble permissif des formes bien formées ; les invariants
inter-champs (la règle items-ou-merkle, l’exclusivité slots ⊕ passphrase de
l’enveloppe de chiffrement, l’appartenance des identifiants d’algorithme à un
registre, les règles de forme d’emplacement par KEM) sont imposés par une passe de
validation typée sur la structure décodée, et non par le CDDL lui-même.
; An extension value is any CBOR value the canonical (deterministic) encoding
; profile admits. Floats and semantic tags are excluded by that profile (they
; are rejected as MALFORMED_CBOR on decode), so the exclusion is not repeated
; here; the reassembled body carries no field-level 64-byte cap.
extension-value =
{ * extension-value => extension-value }
/ [ * extension-value ]
/ int
/ bstr
/ tstr
/ bool
/ null
; A conformant record MUST carry at least one of `items` (>= 1 entry) or
; `merkle` (>= 1 entry); a record with both absent (or both empty) is rejected
; as SCHEMA_EMPTY_RECORD by the typed pass, not at the CDDL layer.
poe-record = {
poe-common,
? "items": [ 1* item-entry ],
? "crit": [ 1* tstr ],
* extension-key => extension-value
}
poe-common = (
"v": 1,
? "merkle": [ 1* merkle-commit ],
? "supersedes": bytes32,
? "sigs": [ 1* sig-entry ],
)
extension-key = tstr .regexp "^x-.+"
/ tstr .regexp "^[a-z]+-.+"
item-entry = {
"hashes": hash-map,
? "uris": [ 1* uri ],
? "enc": enc,
}
; A non-empty CBOR map keyed by a content-hash algorithm identifier with the
; 32-byte digest as value. Map-key uniqueness makes duplicate algorithms
; structurally impossible.
hash-map = { + content-hash-alg => bytes32 }
; A list commitment binds the record to an ordered leaf list. `leaf_count`
; binds the on-chain commitment to the off-chain list size.
merkle-commit = {
"alg": merkle-commit-alg,
"root": bytes32,
"leaf_count": uint32,
? "uris": [ 1* uri ],
}
; `enc` is a choice between the scheme-1 envelope shape and a bounded opaque
; envelope (the degrade-to-opaque rule for an unsupported scheme/kem/aead). The
; typed pass enforces the slots/passphrase exclusivity and the per-KEM
; slot-shape rules over a supported envelope.
enc = enc-scheme-1 / enc-opaque
; `scheme: 1` is not a version counter for the `enc` map alone: it names the
; ENTIRE sealed cryptographic suite — the canonicalEncode rules, the slot
; schema, the HKDF and HMAC hashes, the wrap AEAD, the segmented-STREAM content
; format, the transcript schemas, the in-ciphertext passphrase commitment, the
; pinned X-Wing revision, every domain-separation label, and the Argon2id and
; passphrase-normalization profiles. Changing any one of them requires a new
; `scheme` value; see Sealed PoE for the construction it pins.
enc-scheme-1 = {
"scheme": 1,
"aead": aead-alg,
"nonce": bstr,
? "kem": kem-alg,
? "slots": [ 1* slot ],
? "slots_mac": bytes32,
? "passphrase": passphrase-block,
}
; The opaque reading of an envelope under an unsupported identifier: `scheme`
; is the only structurally required key, and every other entry is any key/value
; pair the canonical profile admits, subject to the generic decode bounds.
enc-opaque = {
"scheme": uint,
* tstr => extension-value
}
slot = classical-slot / hybrid-slot
; enc.kem = "x25519": the per-slot X25519 ephemeral public key + wrapped CEK.
classical-slot = {
"epk": bytes32,
"wrap": bytes48,
}
; enc.kem = "mlkem768x25519": the 1120-byte X-Wing ciphertext plus the wrapped
; CEK. There is NO `epk` — the X25519 ephemeral is the trailing 32 bytes of the
; X-Wing ciphertext inside `kem_ct`.
hybrid-slot = {
"kem_ct": bstr .size 1120,
"wrap": bytes48,
}
passphrase-block = {
"alg": kdf-alg,
"salt": bstr .size (16..64),
"params": { "m": uint32, "t": uint32, "p": uint32 },
}
; A signature entry is a closed map. `cose_sign1` is REQUIRED and carries the
; CBOR-encoded COSE_Sign1 as a single byte string; `cose_key` is OPTIONAL and
; carries the CBOR-encoded COSE_Key for the wallet-signing path as a single
; byte string.
sig-entry = {
"cose_sign1": bstr,
? "cose_key": bstr,
}
; A uri is one absolute URI in a single text string. The URI shape rules
; (absolute, no fragment, closed scheme set {ar://, ipfs://}) are enforced in
; the typed pass; the rule carries no length cap.
uri = tstr
bytes32 = bstr .size 32
bytes48 = bstr .size 48
; uint32 is the pinned range of every numeric field: an unsigned integer
; representable in 4 bytes (0 .. 2^32-1), handled as an exact integer.
uint32 = uint .size 4
; Algorithm-identifier strings are open `tstr`: the registries are
; authoritative for accepted values, and the typed pass emits the precise
; unsupported-algorithm code for any unrecognised identifier.
content-hash-alg = tstr ; e.g. "sha2-256", "blake2b-256"
merkle-commit-alg = tstr ; e.g. "rfc9162-sha256"
aead-alg = tstr
kem-alg = tstr
kdf-alg = tstrPages associées
- Contenu et hachage — la map
hashes, ce sur quoi un condensé s’engage et la sémantique des octets exacts. - Registres d’algorithmes — les identifiants nommés des hachages, des engagements de liste, des AEAD, des KEM et des KDF.
- Signatures — la construction et la vérification de
sigsau niveau de l’enregistrement. - PoE scellée — l’enveloppe
encet les emplacements de clé de destinataire. - Vérification — le pipeline de validation, le profil CID et le catalogue d’erreurs.
Introduction
Ce qu’est Label 309, les principes qu’il garantit et comment quiconque peut vérifier un enregistrement sans faire confiance à un serveur.
Contenu et hachage
Comment Label 309 lie un enregistrement à son contenu : la table des empreintes, ce sur quoi l’empreinte porte son engagement et les engagements Merkle pour ancrer de nombreux éléments sous une seule racine.