Security model

What a Label 309 verifier trusts and what it does not — the standalone-verifiability invariant, the privacy guarantees of sealed PoE, the normative crypto rules every implementation must uphold, and the known limits of the wire format.

Label 309's security rests on one idea: a proof is something the relying party checks for itself. A verifier trusts the public Cardano chain and — for content claims — the bytes it is handed. It trusts nothing else: not the publisher, not a domain, not a server, not the operator of whatever gateway it happened to read the transaction through. Every guarantee on this page either follows from that stance, marks its boundary, or names a residual risk that lies outside it.

This page is the threat model for the standard itself: the trust model a conformant verifier operates under, the privacy properties of an unsigned sealed PoE, the cryptographic obligations every implementation MUST uphold, and the limits the wire format does not — and cannot — overcome. It does not describe any particular deployment's operational security; it describes what the format guarantees to anyone who implements it correctly.

The trust model

A relying party that checks a Label 309 proof is asking a narrow question: did these bytes exist on or before this block's time, and does this verdict depend on anyone's good behaviour besides Cardano's? The standard is built so the answer to the second half is always "no".

What a verifier trusts:

  • The public Cardano chain. The transaction, its metadata under label 309, and its block time are facts replicated across every Cardano node. A verifier reads them through a gateway of its own choosing and may cross-check several.
  • The content bytes, when checking a content claim. A digest in the record commits to a specific byte sequence. A verifier that holds those bytes recomputes the hash and compares; it does not take anyone's word that the bytes match.

What a verifier does not trust:

  • The publisher. Label 309 has no issuer field. Any wallet can publish any record; the record's validity is independent of who submitted it. A verifier never asks "is this publisher reputable?" — the question has no place in the model. See the issuer-agnostic invariant on Introduction.
  • A server or domain. No step of verification contacts a publisher-operated service. There is no canonical registry to consult, no status endpoint to poll, no identity authority to resolve a key against.
  • A gateway operator. The Cardano, Arweave, and IPFS gateways a verifier reads through are interchangeable and content-checked (below). A gateway is a transport, not a trust root.

Standalone-verifiability is the core security property

A Label 309 proof must remain checkable even if every party who created it disappears — the publisher, their server, their company. Given a transaction reference, a public Cardano gateway, and (for content claims) the bytes, any conformant implementation reaches the same verdict from the public chain alone. If a verification path silently needs a specific operator's cooperation, that path is non-conformant.

Why gateways are not a trust root

A verifier may read the same transaction through any Cardano gateway, and read the same content through any Arweave or IPFS gateway. None of these is trusted to return honest data, because what they return is independently checkable:

  • A gateway cannot forge a record that carries a valid signature — it does not hold the signer's private key, and the verifier recomputes the signed bytes and checks them itself. See Signatures.
  • A gateway cannot substitute content under a content-addressed URI without detection: an ipfs:// CID is a multihash the verifier recomputes from the fetched bytes, and an ar:// transaction id commits to the data under Arweave consensus. On a conformant item, the on-chain hashes map is a second, independent binding to the plaintext, recomputed at fetch time.
  • A gateway that withholds a transaction or misreports how deeply it is buried is a denial-of-service shape, not a forgery shape. A verifier that reads through more than one gateway and aborts on disagreement turns "one dishonest gateway" into "collusion across every gateway it chose" — which it controls.

Block depth — how many confirmations a verifier demands before treating a record as settled — is verifier policy, not a value Label 309 mandates. The standard fixes no numeric depth; a relying party sets a threshold for its own risk tolerance. See Verification.

Privacy properties of sealed PoE

A sealed PoE keeps a plaintext confidential while still anchoring its timestamp. Beyond confidentiality, the construction is designed so the chain leaks as little as possible about the message and nothing about its audience. These are wire-format guarantees: they hold for any correct implementation, because they are properties of the bytes, not of any deployment.

Sender anonymity for unsigned sealed PoE

An unsigned sealed PoE — a record carrying enc and no sigsMUST NOT disclose the sender's identity on chain. Its on-wire bytes MUST be independent of the sender's long-term keys.

This holds structurally:

  • No signer key on the wire. A sender's identity key reaches the chain only through a sigs entry. A record with no sigs carries no signer-side byte at all. Authorship is opt-in; anonymity is the default.
  • Fresh per-slot ephemerals. Each recipient slot carries a per-record, per-slot ephemeral public key, freshly generated at seal time. It is unrelated to the sender's long-term key and reveals nothing that links records to a common author.
  • Shuffled slots. The slot array is shuffled with a CSPRNG before publication, so positional ordering ("primary recipient first") carries no signal.

A producer who later signs a record discloses their identity key in that record only; it appears in no earlier unsigned record, and no operation maps the earlier records' ephemerals back to the author. Opting into authorship is a forward act, not a retroactive deanonymisation.

This invariant covers only the label-309 record bytes. The fee-paying Cardano address in the transaction inputs, the producer's network-level identity as seen by a gateway, and any metadata in the off-chain ciphertext blob are outside the wire format — Label 309 lives in the metadata, not in the transaction inputs, and cannot defend against fee-payer correlation. A producer who needs fee-payer anonymity must address it at the transaction-construction layer.

Recipient unlinkability

A sealed record never names its recipients. A recipient recognises a message as theirs only by successfully trial-decrypting a slot; there is no addressee field to read. From this:

  • Recipients cannot see each other. Each slot is an independently wrapped key. A recipient who opens their own slot derives nothing about any other slot and cannot tell who else was addressed.
  • No recipient public keys on the wire. Only the ephemerals and the wrapped keys appear. An observer cannot enumerate recipients — only count slots.

Plaintext-binding

The on-chain digest commits to the plaintext, not to the ciphertext. A recipient who decrypts a sealed PoE recomputes the plaintext hash and compares it to the on-chain hashes map. This means a storage layer that serves a tampered ciphertext is caught after decryption, independent of the URI's own integrity model — the timestamp claim is a claim about the plaintext the sender committed to, and nothing the gateway does can satisfy it with different bytes.

Rebroadcast independence

A record's signatures are fixed at the moment its transaction is submitted. The chain has no notion of an "extended signer set" accumulating across transactions.

Rebroadcasting an identical record body in a separate transaction with a different sigs set creates a separate, independent record at its own block time — never an extension of the original.

A party who wants to endorse an already-published record publishes their own record — referencing the same content, or pointing at the prior transaction via supersedes — signed by their key. They do not append a witness to someone else's record. Consequently, an attacker who copies a signed record's bytes into a fresh transaction does not become a co-signer of the original: they produce a later, duplicate claim with whatever sigs they chose, and the original's earlier block time remains the canonical record of existence. Verifiers and indexers MUST NOT collapse two transactions with identical record bodies into a single "merged signers" view; doing so would falsify the per-record block-time semantics downstream consumers rely on.

Normative rules for implementations

The following are security-normative for any conformant implementation, regardless of language or platform. RFC 2119 / RFC 8174 keywords are used in the normative sense.

RuleObligation
No novel cryptographyEvery primitive is a documented IETF / NIST / W3C standard from an audited library. No hand-rolled ciphers, KDFs, signature schemes, or stanzas.
Authenticated encryption onlyAll symmetric encryption is AEAD. A tag-verification failure MUST raise a typed error; it MUST NOT silently return partial plaintext.
Constant-time secret comparesCompare MAC tags, AEAD tags, and any secret-derived bytes in constant time. A data-dependent compare on these surfaces is an authentication oracle.
Strict Ed25519 verificationVerify signatures in canonical (strict) mode. A cofactored / lax verifier accepts edge-case signatures a strict verifier rejects and disagrees with the reference.
Never log secrets or plaintextKey material, derived keys, and decrypted plaintext MUST NOT appear in logs at any level. Byte-typed values are redacted unconditionally.

No novel cryptography

Label 309 deliberately admits only well-analysed primitives, each named in the algorithm registries and implemented by an audited library. An implementation MUST NOT introduce a custom symmetric cipher, KDF, signature construction, or key-wrapping stanza. The wire format is a composition of standard parts precisely so its security reduces to the security of those parts.

Authenticated encryption only

Every symmetric encryption in Label 309 — the content layer and the per-slot key wrap — is AEAD. There is no unauthenticated cipher mode anywhere in the format. A decryptor whose AEAD tag check fails MUST surface a structured error with a stable code discriminator and MUST NOT fall through to return unauthenticated bytes. The additional authenticated data is part of the tag computation, so a wrong AAD fails identically to a wrong key — there is no partial-success state to probe.

Constant-time comparison of secrets

A comparison loop whose running time depends on secret bytes is an oracle. Every equality check over a secret or a MAC/AEAD tag MUST be constant-time:

  • The slot-set MAC and any HMAC tag — a per-byte timing leak on a 32-byte MAC can, under adversarial repetition, recover the tag.
  • AEAD tag verification — the underlying library's decrypt already returns failure without revealing which byte mismatched; implementations MUST NOT re-implement this check.
  • Signature verification — use the library's verify, never a hand-rolled equation.

A bare == / === on byte arrays touching any of these surfaces is a defect. Routing every such comparison through a single typed helper makes the property auditable.

Strict Ed25519 verification

Label 309 signatures MUST be verified in strict (canonical) mode. A lax, cofactored verifier accepts certain malleable or low-order-key signatures that a strict verifier rejects, which would let two conformant implementations disagree on the same record — breaking the single-verdict property the whole standard depends on. The cross-language conformance corpus pins a low-order test vector exactly to catch a verifier that has slipped into lax mode. See Signatures.

Never log secret material

Seed bytes, derived private keys, key-encryption keys, content-encryption keys, passphrase-derived material, and decrypted plaintext MUST NOT reach logs at any level. Path-based redaction in a logger config is necessary but not sufficient on its own: a value nested deeper than the redaction glob reaches can slip through, so implementations MUST also treat every byte-typed value (Uint8Array, bytes, and the like) as opaque-redacted unconditionally, even for protocol-public values like a nonce. The cheapest secret to protect is the one that never enters a log line.

Algorithm agility as a security property

Every cryptographic choice in a Label 309 record is named by a string from an extensible registry — the hash, the AEAD, the KEM, the KDF, the signature scheme. This is not a stylistic choice; it is the migration substrate that lets the format outlive any single algorithm.

If a primitive is weakened by cryptanalysis:

  1. The relevant registry gains a successor identifier. Nothing in the existing format changes — the new name is additive.
  2. Existing records stay valid. A verifier continues to recognise the old identifier for historical records; their block-time claims do not evaporate because a newer algorithm exists. An implementation MAY surface a record that relies only on a since-weakened algorithm as lower-assurance, but MUST NOT erase or reject it on that basis alone.
  3. New records publish under the successor. A producer who wants defence in depth MAY commit a content hash under two algorithms from distinct design families, so a single-family break does not collapse the record's evidentiary value — though single-algorithm records remain fully conformant.

Because identifiers are strings and the registries are open, migrating to post-quantum hashes, KEMs, or signatures is an additive registry change, never a breaking format revision. The hybrid post-quantum KEM already in the registry is an instance of this property in action, not a special case bolted on.

Known limits of the standard

These are not defects to be fixed in a later revision; they are inherent properties of anchoring proofs on a permanent public ledger and of public-key encryption to long-term keys. An honest security model names them.

On-chain permanence

Cardano metadata is permanent and globally replicated. A published Label 309 record cannot be deleted, redacted, or invalidated — that durability is the entire point of proof of existence. The consequence is a publishing-time responsibility: a content hash, a stake-linked signature, or anything else committed under label 309 is on chain forever. Label 309 deliberately omits free-form descriptive metadata from the record to keep the on-chain footprint minimal, but a producer MUST understand that what they publish is irrevocable before they publish it.

Recipient count is visible

A sealed PoE hides who its recipients are, but the number of recipient slots is the array length, plainly visible on chain. Recipient public keys are hidden by trial-decrypt and slots are shuffled, but count-hiding padding is not part of the v1 baseline. A sender for whom the recipient count is itself sensitive must account for this metadata leak operationally — for instance by padding the slot set themselves, or by publishing separate records.

No per-recipient revocation

There is no on-chain primitive to revoke a single recipient's access to an already-published sealed PoE. Once a record is encrypted to a public key and anchored, that binding is permanent. This is an inherent property of public-key encryption to a long-term key, not a gap in the format. A key believed compromised is handled going forward — by addressing new records to a fresh key, optionally publishing a superseding record as a caveat-emptor signal — never by reaching back to alter what is already on chain.

No recipient forward secrecy, by design

The holder of a recipient private key can decrypt every sealed PoE ever addressed to it, forever. The off-chain ciphertext is permanent and there is no revocation primitive, so a sealed record is private from the world but not from its recipient. This is the expected behaviour of encrypting to a long-term public key. A sender who needs to limit a recipient's future reach must encrypt to a short-lived recipient key rather than a long-term identity key — a sender-side choice the format permits but does not mandate.

Trial-decrypt failures leak no key material

A recipient discovers their slot by trial-decryption, and the failure paths are distinguishable by error type — "no slot opened under my key", "a slot opened but the slot-set MAC failed", "the content AEAD failed". These distinct codes aid debugging and carry no oracle value: an adversary without a matching private key opens no slot at all, and every error path MUST exclude the underlying secret bytes (shared secret, key-encryption key, content-encryption key) from its message and cause chain. Knowing which check failed reveals nothing an attacker can act on; knowing the bytes would — so the bytes never appear.

  • Introduction — the five invariants, including issuer-agnostic and standalone-verifiable.
  • Signatures — strict Ed25519 verification and the fail-soft authorship model.
  • Sealed PoE — the encryption envelope and the privacy properties summarised here.
  • Algorithm registries — the named identifiers that make algorithm agility possible.
  • Verification — the pipeline, confirmation-depth policy, and error catalogue.