從原始碼、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.Y、MUST/SHALL 關鍵字) |
規格 |
Algorithm/Protocol/Figure 標籤、數學符號 |
規格 |
ProVerif 檔案(.pv)包含 process、let、in/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:識別參與者與角色
從以下來源提取參與者名稱:
- 結構/類別名稱:
Client、Server、Initiator、Responder、Prover、Verifier、Dealer、Party、Coordinator - 攜帶角色狀態的函式參數名稱
- 宣告協定角色的註解
- 設定雙人或 N 人場景的測試 fixture
將這些對應到 Mermaid participant 宣告。使用簡短、可讀的別名:
participant I as Initiator
participant R as Responder
步驟 3:追蹤訊息流程
跟隨狀態轉換和網路收發。尋找以下模式:
| 模式 | 意義 |
|---|---|
send(msg) / recv() |
直接訊息交換 |
serialize + transmit |
結構化訊息傳送 |
| 回傳值傳遞給另一方的函式 | 邏輯訊息(程序內) |
round1_output → round2_input |
基於回合的 MPC 步驟 |
結構體欄位命名為 ephemeral_key、ciphertext、mac、tag |
訊息內容 |
對於程序內協定實作(雙方在同一程序中執行),當函式呼叫邊界代表部署時的網路邊界時,將其視為邏輯訊息傳送。
步驟 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:識別協定階段
使用 rect 或 Note 區塊將訊息步驟分組為命名階段:
常見的階段:
- 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 XXXX、MUST/SHALL/SHOULD、ABNF 語法、章節編號的敘述 |
| 學術論文 / 虛擬碼 | Algorithm X、Protocol X、Figure X、編號步驟、數學模式中的 ←/→ |
| 非正式敘述 | 編號列表、「A 傳送 B ...」、純英文描述 |
ProVerif (.pv) |
process、let、in(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:提取參與者與角色
識別所有協定參與者。尋找:
- 敘述或虛擬碼中的命名角色:
Alice、Bob、Client、Server、Initiator、Responder、Prover、Verifier、Dealer、Party_i、Coordinator、Signer - 章節標題:「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: msg、A -> 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)前提 — 接收訊息mOut(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) → σ |
識別安全條件和中止路徑:
- 敘述:「如果驗證失敗,中止」、「僅當 ...」、「如果 ... 則拒絕」
- 虛擬碼:
assert、require、if ... 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.md 或 x3dh-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 檔案
在處理不熟悉的輸入之前,請先研讀相關範例。
支援文件
- references/spec-parsing-patterns.md —
RFC、學術論文/虛擬碼、非正式敘述、ProVerif 和 Tamarin 輸入格式的提取規則;在步驟 S1 期間閱讀 - references/mermaid-sequence-syntax.md —
參與者語法、箭頭類型、激活、分組區塊、跳脫規則和常見渲染陷阱 - references/protocol-patterns.md —
TLS 1.3、Noise、X3DH、Double Ratchet、Shamir 秘密分享、承諾-揭示和通用 MPC 回合的標準訊息流程;在比較實作與規格時作為參考 - references/ascii-sequence-diagram.md —
欄位佈局、箭頭慣例、自迴圈、階段標籤和 ASCII 圖的內嵌輸出格式






