All skills
Skillintermediate

Crypto Protocol Diagram

Produces a Mermaid `sequenceDiagram` (written to file) and an ASCII sequence diagram (printed inline) from either:

Claude Code Knowledge Pack7/10/2026

Overview

Crypto Protocol Diagram

Produces a Mermaid sequenceDiagram (written to file) and an ASCII sequence diagram (printed inline) from either:

  • Source code implementing a cryptographic protocol, or
  • A specification — RFC, academic paper, pseudocode, informal prose, ProVerif (.pv), or Tamarin (.spthy) model.

Tools used: Read, Write, Grep, Glob, Bash, WebFetch (for URL specs).

Unlike the diagramming-code skill (which visualizes code structure), this skill extracts protocol semantics: who sends what to whom, what cryptographic transformations occur at each step, and what protocol phases exist.

For call graphs, class hierarchies, or module dependency maps, use the diagramming-code skill instead.

When to Use

  • User asks to diagram, visualize, or extract a cryptographic protocol
  • Input is source code implementing a handshake, key exchange, or multi-party protocol
  • Input is an RFC, academic paper, pseudocode, or formal model (ProVerif/Tamarin)
  • User names a specific protocol (TLS, Noise, Signal, X3DH, FROST)

When NOT to Use

  • User wants a call graph, class hierarchy, or module dependency map — use diagramming-code
  • User wants to formally verify a protocol — use mermaid-to-proverif (after generating the diagram)
  • Input has no cryptographic protocol semantics (no parties, no message exchange)

Rationalizations to Reject

RationalizationWhy It's WrongRequired Action
"The protocol is simple, I can diagram from memory"Memory-based diagrams miss steps and invert arrowsRead the source or spec systematically
"I'll skip the spec path since code exists"Code may diverge from the spec — both paths catch different bugsWhen both exist, run spec workflow first, then annotate code divergences
"Crypto annotations are optional decoration"Without crypto annotations, the diagram is just a message flow — useless for security reviewAnnotate every cryptographic operation
"The abort path is obvious, no need for alt blocks"Implicit abort handling hides missing error checksShow every abort/error path with alt blocks
"I don't need to check the examples first"The examples define the expected output quality barStudy the relevant example before working on unfamiliar input
"ProVerif/Tamarin models are code, not specs"Formal models are specifications — they describe intended behavior, not implementationUse the spec workflow (S1–S5) for .pv and .spthy files

Workflow

Protocol Diagram Progress:
- [ ] Step 0: Determine input type (code / spec / both)
- [ ] Step 1 (code) or S1–S5 (spec): Extract protocol structure
- [ ] Step 6: Generate sequenceDiagram
- [ ] Step 7: Verify and deliver

Step 0: Determine Input Type

Before doing anything else, classify the input:

SignalInput type
Source file extensions (.py, .rs, .go, .ts, .js, .cpp, .c)Code
Function/class definitions, import statementsCode
RFC-style section headers (§, Section X.Y, MUST/SHALL keywords)Spec
Algorithm/Protocol/Figure labels, mathematical notationSpec
ProVerif file (.pv) with process, let, in/outSpec
Tamarin file (.spthy) with rule, --[...]->Spec
Plain prose or numbered steps describing a protocolSpec
Both source files and a spec documentBoth (annotate divergences with ⚠️)
  • Code only → skip to Step 1 below
  • Spec only → skip to Spec Workflow (S1–S5) below
  • Both → run Spec Workflow first, then use the code-reading steps to verify the implementation against the spec diagram and annotate any divergences with ⚠️
  • Ambiguous → ask the user: "Is this a source code file, a specification document, or both?"

Step 1: Locate Protocol Entry Points

Grep for function names, type names, and comments that reveal the protocol:

# Find handshake, session, round, phase entry points
rg -l "handshake|session_init|round[_0-9]|setup|keygen|send_msg|recv_msg" {targetDir}

# Find crypto primitives in use
rg "sign|verify|encrypt|decrypt|dh|ecdh|kdf|hkdf|hmac|hash|commit|reveal|share" \\
    {targetDir} --type-add 'src:*.{py,rs,go,ts,js,cpp,c}' -t src -l

Start reading from the highest-level orchestration function — the one that calls into handshake phases or the main protocol loop.

Step 2: Identify Parties and Roles

Extract participant names from:

  • Struct/class names: Client, Server, Initiator, Responder, Prover, Verifier, Dealer, Party, Coordinator
  • Function parameter names that carry state for a role
  • Comments declaring the protocol role
  • Test fixtures that set up two-party or N-party scenarios

Map these to Mermaid participant declarations. Use short, readable aliases:

participant I as Initiator
participant R as Responder

Step 3: Trace Message Flow

Follow state transitions and network sends/receives. Look for patterns like:

PatternMeaning
send(msg) / recv()Direct message exchange
serialize + transmitStructured message sent
Return value passed to other party's functionLogical message (in-process)
round1_outputround2_inputRound-based MPC step
Struct fields named ephemeral_key, ciphertext, mac, tagMessage contents

For in-process protocol implementations (where both parties run in the same process), treat function call boundaries as logical message sends when they represent what would be a network boundary in deployment.

Step 4: Annotate Cryptographic Operations

At each protocol step, identify and label:

OperationDiagram annotation
Key generationNote over A: keygen(params) → pk, sk
DH / ECDHNote over A,B: DH(sk_A, pk_B)
KDF / HKDFNote over A: HKDF(ikm, salt, info)
SigningNote over A: Sign(sk, msg) → σ
VerificationNote over B: Verify(pk, msg, σ)
EncryptionNote over A: Enc(key, plaintext) → ct
DecryptionNote over B: Dec(key, ct) → plaintext
CommitmentNote over A: Commit(value, rand) → C
HashNote over A: H(data) → digest
Secret sharingNote over D: Share(secret, t, n) → {s_i}
Threshold combineNote over C: Combine({s_i}) → secret

Keep annotations concise — use mathematical shorthand, not code.

Step 5: Identify Protocol Phases

Group message steps into named phases using rect or Note blocks:

Common phases to detect:

  • Setup / Key Generation: party key creation, trusted setup, parameter gen
  • Handshake / Init: ephemeral key exchange, nonce exchange, version negotiation
  • Authentication: identity proof, certificate exchange, signature verification
  • Key Derivation: session key derivation from shared secrets
  • Data Transfer / Main Protocol: encrypted application data exchange
  • Finalization / Teardown: session close, MAC verification, abort handling

Detect abort/error paths and show them with alt blocks.


Spec Workflow (S1–S5)

Use this path when the input is a specification document rather than source code. After completing S1–S5, continue with Step 6 (Generate sequenceDiagram) and Step 7 (Verify and deliver) from the code workflow above.

Step S1: Ingest the Spec

Obtain the full spec text:

  • File path provided → read with the Read tool
  • URL provided → fetch with WebFetch
  • Pasted inline → work directly from conversation context

Then identify the spec format and read references/spec-parsing-patterns.md for format-specific extraction guidance:

FormatSignals
RFCRFC XXXX, MUST/SHALL/SHOULD, ABNF grammars, section-numbered prose
Academic paper / pseudocodeAlgorithm X, Protocol X, Figure X, numbered steps, / in math mode
Informal proseNumbered lists, "A sends B ...", plain English descriptions
ProVerif (.pv)process, let, in(ch, x), out(ch, msg), ! (replication)
Tamarin (.spthy)rule, --[ ]->, Fr(~x), !Pk(A, pk), In(m), Out(m)

If the spec references a known named protocol (TLS, Noise, Signal, X3DH, Double Ratchet, FROST), also read references/protocol-patterns.md to use its canonical flow as a skeleton and fill in spec-specific details.

Step S2: Extract Parties and Roles

Identify all protocol participants. Look for:

  • Named roles in prose or pseudocode: Alice, Bob, Client, Server, Initiator, Responder, Prover, Verifier, Dealer, Party_i, Coordinator, Signer
  • Section headers: "Parties", "Roles", "Participants", "Setup", "Notation"
  • ProVerif: process names at top level (let ClientProc(...), let ServerProc(...))
  • Tamarin: rule names and fact arguments (e.g. !Pk($A, pk)$A is a party)

Map each role to a Mermaid participant declaration. Use short IDs with descriptive aliases (see naming conventions in references/mermaid-sequence-syntax.md).

Step S3: Extract Message Flow

Trace what each party sends to whom and in what order. Extraction patterns by format:

RFC / informal prose:

  • Arrow notation: A → B: msg, A -> B
  • Sentence patterns: "A sends B ...", "B responds with ...", "A transmits ...", "upon receiving X, B sends Y"
  • Numbered steps: extract in order, inferring sender/receiver from context

Pseudocode:

  • Function signatures with explicit sender/receiver parameters
  • send(party, msg) / receive(party) calls
  • Return values passed as inputs to the other party's function in the next step

ProVerif (.pv):

  • out(ch, msg) — send on channel ch
  • in(ch, x) — receive on channel ch, bind to x
  • Match out/in pairs on the same channel to identify message flows
  • ! (replication) signals a role that handles multiple sessions

Tamarin (.spthy):

  • In(m) premise — receive message m
  • Out(m) conclusion — send message m
  • Rule name and ordering of rules reveal protocol rounds
  • Fr(~x) — fresh random value generated by a party
  • --[ Label ]-> facts — security annotations, not messages

Preserve the ordering and round structure. Group concurrent sends (broadcast) using par blocks in the final diagram.

Step S4: Extract Cryptographic Operations

For each protocol step, identify the cryptographic operations performed and which party performs them:

Spec notationOperationDiagram annotation
keygen(), Gen(1^λ)Key generationNote over A: keygen() → pk, sk
DH(a, B), g^abDH / ECDHNote over A,B: DH(sk_A, pk_B)
KDF(ikm), HKDF(...)Key derivationNote over A: HKDF(ikm, salt, info) → k
Sign(sk, m), σ ← SignSigningNote over A: Sign(sk, msg) → σ
Verify(pk, m, σ)VerificationNote over B: Verify(pk, msg, σ)
Enc(k, m), {m}_kEncryptionNote over A: Enc(k, plaintext) → ct
Dec(k, c)DecryptionNote over B: Dec(k, ct) → plaintext
H(m), hash(m)HashNote over A: H(data) → digest
Commit(v, r), comCommitmentNote over A: Commit(value, rand) → C
ProVerif senc(m, k)Symmetric encryptionNote over A: Enc(k, m) → ct
ProVerif pk(sk)Public key derivationNote over A: pk = pk(sk)
ProVerif sign(m, sk)SigningNote over A: Sign(sk, m) → σ

Identify security conditions and abort paths:

  • Prose: "if verification fails, abort", "only if ...", "reject if ..."
  • Pseudocode: assert, require, if ... abort
  • ProVerif: if m = expected then ... else 0
  • Tamarin: contradicting facts or restriction lemmas

These become alt blocks in the final diagram.

Step S5: Flag Spec Ambiguities

Before moving to Step 6, check for gaps:

  • Unclear message ordering: infer from round structure or section order; annotate with ⚠️ ordering inferred from spec structure
  • Implied parties: if a party's role is implied but unnamed, give it a descriptive name and note the inference
  • Missing steps: if the spec omits a step that the canonical pattern for this protocol requires, annotate: ⚠️ spec omits [step] — canonical protocol requires it
  • Underspecified crypto: if the spec says "encrypt" without specifying the scheme, annotate: ⚠️ encryption scheme not specified
  • ProVerif/Tamarin: private channels (c declared with new c or as a private free name) represent out-of-band channels — note them

Step 6: Generate sequenceDiagram

Produce Mermaid syntax following the rules in references/mermaid-sequence-syntax.md.

Completeness over brevity. Show every distinct message type. Omit repeated loop iterations (use loop blocks instead), but never omit a distinct protocol step.

Correctness over aesthetics. The diagram must match what the code actually does. If the code diverges from a known spec, annotate the divergence:

Note over A,B: ⚠️ spec requires MAC here — implementation omits it

Step 7: Verify and Deliver

Before delivering:

  • Every participant declared actually sends or receives at least one message
  • Arrows point in the correct direction (sender → receiver)
  • Cryptographic operations are on the correct party (the one computing them)
  • If protocol phases are used, no arrows appear outside a phase block
  • alt blocks cover known abort/error paths
  • Diagram renders without syntax errors (check references/mermaid-sequence-syntax.md for common pitfalls)
  • If spec divergence found, annotated with ⚠️

Write the diagram to a file. Choose a filename derived from the protocol name, e.g. noise-xx-handshake.md or x3dh-key-agreement.md. Write a Markdown file with this structure:

#  Sequence Diagram

\\`\\`\\`mermaid
sequenceDiagram
    ...
\\`\\`\\`

## Protocol Summary

- **Parties:** ...
- **Round complexity:** ...
- **Key primitives:** ...
- **Authentication:** ...
- **Forward secrecy:** ...
- **Notable:** [spec deviations or security