Documentation
The Domain-Keyed Document Stamp (DKDS) is an open protocol for verifying the origin and content of documents. This documentation describes version 1 of the protocol, the procedures for issuing and verifying stamps, and the reference implementation, dkds.js.
Documentation by task#
The documentation is arranged by the task of the reader. The specification is the only normative document; the guides and the security considerations explain it and refer to its sections.
Overview#
DKDS involves three parties and one public infrastructure. An issuer, an organisation that holds a domain name, publishes a public key in the Domain Name System (DNS) and signs the key facts of each document it issues. The signed facts are printed on the document as a QR code, the stamp. A verifier, software used by the recipient of the document, reads the stamp, retrieves the public key from the DNS and checks the signature. The reader, the person who uses the verifier, compares the facts shown by the verifier with those printed on the document.
- 1The issuer publishes a public key as a TXT record in the DNS of its domain. This is done once, and again whenever the key is replaced.
- 2For each document, the issuer signs the key facts with the corresponding private key and prints them, together with the signature, as a QR code on the document.
- 3A verifier scans the QR code and reads the facts, the signature and the domain name of the issuer.
- 4The verifier retrieves the public key from the DNS of that domain and checks the signature against it.
No party other than the issuer and the DNS is involved. There is no registry of issuers, no certificate authority and no central service; a verifier needs only the stamp and access to the DNS.
| Party | Function | Specification | Guide |
|---|---|---|---|
| Issuer | Publishes the key record; creates and prints stamps | Sections 4 to 7, 10 | Issuing documents |
| DNS | Holds the key record at <key_id>._dkds.<domain> |
Section 7 | Issuing documents |
| Verifier | Performs the verification procedure; displays the outcome, the domain and the fields | Sections 8 and 9 | Building a verifier |
| Reader | Compares the displayed fields with the printed document | Section 9.1 | Security considerations |
Architecture#
The protocol is defined as five layers. Each layer has a single function and depends only on the layers below it in the definition, so that a later version of the protocol can change one layer without affecting the others (specification, section 11).
"v=DKDS1; k=ed25519; p=6kpsY+KcUgq+9VB7…"
Creating a stamp#
An issuer builds a stamp from the inside out:
- The fields, a list of names and values, are encoded and compressed with raw DEFLATE to form the payload.
- The header (version, domain, key ID and time of issue) and the payload form the signed part of the envelope.
- The signed part, preceded by the ASCII string
DKDS, is signed with the issuer's Ed25519 private key. The 64-byte signature completes the envelope. - The envelope is encoded in Base45, preceded by
DKDS:, and printed as a QR code.
Verifying a stamp#
A verifier reverses these steps, in the fixed order of the verification procedure (section 8.2):
- The QR code is read and the text form decoded into the envelope.
- The header is checked. A stamp that fails any check here is rejected without a DNS query.
- The key record is retrieved from the lookup name
<key_id>._dkds.<domain>. - The signature is verified over
DKDSand the signed part. - Only then is the payload decompressed and the fields read.
The order is part of the protocol: it ensures that every verifier reaches the same outcome for the same stamp, and that untrusted data is processed as little as possible before the signature has been checked.
Standards#
Every component of DKDS is an existing published standard.
| Component | Standard | Used in |
|---|---|---|
| QR code | ISO/IEC 18004 | Section 3.3 |
| Base45 | RFC 9285 | Section 3.2 |
| DEFLATE | RFC 1951 | Section 5.1 |
| UTF-8 | RFC 3629 | Section 5.2 |
| Punycode | RFC 3492 | Section 4.2 |
| Ed25519 | RFC 8032 | Section 6.3 |
| DNS TXT records | RFC 1035 | Section 7 |
| Base64 | RFC 4648 | Section 7.2 |
Design principles#
The specification follows a small number of principles, which explain most of its rules.
- One way to do each thing. A protocol version fixes every choice. There are no options, extensions or negotiation within a version, so that two conforming verifiers always agree.
- One encoding for each value. Base45, Base64 and Ed25519 encodings are accepted only in their canonical form, so that every envelope has exactly one text form.
- Bounded input. Every length is limited, decompression stops at a fixed size, and no DNS query is made for a stamp that is not well formed.
- No intermediary. The issuer's own DNS is the only source of keys. Verification requires no account, registry or fee.
- Statements, not judgements. A verifier reports which domain signed which facts. Whether the facts are true, and whether they match the document, is left to the reader.
Terminology#
- Stamp
- A QR code printed on a document, containing the issuer's domain, a key ID, the time of issue, the fields and a signature. Section 1
- Text form
- The string encoded in the QR code:
DKDS:followed by the Base45 encoding of the envelope. Section 3.1 - Envelope
- The binary structure of a stamp: header, payload and signature. Section 4.1
- Signed part
- The envelope without its signature. Section 4.1
- Field
- A name and a value, both text, stating one fact of the document. Section 5.1
- Payload
- The list of fields, compressed with raw DEFLATE. Section 5
- Key ID
- A short identifier, chosen by the issuer, that distinguishes the keys of one domain. Section 4.3
- Lookup name
- The DNS name at which the key is published:
<key_id>._dkds.<domain>. Section 4.2 - Key record
- The DNS TXT record that holds the public key, for example
v=DKDS1; k=ed25519; p=…. Section 7.2 - Revocation
- Replacing a key record with one whose
ptag is empty, which invalidates every stamp signed with the key. Section 7.4 - Outcome
- The result of verification: one of
valid,malformed,unsupported,key-not-found,key-revoked,invalid-signatureandunavailable. Section 8.1 - Warning
- A notice to the reader, for example about a lookalike domain. Warnings never change the outcome. Section 9.3
Conformance#
An implementation conforms to version 1 when it meets every requirement of the specification.
For a verifier, most requirements are checked mechanically by the test vectors. A verifier passes when, for each of the 145 vectors, it produces the expected outcome, makes the expected DNS queries and, for valid stamps, returns the expected domain, time of issue and fields. The requirements that cannot be checked by comparing outputs, such as the display rules of section 9.1, are listed under requirements not covered by the vectors.
An issuer conforms when every stamp it creates verifies as valid and it follows the issuer
requirements of section 10.
Versions#
| Component | Current version |
|---|---|
| DKDS protocol | 1 |
| dkds.js | 0.1.1 |
The first byte of every envelope identifies the protocol version. A verifier that receives a stamp
of a version it does not implement reports unsupported rather than attempting to read it. Later
versions change one layer at a time, as described in
section 11.