金融与交易
从源码、RFC/论文/伪代码或…
当你需要把实现代码、规范文档或形式化模型中的握手、密钥交换、认证等密码协议画成时序图时,用它可以提取参与方、消息流、密码学操作并输出 Mermaid 和 ASCII 图。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
从源码、RFC/论文/伪代码或 ProV通用
解决思路
- 先判断输入类型:源码扩展名(`.py`、`.rs`、`.go`、`.ts`、`.js`、`.cpp`、`.c`)或函数/类定义/import 语句归为 Code;RFC 风格章节(`§`、`Section X.Y`、`MUST`/`SHALL`)、`Algorithm`/`Protocol`/`Figure` 标签、数学符号归为 Spec;含 `process`、`let`、`in`/`out` 的 `.pv` 归为 Spec;含 `rule`、`--[...]->` 的 `.spthy` 归为 Spec;普通散文或编号步骤归为 Spec;同时有源码和规范文档归为 Both;无法判断时询问用户:“Is this a source code file, a specification document, or both?”。
- 根据输入类型选择路径:Code only 跳到 Step 1;Spec only 跳到 Spec Workflow(S1–S5);Both 先运行 Spec Workflow,再用代码读取步骤验证实现与规范图,并用 `⚠️` 标注差异;Ambiguous 先询问用户。
- 执行 Step 1 定位协议入口:运行 `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` 查找所用密码原语;从最高层编排函数(调用握手阶段或主协议循环的函数)开始阅读。
- 执行 Step 2 识别参与方与角色:从 `Client`、`Server`、`Initiator`、`Responder`、`Prover`、`Verifier`、`Dealer`、`Party`、`Coordinator` 等结构/类名、携带角色状态的函数参数名、声明协议角色的注释、搭建两方或 N 方场景的测试夹具中提取参与方;将它们映射为 Mermaid `participant` 声明,使用短别名,例如 `participant I as Initiator`、`participant R as Responder`。
- 执行 Step 3 追踪消息流:跟随状态转换和网络发送/接收;识别模式:`send(msg)`/`recv()` 表示直接消息交换,`serialize` + `transmit` 表示结构化消息发送,返回值传给另一方函数表示逻辑消息(进程内),`round1_output` → `round2_input` 表示基于轮次的 MPC 步骤,名为 `ephemeral_key`、`ciphertext`、`mac`、`tag` 的结构字段表示消息内容;对于同进程内运行的协议实现,当函数调用边界在部署中会对应网络边界时,将函数调用边界视为逻辑消息发送。
- 执行 Step 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`;标注保持简洁,使用数学简写而非代码。
- 执行 Step 5 识别协议阶段:用 `rect` 或 `Note` 块把消息步骤分组成命名阶段;常见阶段包括 Setup/Key Generation(参与方密钥生成、可信设置、参数生成)、Handshake/Init(临时密钥交换、nonce 交换、版本协商)、Authentication(身份证明、证书交换、签名验证)、Key Derivation(从共享秘密派生会话密钥)、Data Transfer/Main Protocol(加密应用数据交换)、Finalization/Teardown(会话关闭、MAC 验证、中止处理);检测中止/错误路径并用 `alt` 块展示。
- 执行 Spec Workflow S1 摄取规范:文件路径用 Read 工具读取;URL 用 WebFetch 获取;内联粘贴则直接使用对话上下文;识别规范格式并阅读 [references/spec-parsing-patterns.md](references/spec-parsing-patterns.md) 获取格式特定提取指导;格式信号包括:RFC 的 `RFC XXXX`、`MUST`/`SHALL`/`SHOULD`、ABNF 语法、带章节编号的散文;学术论文/伪代码的 `Algorithm X`、`Protocol X`、`Figure X`、编号步骤、数学模式中的 `←`/`→`;普通散文的编号列表、“A sends B ...”、英文描述;ProVerif 的 `process`、`let`、`in(ch, x)`、`out(ch, msg)`、`!`(复制);Tamarin 的 `rule`、`--[ ]->`、`Fr(~x)`、`!Pk(A, pk)`、`In(m)`、`Out(m)`;如果规范引用已知命名协议(TLS、Noise、Signal、X3DH、Double Ratchet、FROST),再阅读 [references/protocol-patterns.md](references/protocol-patterns.md),用其规范流程作为骨架并填入规范特定细节。
- 执行 S2 提取参与方与角色:在散文或伪代码中查找命名角色,如 `Alice`、`Bob`、`Client`、`Server`、`Initiator`、`Responder`、`Prover`、`Verifier`、`Dealer`、`Party_i`、`Coordinator`、`Signer`;检查 “Parties”、“Roles”、“Participants”、“Setup”、“Notation” 等章节标题;ProVerif 中读取顶层进程名(如 `let ClientProc(...)`、`let ServerProc(...)`);Tamarin 中读取规则名和事实参数(如 `!Pk($A, pk)` 中 `$A` 是参与方);将每个角色映射为 Mermaid `participant` 声明,使用短 ID 和描述性别名,参考 [references/mermaid-sequence-syntax.md](references/mermaid-sequence-syntax.md) 的命名约定。
- 执行 S3 提取消息流:按格式提取;RFC/普通散文:识别箭头记法 `A → B: msg`、`A -> B`,句子模式 “A sends B ...”、“B responds with ...”、“A transmits ...”、“upon receiving X, B sends Y”,按编号步骤顺序提取并根据上下文推断发送者/接收者;伪代码:读取带显式 `sender`/`receiver` 参数的函数签名、`send(party, msg)`/`receive(party)` 调用、下一步传给另一方函数输入的返回值;ProVerif:`out(ch, msg)` 是发送、`in(ch, x)` 是接收并绑定到 `x`,匹配同一通道上的 `out`/`in` 对以识别消息流,`!`(复制)表示处理多个会话的角色;Tamarin:`In(m)` 前提表示接收消息 `m`,`Out(m)` 结论表示发送消息 `m`,规则名和规则顺序揭示协议轮次,`Fr(~x)` 是参与方生成的新鲜随机值,`--[ Label ]->` 事实是安全标注而非消息;保留顺序和轮次结构,用 `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) → σ`;识别安全条件和中止路径:散文中的 “if verification fails, abort”、“only if ...”、“reject if ...”,伪代码中的 `assert`、`require`、`if ... abort`,ProVerif 中的 `if m = expected then ... else 0`,Tamarin 中的矛盾事实或 restriction lemmas;这些成为最终图中的 `alt` 块。
- 执行 S5 标记规范歧义:检查缺口;消息顺序不清时根据轮次结构或章节顺序推断,并标注 `⚠️ ordering inferred from spec structure`;参与方隐含但未命名时给描述性名称并注明推断;规范遗漏某步骤而该协议的规范流程需要它时标注 `⚠️ spec omits [step] — canonical protocol requires it`;规范只说 “encrypt” 而未指定方案时标注 `⚠️ encryption scheme not specified`;ProVerif/Tamarin 中私有通道(用 `new c` 声明为私有自由名)表示带外通道,需注明。
- 执行 Step 6 生成 sequenceDiagram:按 [references/mermaid-sequence-syntax.md](references/mermaid-sequence-syntax.md) 的规则生成 Mermaid 语法;完整性优先于简短,展示每个不同消息类型,重复循环迭代用 `loop` 块省略,但绝不省略不同协议步骤;正确性优先于美观,图必须匹配代码实际行为;如果代码偏离已知规范,标注差异,例如 `Note over A,B: ⚠️ spec requires MAC here — implementation omits it`。
- 执行 Step 7 验证与交付前检查:每个声明的 participant 实际至少发送或接收一条消息;箭头方向正确(sender → receiver);密码学操作标在正确参与方(实际计算方);如果使用协议阶段,阶段块外不出现箭头;`alt` 块覆盖已知中止/错误路径;图无语法错误渲染(检查 [references/mermaid-sequence-syntax.md](references/mermaid-sequence-syntax.md) 的常见陷阱);如果发现规范差异,已用 `⚠️` 标注。
- 将图写入文件:根据协议名选择文件名,例如 `noise-xx-handshake.md` 或 `x3dh-key-agreement.md`;写入 Markdown 文件,结构为:`# <Protocol Name> Sequence Diagram`、包含 `sequenceDiagram` 的 ```mermaid 代码块、`## Protocol Summary`,其中列出 `Parties`、`Round complexity`、`Key primitives`、`Authentication`、`Forward secrecy`、`Notable`(规范偏差或安全观察,没有则写 “none”)。
- 写入文件后,在回复中内联打印 ASCII 时序图,随后打印 Protocol Summary,并说明输出文件名,让用户知道 Mermaid 源码位置;遵循 [references/ascii-sequence-diagram.md](references/ascii-sequence-diagram.md) 的所有绘图约定,包括内联输出格式。
- 按 Decision Tree 行动:输入是规范文档则执行 Step S1 并阅读 [references/spec-parsing-patterns.md](references/spec-parsing-patterns.md);输入是源码则执行 Step 1 用 grep 查握手/轮次/send/recv 入口;同时有规范和代码则先运行 Spec Workflow(S1–S5)建立规范图,再读代码并用 `⚠️` 标注差异;已知协议(TLS、Noise、Signal、X3DH、FROST)则阅读 [references/protocol-patterns.md](references/protocol-patterns.md) 并将规范流程作为骨架;ProVerif(`.pv`)或 Tamarin(`.spthy`)则阅读 [references/spec-parsing-patterns.md](references/spec-parsing-patterns.md) 的 Formal Models 部分;规范消息顺序有歧义则根据轮次/章节结构推断并用 `⚠️` 标注;无法从规范识别参与方则检查 “Parties”/“Notation” 章节,ProVerif 读进程名,Tamarin 读规则名和事实参数;不知道哪些代码文件实现协议则执行 Step 1 grep 入口;无法从结构名识别参与方则读测试文件,测试设置揭示角色;协议在进程内运行(无网络调用)则把角色边界处的函数参数传递当作消息;MPC/阈值协议有 N 方则阅读 [references/protocol-patterns.md](references/protocol-patterns.md) 的 MPC 部分;Mermaid 语法错误则阅读 [references/mermaid-sequence-syntax.md](references/mermaid-sequence-syntax.md) 的 Common Pitfalls;ASCII 绘图约定则阅读 [references/ascii-sequence-diagram.md](references/ascii-sequence-diagram.md)。
- 在陌生输入上工作前先研究相关示例:代码路径查看 `examples/simple-handshake/` 的 `protocol.py`(两方认证密钥交换:X25519 DH + Ed25519 签名 + HKDF + ChaCha20-Poly1305)和 `expected-output.md`(该协议应产出的精确 ASCII 图和 Mermaid 文件);Spec/ProVerif 路径查看 `examples/simple-proverif/` 的 `model.pv`(用 ProVerif 建模的 HMAC 挑战-响应认证)和 `expected-output.md`(逐步提取演练:参与方、消息流、密码操作,以及应产出的精确 ASCII 图和 Mermaid 文件)。
- 拒绝以下合理化并执行相应动作:不要因 “协议很简单,可以凭记忆画” 而凭记忆作图——记忆图会漏步骤和颠倒箭头,必须系统读源码或规范;不要因 “已有代码就跳过规范路径” 而跳过——代码可能与规范偏离,两条路径能发现不同 bug,两者都存在时先跑规范工作流再标注代码差异;不要认为 “密码学标注是可选装饰”——没有密码学标注的图只是消息流,对安全审查无用,必须标注每个密码学操作;不要认为 “abort 路径很明显,不需要 alt 块”——隐式中止处理会隐藏缺失的错误检查,每个中止/错误路径都用 `alt` 块展示;不要 “不先检查示例”——示例定义期望输出质量标准,在不熟悉输入前研究相关示例;不要 “把 ProVerif/Tamarin 模型当代码而非规范”——形式化模型是规范,描述预期行为而非实现,对 `.pv` 和 `.spthy` 文件使用 Spec Workflow(S1–S5)。
适用边界 · 注意事项
- 用户想要调用图、类层次或模块依赖图时,不要用本技能,应使用 diagramming-code。
- 用户想要形式化验证协议时,生成图后应使用 mermaid-to-proverif,而不是停在绘图。
- 输入没有密码协议语义(没有参与方、没有消息交换)时不适用。