21 KiB
DateKeys v0.15: threat model, goals and non-goals
Informative English summary of spec §3, §4, §5, §7, §36.1, §55, §55.1 and §55.2 of DateKeys_Protocol_Specification_v0.15.md, with §45 to §50 and §79 where they concern recovery and the clock. The Spanish text is the reference. Additions of v0.14 are marked (v0.14), those of v0.15 (v0.15).
1. Guiding principle (§3)
Never trust the server when the same property can be verified cryptographically on the client:
- date → condition is computed locally;
- provider profiles are pinned locally;
- releases are verified locally, whatever their source: a relay, the Release API, a cache service, an archive or a copy in the caller's hand (v0.15: §47.1, §49, §50**)**;
.dkc,.dkk, APIs and relays are untrusted inputs;- DateKeys must not need the plaintext or final access secrets.
2. Security goals (§4)
- Time confidentiality. Under the provider's assumptions, a time condition cannot be satisfied before the chosen moment.
- Confidentiality from the operator. DateKeys does not need the plaintext or the final access credential.
- Local verifiability. The SDK detects tampered conditions, profiles and releases.
- Integrity. Changes to the framing, header, control or payload cause failure.
- Interoperability. Independent implementations produce and consume compatible objects.
- Independent recovery. If the provider keeps or can serve the release, (v0.15) or a release archive or a cache service keeps it (§50), the ciphertext is still available and the credentials exist, a mature object should open without the DateKeys API, (v0.15) and even without DateKeys software (§79).
- Extensibility. New providers and extensions do not redefine old objects.
- Metadata privacy. Before the date, a format 2 or 3 capsule does not reveal the exact content length or the number of credentials. Format 3 also hides paths, sizes, hashes, dates, comment, declared author and the number of files beyond the bound given by the padding (§55.2).
- Optional authenticity. A format 3 capsule may carry signatures from one or more signers and a time seal. The opener can check that those signers signed this content for this control and, with a seal, that the signature existed before the capsule could be opened (§29.8 to §29.11). Without a signature, a capsule proves no authorship (§36.1).
The completeness review of 29 September 2026 noted that these goals are informal; there is no formal security model or proof (see scope_and_questions.md).
3. Non-goals (§5)
The base protocol does not guarantee:
- the perpetual existence of Quicknet;
- the perpetual preservation of the release history;
- post-quantum resistance of the V1 timelock;
- revocation of a copy already distributed;
- absolute anonymity;
- hiding the unlock date, the access policy,
capsule_idor the padded content size (§55.2); - legal authorship through metadata;
- evidential creation date, except existence before an instant proven by a time seal (§29.11);
- legal validity of a certificate signature: trust in its chain, revocation and qualification are for an external validator (§29.10);
- protection against an already compromised device;
- control of the plaintext after a legitimate decryption;
- (v0.14) that a capsule will open: before the date nobody, the recipient included, can check that its content is what is claimed, that a credential opens it, or that it was written so that it can open (§36.1). A capsule alone cannot prove a bid, a prediction or a commitment before the date;
- (v0.14) expiry: an opened capsule does not close, and its content is not erased after the date;
- (v0.14) conditions other than a round: an event, a vote or the absence of a signal;
- (v0.14) cancellation: the creator cannot prevent or delay opening at the date.
Out of scope (§6): where a .dkc is stored, how it is discovered or distributed, availability policies, external naming, delivery of a .dkk, the .dkc file name and its file-system dates.
4. Adversaries (§7)
4.1 DateKeys server (§7.1)
May try to return a past round, a fake profile or invalid releases; correlate queries; serve stale data; keep copies of the ciphertext. Defences: local round resolution and the past-round check (§15, §17), the pinned profile (§12, §13), local BLS verification (§51), the Release API being keyed by round and not by capsule (§45). (v0.15) The Release API answers with the release object (§47.1), and its user is a network source that verifies every answer and discards a bad one (§45, §49); the object carries no "verified" flag, which would have no value (§51). No DateKeys service offers the Release API today; the implementations fetch releases from drand relays (§45).
4.2 Relay, MITM, DNS (§7.2, §52)
May spoof endpoints, modify, delay or deny responses. Controlling DNS, TLS termination or a relay must not allow a valid release to be forged while the root of trust is pinned, the expected condition is computed locally and the signature is verified (§52). Availability is not protected; the implementation SHOULD support several independent relays (§48).
4.3 Holder of a .dkc (§7.3)
May modify, truncate or reorder bytes; swap headers, controls or payloads; change the declared policy; attempt downgrade; build a format 3 capsule with paths that escape the reader's folder or collide on extraction, confusable names, a head that exhausts memory, or a comment that imitates a verdict; put in the public note a text that imitates a verdict, an author or a warning, or change it after writing. Defences: header_binding (§26), the I_PAYLOAD binding (§30.1), the stanza cardinality rules (§27), the version of CONTROL_CBOR against the format (§31, §70), the path and text rules (§29.5, §29.6), presentation rules (§29.7, §24.1), the mutation corpus (§64).
4.4 Holder of a .dkk (§7.4)
Must be treated as holding a sensitive capability. The .dkk is 32 raw bytes with no MAC or signature (§38, §55.1).
4.5 Supply chain (§7.5, §59)
A compromised SDK or dependency can replace the root of trust, accept false conditions, exfiltrate secrets or weaken the cryptography. §59 lists SHOULD measures: pinned crypto dependencies, SBOM, signed releases, published hashes, signed profiles, reproducible builds, fuzzing, published vectors, and an external cryptographic review of v1.0.
4.6 Provider (§7.6, §50) (v0.14; recovery v0.15)
A time_only capsule depends on a single provider (Quicknet in V1) and has no other way to open: no DateKeys key, recovery or service opens it before or after the date. Two separate things depend on the provider:
- Confidentiality until the date. If as many drand members as the threshold requires collude, or their key shares end up in the same hands, a future round can be signed early, and with it every capsule of that round or earlier can be opened before the date.
- Opening after the date. If the network stops signing before a capsule's round, nobody can ever open it. If it signs the round but nobody keeps the release, opening depends on finding it (§50).
A time_and_key capsule adds a credential the provider does not have: an early signature of the round is not enough, but a missing round leaves it just as closed (§36.1). The official SDK SHOULD recommend it for long horizons or valuable content. A pinned profile is identified by its profile_hash; a provider that changes key, period or chain is another profile, and existing capsules still depend on the old one.
(v0.15) Long-term recovery. The release is the only thing a capsule needs that does not exist when it is sealed: it is published at round_time. Once the round is signed, opening years later depends on someone keeping that release. v0.15 places long-term recovery on release archives with all rounds of the chain and on cache services, from DateKeys or others, that keep and serve the releases of all rounds continuously (§50). Whoever serves a release need not be trusted: for one round and one public key there is a single valid BLS signature, checked against the pinned profile at step 10 (§47.1). What v0.15 does not change:
- if the network stops signing before a capsule's round, nothing opens it; archives keep only rounds that were signed;
- the specification promises no published archive or cache service and says nothing about hosting; a project archive or service is future work (§74). Today a capsule whose round is signed depends on drand relays keeping it, or on whoever keeps an archive;
- the release archive format is informative (§50), with no error codes of its own;
- an archive that keeps only the rounds of known capsules would reveal their dates, and is not recommended (§50);
- the official SDK SHOULD warn when sealing that opening years later needs the
.dkc, the.dkkintime_and_key, and the release, and SHOULD keep the recovery annex next to the.dkc(§53, §62.1 rules 26 and 27).
The rejected alternative, a .dkr release file kept next to each capsule, did not cover the case that matters, someone opening decades after the date when nobody kept anything for that capsule (§76, v0.15 change 4).
Profile registry states (§71, v0.14): activo (write and open); solo lectura (no new capsules; existing ones still open); comprometido (evidence that confidentiality failed; existing capsules still open; the SDK SHOULD warn that the content may have been read before the date). A published entry is never removed.
4.7 Future quantum adversary (§7.7, §53) (v0.14 extended)
- The Quicknet V1 timelock is not post-quantum; there is a harvest-now, decrypt-later risk for long-lived ciphertexts.
- (v0.14) Neither are the X25519 recipients (§37), the Ed25519, ECDSA and RSA author signatures (§29.9, §29.10), or the signatures of time-stamping authorities (§29.11). Over a long horizon, a quantum adversary could forge after the date a signature and a seal that verify, with a time before the round: a verdict F3, F4, F6 or S4 read decades later proves less than the same verdict read soon. Archive re-seals (RFC 4998) are outside the capsule.
- §55.2: decoy indistinguishability rests on Diffie–Hellman in X25519 and does not resist a future quantum adversary, who could recover ephemeral scalars and test candidate public keys.
- The official SDK SHOULD warn about long horizons (§53). A post-quantum access type is future work (§74).
4.8 Creator's device (§7.8)
If compromised before or during encryption, the protocol cannot prevent copying of the plaintext or secrets. §55.2 adds that nobody can check that a writer discarded decoy private keys: a compromised SDK or device could keep one as a hidden credential.
4.9 Signers and time-stamping authorities (§7.9)
With a signature or seal in format 3:
- whoever steals a signer's secret key can sign in their name; a signature with a key of one's own does not prove who holds the key;
- a writer can create two different capsules with the same
capsule_id, both signed (equivocation); the creator can publishcapsule_digestbefore the date against it (§43); - whoever can open a capsule can remake it after the date with another area, without a signature or with another; only a seal earlier than the round proves a signature existed before the date;
- a dishonest or compromised TSA can misdate its seals; the protocol does not audit it, and the verdict names it;
- the external signing application receives AUTHOR_MESSAGE, which does not reveal the content; a compromised page or fake signing application can obtain a signature for a capsule the signer has not seen; a co-signing organisation that signs only AUTHOR_MESSAGE never sees the content. The AUTHOR_MESSAGE code lets the signer compare what is signed with what DateKeys shows;
- a signer may sign under coercion, and the signature does not show it;
- a stolen author key cannot be revoked: a reader that saved it keeps showing its label;
- DateKeys does not check who issued a certificate or a seal: anyone can make a certificate in another's name or a seal with any date; an official validator checks them with the evidence the capsule keeps.
4.10 Web client (§7.10, §59) (v0.14)
A client the browser downloads on each visit, such as a page that encrypts or opens capsules, can be replaced by whoever serves the page, controls its domain or compromises its build. A replaced client can copy the content, the credentials and the words of a key before encrypting or after opening, or write a capsule that will not open. No format rule detects it: the capsule it writes is valid. §59 asks (SHOULD) for reproducible builds with published hashes, Subresource Integrity on every script, a content policy that loads no code from another origin, and the same client usable offline.
4.11 The reader's local clock (§17, §49, §63 step 9.c) (v0.15)
Not an adversary section of §7, but a change of v0.15 in what the clock decides:
- Before v0.15, step 9.c refused to open when the local time was before the DateKey's
round_time, even with a release that step 10 would verify. - Since v0.15, 9.c applies only before a network request: a network source is not asked before
round_time(the reasons are network ones: no useless or observable requests, fail early). The person MAY expressly ask for the request anyway, because the clock may be wrong. - A release in hand (a release object or drand's JSON from a file, or the entry of a local archive) is not compared with the clock; the reader MAY warn that its clock may be behind. A valid signature of a future round exists only if the provider is compromised (§7.6), and then the clock no longer protects confidentiality. The clock had been vetoing a verifiable release on a local value nobody can verify (§3), for example on a machine with a dead CMOS battery or a virtual machine (§76, v0.15 change 3).
- Whatever the clock says, opening still needs the signature of the round, verified at step 10 against the pinned key (§51).
- The writer's clock is unchanged: a writer with a clock running late can still seal to an already published round (§62.1 rule 2, section 8).
5. Authenticity semantics (§36.1)
time_onlyprovides no creator authenticity, before or after maturity, unless an author signature (§29.8) or a signature extension adds it.- Forgery is possible from creation time: encrypting to a future round needs only the profile's public key and the public condition. header_binding is computed from public bytes only. A third party can build another CONTROL_CBOR with a correct header_binding, its own I_PAYLOAD and PAYLOAD_AGE, and seal it to the same DateKey without waiting.
- So
capsule_id, the DateKey and header_binding give internal coherence, not authorship. time_and_keyadds an access barrier: a third party without the required identity cannot open INNER_ACCESS_AGE, even with an early round signature from a compromised provider (§7.6). It does not replace a creator signature.- Decoys add no access barrier and no authenticity.
- In format 3, the declared author is creator text. A valid signature proves that its signers signed this content for this control, not who created the
.dkc: after the date, whoever can open the capsule can remake it without the signature or with another. Only a seal earlier than the round proves the signature existed before the date.
6. Auxiliary integrity and trust per section (§55, §55.1)
Public hashes MAY be used for identification, caching, deduplication, audit and UX; they do not replace the age header MAC, X25519 wrapping, tlock, STREAM authentication or header_binding (§55).
§55.1 is normative: an implementation MUST NOT present a section as proof of something its "never proves" column excludes, unless a valid signature or seal of security, or a signature extension, covers it.
| Section | Who can write it | Bound from step, by | Never proves |
|---|---|---|---|
| PRELUDE and PUBLIC_HEADER | Anyone with the .dkc: in clear, no key protects them |
Step 15: header_binding inside CONTROL_CBOR covers their exact bytes. Steps 1–8 check only structure | Authorship or creation date. Before step 15, not even coherence with the control |
| CONTROL_CBOR | Anyone can seal a control to the DateKey (only the profile's public key is needed). In time_and_key, one that a given credential opens only someone who knows its recipient's public key |
Step 11: age MAC and STREAM of OUTER_TIME_AGE (and INNER at step 13) against whoever does not know the file key. Step 15: header_binding | That the creator of PUBLIC_HEADER wrote it. After opening, whoever knows FK_TIME or FK_ACCESS can rewrite it |
| PAYLOAD_AGE | Whoever knows R_PAYLOAD: before opening, only the sealer of the control; after, anyone who obtained I_PAYLOAD | Step 17: I_PAYLOAD unwraps FK_PAYLOAD; MAC and STREAM authenticate every byte. Formats 2 and 3: L and the code fix length and padding | Authorship; that it is still the original payload after someone opened the capsule; that L is the original length (another L of the same P can be declared) |
| Format 3 content: security, head, files | Whoever writes PAYLOAD_AGE | Step 17: MAC and STREAM of PAYLOAD_AGE; the head fixes size and SHA-256 per file | Authorship or date: declared author, comment, paths and mtimes are creator text. security proves only what its verdicts say |
.dkk body |
Anyone with the .dkk: no MAC or signature |
Step 9.a: its capsule_id must equal the header's (a public value); its capsule_digest, if present and checked, binds it to exact .dkc bytes. Step 13: access_material opens INNER only if it is one of its recipients |
That the capsule creator issued it. Its extension data is bound to nothing |
A security decision of the reader (authorisation, identity, integrity or date) cannot rest on PUBLIC_HEADER or a .dkk without a signature covering them.
7. Privacy (§55.2)
Formats 2 and 3 (format 1 reveals more):
- Visible to any holder, before and after the date: VERSION, PUBLIC_HEADER_LEN, SEALED_CONTROL_LEN;
capsule_id; the DateKey (profile, round, unlock instant);access_policy; PUBLIC_HEADER extensions with their data, the public note included; the tlock stanza (round and chain hash); the PAYLOAD_AGE header and its length, which gives P exactly; the length of CONTROL_CBOR (103 bytes plus extensions), which does not depend on L or the number of credentials. In format 3 with a 32 KiB area and few files, P also bounds the number of files: n ≤ (P − 32835)/45, at most 44 files with P = 34 816. P sometimes reveals thebloque256code. - Hidden until the date: the content and its exact length L; the padding code (except what P reveals); I_PAYLOAD and all of CONTROL_CBOR; in format 3,
security, the head and the files; intime_and_key, the number of credentials and the INNER header. - After the date:
time_only: anyone reads everything.time_and_key: anyone sees the INNER header with 16 stanzas; CONTROL_CBOR and the content stay hidden from those without a credential; a credential holder learns which stanza is theirs but not which of the other 15 are decoys; several credential holders together learn only a lower bound on the number of credentials. - Never visible (under Diffie–Hellman in X25519): the recipients; whether a stanza is a decoy; whether a portable
.dkkexists; the number of credentials beyond the lower bound above. - Signature and seal: before the date, whether a capsule is signed is hidden while it uses the common 32 KiB area; a 64 KiB area reveals it; a v0.10 capsule with a 512-byte area reveals it carries no seal when P is small. Signers and TSA names are visible after the date (to anyone in
time_only), including a signer's national identifier in the certificate. OCSP requests, often over unencrypted HTTP, reveal the certificate serial number; a writer that uses an intermediary for OCSP or the seal MUST declare it. - Outside the
.dkc: a.dkkcarries the credential in clear, pluscapsule_id,credential_id, the optionalcapsule_digestand extension data;datekeys.capsulecarries the note and the date in clear and the locator encrypted to the date; the host of an envelope rest sees random bytes and their size; fetching a release reveals the profile, round and requester address to the API and relays, notcapsule_id; (v0.15) the same holds for a cache service and a remote archive (read, for example, with an HTTP range), which are network sources, while a local archive or a release in hand reveals nothing (§49, §50). - Format 1: SEALED_CONTROL_LEN grows 98 bytes per INNER stanza, and the PAYLOAD_AGE length gives L exactly.
8. Things the specification already says are not checked
These are stated limits, not findings:
- Before the date nobody can check that a capsule will open (§5, v0.14).
- Nobody can check that decoy private keys were discarded (§55.2).
- The locator is not authenticated against whoever wrote the
.dkk(§44.1). - A writer with a clock running late can seal to an already published round; comparing with the last published round is only a MAY (§62.1 rule 2).
- The
.dkkhas no integrity check of its own (§55.1). - DateKeys never checks who issued a certificate or a seal (§29.10, §29.11).
- (v0.15) No release archive or cache service is promised or hosted; long-term opening depends on someone keeping the releases (§50, §74).
- (v0.15) A release in hand is not compared with the reader's clock (§63 step 9.c).
- (v0.15) The recovery annex does not check canonical encodings,
header_binding, the 16 stanzas, the zero padding or the path rules; a capsule a conforming reader would reject may open by the annex (§79.8).