Skip to content

Test vectors and the independent verifier

Two things keep implementations honest: fixed test vectors that every implementation must reproduce exactly, and a verifier written from the spec text alone that shares no code with any SDK. The rest of this page is generated from test-vectors/README.md and scripts/independent_verifier.py.

scripts/independent_verifier.py is one Python file whose only dependency is cryptography. It reads a registry over HTTP and never writes. It checks the signed checkpoint against the key from /v1/spec, random RFC 6962 inclusion proofs, and random object signatures (eddsa-jcs-2022, did:key), then prints a report and exits non-zero on any failure. Pointed at the vectors directory, it checks every vector instead. scripts/verify.sh runs it on every push.

uv run scripts/independent_verifier.py https://openentity.org [--samples 100]
uv run scripts/independent_verifier.py --vectors test-vectors

WARNING: PUBLISHED THROWAWAY KEYS. Every key here comes from a seed printed in keys.json. Anyone can sign as these EIDs. Never use these seeds or keys for anything real.

KeySeed (32 bytes, hex)Used for
entity0102...1f20 (bytes 0x01 to 0x20)The entity: document, declaration, record entries, previous key of the continuity link
second2122...3f40 (bytes 0x21 to 0x40)Attestation issuer and successor key of the continuity link
log4142...5f60 (bytes 0x41 to 0x60)Signs the checkpoint note, key name openentity.org/log

Every timestamp and nonce is fixed and Ed25519 is deterministic, so the files are byte-for-byte reproducible:

pnpm --filter @openentity/sdk gen:vectors

A test in sdk/ts regenerates them in memory and fails if a committed file differs.

<name>.json for each object is {description, object, canonical, sha256, unsigned_canonical}: canonical is the RFC 8785 (JCS) string of the object including proof (or proofs), sha256 is the hex SHA-256 of its UTF-8 bytes (this is the leaf object_sha256 and, for record entries, the next entry's prev), and unsigned_canonical is the JCS string without proof/proofs, the second half of the eddsa-jcs-2022 signing input.

FileContent
keys.jsonSeeds, EIDs, public keys and the log note vkey
declaration.jsonSigned Declaration
entity-document.jsonSigned Entity Document, seq 1, pointing at the declaration's hash
record-1.json, record-2.jsonTwo chained Record entries (prev of 2 is sha256 of 1)
attestation.jsonstage attestation by the second key about the entity
claim-liveness.json, claim-endpoint-reliability.json, claim-vision-privacy.json, claim-gateway-governed.jsonOne signed attestation each (second key about the entity) for the registered custom claim types in spec/claim-types.md; the claim of each validates against spec/schemas/claims/. Not log leaves
rotation.jsonThe POST /v1/continuity body from buildRotation: the link signed by both keys plus the successor's seq 1 document (re-keyed from entity-document.json, signed by the second key). Not {object, canonical, ...}: the payload is under request. Python's build_rotation reproduces it byte for byte
http-signature.jsonRFC 9421 vectors for the HTTP message signature helpers: valid cases (inputs plus the exact headers both SDKs must produce) and invalid cases (each must fail with its code). Signed with the entity key. Not {object, canonical, ...}
continuity-link.jsonrotation link with proofs by both keys
log-leaf-0.json to log-leaf-5.jsonLeaves for the six objects above in that order, each with leaf_hash = SHA-256 of 0x00 followed by the canonical bytes
checkpoint.jsonTree size, root, C2SP checkpoint body, signed note and the inclusion proof of every leaf

The signed note's signature line starts with U+2014, which the JSON files carry escaped as \u2014.