# minichain（OKT 链）威胁模型

> 状态：**原型，未经任何第三方安全审计**。本文是为审计做准备的自评材料，不代表安全性结论。

## 1. 系统与资产

| 资产 | 位置 | 安全目标 |
|---|---|---|
| 用户私钥（钱包） | `wallet.json`（scrypt + AES-256-GCM） | 机密性；离线暴力破解成本高 |
| 节点私钥（P2P 身份） | `data/node_key.json`（0600）或 `node_key.enc`（`-encryptkeys`） | 机密性；身份不可冒充 |
| 本地 API 令牌 | `data/api_token`（0600）或 `api_token.enc` | 只有本机授权用户能提交交易、出块 |
| 账本状态（余额、nonce、合约存储、代币及其唯一名称索引） | 内存 + `data/chain.db`（bbolt） | 完整性：只能由有效区块按共识规则改变；崩溃后一致 |
| 共识规则（供应上限 2100 万 OKT、减半、难度、代币名唯一、OKT 保留） | `chain/` | 任何节点都不能让诚实节点接受违规区块 |
| 节点可用性 | 网络层 | 资源（CPU、内存、磁盘、连接、带宽）有上限，攻击者不能廉价耗尽 |

## 2. 攻击者模型

| 编号 | 攻击者 | 能力 | 不在范围内 |
|---|---|---|---|
| A1 | 远程网络攻击者 | 任意连接 P2P 端口、发送任意字节、开大量 TCP 连接 | 无法获得受害者私钥 |
| A2 | 恶意对等节点（含女巫） | 完成合法握手（付出身份 PoW）、运行自己的服务、撒谎、发送无效/超大数据、控制多个 IP | 控制全网多数算力 |
| A3 | 恶意矿工（少数算力） | 产生满足 PoW 的区块（本原型难度很低！）、自由选择时间戳/交易 | — |
| A4 | 本机其他用户 | 读取非 0600 文件、访问回环端口 | root / 同一用户 |
| A5 | 跨网/跨链重放者 | 拿到另一条链（不同参数/创世）上的已签名交易 | — |
| A6 | 磁盘故障 / 断电 / kill -9 | 进程在任意时刻终止 | 存储介质静默损坏、恶意篡改后重新计算所有哈希（见 §5） |

**明确不防御**：拥有 >50% 算力的攻击者（PoW 链固有）；拥有节点运行用户权限的本地攻击者；侧信道；隐私（所有交易公开）。

## 3. 信任边界与入口

1. **P2P 端口**（mTLS 1.3）：`/p2p/ping, hello, status, peers, headers, bodies, tx, block` —— 完全不可信输入。
2. **本地 API**（默认仅 127.0.0.1，Bearer 令牌；非回环必须 TLS）：可信度取决于令牌保密性。
3. **磁盘数据目录**：可信但可能损坏（打开时完整性检查）。
4. **CLI 输入**（文件路径、URL、口令）：来自操作者本人，视为可信。

## 4. 威胁与缓解

### 4.1 共识 / 账本

| 威胁 | 缓解 | 残留风险 |
|---|---|---|
| 超发 OKT | 奖励必须严格等于 `BlockReward(height, halving, minted)`；`minted + reward ≤ MaxSupply`；打开数据库时验证 `Σ余额 = 已发行 ≤ 上限`；不变量测试 + 模糊测试 | — |
| 负余额 / 整数溢出 | 转账前检查余额；金额 >0；VM 加减乘为检查溢出运算（溢出 → 交易失败）；BlockReward 移位量 <63 | 合约数值仅 int64 |
| 重复/仿冒代币名 | NFKC + 大小写折叠 + UTS #39 同形骨架作为唯一键；拒绝混合文字、零宽/控制/双向字符；符号仅 ASCII A-Z0-9；`OKT` 及其同形变体保留 | 表外的视觉相似、字体相关相似 |
| 跨链重放 | **交易签名覆盖 `chain_id`**（= H(创世哈希, 共识参数哈希)），状态只接受本链 ID | 同一链的分叉（同参数）之间仍可重放（与比特币相同） |
| 同链重放 | 账户 nonce 严格递增 | — |
| 交易可塑性 | 只接受规范小写 hex 的签名/公钥/地址；ed25519 验证拒绝非规范 S | — |
| 无效区块 / 状态分歧 | 每个区块完整重新执行；执行失败的块按哈希标记无效（不再重复执行）；无效分支的后代一律拒绝；重组失败恢复原链 | 共识逻辑未经形式化验证 |
| 时间戳操纵 | 必须大于前 11 块中位时间（MTP），不超前本地时钟 2 h；重定向基于 MTP、单次 ≤4× | 本地时钟错误会影响判断；2 h 窗口内仍可小幅操纵难度 |
| 深度重组 | 最大重组深度 2000；`-finality` 最终性深度；`-checkpoints` | 检查点/最终性是本地策略，配置不同会分裂 |
| 合约资源滥用 | gas 上限 ≤ 1e6；栈 ≤ 1024；代码 ≤ 16 KB；存储 ≤ 1024 键；参数 ≤ 16 ; 共识最低手续费与 gas 价格；内存池最低转发费率、RBF 提价、最低费驱逐 | gas 计价未按实际成本校准 |

### 4.2 网络

| 威胁 | 缓解 | 残留风险 |
|---|---|---|
| 女巫 | 节点 ID 工作量证明（默认 16 比特）；负载下握手难题；新节点低信任期 | 有算力者仍可批量造 ID |
| 身份冒充 / 中间人 | 证书公钥 = 节点 ID 并钉扎；签名挑战握手；`VerifyConnection` 覆盖会话恢复，且禁用会话票据 | `-strictpin` 关闭时首次连接仍为 TOFU |
| 日蚀 | 秘密分桶 addrman（new/tried）、/16（IPv6 /32）分组多样性、锚点、出站轮换（CSPRNG 选择）、feeler、种子、受信白名单 | `-asmap` 提供时按 ASN 分组；无内置 ASN 数据 |
| 谎报工作量 | headers-first：区块头链必须证明声明的工作量；**头链结束于对方声明的链尖却证明不足 → 立即判定撒谎**；不一致时用新 status 重试一次，仍不一致才扣分（减少误判） | 低难度下伪造头链成本低（见 §5） |
| 区块体投毒 / 慢节点 | 多节点并行下载：体必须匹配已验证头（tx_root + 哈希）；超时 → 重新分配给其他节点、轻度扣分，连续 2 次超时停止分配；错误数据 → 重度扣分并停止分配 | 头链从工作量最多的节点下载并与其他节点交叉检查；仍不能防御全部节点被控制 |
| 资源耗尽（CPU/内存/连接） | TLS 前连接上限、握手截止时间、HTTP 超时、消息大小上限、每 peer/全局限流、有界 LRU/内存池/孤块池、分页上限 | 单进程无优先级调度；不防带宽型 DDoS |
| 恶意行为累积 | 按 ID/IP/子网打分封禁（持久化，0600）、分数衰减 | 测试模式下回环 IP 不封禁 |

### 4.3 本地

| 威胁 | 缓解 | 残留风险 |
|---|---|---|
| 未授权 API 调用 | 32 字节随机令牌、常量时间比较、默认只绑定回环、非回环强制 TLS | 令牌泄漏即完全控制节点 API |
| 钱包被盗后离线破解 | scrypt N=2^15,r=8,p=1 + AES-GCM（地址为 AAD）；口令 ≥ 8 字符；终端输入不回显（x/term） | 弱口令仍可被破解 |
| 节点私钥/令牌泄漏 | 0600；可选 `-encryptkeys` 静态加密（迁移后删除明文） | 口令可经 FD/文件传入并在使用后清零；Go GC 不保证无副本；运行中私钥在内存 |
| 崩溃导致数据损坏 | bbolt 单写事务按块原子提交（区块、索引、规范链、撤销日志、状态差异、链尖）；打开时完整性检查；`-reindex` 从已存区块完整重建 | 区块头含状态根，打开时重算；`-verifystate` 全链重放；提交失败可在线恢复；fsync 依赖文件系统语义 |

## 5. 已知结构性弱点（原型取舍）

1. mainnet 初始难度 30 比特（devnet 16）：没有真实算力时伪造头链成本仍低。
2. 状态根为稀疏 Merkle 树（第 8 阶段，sha256，支持包含/不存在证明）；轻客户端仍需下载全部区块头。
3. 打开时默认只重算状态根并与链尖头比对；完整重放需 `-verifystate`（10k 块级别耗时数秒）。
4. 隐私协议未经审计（见 §6）。
5. 断电测试使用 FUSE 故障注入文件系统（撕裂写、丢弃/谎报 fsync），元数据立即持久是简化；回滚标记与数据库同依赖文件系统。
6. 共识手续费的 50%（30% + 20%）流向两个固定地址：这是**中心化的信任前提**——这两个地址的私钥保管者获得持续收入；主网前必须改为离线多方保管并公开披露。测试网使用公开口令的测试钱包，任何人都可以动用这些余额。

## 6. 隐私（第 7 阶段，**最高优先级审计范围，未经审计**）

资产：隐私输出的金额与所有者、交易图；以及总量（隐私层通胀不可见，最危险）。

| 威胁 | 缓解 | 残余风险 |
|---|---|---|
| 隐藏通胀（伪造承诺平衡 / 负金额） | 承诺平衡检查；每个输出 64 位 Bulletproofs+（第 8 阶段）；屏蔽池不得为负（透明可见的上界：隐私层最多只能盗取池内金额） | Bulletproofs/CLSAG 实现错误可导致通胀，直到池耗尽前不可见 |
| 双花 | 密钥镜像集合（共识状态，重组可撤销）；I 的子群检查 | Hp 实现错误会导致镜像可变形 |
| 小阶点 / 非规范编码 | 所有点检查素数阶子群；标量规范化检查 | — |
| 环成员链接（统计） | gamma 诱饵、环 16、10 块锁定 | 低使用量下匿名集小 |
| shield/unshield 金额关联 | 固定面额（共识参数 `priv_denoms`）；钱包自动拆分并显示风险提示；隐私→隐私为默认 | 时间关联、拆分交易聚类仍可能去匿名化 |
| 钱包泄露 | 本地用查看密钥扫描；下载完整已花费密钥镜像集合本地比对（不逐个查询） | 节点仍能看到钱包的连接时间与 IP；全量下载带宽随链增长 |
| 交易来源 IP | Dandelion++ 茎阶段 + 禁运计时器；可选 Tor/SOCKS5 出站 | 单出边简化；第一个茎中继知道来源；入站连接不匿名 |
| 验证 DoS | 静态检查先于密码学；签名缓存；区块内批量范围证明；手续费按字节 | 隐私交易验证约 12 ms/笔，大块验证成本高 |
| 跨链重放 | 签名消息含链 ID | — |

Bulletproofs+（第 8 阶段已实现，直接替换，未做激活高度切换——原型无已上线网络）：证明 640 B（m=2），批量验证。**尚未用外部测试向量交叉验证**，审计需重点检查转录构造、加权内积的最后一轮与批量验证的随机权重。


## 7. 第 8 阶段新增面（**未经审计**）

| 威胁 | 缓解 | 残余风险 |
|---|---|---|
| Web 钱包 CSRF / DNS 重绑定 | 只绑定回环；Host 校验；非 GET 必须 JSON 且同源；SameSite=Strict + HttpOnly cookie；严格 CSP；转义输出 | 同机其他用户/进程可访问回环端口（仍需口令解锁）；解锁期间同机恶意软件可调用钱包 |
| Web 钱包私钥 | 加密文件 + 解锁后 mlock 内存，空闲 15 分钟锁定，签名在服务端 | 解锁会话内私钥在内存中 |
| API 令牌泄漏到浏览器 | 代理在服务端注入令牌，只暴露白名单 | — |
| 手续费规则绕过 | 交易 fee 必须恰好等于规定值；代币手续费在数量之外扣除并检查余额；分配在区块执行中完成并被撤销记录覆盖 | 规则本身（1%）对大额转账成本高——这是政策选择，不是安全属性 |
| 轻客户端被欺骗 | 全部区块头按网络共识参数验证 + SMT 证明对头中状态根 | 被完全隔离（eclipse）且对方投入真实算力时仍可欺骗；低难度测试网成本低 |
| 内存中的密钥 | 堆页 mlock + DONTDUMP、清零、退出时清零 | 尽力而为（见 README 局限） |
