# the-sarge/cpace architecture

> Architecture diagram of the GitHub repository the-sarge/cpace, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-18). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/the-sarge/cpace
- Repository: https://github.com/the-sarge/cpace

## Overview

1. **Repository shape**
This is a single-package Go cryptography library, not an application service. The root package implements the CPace draft-21 PAKE profile `CPACE-RISTR255-SHA512`, with the public API centered in `api.go` and the protocol/state machinery split across small internal files.

2. **Top-level protocol boundary**
The public surface is an initiator/responder exchange with mandatory explicit key confirmation: `Start` creates initiator state and message A, `Respond` consumes A and emits responder state and message B, `Initiator.Finish` verifies B and emits message C plus a `Session`, and `Responder.Finish` verifies C and yields its `Session`. Authentication only exists after the finish calls succeed; `Respond` alone is not authentication.

3. **Core data flow**
The main flow is: caller supplies `Input` and role identity data → the library constructs CPace CI and transcript state → the peer message is framed/unframed → confirmation tags are checked during finish → a shared session key is derived and exposed through `Session.Export`. Message bytes are intended to be opaque to applications.

4. **Protocol state and lifecycle**
`core.go`, `session.go`, and `terminal_state.go` appear to implement the protocol state machine and lifecycle rules. The design is intentionally single-use for finish operations, with explicit `Close` methods to release local secrets if a half-finished exchange is abandoned. Value copies share terminal state, so lifecycle is tied to the underlying state rather than the Go value copy.

5. **Input and identity binding**
`input.go` defines the role-local input contract. Each side provides `SelfID`, `PeerID`, password, context, session ID, and local associated data. The library binds stable application identities into CI; it does not infer identities from wire messages. The README stresses that session IDs must be fresh and non-secret, and that outer negotiation/downgrade protection is out of scope.

6. **Framing and wire format**
`framing.go`, `length_value.go`, `peer_share.go`, and `transcript.go` handle the package-owned binary encoding. The wire format is versioned by this module and begins with a fixed prefix byte `0xc1`. Validation includes exact public-share/tag lengths plus an aggregate decoder backstop before deeper field parsing, so malformed framed inputs fail early.

7. **Cryptographic operations**
`crypto.go` and `caps.go` cover the cryptographic primitives and capability/cipher-suite constraints for the chosen draft profile. Randomness is sourced only from Go’s `crypto/rand.Reader`; callers do not supply entropy. `Session.Export` is a deterministic, domain-separated KDF-style export from the confirmed shared secret, not a randomness source.

8. **Error and invariant handling**
`errors.go` and `caps.go` encode package-specific failure modes and bounds. The library enforces per-field size limits on passwords, party IDs, context, session IDs, and local associated data. Empty session IDs are rejected by default, malformed or failed confirmation messages consume one-time state, and closed sessions later reject export operations.

9. **Tests and evidence**
The repository has broad unit, vector, fuzz, and benchmark coverage in `*_test.go`, plus draft test vectors in `testdata/`. This is a crypto repository that relies heavily on correctness evidence: tests for framing, caps, strings, vectors, and examples help validate both protocol semantics and boundary conditions.

10. **Tooling, CI, and release governance**
The repo includes a substantial security/release pipeline under `.github/workflows`, `Taskfile.yml`, `scripts/`, and `tools/`. There are custom helper tools for evidence-baseline checks and release-policy checks, plus OSS-Fuzz integration under `ossfuzz/`. The documentation tree is unusually important to the architecture because it records threat model, security gates, fuzz evidence, release policy, and ADRs that constrain future changes.

11. **Architectural summary**
This is a tightly scoped, security-driven protocol library: one protocol profile, one wire format, one authenticated key-exchange flow, and a strong emphasis on explicit lifecycle and validation boundaries. If you are drawing the architecture, the key boxes are: caller input, protocol state machine, framing/validation, cryptographic derivation, session export, and the surrounding verification/release infrastructure.

Main entry points: [`core.go`](https://github.com/the-sarge/cpace/blob/main/core.go) (State core), [`framing.go`](https://github.com/the-sarge/cpace/blob/main/framing.go) (Framing), [`api.go`](https://github.com/the-sarge/cpace/blob/main/api.go) (API), [`terminal_state.go`](https://github.com/the-sarge/cpace/blob/main/terminal_state.go) (Terminal state)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_core["Protocol core"]
  node_api["API<br/>public surface<br/>[api.go]"]
  node_input["Input<br/>role binding<br/>[input.go]"]
  node_core_state["State core<br/>state machine<br/>[core.go]"]
  node_terminal_state["Terminal state<br/>lifecycle guard<br/>[terminal_state.go]"]
  node_session[("Session<br/>key container<br/>[session.go]")]
end

subgraph group_wire["Wire format"]
  node_framing["Framing<br/>wire codec<br/>[framing.go]"]
  node_peer_share["Peer share<br/>wire payload<br/>[peer_share.go]"]
  node_transcript["Transcript<br/>context hash<br/>[transcript.go]"]
  node_length_value["L/V codec<br/>binary encoding<br/>[length_value.go]"]
end

subgraph group_crypto["Crypto engine"]
  node_crypto["Primitives<br/>cryptographic ops<br/>[crypto.go]"]
  node_caps["Caps<br/>suite limits<br/>[caps.go]"]
  node_errors["Errors<br/>invariants<br/>[errors.go]"]
end

subgraph group_policy["Assurance"]
  node_api_test["API tests<br/>protocol tests<br/>[api_test.go]"]
  node_vectors["Vectors<br/>draft evidence<br/>[vectors_test.go]"]
  node_fuzz["Fuzzing<br/>robustness tests<br/>[fuzz_test.go]"]
  node_docs["Docs"]
  node_ci["CI and release<br/>automation<br/>[workflows]"]
  node_ossfuzz["OSS-Fuzz<br/>fuzz harness"]
end

node_api -->|"consumes"| node_input
node_api -->|"starts"| node_core_state
node_core_state -->|"frames"| node_framing
node_core_state -->|"updates"| node_transcript
node_core_state -->|"derives"| node_crypto
node_core_state -->|"finalizes"| node_terminal_state
node_terminal_state -->|"yields"| node_session
node_session -->|"exports"| node_crypto
node_framing -->|"encodes"| node_peer_share
node_framing -->|"uses"| node_length_value
node_peer_share -->|"bounds"| node_caps
node_crypto -->|"constrained by"| node_caps
node_errors -->|"guards"| node_terminal_state
node_errors -->|"blocks"| node_session
node_api_test -->|"exercises"| node_api
node_vectors -->|"verifies"| node_framing
node_fuzz -->|"hammers"| node_framing
node_docs -.->|"guides"| node_ci
node_ci -->|"integrates"| node_ossfuzz
node_docs -.->|"specifies"| node_api

click node_api "https://github.com/the-sarge/cpace/blob/main/api.go"
click node_input "https://github.com/the-sarge/cpace/blob/main/input.go"
click node_core_state "https://github.com/the-sarge/cpace/blob/main/core.go"
click node_terminal_state "https://github.com/the-sarge/cpace/blob/main/terminal_state.go"
click node_session "https://github.com/the-sarge/cpace/blob/main/session.go"
click node_framing "https://github.com/the-sarge/cpace/blob/main/framing.go"
click node_peer_share "https://github.com/the-sarge/cpace/blob/main/peer_share.go"
click node_transcript "https://github.com/the-sarge/cpace/blob/main/transcript.go"
click node_length_value "https://github.com/the-sarge/cpace/blob/main/length_value.go"
click node_crypto "https://github.com/the-sarge/cpace/blob/main/crypto.go"
click node_caps "https://github.com/the-sarge/cpace/blob/main/caps.go"
click node_errors "https://github.com/the-sarge/cpace/blob/main/errors.go"
click node_api_test "https://github.com/the-sarge/cpace/blob/main/api_test.go"
click node_vectors "https://github.com/the-sarge/cpace/blob/main/vectors_test.go"
click node_fuzz "https://github.com/the-sarge/cpace/blob/main/fuzz_test.go"
click node_docs "https://github.com/the-sarge/cpace/tree/main/docs"
click node_ci "https://github.com/the-sarge/cpace/blob/main/.github/workflows"
click node_ossfuzz "https://github.com/the-sarge/cpace/tree/main/ossfuzz"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_api,node_input,node_core_state,node_terminal_state,node_session toneBlue
class node_framing,node_peer_share,node_transcript,node_length_value toneAmber
class node_crypto,node_caps,node_errors toneMint
class node_api_test,node_vectors,node_fuzz,node_docs,node_ci,node_ossfuzz toneRose
```

## Components

### Protocol core

Public API, state machine, and session lifecycle for CPace exchanges.

- [API](https://github.com/the-sarge/cpace/blob/main/api.go): public surface · Start/Respond/Finish entry points for the CPace exchange. · `api.go`
- [Input](https://github.com/the-sarge/cpace/blob/main/input.go): role binding · Caller-supplied identities, password, context, session ID, and AAD. · `input.go`
- [State core](https://github.com/the-sarge/cpace/blob/main/core.go): state machine · Protocol coordination and exchange progression. · `core.go`
- [Terminal state](https://github.com/the-sarge/cpace/blob/main/terminal_state.go): lifecycle guard · Single-use finish semantics, closure, and shared terminal ownership. · `terminal_state.go`
- [Session](https://github.com/the-sarge/cpace/blob/main/session.go): key container · Confirmed shared secret and export operations. · `session.go`

### Wire format

Package-owned encoding, framing, and transcript handling.

- [Framing](https://github.com/the-sarge/cpace/blob/main/framing.go): wire codec · Module-owned message prefixing and validation. · `framing.go`
- [Peer share](https://github.com/the-sarge/cpace/blob/main/peer_share.go): wire payload · Encoded peer public-share and confirmation-tag payloads. · `peer_share.go`
- [Transcript](https://github.com/the-sarge/cpace/blob/main/transcript.go): context hash · Transcript state bound into confirmation and key derivation. · `transcript.go`
- [L/V codec](https://github.com/the-sarge/cpace/blob/main/length_value.go): binary encoding · Length-value framing and aggregate decode bounds. · `length_value.go`

### Crypto engine

Primitive operations, suite constraints, and export derivation.

- [Primitives](https://github.com/the-sarge/cpace/blob/main/crypto.go): cryptographic ops · Randomness, hashing, and profile-specific cryptographic operations. · `crypto.go`
- [Caps](https://github.com/the-sarge/cpace/blob/main/caps.go): suite limits · Draft-profile capability and size constraints. · `caps.go`
- [Errors](https://github.com/the-sarge/cpace/blob/main/errors.go): invariants · Package-specific failure modes and state-rejection behavior. · `errors.go`

### Assurance

Tests, vectors, fuzzing, docs, and release/security governance.

- [API tests](https://github.com/the-sarge/cpace/blob/main/api_test.go): protocol tests · Integration tests for the exchange flow and semantics. · `api_test.go`
- [Vectors](https://github.com/the-sarge/cpace/blob/main/vectors_test.go): draft evidence · Draft-profile test vectors and correctness checks. · `vectors_test.go`
- [Fuzzing](https://github.com/the-sarge/cpace/blob/main/fuzz_test.go): robustness tests · Fuzz coverage for framing, parsing, and protocol boundaries. · `fuzz_test.go`
- [Docs](https://github.com/the-sarge/cpace/tree/main/docs): governance docs · Threat model, ADRs, security gates, release policy, and evidence records. · `docs`
- [CI and release](https://github.com/the-sarge/cpace/blob/main/.github/workflows): automation · Workflows, scripts, tools, and release/security checks. · `.github/workflows`
- [OSS-Fuzz](https://github.com/the-sarge/cpace/tree/main/ossfuzz): fuzz harness · External fuzz integration and build harness. · `ossfuzz`

## Connections

- API → Input: consumes · Caller-provided role identity and secret inputs are bound into the exchange.
- API → State core: starts · Start/Respond/Finish drive the protocol state machine.
- State core → Framing: frames · Protocol messages are encoded and decoded through package-owned framing.
- State core → Transcript: updates · Each step contributes to the transcript bound into confirmation.
- State core → Primitives: derives · Protocol steps use cryptographic operations and randomness.
- State core → Terminal state: finalizes · Finish transitions create terminal state and enforce single-use semantics.
- Terminal state → Session: yields · Successful completion exposes a confirmed shared session.
- Session → Primitives: exports · Session export is a deterministic derivation from the confirmed secret.
- Framing → Peer share: encodes · Peer shares and confirmation tags are wrapped in module-owned wire bytes.
- Framing → L/V codec: uses · Framing depends on length-value bounds and decode backstops.
- Peer share → Caps: bounds · Encoded shares are constrained by profile-specific lengths.
- Primitives → Caps: constrained by · Primitive use is restricted by suite and size caps.
- Errors → Terminal state: guards · Invalid or failed finalization consumes one-time state and rejects reuse.
- Errors → Session: blocks · Closed or invalid sessions reject later export operations.
- API tests → API: exercises · Tests cover the public exchange API and lifecycle semantics.
- Vectors → Framing: verifies · Draft vectors validate wire format and confirmation behavior.
- Fuzzing → Framing: hammers · Fuzz targets stress malformed encodings and protocol boundaries.
- Docs → CI and release: guides · Documentation records security gates, evidence, and release policy enforced by automation.
- CI and release → OSS-Fuzz: integrates · Automation includes fuzzing and security/release checks.
- Docs → API: specifies · Architecture and threat-model documents constrain the public protocol contract.
