一次抽取的证据链
抽取提交成功之后才会发布证明:一旦回滚,不会留下任何证明;发布失败也不会反过来否定已经提交的结果。
抽取并提交历史与临时记录在一个事务里完成
本地证明立即写入可重放证明文件
时间戳摘要交给 RFC 3161 权威
事后复核重放结果、核对证据评分
时间戳以「证明文件已经写好」为前提。它证明的是「这份内容在某个时刻已经存在」,
而不是「抽取一定发生在那个时刻」。这是本项目刻意保留的诚实边界。
Up / Own 双链证明
每次抽取写入的是一个证明对,而不是一个孤立文件。
Up 链 · *.srproof.json
与上游格式兼容的记录,刻意不携带信标字段。它是追加式哈希链:每个节点把序号、前一个节点哈希与本次证明的规范哈希一起计入自身哈希。
追加式上游可识别
Own 链 · *.ownproof.json
仅在开启信标熵时写入的参考声明。它记录所依赖的 Up 节点、脉冲序号与一次性的增量序号,并保留原始签名脉冲副本。
仅信标模式参考声明
链头与删除记录
- 链头保存在 data/proofs/chain-head.json,记录最新序号、前序哈希与一个「已记录删除」的最低序号
- 清理证明时会把每个被删除的序号登记下来,因此正常保留期清理留下的空档可以被解释
- 删除 Up 证明会一并删除同名的 Own 引用节点,不会留下指向不存在节点的半条链
- 链的最低序号只会在「连续前缀都被登记过」时前移;零散删除不会把整段空洞解释掉
- 本地保留默认不设期限(年龄与容量上限都为 0 即不限制)——删证明只会损失证据价值,而一份证明只有几 KB
本地链带来的是可见性,不是保护。能完全控制这台机器的人可以同时重建链条与链头,让它们彼此自洽。
链的价值在于:任何删改都会与链头、删除记录产生可比较的不一致。
信标熵
开启后,抽取种子不再来自本机随机数,而是由外部公开信标的最新脉冲推导:
seed derivation
seed = SHA256("SecRandomBeacon/v1" ‖ pulseIndex ‖ chainIndex ‖ outputValue ‖ sequence)
- 本地随机材料、系统时钟与调用方传入的值都不参与推导——这正是这条路径存在的理由
- 每个脉冲的序号从 0 开始,每次抽取加 1;锚点先原子落盘、再释放种子,抽取失败只会留下一个可见的缺口,不会复用种子
- 脉冲序号回退,或同一序号出现不同的值,会被拒绝,而不是被重置
- 信标取不到时抽取直接失败,绝不回退本地种子;错误必须显性发生
- 预取只是提前把脉冲放进缓存,不占用序号;一次没有真正发生的抽取不会留下链上缺口
三种熵源的诚实差别
| 熵源 | 可验证性 | 局限 |
| NIST Beacon v2 |
抓取时即验证签名,带公开时间线 |
依赖外部服务可用性;不可用时抽取失败 |
| drand quicknet |
记录轮次、随机值与签名,可事后做 BLS 校验 |
客户端的即时校验弱于 NIST 路径 |
| random.org |
没有可验证的时间线或签名 |
无法阻止主持人多取几块再挑一块,界面会提示可复核性受损 |
random.org 没有脉冲序号,因此该源不会套用每脉冲序号与链上锚点——否则每一次抽取都会被误判为序号冲突。
时间戳
默认开启,可以显式关闭。关闭时会弹窗说明它对信标周期锚定的影响,需要确认后才会保存。
- 只把证明的规范摘要交给固定的 RFC 3161 权威,不发送名单,也不发送抽取内容
- 返回的令牌写入证明的 witness.timestampToken,并校验签名与证书链
- 接受操作系统信任库或内置的权威根证书;为了离线可用,不检查吊销状态
- 权威地址不可配置:一个用户可改的时间戳地址,等于给了一条静默关闭锚定的路
- 开启信标时,时间戳还能把证明时间对齐到信标脉冲周期,帮助确认种子来自哪个脉冲
时间戳只证明摘要「不晚于」该时刻已经存在。它不能证明抽取恰好发生在那一刻。
这一步会把去标识化的摘要发送给第三方时间戳机构,隐私页有单独披露。
证明重放
普通校验只回答一个问题:证明宣称的结果,是否与用同样参数算出来的理论输出一致。它不核对「屏幕上当时显示的是不是同一个人」。
证明重放补上这一环:
- 由你在本地载入一份自己认可的名单文件
- 用证明里的参数重新运行,得到理论上的中签记录
- 把这些记录解析成姓名,与证明宣称的显示结果逐一比对
- 选中任意一份证明,还能展开查看输入承诺、随机材料与抽样策略等公开参数
重放比对的是「证明文件与这份名单」之间的一致性;它不能替代对名单本身的现实核对。
可信度评分
不是一个笼统的「安全分」,而是一份可解释的证据清单。你先选择自己信任哪些来源,评分只报告这些来源中实际到场了多少。
链完整性
本地证明链是否连续、链头是否自洽
时间戳
是否存在有效的 RFC 3161 令牌
人工佐证
是否有人能在一个时间窗内为当时的结果作证
- 来源等权,评分是「所选来源中到场者的占比」
- 链本身不完整时直接为 0 分,其余证据再齐全也不会拉高
- 信标脉冲超过一个周期会打折;超出容忍范围后该项不再计分
- 人工佐证按其可信时间窗计分,不同置信度对应不同窗口
证明详情
任意一份证明都能展开查看公开参数:输入承诺、审计承诺、随机材料、候选池规则、抽样策略、平均差距保护与 share-debt 参数。
弹窗顶部会明确标注:这些是证明文件自身宣称的信息。要判断可信程度,需要结合证据评分与重放结果。
平均差距门证据
启用平均差距保护时,抽取前可能会移除一部分候选。这类「看不见的筛选」也会留下可复核的记录。
- 只有门规则确实移除过候选时,才会额外写入 *.gateevidence.json
- 文件记录门之前的完整候选池(每个记录 ID 与门看到的抽取次数),以及被移除的子集
- 它绑定到对应 Up 节点的链哈希,随该证明一起删除,始终只留在本机
- 复核时会用同一套规则重跑这个候选池,检查「移除是否真的由规则导致」以及「该移除的是否都移除了」
- 它单独报告,不影响 Up 链的健康判定
名单摘要
候选池本身是匿名的,所以证明额外承诺了抽取时名单的映射摘要。
- 摘下「记录 ID → 显示信息」的规范摘要,按记录 ID 排序,因此调整名单顺序不算变化
- 改名、换学号、改组别或禁用成员会被识别为变化
- 摘要只写入本地证明文件,不会离开这台机器
- 只有当本机当前名单正是被抽取的那份名单时,才会写入摘要
验证边界
下面这张表是这份文档里最重要的部分。它是项目威胁模型的摘要,随代码一起维护。
| 模式 | 可以做到 | 不能证明 |
| 离线证明 |
复查已完成的抽取过程;事后改动证明文件、删除旧证明或删光重建,都能被发现 |
不能证明抽取之前本地程序、随机种子或名单未被改动;也不能排除抽取前反复试验后再选择结果 |
离线证明 + 信标 本分支能力 |
在上一行基础之上,还能发现恶意指定种子 |
在无法确定确切抽取时间时,攻击者仍可伺机等到一个有利结果再执行抽取 |
几点补充
- 本机证明按追加式哈希链保存,删除或改写会留下缺口;链头与删除记录让「删掉重来」难以自洽
- 证明承诺抽取那一刻的名单映射,因此抽取之后改名单、把中签记录指向别人会被发现
- 抽取之前筛掉某个学生再抽,无法被证明;要覆盖这种情况,需要「抽取前先向第三方确认名单」的流程,目前不做
- 信标模式把信任根转到公开信标上:你不再需要相信主持人,但需要相信信标服务与它的时间线
- 验证不需要在线账户或任何托管服务;评委可以在自己的机器上独立完成重放
阅读完整的威胁模型(逐项攻击与覆盖状态)