# jedisct1/cpace architecture

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

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

## Overview

1. **Repository purpose**
   - This is a small C library implementing **CPace** over **Ristretto255** for deriving shared keys from a low-entropy secret.
   - The repo is structured as a reusable cryptographic library plus a standalone test program.

2. **Primary architecture**
   - The codebase is centered around a single public API in `src/crypto_cpace.h` and its implementation in `src/crypto_cpace.c`.
   - There are no services, daemons, or application layers beyond the library and test harness.

3. **Public library boundary**
   - `crypto_cpace.h` is the main contract for consumers.
   - It exposes:
     - initialization (`crypto_cpace_init`)
     - client-side phase 1 and phase 3
     - server-side phase 2
     - state and shared-key result types
     - protocol size constants such as public data, response, and shared-key byte lengths

4. **Protocol flow**
   - The library implements a **single round-trip** PAKE:
     - client computes public data
     - server consumes that public data and returns a response
     - client consumes the response and derives the final shared keys
   - This is a strict client/server interaction boundary, not a bidirectional stream or session manager.

5. **Data model**
   - The important state object is `crypto_cpace_state`, used by the client across steps 1 and 3.
   - The result object `crypto_cpace_shared_keys` holds two direction-specific 256-bit keys:
     - one for client-to-server
     - one for server-to-client
   - Identifiers, password, and optional additional data are all input parameters to the protocol.

6. **Cryptographic dependency boundary**
   - The implementation depends on **libsodium 1.0.17+**.
   - The README notes it uses:
     - **Ristretto255** as the group
     - **SHA-512** as the hash function
   - `crypto_cpace_init()` is effectively a thin wrapper around `sodium_init()`.

7. **Client-side responsibilities**
   - The client is responsible for:
     - initializing the protocol state
     - generating the outbound public data
     - later consuming the server response to finalize the shared keys
   - The client does not directly compute the server-side key material; both sides independently derive matching keys from the shared inputs.

8. **Server-side responsibilities**
   - The server takes the client’s public data and the same shared secret/identifiers.
   - It computes the shared keys immediately and returns a protocol response for the client.
   - This makes the server step a combined “verify + derive + respond” operation.

9. **Testing boundary**
   - `test/test.c` is a standalone validation program, not a unit-test framework tree.
   - Its role is to exercise the full protocol round-trip and confirm that client- and server-computed keys match.

10. **Integration surface**
   - Consumers only need to link against this library and libsodium.
   - The README example shows the intended usage pattern: initialize, run the three protocol steps, then compare or use the derived keys.

11. **Portability and constraints**
   - The README explicitly calls out portability goals toward **wasm-crypto**, which is why the design is lightweight and uses common primitives.
   - Input identifiers are bounded to **255 bytes**, which is a protocol constraint that affects calling code and data validation.

12. **What an architecture diagram should show**
   - A minimal diagram should include:
     - a client component
     - a server component
     - the CPace library boundary inside both
     - the libsodium dependency beneath the library
     - the one-round-trip message exchange: public data out, response back, shared keys produced on both sides

Main entry points: [`test/test.c`](https://github.com/jedisct1/cpace/blob/master/test/test.c) (Round-trip test), [`src/crypto_cpace.c`](https://github.com/jedisct1/cpace/blob/master/src/crypto_cpace.c) (CPace core), [`src/crypto_cpace.h`](https://github.com/jedisct1/cpace/blob/master/src/crypto_cpace.h) (Public API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_library["CPace library"]
  node_node_header["Public API<br/>header<br/>[crypto_cpace.h]"]
  node_node_impl["CPace core<br/>implementation<br/>[crypto_cpace.c]"]
  node_node_init["Init<br/>api entrypoint<br/>[crypto_cpace.c]"]
  node_node_sodium{{"libsodium<br/>crypto dependency"}}
end

subgraph group_group_protocol["Protocol flow"]
  node_node_client1(("Client phase 1<br/>client step"))
  node_node_server2(("Server phase 2<br/>server step"))
  node_node_client3(("Client phase 3<br/>client step"))
  node_node_state[("Session state<br/>client state")]
  node_node_keys[("Shared keys<br/>key result")]
  node_node_pubdata["Public data<br/>message"]
  node_node_response["Response<br/>message"]
end

subgraph group_group_validation["Validation"]
  node_node_test["Round-trip test<br/>validation program<br/>[test.c]"]
end

node_node_header -->|"declares"| node_node_impl
node_node_impl -->|"uses"| node_node_sodium
node_node_init -->|"calls"| node_node_sodium
node_node_client1 -->|"writes"| node_node_state
node_node_client1 -->|"emits"| node_node_pubdata
node_node_pubdata -->|"inputs"| node_node_server2
node_node_server2 -->|"emits"| node_node_response
node_node_server2 -->|"derives"| node_node_keys
node_node_response -->|"inputs"| node_node_client3
node_node_client3 -->|"finalizes"| node_node_keys
node_node_state -->|"reads"| node_node_client3
node_node_test -->|"exercises"| node_node_client1
node_node_test -->|"exercises"| node_node_server2
node_node_test -->|"verifies"| node_node_keys

click node_node_header "https://github.com/jedisct1/cpace/blob/master/src/crypto_cpace.h"
click node_node_impl "https://github.com/jedisct1/cpace/blob/master/src/crypto_cpace.c"
click node_node_init "https://github.com/jedisct1/cpace/blob/master/src/crypto_cpace.c"
click node_node_test "https://github.com/jedisct1/cpace/blob/master/test/test.c"

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_node_header,node_node_impl,node_node_init,node_node_sodium toneBlue
class node_node_client1,node_node_server2,node_node_client3,node_node_state,node_node_keys,node_node_pubdata,node_node_response toneAmber
class node_node_test toneMint
```

## Components

### CPace library

Public API, implementation, and cryptographic backend.

- [Public API](https://github.com/jedisct1/cpace/blob/master/src/crypto_cpace.h): header · Main contract for consumers: init, protocol phases, state, shared-key types, and size constants. · `src/crypto_cpace.h`
- [CPace core](https://github.com/jedisct1/cpace/blob/master/src/crypto_cpace.c): implementation · Implements the CPace protocol over Ristretto255 using libsodium primitives. · `src/crypto_cpace.c`
- [Init](https://github.com/jedisct1/cpace/blob/master/src/crypto_cpace.c): api entrypoint · Wraps sodium_init() to prepare the library for use. · `src/crypto_cpace.c`
- **libsodium**: crypto dependency · External dependency providing sodium_init(), SHA-512, and Ristretto255-backed primitives.

### Protocol flow

Client/server round-trip and derived shared keys.

- **Client phase 1**: client step · Initializes client state and generates outbound public data.
- **Server phase 2**: server step · Consumes client public data, verifies inputs, derives shared keys, and produces the response.
- **Client phase 3**: client step · Consumes the server response and finalizes shared keys.
- **Session state**: client state · Client-side protocol state carried between phases 1 and 3.
- **Shared keys**: key result · Two direction-specific 256-bit keys for client-to-server and server-to-client traffic.
- **Public data**: message · Client-to-server protocol message carrying the outbound public data.
- **Response**: message · Server-to-client protocol message carrying the CPace response.

### Validation

Standalone round-trip exercise program.

- [Round-trip test](https://github.com/jedisct1/cpace/blob/master/test/test.c): validation program · Standalone program that runs the full protocol and checks that both sides derive matching keys. · `test/test.c`

## Connections

- Public API → CPace core: declares · The public API is implemented by the library core.
- CPace core → libsodium: uses · The implementation depends on libsodium for initialization and cryptographic primitives.
- Init → libsodium: calls · Initialization delegates to sodium_init().
- Client phase 1 → Session state: writes · Phase 1 creates and stores client state.
- Client phase 1 → Public data: emits · The client produces public data for the server.
- Public data → Server phase 2: inputs · The server consumes the client's public data.
- Server phase 2 → Response: emits · The server returns the protocol response.
- Server phase 2 → Shared keys: derives · The server independently derives the shared keys.
- Response → Client phase 3: inputs · The client consumes the server response.
- Client phase 3 → Shared keys: finalizes · The client completes key derivation from the response.
- Session state → Client phase 3: reads · Phase 3 uses the client state from phase 1.
- Round-trip test → Client phase 1: exercises · The test program drives the client side of the protocol.
- Round-trip test → Server phase 2: exercises · The test program drives the server side of the protocol.
- Round-trip test → Shared keys: verifies · The test confirms both sides derive matching keys.
