crypto-protocol-diagram

crypto-protocol-diagram

熱門

從原始碼、RFC、學術論文、虛擬碼、非正式敘述、ProVerif (.pv) 或 Tamarin (.spthy) 模型中提取協定訊息流程,並產生帶有密碼學註解的 Mermaid sequenceDiagram。適用於繪製密碼協定圖、視覺化握手或金鑰交換流程、從規格或 RFC 提取訊息流程、繪製 ProVerif 或 Tamarin 模型圖,或為 TLS、Noise、Signal、X3DH、Double Ratchet、FROST、DH 或 ECDH 協定繪製序列圖。

6336星標
545分支
更新於 2026/7/30
SKILL.md
唯讀
名稱
crypto-protocol-diagram
描述

從原始碼、RFC、學術論文、虛擬碼、非正式敘述、ProVerif (.pv) 或 Tamarin (.spthy) 模型中提取協定訊息流程,並產生帶有密碼學註解的 Mermaid sequenceDiagram。適用於繪製密碼協定圖、視覺化握手或金鑰交換流程、從規格或 RFC 提取訊息流程、繪製 ProVerif 或 Tamarin 模型圖,或為 TLS、Noise、Signal、X3DH、Double Ratchet、FROST、DH 或 ECDH 協定繪製序列圖。

Crypto Protocol Diagram

產生一個 Mermaid sequenceDiagram(寫入檔案)和一個 ASCII 序列圖(內嵌列印),來源可以是:

  • 原始碼實作的密碼協定,或
  • 規格文件 — RFC、學術論文、虛擬碼、非正式敘述、ProVerif (.pv) 或 Tamarin (.spthy) 模型。

使用的工具: Read、Write、Grep、Glob、Bash、WebFetch(用於 URL 規格)。

diagramming-code 技能(視覺化程式碼結構)不同,此技能提取的是協定語意:誰傳送了什麼給誰、每個步驟發生了哪些密碼學轉換,以及有哪些協定階段。

如需呼叫圖、類別階層或模組依賴圖,請改用 diagramming-code 技能。

使用時機

  • 使用者要求繪製、視覺化或提取密碼協定
  • 輸入是實作握手、金鑰交換或多方協定的原始碼
  • 輸入是 RFC、學術論文、虛擬碼或形式化模型(ProVerif/Tamarin)
  • 使用者指定特定協定(TLS、Noise、Signal、X3DH、FROST)

不應使用時機

  • 使用者想要呼叫圖、類別階層或模組依賴圖 — 請使用 diagramming-code
  • 使用者想要形式化驗證協定 — 請使用 mermaid-to-proverif(在產生圖表之後)
  • 輸入沒有密碼協定語意(沒有參與者、沒有訊息交換)

應拒絕的合理化藉口

合理化藉口 錯誤原因 應採取行動
"協定很簡單,我可以憑記憶畫圖" 憑記憶畫圖會遺漏步驟並反轉箭頭 系統性地閱讀原始碼或規格
"既然有原始碼,我就跳過規格路徑" 原始碼可能偏離規格 — 兩條路徑能發現不同的錯誤 兩者都存在時,先執行規格工作流程,再用原始碼註解偏離處
"密碼學註解只是可選的裝飾" 沒有密碼學註解,圖表只是訊息流程,對安全審查毫無用處 標註每一個密碼學操作
"中止路徑很明顯,不需要 alt 區塊" 隱含的中止處理會遺漏錯誤檢查 alt 區塊顯示每個中止/錯誤路徑
"我不需要先檢查範例" 範例定義了預期的輸出品質標準 在處理不熟悉的輸入前,先研讀相關範例
"ProVerif/Tamarin 模型是程式碼,不是規格" 形式化模型就是規格 — 它們描述的是預期行為,而非實作 .pv.spthy 檔案使用規格工作流程(S1–S5)

工作流程

協定圖進度:
- [ ] 步驟 0:判斷輸入類型(程式碼 / 規格 / 兩者)
- [ ] 步驟 1(程式碼)或 S1–S5(規格):提取協定結構
- [ ] 步驟 6:產生 sequenceDiagram
- [ ] 步驟 7:驗證並交付

步驟 0:判斷輸入類型

在執行任何其他操作之前,先分類輸入:

訊號 輸入類型
原始碼副檔名(.py.rs.go.ts.js.cpp.c 程式碼
函式/類別定義、import 陳述式 程式碼
RFC 風格的章節標題(§Section X.YMUST/SHALL 關鍵字) 規格
Algorithm/Protocol/Figure 標籤、數學符號 規格
ProVerif 檔案(.pv)包含 processletin/out 規格
Tamarin 檔案(.spthy)包含 rule--[...]-> 規格
描述協定的純文字或編號步驟 規格
同時有原始碼和規格文件 兩者(用 ⚠️ 註解偏離處)
  • 僅程式碼 → 跳到下面的步驟 1
  • 僅規格 → 跳到下面的規格工作流程(S1–S5)
  • 兩者 → 先執行規格工作流程,再用程式碼閱讀步驟驗證實作是否符合規格圖表,並用 ⚠️ 註解任何偏離處
  • 不明確 → 詢問使用者:「這是原始碼檔案、規格文件,還是兩者都有?」

步驟 1:定位協定進入點

使用 Grep 搜尋能揭示協定的函式名稱、型別名稱和註解:

# 尋找握手、session、round、phase 進入點
rg -l "handshake|session_init|round[_0-9]|setup|keygen|send_msg|recv_msg" {targetDir}

# 尋找使用的密碼學原語
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

從最高層級的協調函式開始閱讀 — 也就是呼叫握手階段或主要協定迴圈的函式。

步驟 2:識別參與者與角色

從以下來源提取參與者名稱:

  • 結構/類別名稱:ClientServerInitiatorResponderProverVerifierDealerPartyCoordinator
  • 攜帶角色狀態的函式參數名稱
  • 宣告協定角色的註解
  • 設定雙人或 N 人場景的測試 fixture

將這些對應到 Mermaid participant 宣告。使用簡短、可讀的別名:

participant I as Initiator
participant R as Responder

步驟 3:追蹤訊息流程

跟隨狀態轉換和網路收發。尋找以下模式:

模式 意義
send(msg) / recv() 直接訊息交換
serialize + transmit 結構化訊息傳送
回傳值傳遞給另一方的函式 邏輯訊息(程序內)
round1_outputround2_input 基於回合的 MPC 步驟
結構體欄位命名為 ephemeral_keyciphertextmactag 訊息內容

對於程序內協定實作(雙方在同一程序中執行),當函式呼叫邊界代表部署時的網路邊界時,將其視為邏輯訊息傳送。

步驟 4:標註密碼學操作

在每個協定步驟中,識別並標註:

操作 圖表註解
金鑰生成 Note over A: keygen(params) → pk, sk
DH / ECDH Note over A,B: DH(sk_A, pk_B)
KDF / HKDF Note over A: HKDF(ikm, salt, info)
簽章 Note over A: Sign(sk, msg) → σ
驗證 Note over B: Verify(pk, msg, σ)
加密 Note over A: Enc(key, plaintext) → ct
解密 Note over B: Dec(key, ct) → plaintext
承諾 Note over A: Commit(value, rand) → C
雜湊 Note over A: H(data) → digest
秘密分享 Note over D: Share(secret, t, n) → {s_i}
門檻值合併 Note over C: Combine({s_i}) → secret

保持註解簡潔 — 使用數學簡寫,而非程式碼。

步驟 5:識別協定階段

使用 rectNote 區塊將訊息步驟分組為命名階段:

常見的階段:

  • Setup / Key Generation:參與者金鑰建立、信任設定、參數生成
  • Handshake / Init:臨時金鑰交換、nonce 交換、版本協商
  • Authentication:身分證明、憑證交換、簽章驗證
  • Key Derivation:從共享秘密推導 session 金鑰
  • Data Transfer / Main Protocol:加密的應用資料交換
  • Finalization / Teardown:session 關閉、MAC 驗證、中止處理

偵測中止/錯誤路徑,並用 alt 區塊顯示。


規格工作流程(S1–S5)

當輸入是規格文件而非原始碼時,使用此路徑。完成 S1–S5 後,繼續執行上述程式碼工作流程的步驟 6(產生 sequenceDiagram)和步驟 7(驗證並交付)。

步驟 S1:讀取規格

取得完整的規格文字:

  • 提供檔案路徑 → 使用 Read 工具讀取
  • 提供 URL → 使用 WebFetch 擷取
  • 內嵌貼上 → 直接從對話上下文處理

然後識別規格格式,並閱讀
references/spec-parsing-patterns.md 以取得格式特定的提取指引:

格式 訊號
RFC RFC XXXXMUST/SHALL/SHOULD、ABNF 語法、章節編號的敘述
學術論文 / 虛擬碼 Algorithm XProtocol XFigure X、編號步驟、數學模式中的 /
非正式敘述 編號列表、「A 傳送 B ...」、純英文描述
ProVerif (.pv) processletin(ch, x)out(ch, msg)!(複製)
Tamarin (.spthy) rule--[ ]->Fr(~x)!Pk(A, pk)In(m)Out(m)

如果規格參考了已知的命名協定(TLS、Noise、Signal、X3DH、Double Ratchet、FROST),也請閱讀
references/protocol-patterns.md,以其標準流程作為骨架,並填入規格特定的細節。

步驟 S2:提取參與者與角色

識別所有協定參與者。尋找:

  • 敘述或虛擬碼中的命名角色AliceBobClientServerInitiatorResponderProverVerifierDealerParty_iCoordinatorSigner
  • 章節標題:「Parties」、「Roles」、「Participants」、「Setup」、「Notation」
  • ProVerif:頂層的 process 名稱(let ClientProc(...)let ServerProc(...)
  • Tamarin:rule 名稱和 fact 參數(例如 !Pk($A, pk)$A 是一個參與者)

將每個角色對應到 Mermaid participant 宣告。使用簡短的 ID 和描述性別名(請參閱
references/mermaid-sequence-syntax.md 中的命名慣例)。

步驟 S3:提取訊息流程

追蹤每個參與者傳送了什麼給誰,以及順序為何。按格式的提取模式:

RFC / 非正式敘述:

  • 箭頭符號:A → B: msgA -> B
  • 句型模式:「A 傳送 B ...」、「B 回應 ...」、「A 傳輸 ...」、「收到 X 後,B 傳送 Y」
  • 編號步驟:按順序提取,從上下文推斷傳送者/接收者

虛擬碼:

  • 帶有明確 sender/receiver 參數的函式簽章
  • send(party, msg) / receive(party) 呼叫
  • 回傳值作為下一步另一方函式的輸入

ProVerif (.pv):

  • out(ch, msg) — 在通道 ch 上傳送
  • in(ch, x) — 在通道 ch 上接收,綁定到 x
  • 比對同一通道上的 out/in 配對以識別訊息流
  • !(複製)表示處理多個 session 的角色

Tamarin (.spthy):

  • In(m) 前提 — 接收訊息 m
  • Out(m) 結論 — 傳送訊息 m
  • rule 名稱和 rule 順序揭示協定回合
  • Fr(~x) — 參與者產生的新鮮隨機值
  • --[ Label ]-> facts — 安全註解,非訊息

保留順序和回合結構。在最終圖表中使用 par 區塊對並行傳送(廣播)進行分組。

步驟 S4:提取密碼學操作

對於每個協定步驟,識別執行的密碼學操作以及執行該操作的參與者:

規格符號 操作 圖表註解
keygen()Gen(1^λ) 金鑰生成 Note over A: keygen() → pk, sk
DH(a, B)g^ab DH / ECDH Note over A,B: DH(sk_A, pk_B)
KDF(ikm)HKDF(...) 金鑰推導 Note over A: HKDF(ikm, salt, info) → k
Sign(sk, m)σ ← Sign 簽章 Note over A: Sign(sk, msg) → σ
Verify(pk, m, σ) 驗證 Note over B: Verify(pk, msg, σ)
Enc(k, m){m}_k 加密 Note over A: Enc(k, plaintext) → ct
Dec(k, c) 解密 Note over B: Dec(k, ct) → plaintext
H(m)hash(m) 雜湊 Note over A: H(data) → digest
Commit(v, r)com 承諾 Note over A: Commit(value, rand) → C
ProVerif senc(m, k) 對稱加密 Note over A: Enc(k, m) → ct
ProVerif pk(sk) 公鑰推導 Note over A: pk = pk(sk)
ProVerif sign(m, sk) 簽章 Note over A: Sign(sk, m) → σ

識別安全條件和中止路徑:

  • 敘述:「如果驗證失敗,中止」、「僅當 ...」、「如果 ... 則拒絕」
  • 虛擬碼:assertrequireif ... abort
  • ProVerif:if m = expected then ... else 0
  • Tamarin:矛盾的 fact 或 restriction lemma

這些將成為最終圖表中的 alt 區塊。

步驟 S5:標記規格不明確之處

在進入步驟 6 之前,檢查是否有缺口:

  • 不明確的訊息順序:從回合結構或章節順序推斷;用 ⚠️ ordering inferred from spec structure 註解
  • 隱含的參與者:如果參與者的角色是隱含但未命名的,給它一個描述性名稱並註明推斷
  • 遺漏的步驟:如果規格遺漏了該協定標準模式所需的步驟,註解:
    ⚠️ spec omits [step] — canonical protocol requires it
  • 未指定的密碼學:如果規格只說「加密」而未指定方案,註解:⚠️ encryption scheme not specified
  • ProVerif/Tamarin:私有通道(用 new c 宣告或作為私有自由名稱的 c)代表帶外通道 — 請註明

<!-- 程式碼路徑(步驟 1–5)和規格路徑(步驟 S1–S5)都在此繼續 -->

步驟 6:產生 sequenceDiagram

按照
references/mermaid-sequence-syntax.md 中的規則產生 Mermaid 語法。

完整性重於簡潔。 顯示每一種不同的訊息類型。省略重複的迴圈迭代(改用 loop 區塊),但絕不省略任何不同的協定步驟。

正確性重於美觀。 圖表必須與程式碼實際行為一致。如果程式碼偏離已知規格,請註解偏離處:

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

步驟 7:驗證並交付

在交付之前:

  • [ ] 每個宣告的參與者至少傳送或接收一則訊息
  • [ ] 箭頭指向正確方向(傳送者 → 接收者)
  • [ ] 密碼學操作位於正確的參與者(執行該操作的參與者)
  • [ ] 如果使用了協定階段,則沒有箭頭出現在階段區塊之外
  • [ ] alt 區塊涵蓋已知的中止/錯誤路徑
  • [ ] 圖表渲染無語法錯誤(請查閱
    references/mermaid-sequence-syntax.md 中的常見陷阱)
  • [ ] 如果發現規格偏離,已用 ⚠️ 註解

將圖表寫入檔案。 選擇一個從協定名稱衍生的檔名,例如 noise-xx-handshake.mdx3dh-key-agreement.md。寫入一個具有以下結構的 Markdown 檔案:

# <協定名稱> 序列圖

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

## 協定摘要

- **參與者:** ...
- **回合複雜度:** ...
- **主要密碼學原語:** ...
- **認證方式:** ...
- **前向安全性:** ...
- **注意事項:** [規格偏離或安全觀察,或「無」]

寫入檔案後,在回應中內嵌列印一個 ASCII 序列圖,接著是協定摘要。說明輸出檔名,讓使用者知道在哪裡找到 Mermaid 原始碼。

遵循
references/ascii-sequence-diagram.md 中的所有繪圖慣例,包括內嵌輸出格式。


決策樹

── 輸入是規格文件(非程式碼)?
│  └─ 步驟 S1:識別格式,閱讀 references/spec-parsing-patterns.md
│
── 輸入是原始碼(非規格)?
│  └─ 步驟 1:grep 搜尋 handshake/round/send/recv 進入點
│
── 同時提供了規格和程式碼?
│  └─ 先執行規格工作流程(S1–S5)建立標準圖表,
│     再閱讀程式碼並用 ⚠️ 註解偏離處
│
── 規格是已知協定(TLS、Noise、Signal、X3DH、FROST)?
│  └─ 閱讀 references/protocol-patterns.md 並以標準流程作為骨架
│
── 規格是 ProVerif (.pv) 或 Tamarin (.spthy)?
│  └─ 閱讀 references/spec-parsing-patterns.md → 形式化模型章節
│
── 規格訊息順序不明確?
│  └─ 從回合/章節結構推斷,用 ⚠️ 註解
│
── 無法從規格識別參與者?
│  └─ 檢查「Parties」/「Notation」章節;對於 ProVerif 閱讀 process 名稱;
│     對於 Tamarin 閱讀 rule 名稱和 fact 參數
│
── 不知道哪些程式碼檔案實作了協定?
│  └─ 步驟 1:grep 搜尋 handshake/round/send/recv 進入點
│
── 無法從結構名稱識別參與者?
│  └─ 閱讀測試檔案 — 測試設定會揭示角色
│
── 協定在程序內執行(無網路呼叫)?
│  └─ 將角色邊界的函式參數傳遞視為訊息
│
── MPC / 門檻值協定,有 N 個參與者?
│  └─ 閱讀 references/protocol-patterns.md → MPC 章節
│
── Mermaid 語法錯誤?
│  └─ 閱讀 references/mermaid-sequence-syntax.md → 常見陷阱
│
└─ ASCII 繪圖慣例?
   └─ 閱讀 references/ascii-sequence-diagram.md

範例

程式碼路徑examples/simple-handshake/

  • protocol.py — 雙人認證金鑰交換(X25519 DH + Ed25519 簽章 + HKDF + ChaCha20-Poly1305)
  • expected-output.md — 該技能應為該協定產生的確切 ASCII 圖表和 Mermaid 檔案

規格路徑(ProVerif)examples/simple-proverif/

  • model.pv — 在 ProVerif 中建模的 HMAC 挑戰-回應認證
  • expected-output.md — 逐步提取說明(參與者、訊息流程、密碼學操作)以及該技能應產生的確切 ASCII 圖表和 Mermaid 檔案

在處理不熟悉的輸入之前,請先研讀相關範例。


支援文件