Algorithm registries
The named-identifier registries for hashes, AEADs, KEMs, KDFs, and signatures — and the agility rule that makes post-quantum migration additive rather than breaking.
Every cryptographic choice in Label 309 is named by a string identifier drawn
from an extensible registry — sha2-256, xchacha20-poly1305, EdDSA, and so
on. A record never carries a raw algorithm number or an implicit assumption; it
states which primitive it used, and a verifier looks that identifier up. This is
the mechanism behind the algorithm-agile invariant: the registries can grow
over time, and a verifier that meets an identifier it does not implement
rejects the record with a stable, typed error — it never crashes, and it
never silently accepts something it cannot check.
That single rule is what makes the migration to post-quantum algorithms additive. A new identifier is a new row in a table, not a new version of the wire format. Older records keep verifying exactly as before, and older verifiers fail closed against records they were never built to understand.
Two standing rules
Across every registry, two constraints are absolute. Implementations MUST NOT invent novel cryptography — every primitive traces to a named public standard. And all encryption MUST be authenticated: only AEAD constructions are permitted, never an unauthenticated cipher with a bolt-on (or absent) integrity check.
Hash
The content hash is the primary claim of every record, so the hash registry is the most load-bearing. Both registered functions produce a 32-byte digest, and both are mandatory for a conformant implementation to support.
| Identifier | Algorithm | Digest |
|---|---|---|
sha2-256 | SHA-256 (FIPS 180-4) | 32 B |
blake2b-256 | BLAKE2b-256 (RFC 7693) | 32 B |
A producer MAY hash the same content under both functions for defense in depth; a single hash is sufficient for a valid record.
Merkle commitment
For committing to an ordered list of leaves under a single on-chain root, Label 309
registers one Merkle-commitment identifier. It is the IANA-registered string for
the SHA-256 binary Merkle tree, sharing the leaf-prefix (0x00) and
internal-node-prefix (0x01) domain separation that prevents leaf/node
collisions.
| Identifier | Algorithm | Root |
|---|---|---|
rfc9162-sha256 | RFC 9162 binary Merkle tree, SHA-256 | 32 B |
A single-leaf tree commits to SHA-256(0x00 ‖ leaf), not to the bare leaf —
so a one-file proof MUST use a plain hash identifier, never a 1-leaf tree.
AEAD
The AEAD registry governs which authenticated cipher protects a sealed payload on
the wire. The on-wire content cipher is xchacha20-poly1305: its 24-byte nonce
makes random nonces safe even across high-volume key streams, which is why it is
the v1 default.
| Identifier | Algorithm | Key / Nonce / Tag | Status |
|---|---|---|---|
xchacha20-poly1305 | XChaCha20-Poly1305 | 32 B / 24 B / 16 B | Mandatory — the wire AEAD |
aes-256-gcm | AES-256-GCM | — | Reserved (future profile) |
xchacha20-poly1305 is the only identifier that may appear as the on-wire
content AEAD. A separate cipher, chacha20-poly1305 (RFC 8439, 32-byte key /
12-byte nonce / 16-byte tag), is used internally to wrap a per-recipient key
inside the sealed construction — it is a building block, not a wire identifier,
and a record that names it in its content-AEAD slot MUST be rejected. aes-256-gcm
is named but inactive; it is reserved for a future encryption profile and a v1
verifier rejects any record that selects it.
KEM
The KEM registry covers the key-encapsulation mechanisms used to address a sealed payload to specific recipients. Label 309 registers a classical curve KEM and a post-quantum hybrid that ships active from the first release.
| Identifier | Algorithm | Public key / Secret | Ciphertext / Shared secret |
|---|---|---|---|
x25519 | X25519 ECDH (RFC 7748) | 32 B / 32 B | 32 B / 32 B |
mlkem768x25519 | X-Wing hybrid (ML-KEM-768 + X25519) | 1216 B / 32 B | 1120 B / 32 B |
mlkem768x25519 is the X-Wing construction from the CFRG X-Wing draft: it pairs
ML-KEM-768 with X25519 so that an attacker must break both to recover the
shared secret. The public key is the ML-KEM-768 encapsulation key concatenated
with the X25519 public key (1184 B ‖ 32 B = 1216 B); the secret is a 32-byte seed
from which the full key is derived. Each recipient's ciphertext is the ML-KEM-768
ciphertext concatenated with an ephemeral X25519 public key (1088 B ‖ 32 B =
1120 B), and the two shared secrets are combined with SHA3-256 into the final
32-byte secret. The identifier is written without internal hyphens to match the
established X-Wing spelling.
The hybrid is selected per-record by the encryption header, independently of the content AEAD. Because it is already registered, post-quantum confidentiality is a matter of choosing the identifier — not waiting for a new wire-format version.
KDF
The KDF registry names the key-derivation functions. hkdf-sha256 derives keys
inside the sealed construction; argon2id stretches a human passphrase against
brute force and carries a mandatory parameter floor.
| Identifier | Algorithm | Parameters |
|---|---|---|
hkdf-sha256 | HKDF-SHA-256 (RFC 5869) | salt (optional), info (optional), output length |
argon2id | Argon2id (RFC 9106) | memory ≥ 65536 KiB, iterations ≥ 3, parallelism ≥ 1 |
The Argon2id floor is normative: a passphrase-protected payload MUST use at least 64 MiB of memory, at least three iterations, and at least one lane. A producer MAY choose stronger parameters, and they travel with the record so a verifier can reproduce the derivation.
Signature
Label 309 registers one signature algorithm. Authorship signatures are always
optional, but when present they are carried as COSE_Sign1 (RFC 9052) using
Ed25519.
| Identifier | COSE alg | Algorithm | Wrapper |
|---|---|---|---|
EdDSA | -8 | Ed25519 (RFC 8032) | COSE_Sign1 (RFC 9052) |
Verification is strict per RFC 8032 §5.1.7: implementations MUST reject non-canonical signature encodings and small-order points (no cofactor-clearing extension). This matches the conservative acceptance criteria used across Cardano wallets, so a signature that verifies under one conformant implementation verifies under all of them.
Signature support is independent of the content claim. A verifier that does not implement a record's signature algorithm marks that signature slot as unsupported and leaves the timestamp and content claims fully valid — an unknown signature algorithm never invalidates the record itself.
Reserved identifiers
Several identifiers are named but not yet active. They mark the agreed migration path so that future profiles use stable, pre-committed names rather than ad-hoc strings. A conformant producer MUST NOT emit them, and a conformant verifier MUST reject any record that uses one, with the matching typed error.
| Identifier | Algorithm | Role |
|---|---|---|
aes-256-gcm | AES-256-GCM (NIST SP 800-38D) | Content AEAD |
ml-kem-768 | ML-KEM-768 (FIPS 203), standalone | KEM |
ml-dsa-65 | ML-DSA (FIPS 204) | Signature |
slh-dsa-sha2-128s | SLH-DSA (FIPS 205) | Signature |
ml-kem-768 is the bare post-quantum KEM, distinct from the registered hybrid
mlkem768x25519; the hybrid is what Label 309 ships, on the principle that a
classical fallback should remain even after the post-quantum half is added.
Algorithm agility and migration
Adding an algorithm is a self-contained, additive operation: cite a public standard for the primitive, add the identifier to the appropriate registry, provide a vetted, well-reviewed implementation of it, and publish a cross-language conformance fixture so independent implementations agree byte-for-byte. The wire-format version does not change, because the schema does not change — only the set of recognized strings grows.
The consequences follow directly from the registry design:
- Old records stay verifiable. Their identifiers are still in the registry, so every existing record verifies exactly as it did the day it was published.
- Old verifiers fail closed. A verifier that predates a new identifier
rejects records using it with a stable
UNSUPPORTED_*error rather than guessing — there is no path to silent acceptance. - Post-quantum support is additive. Because
mlkem768x25519is already registered, and because new KEMs and signatures slot into the same mechanism, the post-quantum transition is a registry growth, not a breaking migration.
A wire-format version bump is reserved for genuinely breaking schema changes — a new required field, a removed field, a changed type. Registry growth never qualifies, which is precisely what lets the cryptographic catalogue evolve without ever stranding a published proof.
Content & hashing
How Label 309 binds a record to its content — the hashes map, what the digest commits to, and Merkle commitments for anchoring many items under one root.
Keys
The Label 309 key model — one 32-byte seed, three algorithm keypairs derived from it by domain-separated HKDF-SHA-256, and how recipient public keys are encoded and exchanged.