Skip to content

Commit ff9c6bf

Browse files
committed
Add CLAUDE.md for Claude Code guidance
1 parent c834b83 commit ff9c6bf

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
cactus is a Go ACME server that issues **Merkle Tree certificates** per
6+
[draft-ietf-plants-merkle-tree-certs-04], for **testing only** (not a production CA).
7+
Read [MTC.md](MTC.md) for how MTC works (why certs have no real signature, what the
8+
inclusion proof proves, how landmarks and mirrors fit) and [README.md](README.md) for
9+
operating details and the full config reference.
10+
11+
## Toolchain (non-obvious, important)
12+
13+
cactus is **ML-DSA-44 only** and uses Go's built-in `crypto/mldsa`, so it **requires
14+
Go 1.27+** (`go.mod` declares `go 1.27`). There are no build tags — an older toolchain
15+
simply won't compile. Until 1.27 ships, build and test with **`gotip`** (a 1.27-devel
16+
toolchain). The `Makefile` defaults `GO ?= gotip`; override with `make GO=go` once a
17+
1.27 release is installed. ECDSA support has been removed.
18+
19+
## Commands
20+
21+
```sh
22+
make build # builds bin/cactus, bin/cactus-cli, bin/cactus-keygen
23+
make test # gotip test ./...
24+
make test-race # gotip test -race ./...
25+
make vet # gotip vet ./...
26+
make integration # gotip test -race -count=1 -tags=integration ./integration/...
27+
28+
# Single test / package:
29+
gotip test ./log/...
30+
gotip test -run TestParallelIssuance -tags=integration ./integration/...
31+
32+
# Fuzz targets:
33+
gotip test -fuzz=FuzzParseMTCProof -fuzztime=30s ./cert/...
34+
gotip test -fuzz=FuzzParseSignSubtreeRequest -fuzztime=30s ./mirror/...
35+
```
36+
37+
Integration tests live in `./integration/` behind the `integration` build tag; some of
38+
them compile and run the actual `cactus` binary over HTTP.
39+
40+
## Architecture
41+
42+
One binary (`cmd/cactus`) brings up whichever subsystems the JSON config asks for — there
43+
is no fixed mode enum. The three composable concerns are **CA** (`acme` + `log` +
44+
`ca_cosigner`), **CA-side mirror quorum collection** (`ca_cosigner_quorum.mirrors[]`), and
45+
**mirror operating mode** (`mirror.enabled`). The config validator enforces hygiene rules
46+
— notably, CA and mirror cosigner keys in the same binary must differ.
47+
48+
Cert issuance data flow (CSR → verifiable bytes on disk):
49+
50+
1. **`acme/`** — RFC 8555 server with the draft §9 cert-download extensions. Validates
51+
the order, then calls the CA issuer.
52+
2. **`ca/`** — turns a CSR into a standalone X.509 cert whose `signatureAlgorithm` is
53+
`id-alg-mtcProof` and whose `signatureValue` is an `MTCProof` blob (inclusion proof +
54+
cosigner signatures). Builds the log entry and waits on the log.
55+
3. **`log/`** — the single-writer issuance log. `Log.Append` assigns an index
56+
immediately; `Log.Wait` blocks until the entry is in a published checkpoint **and** a
57+
covering signed subtree (§4.5) exists. A sequencer flushes pooled entries every
58+
`checkpoint_period_ms`, writes tiles, and signs a new checkpoint (c2sp signed-note).
59+
In CA-quorum mode, each flush fires parallel `sign-subtree` requests to configured
60+
mirrors and `Wait` blocks for `1 + min_signatures` cosignatures.
61+
4. **`tile/`** — read-path HTTP server with a tlog-tiles-compatible layout
62+
(`/<lognum>/checkpoint`, `/<lognum>/tile/…`, `/<lognum>/landmarks`).
63+
64+
Supporting packages: **`cert/`** holds the wire types (`TBSCertificateLogEntry`,
65+
`MTCProof`, `MTCSubtreeSignatureInput`, `CertificatePropertyList`) and the multi-mirror
66+
request client. **`tlogx/`** extends `x/mod/sumdb/tlog` with the §4 subtree primitives
67+
(consistency, inclusion, covering subtrees). **`signer/`** is the ML-DSA cosigner
68+
abstraction. **`landmark/`** allocates §6.3 landmark sequences and serves `/landmarks`.
69+
**`mirror/`** is the upstream follower plus the `/sign-subtree` server. **`storage/`** is
70+
on-disk K/V using atomic-rename writes.
71+
72+
**Single-writer assumption**: the log has no locks or shared-state coordination across
73+
processes — single-writer is enforced by documentation, not by code. See
74+
[docs/threat-model.md](docs/threat-model.md), [docs/disk-layout.md](docs/disk-layout.md).
75+
76+
## IDs are derived, not independent
77+
78+
The **CA ID** (`ca_cosigner.id`, e.g. `1.3.6.1.4.1.44363.47.1.99`) is load-bearing: draft
79+
§5.4 requires the CA cosigner ID to equal the CA ID, so this one value identifies the CA,
80+
seeds the issuer DN, and roots all derived IDs — the log ID is `<CA-ID>.0.<lognum>` and
81+
landmark trust-anchor IDs are `<CA-ID>.1.<lognum>.L`. There is no separate `base_id`.
82+
83+
## cactus-cli (debugging / verification)
84+
85+
```
86+
cactus-cli tree show|verify <log-url> # checkpoint vs. recomputed root from tiles
87+
cactus-cli entry <log-url> <index> # decode one §5.2.1 entry
88+
cactus-cli cert verify <cert.pem> <log-url> # full §7.2 verification, prints OK
89+
cactus-cli prove <log-url> <index> # JSON inclusion proof
90+
```
91+
92+
[draft-ietf-plants-merkle-tree-certs-04]: https://www.ietf.org/archive/id/draft-ietf-plants-merkle-tree-certs-04.txt

0 commit comments

Comments
 (0)