paperspec0.1.0

23. The transparency log

A receipt's at is what its signer wrote, and a roster is a file a package carries. Neither proves that a receipt existed before the key that signed it was revoked, or that the roster a verifier holds is the one the team published. A team's transparency log settles both: an append-only record of every receipt, revocation and roster the team publishes, whose state is a Merkle tree root that the team signs and that witnesses may cosign. The log is the same tree as receipts and the correction history (8.5, 11.5), with the same proofs. Both formats of this chapter are provisional (0.4): the design follows the specifications that transparency logs share, and the first deployment will shape the details.

23.1 Entries#

An entry, scienting-log-entry/1, is one item of the tree, [kind, id, hash]:

kindidhash
receiptThe receipt's record ID.Its record hash (8.4).
revocationThe revocation's record ID.Its record hash.
rosterThe store the roster is for.SHA-256 of the canonical JSON of the roster.

Entries are appended in the order the team publishes them and never removed. The leaf hash of an entry is SHA-256 of the byte 0x00 and its canonical JSON, the interior hashes follow RFC 9162, and the root over no entries is SHA-256 of the empty string, as for the history root. A roster is logged before any receipt a key it adds may sign, so a verifier can find the roster that governed a receipt by looking at the entries before it.

23.2 Checkpoints#

A checkpoint, scienting-checkpoint/1, is a signed note in the format transparency logs share: an origin line, the tree size, the root hash in Base64, an empty line, and one signature line per signer.

scient.ing/log/smithlab
41
Q2xlYXIgdGV4dCBpcyBub3QgYSByb290IGhhc2guLi4uLi4uLi4=

— ana AAAAAAHZ…

The origin names the log, and a team's logs are named scient.ing/log/<store> or under a domain the team controls. A signature line is an em dash (U+2014), a space, the signer's roster key, a space, and Base64 of the signer's four-byte key hash followed by the signature. The key hash is the first four bytes of SHA-256 of the signer's name, a newline, the byte 0x01 and the Ed25519 public key; the signature is Ed25519 over the note's first three lines, each ending in a newline. A note parsed into JSON has format, origin, size, root as hex, signatures as {name, key_hash, value} and the note text itself; the schema is checkpoint.schema.json. checkpoint.jsonl gives a checkpoint over the example paper's receipts and its verification.

A checkpoint may carry further signature lines from witnesses: roster keys with the witness purpose, held by independent parties, that cosign only a checkpoint consistent with every earlier one they saw. A verifier that holds two checkpoints of one log checks a consistency proof between them (11.5); a log that cannot produce one has rewritten its past. A project accepts a checkpoint when its origin is the project's log, a key with the role owner and the sign purpose signed it, and at least the project's threshold of its listed witnesses cosigned it (20); fixtures/records/log/checkpoint is signed by the team and one witness.

23.3 What a log settles#

When a project names a log in its settings (20), a receipt counts toward a level only when the log holds it, and the log's order replaces the records' own times in two rules:

  1. A revocation of a signer's period revokes the receipts logged before the revocation that fall in the period; a receipt logged after a revocation of its key never counts, whatever its at says.
  2. The roster that governs a receipt is the latest roster entry before it.

A reader fetches the latest checkpoint, verifies its signatures against the roster and its consistency with the checkpoint it last saw, then verifies inclusion proofs for the receipts it relies on. Without a log the rules of 8.6 stand, and the at of each record is taken at its word.

23.4 Serving a log#

A log is served as static files in the tile layout transparency logs share, so that a client fetches only the subtrees it needs and any file server can host a log.

PathHolds
checkpointThe latest checkpoint note (23.2).
tile/<L>/<N>Hash tile N of level L: the 32-byte hashes of the 256 complete subtrees of 256^L entries each that the tile covers, in order. Level 0 holds the leaf hashes.
tile/<L>/<N>.p/<W>The rightmost, partial tile of level L, holding W hashes.
tile/entries/<N> and tile/entries/<N>.p/<W>The entries themselves, 256 to a tile, as canonical JSON Lines.

N is written as 3-digit groups, every group but the last prefixed x: tile 1234067 is tile/0/x001/x234/067. A tile at level L holds only the hashes of complete subtrees, so the hashes a partial tree still needs are computed from lower levels, as RFC 9162 computes a root from its subtrees. fixtures/records/log/ is the example paper's log in this layout, and checkpoint.jsonl lists its tile paths.

Source: spec/23-log.md · raw