# Test vectors

[/test-vectors.json](/test-vectors.json) — the specification in executable form. Raw JSON, the file as it is in the repository at `648b53f` (also at `/sha256/5fe0405db81a841fbab2fff8b9622857988ba321895f9e4fa79354589fb6e3d1/test-vectors.json`, which never changes).

| | |
|---|---|
| `spec` field | `sigelo v0.1 (wire sigelo/0)` |
| sha256 | `5fe0405db81a841fbab2fff8b9622857988ba321895f9e4fa79354589fb6e3d1` |
| fixed `now` | `1757289600` |
| documented seeds | 9 (32 bytes, all zero except the last) |
| positive entries (`vectors`) | 21 |
| negative cases (`negative`, besides `parity`) | 41 |
| parity cases (`negative.parity.cases`) | 87 |

Status: draft. The vectors are versioned with the wire, not the packages; after the freeze at tag v0.2 the file only grows ([versioning §3](/versioning.md#3-test-vectors)).

## What conformant means

From [SPEC §10](/spec.md#10-test-vectors): every positive vector reproduced byte for byte, every vector carrying a `bundle` and `expect` reproduced as a §9.1 result compared by value, every negative rejected for the stated reason. The `rotation_recovery` versus `rotation_hostile_carried` pair is the one that matters: the recovery wins although the thief's rotation is newer.

- **Positive groups** include a four-node chain with two hostile rotations defeated by an earlier recovery, a recovery that changes the commitment followed by a second recovery under the new key, an attestation whose `claims` exercise the JCS rules, Monero bindings (base address and subaddresses), and two bundles with their expected §9.1 result (`bundle`, `bundle_minimal`).
- **Negatives** include a missing domain prefix, `typ` mismatch, a stale recovery key, a voluntary rotation changing the commitment, a fork, a cycle, a duplicate key, an integer outside ±2^53−1, unknown fields, and malformed Monero addresses and signatures.
- **Parity cases** are malformed objects both implementations must treat identically: raise with the stated reason, or return the stated proofs and counts.
- The signing input is `"sigelo\n" || JCS(body)`; the vectors carry canonical strings to diff against (`attestation_unicode`).

## Run them

```sh
sigelo-verify --conformance test-vectors.json                    # the reference verifier over every vector
sigelo-verify --conformance test-vectors.json --impl '<your cmd>'   # your verifier over 139 bundle cases
```

Details on [verify](/verify.md). The vectors are regenerated from the seeds by the repository's `ts/src/gen_vectors.ts`, and CI diffs the result against the committed file byte for byte.

## Schemas

JSON Schema 2020-12 for every signed object, checked in CI against every vector (12 files): [`attestation-envelope.json`](/raw/schema/attestation-envelope.json) · [`attestation.json`](/raw/schema/attestation.json) · [`binding-envelope.json`](/raw/schema/binding-envelope.json) · [`binding.json`](/raw/schema/binding.json) · [`bundle.json`](/raw/schema/bundle.json) · [`challenge.json`](/raw/schema/challenge.json) · [`common.json`](/raw/schema/common.json) · [`genesis.json`](/raw/schema/genesis.json) · [`invoice.json`](/raw/schema/invoice.json) · [`rotation-envelope.json`](/raw/schema/rotation-envelope.json) · [`rotation.json`](/raw/schema/rotation.json) · [`verify-result.json`](/raw/schema/verify-result.json). They are hand-written from SPEC §3.1, not generated; one parity vector cannot be expressed in them.
