# MPC System API 流程文档 本文档描述 MPC 系统中的 Keygen、Sign 以及签名方配置 API 的调用流程。 **重要设计原则:** - `username` 是整个 MPC 系统中所有逻辑关系的唯一标识 - 事件型数据库设计:只插入不修改,保证数据安全性和可追溯性 ## 目录 1. [Keygen API](#1-keygen-api) 2. [Sign API](#2-sign-api) 3. [签名方配置 API](#3-签名方配置-api) 4. [API 参数汇总](#4-api-参数汇总) 5. [签名方选择逻辑](#5-签名方选择逻辑) 6. [事件型数据库设计](#6-事件型数据库设计) --- ## 1. Keygen API ### 端点 ``` POST /mpc/keygen ``` ### 流程图 ``` ┌─────────┐ ┌─────────────┐ ┌──────────────────┐ ┌─────────────┐ │ Client │────▶│ Account API │────▶│ Session Coordinator │────▶│ Server Party │ └─────────┘ └─────────────┘ └──────────────────┘ └─────────────┘ │ │ │ │ │ POST /keygen │ │ │ │ {username, │ │ │ │ threshold_n, │ 检查 username │ │ │ threshold_t} │ 是否已存在 │ │ │───────────────▶│─────┐ │ │ │ │ │ │ │ │ │◀────┘ │ │ │ │ │ │ │ │ CreateSession │ │ │ │ (keygen, n, t) │ │ │ │─────────────────────▶│ │ │ │ │ │ │ │ │ NotifyParties │ │ │ │─────────────────────▶│ │ │ │ │ │ │ session_id │ │ │ │◀─────────────────────│ │ │ │ │ │ │ {session_id, │ │ │ │ username, │ │ │ │ status} │ │ │ │◀───────────────│ │ │ │ │ │ │ │ [MPC Keygen Protocol Execution] │ │ │ │ │ │ WebSocket │ │ │ │ 完成通知 │ │ │ │◀═══════════════│ │ │ │ {public_key} │ │ │ ``` ### 请求参数 ```json { "username": "string", // 用户名(必填,唯一标识) "threshold_n": 3, // 总参与方数量(必填) "threshold_t": 2, // 签名阈值(必填) "require_delegate": true // 是否需要委托方(可选) } ``` ### 响应 ```json { "session_id": "uuid", "session_type": "keygen", "username": "string", "threshold_n": 3, "threshold_t": 2, "selected_parties": ["party1", "party2", "party3"], "delegate_party": "party3", "status": "created" } ``` ### 错误响应 - `409 Conflict`: username 已存在(应使用 Sign API) - `400 Bad Request`: threshold_t > threshold_n --- ## 2. Sign API ### 端点 ``` POST /mpc/sign ``` ### 流程图 ``` ┌─────────┐ ┌─────────────┐ ┌──────────────────┐ ┌─────────────┐ │ Client │────▶│ Account API │────▶│ Session Coordinator │────▶│ Server Party │ └─────────┘ └─────────────┘ └──────────────────┘ └─────────────┘ │ │ │ │ │ POST /sign │ │ │ │ {username, │ │ │ │ message_hash,│ 通过 username │ │ │ user_share} │ 查询 Account │ │ │───────────────▶│ 检查 SigningParties │ │ │ │─────┐ │ │ │ │ │ │ │ │ │◀────┘ │ │ │ │ │ │ │ │ CreateSession │ │ │ │ (sign, parties) │ │ │ │─────────────────────▶│ │ │ │ │ │ │ │ │ NotifyParties │ │ │ │ (configured or all) │ │ │ │─────────────────────▶│ │ │ │ │ │ │ session_id │ │ │ │◀─────────────────────│ │ │ │ │ │ │ {session_id, │ │ │ │ username, │ │ │ │ status} │ │ │ │◀───────────────│ │ │ │ │ │ │ │ [MPC Sign Protocol Execution] │ │ │ │ │ │ WebSocket │ │ │ │ 完成通知 │ │ │ │◀═══════════════│ │ │ │ {signature} │ │ │ ``` ### 请求参数 ```json { "username": "string", // 用户名(必填,唯一标识) "message_hash": "hex", // 待签名消息哈希(必填,32字节SHA-256) "user_share": "hex" // 用户Share(可选,账户有delegate时必填) } ``` ### 响应 ```json { "session_id": "uuid", "session_type": "sign", "username": "string", "message_hash": "hex", "threshold_t": 2, "selected_parties": ["party1", "party2"], "has_delegate": true, "delegate_party_id": "party2", "status": "created" } ``` ### 错误响应 - `404 Not Found`: username 不存在 - `400 Bad Request`: 账户有 delegate 但未提供 user_share ### 签名方选择逻辑 1. 如果 Account 配置了 `signing_parties`(非空)→ 使用配置的参与方 2. 如果 Account 未配置 `signing_parties`(空或NULL)→ 使用所有活跃的参与方 --- ## 3. 签名方配置 API **所有签名方配置 API 使用 username 作为路径参数** ### 3.1 设置签名方配置(首次) #### 端点 ``` POST /accounts/by-username/:username/signing-config ``` #### 流程图 ``` ┌─────────┐ ┌─────────────┐ ┌──────────────┐ ┌────────────┐ │ Client │────▶│ Account API │────▶│ Account Repo │────▶│ PostgreSQL │ └─────────┘ └─────────────┘ └──────────────┘ └────────────┘ │ │ │ │ │ POST │ │ │ │ /signing-config │ │ │ {party_ids} │ │ │ │───────────────▶│ │ │ │ │ │ │ │ │ GetByUsername │ │ │ │────────────────────▶│ │ │ │ │ SELECT │ │ │ │──────────────────▶│ │ │ │◀──────────────────│ │ │◀────────────────────│ │ │ │ │ │ │ │ 检查: │ │ │ │ - 是否已配置? │ │ │ │ - party数量=t? │ │ │ │─────┐ │ │ │ │ │ │ │ │ │◀────┘ │ │ │ │ │ │ │ │ Update │ │ │ │ (signing_parties) │ │ │ │────────────────────▶│ │ │ │ │ UPDATE │ │ │ │──────────────────▶│ │ │ │◀──────────────────│ │ │◀────────────────────│ │ │ │ │ │ │ {success, │ │ │ │ username, │ │ │ │ party_ids} │ │ │ │◀───────────────│ │ │ ``` #### 请求参数 ```json { "party_ids": ["party1", "party2"] // 签名方ID列表(必填,数量必须等于threshold_t) } ``` #### 响应 ```json { "message": "signing parties configured successfully", "username": "string", "signing_parties": ["party1", "party2"], "threshold_t": 2 } ``` #### 错误响应 - `400 Bad Request`: 参与方数量不等于 threshold_t - `409 Conflict`: 已存在配置(应使用 PUT 更新) - `404 Not Found`: username 不存在 --- ### 3.2 更新签名方配置 #### 端点 ``` PUT /accounts/by-username/:username/signing-config ``` #### 请求参数 ```json { "party_ids": ["party1", "party3"] // 新的签名方ID列表 } ``` #### 响应 ```json { "message": "signing parties updated successfully", "username": "string", "signing_parties": ["party1", "party3"], "threshold_t": 2 } ``` #### 错误响应 - `400 Bad Request`: 参与方数量不等于 threshold_t - `404 Not Found`: username 不存在或未配置签名方 --- ### 3.3 清除签名方配置 #### 端点 ``` DELETE /accounts/by-username/:username/signing-config ``` #### 响应 ```json { "message": "signing parties cleared - all active parties will be used for signing", "username": "string" } ``` --- ### 3.4 查询签名方配置 #### 端点 ``` GET /accounts/by-username/:username/signing-config ``` #### 响应(已配置) ```json { "configured": true, "username": "string", "signing_parties": ["party1", "party2"], "threshold_t": 2 } ``` #### 响应(未配置) ```json { "configured": false, "username": "string", "message": "no signing parties configured - all active parties will be used", "active_parties": ["party1", "party2", "party3"], "threshold_t": 2 } ``` --- ## 4. API 参数汇总 | API | Method | 路径 | 主要参数 | 返回值 | |-----|--------|------|----------|--------| | Keygen | POST | `/mpc/keygen` | username, threshold_n, threshold_t | session_id, username, status | | Sign | POST | `/mpc/sign` | username, message_hash, user_share | session_id, username, parties | | 设置签名方 | POST | `/accounts/by-username/:username/signing-config` | party_ids[] | username, signing_parties | | 更新签名方 | PUT | `/accounts/by-username/:username/signing-config` | party_ids[] | username, signing_parties | | 清除签名方 | DELETE | `/accounts/by-username/:username/signing-config` | - | username, message | | 查询签名方 | GET | `/accounts/by-username/:username/signing-config` | - | username, signing_parties, configured | --- ## 5. 签名方选择逻辑 ``` ┌─────────────────┐ │ Sign Request │ │ (username) │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ GetByUsername │ │ 查询 Account │ │ SigningParties │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ HasSigningParties│ │ Config? │ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ YES │ NO ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ 使用配置的 │ │ 查询所有活跃的 │ │ SigningParties │ │ Server Parties │ │ (固定 t 个) │ │ (可能 > t 个) │ └────────┬────────┘ └────────┬────────┘ │ │ └──────────────┬─────────────┘ │ ▼ ┌─────────────────┐ │ 创建签名会话 │ │ (指定参与方) │ └─────────────────┘ ``` ### 使用场景 1. **默认模式(未配置)** - 所有活跃的 Server Party 都会参与签名 - 适用于需要最大灵活性的场景 2. **配置模式(已配置)** - 只有指定的 Party 参与签名 - 适用于固定签名方组合的场景 - 例如:指定 "server-party-1" 和 "delegate-party" 作为签名方 ### 验证规则 - `party_ids` 数量必须等于账户的 `threshold_t` - `party_ids` 中不能有重复项 - `party_ids` 中不能有空字符串 - `party_ids` 必须是账户的活跃 share --- ## 6. 事件型数据库设计 ### 设计原则 为保证数据安全性和可追溯性,采用事件溯源(Event Sourcing)模式: - **只插入,不修改** - 所有状态变更都作为新事件插入 - **不可变日志** - 事件记录一旦写入不可更改 - **状态可重建** - 当前状态可通过重放事件得到 ### session_events 表结构 ```sql CREATE TABLE session_events ( id UUID PRIMARY KEY, session_id UUID NOT NULL, username VARCHAR(255) NOT NULL, -- 用户唯一标识 event_type VARCHAR(50) NOT NULL, -- 事件类型 session_type VARCHAR(20) NOT NULL, -- keygen 或 sign -- 事件快照数据 threshold_n INTEGER, threshold_t INTEGER, party_id VARCHAR(255), party_index INTEGER, message_hash BYTEA, public_key BYTEA, signature BYTEA, error_message TEXT, metadata JSONB, created_at TIMESTAMP NOT NULL DEFAULT NOW() ); ``` ### 事件类型 | 事件类型 | 描述 | |---------|------| | `session_created` | 会话创建 | | `party_joined` | 参与方加入 | | `party_ready` | 参与方就绪 | | `round_started` | MPC 轮次开始 | | `round_completed` | MPC 轮次完成 | | `session_completed` | 会话成功完成 | | `session_failed` | 会话失败 | | `session_expired` | 会话过期 | | `delegate_share_sent` | 委托 share 已发送给用户 | | `signing_config_set` | 签名方配置已设置 | | `signing_config_cleared` | 签名方配置已清除 | ### 查询当前状态 通过视图 `session_current_state` 获取最新状态: ```sql SELECT * FROM session_current_state WHERE username = 'alice'; ``` --- ## 更新日志 | 日期 | 版本 | 描述 | |------|------|------| | 2024-XX-XX | 1.0 | 初始版本 | | 2024-XX-XX | 2.0 | 全面采用 username 作为唯一标识,添加事件型数据库设计 |