carlos / contra Public

Clone
git clone https://amadan.net/carlos/contra

Plain git — no account needed to clone.

Download

Download this file

1# πŸ€– Golden vectors β€” the cross-language crypto contract
2
3`contra-v1.json` is the reference for every derivation in `PROTOCOL.md`.
4
5CONTRA implements the same crypto three times: Go on the instance, JavaScript
6in the console, Swift on the Mac. They must produce identical bytes. **All
7three suites pass this one file, or the contract is not being kept** β€” a second
8implementation that passes vectors of its own has proved nothing, and cross-
9platform KDF drift is the bug class behind the 1Password PRF mismatch that
10shaped our whole recovery design.
11
12Changing a value in this file is changing the protocol.
13
14## What it pins
15
16Argon2id at `m=64MiB, t=3, p=1`; all five `contra/v1/*` HKDF labels; the KCV
17construction; P-256 derivation from a seed, including a seed that forces the
18rejection branch; Crockford Base32 with the O→0 and I/L→1 mappings; the 20-bit
19checksum and a single-substitution repair; AES-256-GCM with its AAD binding.
20`account_chain` is the whole hierarchy end to end, so a new implementation can
21bisect where it diverges rather than staring at one wrong key.
22
23The wire formats `PROTOCOL.md` leaves open β€” HKDF mode, the AAD layout,
24Crockford packing, the rejection loop β€” are pinned in **discussion 19**. Read
25that before implementing against this file.
26
27## Where the numbers come from
28
29The generator is `gen/gen.c`, **C against OpenSSL** β€” deliberately not Go.
30
31Generating vectors from an implementation and then testing that implementation
32against them proves only that the code agrees with itself. So the vectors come
33from an implementation nobody here wrote, and the Go package is only ever the
34thing under test. If you are ever tempted to regenerate this file to make a
35test pass, stop: that is the exact failure the arrangement exists to prevent.
36Fix the code, or argue on the record that the spec is wrong.
37
38`gen.c` also re-computes published third-party vectors β€” the PHC Argon2id
39reference outputs, RFC 5869, RFC 4231, NIST CAVP AES-GCM β€” and aborts if any
40disagrees. Otherwise "independent" would only mean the two implementations are
41not the same, not that either is right.
42
43Every input is generated from its own published label:
44
45 fixture(label, n) = SHA-256("contra/v1/vectors/" || label)[0..n]
46
47so the file regenerates from the source alone, and nothing in it is, or may be
48reused as, a real secret (`AGENTS.md` decision 8).
49
50## Regenerating
51
52 cd gen && make vectors
53
54`REJECT_K` in the `Makefile` is the seed witness that forces a P-256 rejection.
55It is pinned rather than searched each time because finding one costs a few
56billion HKDF evaluations β€” a rejection is a ~2^-32 event. If the
57`contra/v1/ec-p256` label ever changes, the witness dies with it: run
58`make search` (minutes, all cores) and pin the new `k`.
59
60## Verifying the Go side
61
62 go test ./internal/contra/crypto/
63
64The suite has been mutation-checked: lowering the Argon2 time cost, typoing an
65HKDF label, truncating the KCV, dropping the AAD length prefixes or its domain
66tag, skipping the rejected EC candidate, accepting non-zero Base32 pad bits,
67widening the checksum, and dropping the O/I/L mappings each turn it red. A
68vector nobody has watched fail is a vector nobody should trust.
69