{
 "spec": "1.2",
 "vectors": [
  {
   "file": "valid-basic.json",
   "description": "Two unchained entries signed before the chain, then publish, revise, withdraw and republish by one provider, and an independent publication by a second provider with the same external_id. Head names the newest entry.",
   "sha256": "9e175ffa21c3084a9633162d6d9a3d86837c8b068c37805358d11262528b2269",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-genesis-only.json",
   "description": "A feed with exactly one entry, the first of the chain (no entry before it).",
   "sha256": "03030941fc631d2ad2039fa70c6d53a325f9f2a45cacc20608aa5cd615b63e57",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-gaps-in-seq.json",
   "description": "Sequence numbers are not contiguous (rolled-back writes used some numbers). prev_seq names the real previous entry, so nothing is missing.",
   "sha256": "ada986cfdd6d40a271c49cdb1b4b37e6fa329fbc301acb9d4d9aea2b257a1e68",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-one-page-1.json",
   "description": "One feed page holding 1 chained entries and the signed head.",
   "sha256": "77733030dc8cd9a73dd8576f781592f2887a08862eb7599c63c051ffd2f2a499",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-one-page-7.json",
   "description": "One feed page holding 7 chained entries and the signed head.",
   "sha256": "4e79c7c0c7eb9c78f3b52264aa8f04c9d6da8eb4ef0c7c3b49ee9e786deab11a",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-one-page-100.json",
   "description": "One feed page holding 100 chained entries and the signed head.",
   "sha256": "93acec74de31c3af532c485edd3e95677550ad52489fe3f1830498648ecdd8a5",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-one-page-500.json",
   "description": "One feed page holding 500 chained entries and the signed head.",
   "sha256": "23881be3519931633a452abbb50e781696e1a46e2259ea2a41cdfbb96c26303a",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-paged-limit-1.json",
   "description": "The same 100 entries read in pages of 1. Each page carries the head of the whole feed (it is read after the entries); the last page has has_more false.",
   "sha256": "30b4d64aaaae6168b3e769fd42de3718a71aa4921e3e4e17bc3cb1014f0fc8d5",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-paged-limit-7.json",
   "description": "The same 100 entries read in pages of 7. Each page carries the head of the whole feed (it is read after the entries); the last page has has_more false.",
   "sha256": "1f6c14104851b260d79fe4e8430d7d7fe70d57df3f33d8dfee56978c8bfb8ccd",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-paged-limit-100.json",
   "description": "The same 100 entries read in pages of 100. Each page carries the head of the whole feed (it is read after the entries); the last page has has_more false.",
   "sha256": "b9d1cc67d485b8039144e8b456192a164332a0d3d1aa0942b30e1b8e9b823b5b",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-text-edge-cases.json",
   "description": "Text that tests the canonical JSON rules: quotes, backslashes, slashes left unescaped, control characters escaped in lower-case hex, the two line separators U+2028 and U+2029 escaped, DEL and astral characters left as they are, empty strings treated as null.",
   "sha256": "90adfa1fb6f7a22d7894ada0e0761975e36b36386716844d811d8612d97e4db8",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-attachments.json",
   "description": "A record with two attachments. download_url is not signed and is left out of the signed form; the four signed attachment fields are in the fixed order.",
   "sha256": "55a7ad2d81a6d6fa3cb6b4935d23b3069100b8d94af4997b23647ff46727b097",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "valid-key-rotation.json",
   "description": "Entries 1 and 2 are signed by the first key (now listed as retired), entries 3 and 4 and the head by the second key. The key file lists both.",
   "sha256": "6f6b6698a08b7e639ff28df3196eb367c9e1786ee4db93cc6954b8b26ed57c1d",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "key-retired-key-missing.json",
   "description": "The same stream, but the key file lists only the new key. The entries signed by the old key cannot be verified.",
   "sha256": "34509f2ecbe743e362a93dbcb994869a5d4502965bf0baff8e0cbba1abe952f3",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-body.json",
   "description": "The body of entry 3 is changed after signing.",
   "sha256": "b6a17d64cf8692d46e0b0294c697f71e58554c13058412f623f9a95198f221dd",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-title.json",
   "description": "The title of entry 3 is changed after signing.",
   "sha256": "4d6e70b631c2011697aa1e826967d3669e6a9ccd04d276e69a8758872cb556f6",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-authority.json",
   "description": "The authority name of entry 2 is changed after signing.",
   "sha256": "31bc14d3bfd115bcc672139495de5e63f5e6920cb4cae96aa0687ba41918a897",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-provider-name.json",
   "description": "The provider name (a field added in the publishing path) of entry 4 is changed after signing.",
   "sha256": "78227bc3d62f1d6bffd714e130ee069ba715ad358e7f003b030b045d8e8f5437",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-revision.json",
   "description": "The revision number of entry 2 is changed after signing.",
   "sha256": "53a02e707ac767ce237fa8f615f2e4b683fdcbecaf1691684a470b4444ee96d9",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-received-at.json",
   "description": "The received time of entry 5 is changed after signing.",
   "sha256": "803096b85a7c131c78f850c24b1602b8034e4716bd3e2a4dafad3f06a98cde03",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-signature.json",
   "description": "One character of the signature of entry 3 is changed.",
   "sha256": "c4baa9338bbd244dee4215cb7d98e64f91a6c768d93d6b7d62392b09d8de3db0",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-signature-garbage.json",
   "description": "The signature of entry 3 is not hexadecimal at all.",
   "sha256": "cf22953a070cf5b96db9a871d8cefca7e729e876e8e8b6b57fd4d319eef745a8",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-prev-hash.json",
   "description": "prev_hash of entry 4 is changed after signing (the hash no longer matches, and the chain no longer matches).",
   "sha256": "e2745023390afcdee4b780f376d1edaa80c83e837565604a73cbb8078ffe7488",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-key-id-unknown.json",
   "description": "Entry 2 names a key that is not in the key file.",
   "sha256": "774d0b4dd09c70dbd2b9151d2dfc5f04f1ee281d3b5a266087b0281e7bab0df1",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-algorithm.json",
   "description": "Entry 2 declares a signature algorithm other than Ed25519.",
   "sha256": "94160be6304e5ee4b1d848f4c32232104baf979acc3e317ba357b9baf2f2ce4e",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-hash-uppercase.json",
   "description": "The hash of entry 3 is the right value written in upper case (the format is lower-case hex), so entry 4 also fails to chain to it.",
   "sha256": "65593c89c26071041465eddb64a5a1538c59b126c7834e61c92fa06ba088efbd",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-record-hash.json",
   "description": "The record hash of entry 3 is replaced by another value; the next entry still names the original.",
   "sha256": "6415e1b431b67862794564b7f7fce381d200cda10a4895dc0d638a2271e7e9a6",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "unsigned-fields-ignored.json",
   "description": "Fields outside the signed form (download_url, removed_at, an unknown extra field) are not covered by the signature; changing or adding them does not change the result. Verifiers must not read meaning from them.",
   "sha256": "23855fa00b9fc6f0b84adc57af92090f112e1ed7e2daea362c39108c65a9d595",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "tamper-signed-by-other-key.json",
   "description": "Entry 2 is signed by a key that is not the one it names.",
   "sha256": "2cd4aa952ce5e6bb9ad281bae90cf56c42a50dc55f88cf2af90cddfa99de518a",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "forged-entry-attacker-key.json",
   "description": "Entry 2 is re-signed by an attacker key that is not in the published key file.",
   "sha256": "f4c0339bdd29ee2a3fbeac93e08602a16b44273969a915b0e8fa5df6946b18d4",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "omission-middle.json",
   "description": "Entry 3 is left out of the stream. Entry 4 names entry 3 as its predecessor, so the chain shows the gap.",
   "sha256": "7af73373816300cb31a5248332314c4afbdf5885bfc11b11b2c3b191885f22ab",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "omission-first-after-anchor.json",
   "description": "A reader that stored seq 2 and its hash starts reading after it; entry 3 is missing, so the first entry received does not follow the stored one.",
   "sha256": "e0a56b4c43341e3216b209e51e838912245c4b07cb2487e6282271859c1e543d",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "anchor-ok.json",
   "description": "A reader that stored seq 3 and its hash reads on from entry 4; the first entry follows the stored one.",
   "sha256": "d1a4fad0ea78b2df64cf284fbcf08dd38e1d3b75a33b256123c1a1f625df0a1e",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "start-mid-stream-no-anchor.json",
   "description": "A reader with no stored cursor starts at entry 4. Nothing can be checked about the link before it; the verifier says so and does not call it an error.",
   "sha256": "e05e4466d38e453f8331a1547792b045c397969be1e0b41fe39d2a06a0cff046",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "reordered.json",
   "description": "Entries 3 and 4 swap places.",
   "sha256": "b8d9ebbd9df2bc0c066a8fc7827b86a5242c4d61344fe06350b49f99f1e66c1b",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "duplicated-entry.json",
   "description": "Entry 3 appears twice in a row (the second copy does not follow the first, and repeats a revision).",
   "sha256": "cd5f280a2ec72f57ee249789a4aa9ecdd696b72d3d8ff51c013642c08e158311",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "replayed-old-entry-at-end.json",
   "description": "An old entry (2) is repeated after the newest.",
   "sha256": "3f747f986748645a0735394f02d249f337c43a42880dd9f2a107b78abd0ee3ed",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tail-truncated-no-head.json",
   "description": "The newest two entries are not delivered and the response has no signed head. A verifier cannot tell; it says so (no_head).",
   "sha256": "93104182dbb6f89a781535dbf08327b5e00465daa295497dc3971c05b9b7877f",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "tail-truncated-with-head.json",
   "description": "The newest two entries are not delivered, but the response carries the signed head naming entry 6 and says there is no more to read. The verifier reports the missing tail.",
   "sha256": "b102c38704fc5b952432535b1253e34ddc83c4bdaa4b245989ce5d6cffffd819",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "page-incomplete-with-head.json",
   "description": "The first page of a longer read: has_more is true, the head names the newest entry. Not an error; the stream is incomplete.",
   "sha256": "1397b4e29e34605d63e7545ae61e2a5685e8a2349348bcc240bc542ebe4e7bef",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "head-tampered-signature.json",
   "description": "The signature of the head is altered.",
   "sha256": "67f2b25cd3991302c1ddcd1db05b432e69f49315442bc4330dba16a08f9ea6d0",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "head-tampered-seq.json",
   "description": "The head claims entry 7 without being re-signed.",
   "sha256": "a96b915c48eba22e1deeb44c47a949238b20d294bb98d7a34981f1f8b1414aab",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "head-tampered-hash.json",
   "description": "The hash named by the head is altered without re-signing.",
   "sha256": "64eda26f05071eb0511b6eb51c9aa5da2a07427077a2361334cc746c3add7afb",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "head-names-different-entry.json",
   "description": "A properly signed head names seq 6 with a hash that is not the hash of the entry delivered as seq 6 (a split-view sign).",
   "sha256": "c5ab5a5eb0b0521f08f0bee8a51e531eaf597026e33146d365e8b8beee38648b",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "head-unknown-key.json",
   "description": "The head is signed by a key that is not in the key file.",
   "sha256": "9e05a7a5b041419e08af16c5b2edcc700cbbbc9823e3076bb99c8f0b2c200be7",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "head-behind-entries.json",
   "description": "The head names entry 4 but entries up to 6 are delivered: a head is never older than the entries of its own response.",
   "sha256": "296c8576ff4c2c9e550109219e995c3527aa6c862a621fe16902d275942f2133",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "head-malformed.json",
   "description": "The head lacks its signature field.",
   "sha256": "b5c0e88db43a95a7c08ec61d1bf3a3d4f15128311a1b754c380437ed231ea4fe",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "page-cursor-wrong.json",
   "description": "next_after does not name the last entry of the page.",
   "sha256": "0b88abce3c414f6b3e480862dae4940bf46e3d488b78cc8bd56b0c38f972cdab",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "chain-fields-removed.json",
   "description": "Entry 3 is re-signed with its chain fields left out (an attacker with the key hiding a break). A chained stream may not go back to an unchained entry.",
   "sha256": "dc64c0f20ebf533e694aca99be1949b7cebccf3578288f256600fceb8f106dab",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revision-gap.json",
   "description": "A publication goes from revision 1 to revision 3.",
   "sha256": "898c814683d12a67a341c598f378040ae870a1f5553d8be31f3bf15679fab55a",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "supersedes-wrong.json",
   "description": "Revision 2 names the wrong earlier entry (the one of another publication).",
   "sha256": "cfb23369164e8661c7b06595906a25b6a8b814efd5e29064d953dc2218a66706",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "first-revision-supersedes.json",
   "description": "Revision 1 claims to supersede an entry.",
   "sha256": "940b6882c51db1f3832c68911eddf33eb01e4afbe9e227128ee42afba8f30a74",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "valid-revisions.json",
   "description": "Three revisions of one publication.",
   "sha256": "2240398dd0bbd650a3dee7e77c79831e4c840c6f4611dd7041c0ae6add60709f",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "revisions-read-from-the-middle.json",
   "description": "A reader starts at revision 2 of a publication; what came before cannot be checked and is reported as such.",
   "sha256": "590734dd73d66c077f5fe2565194f2628c777a1585bee62f894b0001f5c48174",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "two-providers-same-external-id.json",
   "description": "Two providers use the same external_id under their own authority records; their revisions are independent.",
   "sha256": "fc4d4bf4be1ad3edfc7cc13daf6f1dddb48d156ca08f4ac36fedbc6013d0f426",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "publication-entry-incomplete.json",
   "description": "A publication entry that names an authority record but has no revision or government identifier.",
   "sha256": "5b8337d5cb58e2fd00a896516d8582d4b9c1edf104593e364a02a9f464e25525",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-administrative-events.json",
   "description": "Suspension and reinstatement of a provider, suspension, reinstatement and ending of an authority record. None of them touches an entry.",
   "sha256": "70834ccadb767cf610d39c54fcd219911b2cf6ad1382d74f34da461aaa62b05b",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "status-revoke-publication.json",
   "description": "One publication is revoked over a range of entries. Entries 1 and 3 (publication a, inside the range) stand revoked; publication b and the other provider do not.",
   "sha256": "76e4b3c7de883b7424e66458d07058cfe577d4e8f158e7da724b5cf7a1920008",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "status-revoke-record-range.json",
   "description": "An authority record is revoked for entries 2 to 3 only; entry 1 stands.",
   "sha256": "43ac0c2b6bf92b8d3f3d911f3f27a1ca21b100174b14174ce632c22823ca1083",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "status-revoke-provider.json",
   "description": "A provider is revoked for entries 1 to 3. Its entries 1 and 3 stand revoked; the other provider entry 2 does not.",
   "sha256": "8443e57c8f05793bea63d0f68932192cb213648fc6d94267b0c2f36ab530b0dd",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "status-lift.json",
   "description": "A revocation is lifted by a later entry; nothing stands revoked afterwards.",
   "sha256": "275e69c93747af1cae90c6fea8ddb3dac12cbff2594b48598b63dd573522c3e5",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "status-lift-twice.json",
   "description": "The same revocation is lifted a second time.",
   "sha256": "a70fae159d4f9c77b7eb607149dee0e4760194d2479d4fcf70195d39e1e8aec1",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-reinstate-does-not-lift.json",
   "description": "Reinstating a record does not undo a revoked range: entry 1 still stands revoked.",
   "sha256": "66e6ada2112bba21390c63622c53e55785fdbffcfd12109ffc7b0a193e1f6111",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "status-lift-wrong-scope.json",
   "description": "A provider-level lift names a revocation made at record level.",
   "sha256": "ead7b539d7d522dfa7a8ee0f0f4499bb7f13484e3dca391f7d396d111da73aa9",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-bad-event-for-scope.json",
   "description": "A publication-level suspension (publications can only be revoked or have a revocation lifted).",
   "sha256": "f42c58ec5a94103930744143dbf859aa5ee6d61196d4cf7f9f38a24ee0d51e39",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-suspend-compromise-reason.json",
   "description": "A suspension that uses a compromise reason.",
   "sha256": "e324d0ca2dda99782edb363e9798d67c7873a26f1345a50ecf1ee7a354dbd835",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-revoke-administrative-reason.json",
   "description": "A revocation that uses an administrative reason.",
   "sha256": "39abf281500b418211e8ebe319bc99b633507d7af7ed99930c2481c1328f633f",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-revoke-range-reaches-itself.json",
   "description": "A revocation whose range reaches its own sequence number.",
   "sha256": "35f1ec7918219cc91d8d46bc2e31e0a7866f13f488c0e96fe39015270db57a54",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-revoke-range-backwards.json",
   "description": "A revocation whose range ends before it starts.",
   "sha256": "e2109c341d4d9bfa3b49710136ac03faf5e91da6a53fb6653db787bd17f5fb25",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-revoke-empty-range.json",
   "description": "A record revocation whose range holds no entry of that record (the entries in the range belong to another provider).",
   "sha256": "f111e4e967818d2631811eab7200e6b58f5e9d5f175f8019c6201a0a022ef9fe",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-carries-publication-fields.json",
   "description": "A status entry that also carries a title.",
   "sha256": "343912d21ce8ac3eaf4cb6c5a67423b97c05043e97b68a33038eb403f97e6365",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-lift-of-non-revocation.json",
   "description": "A lift that names an entry that is not a revocation.",
   "sha256": "0a34ee758fd5df67c698d5b8257ccb0ab37588f56d8fb91f14864bc2ece14130",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-end-wrong-reason.json",
   "description": "Ending a record with a reason other than provider_request.",
   "sha256": "57c01a553a4ae45235baf96a7b80b265eb0eb4b3a340bf74079758323e25f5b6",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-provider-names-record.json",
   "description": "A provider-level entry that names an authority record.",
   "sha256": "7930315d6c3dcb75be2932ab0520d095d397c013d1169c865f46898a1dff77e3",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "status-record-without-government.json",
   "description": "A record-level entry that names no government.",
   "sha256": "3abb98f5bde2c04302e297e9977364923542f377a093a1f676149994bc45608b",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "unreadable-lone-surrogate.json",
   "description": "A string holds a lone surrogate half (not valid text). The input cannot be read; no verdict about the entries is given.",
   "sha256": "a7eb1a2ab5883ad423ad55557389673ece166ecdc473cd4096ccc61848014db3",
   "expect_ok": null,
   "expect_unreadable": true
  },
  {
   "file": "malformed-seq-as-text.json",
   "description": "seq is written as text instead of a number.",
   "sha256": "a8c5edb95149c5fafe2151163daea69a84dda7f3074577789add9ba7f7963c55",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "malformed-no-authority.json",
   "description": "An entry has no authority object.",
   "sha256": "ae19fc47c91585e1f0ac74166a43f1d2d838b84f8a04e2929f5e1359647afe5b",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "malformed-attachments.json",
   "description": "attachments is text instead of a list.",
   "sha256": "5ac42b9bdab1f7af993ed537632c344a08ef0c6c26e93c2289a32e4ca6f08a31",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "malformed-revision-as-text.json",
   "description": "revision is written as text.",
   "sha256": "07972b292db7064b11c58eb29b5a609db0bc71e515a6e295d5f6d5a5c5d1394a",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "empty-feed.json",
   "description": "A feed with no entries and no head (a new, empty feed).",
   "sha256": "30fd7f7bd28a6b697dc817e6a46f359a28244880fae42ad220ddd2b3e32a30fc",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "no-key-file-keys.json",
   "description": "The key file lists no keys: nothing can be verified.",
   "sha256": "1870dc1705c11c5b4ca6436e90ff61630facf19eee2ba37c98cb400b934f3b7e",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-valid-authority-record.json",
   "description": "The feed read with the filter authority_record_id=7: only that record's entries and the provider-level status entries of its provider. The links do not follow one another (entries of other records are not in the stream) and the head is newer than the last entry; neither is a problem in a filtered read.",
   "sha256": "97fd0008d626765d13be73406c85575e89a633d8f4dd66f78077c7d23ee271ba",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "filtered-valid-provider.json",
   "description": "The feed read with the filter provider_id=2: everything provider 2 wrote (records, withdrawals, status entries). The stream does not start at the first entry of the feed, and a filtered read has no anchor.",
   "sha256": "df1f7ec2763b4ebc621ee4f487a14ee9daa6ab042816f3256f9d04655904fbc5",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "filtered-valid-government.json",
   "description": "The feed read with the filter for the government (official_id_type census_pid6, official_id 161633): both providers hold it, so this stream is the whole feed.",
   "sha256": "8bf41d906f804a32933fd925df30dad38ac81ded6588178b83e42860d8f8f063",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "filtered-valid-paged.json",
   "description": "The record-7 filtered read taken two entries to a page; has_more is true on all but the last page.",
   "sha256": "c3234bb4e51ee6ccde69110bed92bb4f1050f6b3f0078c66567dbfa618ba8e79",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "filtered-read-checked-as-complete.json",
   "description": "The same pages as filtered-valid-authority-record, but checked as an unfiltered read. A verifier that is not told the read was filtered finds the gaps in the chain (and a head newer than the last entry), so a filtered stream can never pass as the complete feed.",
   "sha256": "41ce0630654de3a7753248eba3a0ff9fd43a680f9374b97f25f32b8f48f26270",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-anchor-refused.json",
   "description": "A filtered read cannot be checked against an anchor (no entry follows the anchor). The verifier refuses rather than guessing.",
   "sha256": "0d04be72c866f748ba7d7742c3e3f941c01cf9470ebb0b8846c366b3aea07abf",
   "expect_ok": null,
   "expect_unreadable": true
  },
  {
   "file": "filtered-omitted-revision.json",
   "description": "Revision 2 of publication a (entry 3) is left out of a record-7 read. The revision numbers and supersession links of the remaining entries expose the gap, even though the chain cannot.",
   "sha256": "b176be342fbb03eb86144ae2bfc801ddea32d6e23702781391053708f323896f",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-tamper-body.json",
   "description": "The body of entry 5 is changed after signing, in a filtered read.",
   "sha256": "08f23faca1d1e2cb9c917a5952a13e4299b50973aa58a2566434a869851787a8",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-signed-by-other-key.json",
   "description": "Entry 5 of a filtered read carries a signature made with a key that is not the one it names.",
   "sha256": "3f20441dc9aae35f829c75cc6937ec05b5b82b121de81b0aa549540adba6efac",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-link-to-entry-in-stream-wrong.json",
   "description": "Entry 6 names entry 5 as its predecessor, and entry 5 is in the stream, but prev_hash is not entry 5's hash (the entry was re-signed, so its own hash and signature are valid). A link that can be checked is checked.",
   "sha256": "a999e39a6eda313eb400ea2a1ba18bae80b0481919d159e07e69f38e723d5f70",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-link-not-to-earlier-entry.json",
   "description": "Entry 3 names itself as its predecessor (re-signed, so its hash and signature are valid).",
   "sha256": "96aab3f41ce4b947d3a88e8ede4e70868fc76f66af9705591dab6e4a749d3fc1",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-unchained-after-chained.json",
   "description": "Entry 6 has no chain fields although entries before it do (re-signed). Unchained entries exist only at the very start of the feed.",
   "sha256": "2dd8fa12110e2eabb4ac6616b72c97b3fc3fc6c8e08d8bb8cbd8ae93cf4909a0",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-key-unknown.json",
   "description": "The last entry names a key that is not in the key file.",
   "sha256": "ca8544ee35fdda4dc9e3c0d43e30b3915964b9b041ee1aee1e66f2afdf19beb5",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-head-forged.json",
   "description": "The signed head of a filtered read carries a signature made with another key. The head is checked in a filtered read too.",
   "sha256": "1ebe83bcd277ee5ead096708a89dfd44276742d659f082237fecf35be1dae676",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-head-names-wrong-entry.json",
   "description": "The (validly signed) head names entry 10 with a hash that is not entry 10's hash, and entry 10 is in the stream.",
   "sha256": "b0361d27f75f611648766c4ae02ffa6e8dd1ba4e793568f8777c29a5f97029aa",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-head-behind.json",
   "description": "The signed head is older than the last entry of the page (head seq 4, last entry 10).",
   "sha256": "4474275155ba843bc267255f6749dbc9db664e48c942041862580cb5ead7fa97",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "filtered-revocation-range-outside-stream.json",
   "description": "A provider-level revocation covers entry 2, which belongs to another record of the same provider and so is not in a record-7 read. In a filtered read the range cannot be checked against the stream, so the revocation is accepted; entry 1 is not in the range and stands.",
   "sha256": "48df0ecc9b6c674157aeab14a0a4d260f19ce4628eee4ae114e573cd09714d1b",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "revoke-valid-prefix.json",
   "description": "The first key was revoked. The signed notice names entry 6 as the last trusted entry and gives its hash. Entries 1 to 6 (signed by the revoked key) are accepted because the stream reaches entry 6 with that hash; entries 7 to 9 and the head are signed by the new key.",
   "sha256": "19d0e848f67e9724b06d3a3769196d41d86c823feb8b58982ae2226177be82c0",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "revoke-entry-after-trusted-point.json",
   "description": "Entry 7 is signed by the revoked key but the notice trusts it only up to entry 6. Entry 7 is a problem; entries 1 to 6 are still accepted.",
   "sha256": "1e01b137df21d37a9773c0f9f5c8a9c328ac00a1f15de45396a2c70431114765",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-notice-bad-signature.json",
   "description": "The revocation notice is signed with a key that is not the one it names. The notice is not valid, so nothing the revoked key signed can be trusted.",
   "sha256": "2b6718d13f2ec2badd6262c43f487137f7d29bc1b86a3e9be8cd8a489d8e88a5",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-notice-field-changed.json",
   "description": "A field of the notice (last_trusted_seq) was changed after it was signed, so the signature no longer matches.",
   "sha256": "f5954e6bdea57c8781697e657a10859849c7e90d50b9b03d414550b9890b5d03",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-notice-signed-by-itself.json",
   "description": "The notice is signed by the revoked key itself. Whoever stole the key could have written it, so it counts for nothing.",
   "sha256": "1c0f13d92536494a597953dc42b6a19a1618f81836b1a9aa29a4db59fc7e00c3",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-notice-signer-unknown.json",
   "description": "The notice names a signing key that is not in the key file.",
   "sha256": "17e805c3da8211c67d0d52de56483060ab9ce882b1d4b66032a2e2495b0cda16",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-notice-times-reversed.json",
   "description": "compromised_since is later than revoked_at, which cannot be true. The notice is not valid.",
   "sha256": "e23576c1623b8d120465df5144befccbdb87252a28bc1a6a35aa428879862fb7",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-notice-missing.json",
   "description": "The key file marks the first key revoked but carries no notice (no last trusted entry, no signature). Nothing it signed can be trusted.",
   "sha256": "801e3dbf02372ec5b9f33474a1b6da870e85e1bb8f155c6a143e0df9f085abb8",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-trusted-hash-differs.json",
   "description": "The (valid) notice says entry 6 had the hash of entry 5. The stream holds entry 6 with its real hash, so the stream does not reach the point the notice trusts and nothing signed by the revoked key is accepted.",
   "sha256": "d3098da761fd50d03df8d6ecd6cbb86bbeb3157dfbea229ffa41764f7419829b",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-forged-alternate-chain.json",
   "description": "Someone holding the stolen first key built a different history: entries 1 to 4 are real, entries 5 to 8 are forged (valid signatures, unbroken chain, a head signed after the compromise began). Entry 6 does not have the hash the notice names, so every entry signed by the revoked key is rejected and the head is rejected.",
   "sha256": "eaec09e9759c60a39e35c2d42980cf32fc4ef935fc4698f36aec9e4d50c7e946",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-nothing-trusted.json",
   "description": "The notice trusts no entry at all (last_trusted_seq 0, no hash): the key was compromised from the start. Every entry it signed is a problem.",
   "sha256": "93e0127712b7454c8f6decdb8714d55ce44d8e7e076afe2b0e75d6dec7a4f84f",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-stream-after-trusted-point.json",
   "description": "A stream that starts after the revoked key stopped signing (entries 7 to 9, all by the new key). The revoked key being listed changes nothing.",
   "sha256": "09704879a61f2c80f8b8e579763f66fdcd158cad8f42d8bee4ddbe31f2fd0c28",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "revoke-old-page-head-before-compromise.json",
   "description": "An old stored page that ends at entry 6 with a head signed by the first key at 13:00, before compromised_since (14:00). Both are accepted.",
   "sha256": "d0e45014429339726a8ca691801eb3ac32f9f0593e62927258bb2ede0c3a8314",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "revoke-head-after-compromise.json",
   "description": "A page that ends at entry 6 whose head is signed by the revoked key at 16:00, after compromised_since (14:00). The entries are accepted; the head is not.",
   "sha256": "11e06aaeafd7d4251565ff9f8527418055e4d85fb73becbf33a45bb827ff0e44",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "revoke-filtered-prefix-unconfirmed.json",
   "description": "A filtered read (provider 1 only) that does not include entry 8, the last trusted entry named by the notice. The entries signed by the revoked key are not past entry 8, but the stream cannot show the chain reaches it, so the note says the prefix is unconfirmed.",
   "sha256": "ce76902337f047a57149ea881d6bd87dfeff96ce7f236a61ac9d8b9592fd4fbd",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "revoke-two-keys-in-turn.json",
   "description": "The first key was revoked (notice signed by the second key); later the second key was revoked (notice signed by the third). Each key is trusted up to its own last trusted entry. The earlier notice stays valid.",
   "sha256": "ab17fec049a5247ad257867053fca9e608ebe44ef1dcaf1bad1fd87d5731d4bb",
   "expect_ok": true,
   "expect_unreadable": false
  },
  {
   "file": "unreadable-number-fraction.json",
   "description": "A number with a fraction (seq 2.5). Only whole numbers within 2^53-1 are read; anything else makes the input unreadable, the same in every verifier.",
   "sha256": "8685c5d8a2ff564e0f7763297646e55a610afb2734b9b1862ed401cd97860e48",
   "expect_ok": null,
   "expect_unreadable": true
  },
  {
   "file": "unreadable-number-written-as-float.json",
   "description": "A whole number written with a decimal point (seq 2.0). Not read, because different languages would read it differently.",
   "sha256": "68e60707761f8510ddbdf6f8be7510f692585931acf27e66c5cc970e2ae02a8b",
   "expect_ok": null,
   "expect_unreadable": true
  },
  {
   "file": "unreadable-number-exponent.json",
   "description": "A number written with an exponent (seq 2e0).",
   "sha256": "c8aff71dc048c16149fa6cda3663ee03b66e9a29d639317762599bab5f65661b",
   "expect_ok": null,
   "expect_unreadable": true
  },
  {
   "file": "unreadable-number-too-large.json",
   "description": "A whole number above 2^53-1 (9007199254740993), which Node cannot hold exactly.",
   "sha256": "a0c608add434a569e6668dedf304fb6c5a1eb95f6f66edbcd5579f3dbb538bfe",
   "expect_ok": null,
   "expect_unreadable": true
  },
  {
   "file": "unreadable-number-nan.json",
   "description": "NaN written where a value belongs. Not JSON; one reader would otherwise accept it.",
   "sha256": "339b21c781d6ac8bc5fef2c75dfdcfef66b41843fba18f2d8707458823ec1393",
   "expect_ok": null,
   "expect_unreadable": true
  },
  {
   "file": "unreadable-nested-too-deep.json",
   "description": "Brackets nested 70 levels deep. More than 64 levels is not read.",
   "sha256": "acd822031a66b05179337f2104e425b315f08f4a2952467836e4ff7a135102e7",
   "expect_ok": null,
   "expect_unreadable": true
  },
  {
   "file": "malformed-authority-empty-list.json",
   "description": "authority is an empty list instead of an object (a reader that does not tell [] from {} would accept it).",
   "sha256": "0bf531319026fcd4abb80345a1e6e9eba407da583564e97c6934b999796d0895",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "keys-not-a-list.json",
   "description": "The key file holds a number where the list of keys belongs, so no key is usable: every entry and the head name a key that is unknown.",
   "sha256": "e53f5619e73893a4b9d9fbf46173ee0b65aeaa6e1e8ca9770c63eb930009c649",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "tamper-signature-trailing-newline.json",
   "description": "A correct signature followed by a newline. The signature must be exactly 128 hex characters.",
   "sha256": "e4b130e82e09e1474dcba048c0349e64adefb1a0d101e836b6940450b7690d54",
   "expect_ok": false,
   "expect_unreadable": false
  },
  {
   "file": "key-small-order-forgery.json",
   "description": "The key file lists a public key that is a point of small order (01 followed by 31 zero bytes) and the entries carry the signature 01 00..00 / 00..00. Some libraries accept that signature for ANY text under such a key. A key of small order is not usable, so the entries name an unknown key.",
   "sha256": "0a8d2faf5120e39b24642e82f8f28396883aface618f545b0b4648d3afcba655",
   "expect_ok": false,
   "expect_unreadable": false
  }
 ]
}
