How 1password/cpace works
1. What this repository is
- This is a single Rust library crate implementing CPace, a balanced PAKE, for Ristretto255 with SHA-512.
- It is intentionally no_std compatible, so the architecture is focused on pure cryptographic protocol logic rather than OS, network, or application integration.
2. Top-level shape
- The crate is small and modular: src/lib.rs is the public entry point, and the implementation is split into a few internal support modules:
- encoding.rs
- formatting.rs
- keys.rs
- errors.rs
- There are no subcrates, services, or runtime processes; this is a library-only architecture.
3. Public API boundary
- lib.rs is the main boundary between consumers and the protocol implementation.
- It likely exposes the CPace session flow, key material types, and protocol-side operations, while keeping protocol internals hidden in the helper modules.
- For an architecture diagram, treat this as the API façade.
4. Protocol flow
- The core data flow is: shared password/secret + protocol context/identifiers → CPace formatting/encoding → ephemeral protocol exchange → shared session key → key confirmation.
- The README makes clear that the library enforces an extra key-confirmation round beyond the bare CPace exchange, so the protocol flow is not just key derivation but also mutual proof of key agreement.
5. formatting.rs role
- This module is the protocol’s domain-separation and transcript-construction layer.
- In a PAKE, this is where identities, labels, and context are normalized into the byte strings that feed later cryptographic steps.
- Architecturally, it sits between caller-provided inputs and low-level hashing/encoding.
6. encoding.rs role
- This module handles byte-level representation of protocol values.
- It is the likely place for translating group elements, scalars, and transcript fields into canonical encoded forms used by the protocol.
- For a diagram, this is the serialization/normalization boundary that prevents higher layers from depending on raw internal representations.
7. keys.rs role
- This module is the key schedule and key confirmation layer.
- It likely derives the final shared key from protocol secrets and then produces/verifies confirmation material so both sides can prove they arrived at the same result.
- This is the most security-sensitive part of the control flow after the core group operations.
8. errors.rs role
- This module centralizes the crate’s failure model.
- In a crypto library, this usually represents invalid inputs, decoding/encoding failures, protocol-state mismatches, or confirmation failures.
- It forms the boundary for how the library reports recoverable issues to callers without exposing internals.
9. Cryptographic constraints and assumptions
- The implementation is fixed to Ristretto255 + SHA-512, which simplifies the architecture by removing algorithm selection at runtime.
- That hardcoding means the protocol code can rely on a specific group abstraction and avoid unsafe low-level input handling from network attackers.
- The diagram should reflect this as a fixed crypto backend, not a pluggable one.
10. External dependencies and system boundaries
- There is no evidence of networking, storage, UI, or async runtime integration in this repo.
- The external surface is the Rust consumer of the library; everything else is internal protocol machinery.
- The included Cure53 audit PDF is documentation/assurance material, not part of execution flow.
11. How to draw it
- Show one outer box: Rust application / consumer.
- Inside the crate, show a public CPace API in lib.rs, feeding into helper layers:
- input formatting/domain separation
- encoding/decoding of protocol values
- key derivation and confirmation
- error handling
- Annotate the cryptographic core with Ristretto255 + SHA-512, and the protocol outcome as shared session key + confirmation success.
Main entry points: lib.rs CPace API · keys.rs Key schedule · encoding.rs Encoding · errors.rs Errors
Components 11
External
Rust application or library consumer
- Rust consumer · Caller using the CPace library
- Protocol inputs · Password, identities, and protocol context supplied by the caller
cpace crate
Internal protocol implementation
- CPace API · Public entry point and protocol boundary
src/lib.rs - Formatting · Normalizes identities, labels, and context into protocol inputs
src/formatting.rs - Encoding · Canonical byte encoding and decoding of protocol values
src/encoding.rs - Key schedule · Derives the shared key and confirmation material
src/keys.rs - Errors · Shared recoverable error types for invalid inputs and protocol failures
src/errors.rs - Ristretto255 + SHA-512 · Hardcoded group and hash foundation for the protocol
- CPace exchange · Core protocol round that mixes inputs into a shared secret
- Session key · Shared key material produced by the protocol
- Confirm result · Verification that both sides derived the same session key
Connections 15
- Rust consumer → CPace API: calls · Consumer invokes the public CPace API
- Protocol inputs → CPace API: provides · Caller supplies password, identities, and context
- CPace API → Formatting: normalizes · API passes protocol context into transcript construction
- CPace API → Encoding: encodes · API routes protocol values through canonical byte handling
- CPace API → Key schedule: drives · API coordinates key derivation and confirmation
- CPace API → Errors: reports · API surfaces recoverable failures through the crate error model
- Formatting → Encoding: feeds · Formatted transcript material becomes encoded protocol data
- Encoding → CPace exchange: prepares · Encoded values are consumed by the core exchange
- Ristretto255 + SHA-512 → CPace exchange: powers · Fixed Ristretto255 + SHA-512 backend underpins the PAKE computation
- CPace exchange → Session key: derives · The balanced PAKE round yields shared session key material
- Session key → Key schedule: confirms · Derived key is used for mutual confirmation
- Key schedule → Confirm result: verifies · Key confirmation success proves agreement
- CPace exchange → Errors: fails · Protocol and decoding failures are mapped to crate errors
- Key schedule → Errors: fails · Confirmation mismatches and key schedule issues become errors
- Confirm result → Rust consumer: returns · Successful completion is observed by the caller