这篇论文里面,第2部分,系统设计给我介绍一下
作成日: 2026年2月23日
使用モデル GPT-5.2 Thinking by Chat01
作成日: 2026年2月23日
使用モデル GPT-5.2 Thinking by Chat01
这篇论文里面,第2部分,系统设计给我介绍一下
下面按论文第 2 部分(系统设计)的结构,把 GeneralDID 的核心设计讲清楚(对应 2.1~2.3)。
GeneralDID 的系统设计由两块组成:分布式身份管理方案 + 双凭证模型。前者用“唯一 MainID + 多个 UserID”在可监管与不可链接之间取平衡:MainID 用来监督/防 Sybil,多 UserID 用来缓解属性链接的隐私问题;后者用承诺证明与零知识证明保护敏感凭证属性、链上身份数据与加密凭证之间的关联隐私。 (基于区块链的物联网身份管理系统.pdf)
系统包含 发行者、验证者、用户(持有人)、监管者,总体交互关系见图 2。(基于区块链的物联网身份管理系统.pdf) (基于区块链的物联网身份管理系统.pdf)
论文明确指出:可监管要求追溯真实身份、隐私要求不可链接,两者矛盾;GeneralDID 通过建立 MainID 与 UserID 的映射表,在保证隐私下提供监管,同时抵御 Sybil 与链接攻击。(基于区块链的物联网身份管理系统.pdf)
身份验证时,理论上每个凭证随机数都不同,监管者若要“打开承诺”需要对应的 r,全部记录会造成负担;因此系统让用户提供一个可公开验证的令牌 Tk=(pk)^r,使监管者无需存储 r 也能打开承诺并完成证明(文中给出对数等式证明思路),同时支持批量验证。(基于区块链的物联网身份管理系统.pdf)
如果你想更“落地”一点,我也可以按 “注册→拿到 MainID/UserID→申请凭证→验证凭证” 画一条时序流程,把每一步谁发什么数据、链上记录什么、链下保存什么梳理成一页笔记。
MainID/UserID我没看懂他俩的区别,另外,这两和DID的关系是啥?
你可以把它理解成:MainID = “可监管的主身份锚点(根身份)”,UserID = “对外使用的多个假名身份(化名/子身份)”;作者把两者“绑成一对”来用,从而兼顾监管与隐私。 (基于区块链的物联网身份管理系统.pdf)
更形象一点:
论文里有两层“DID”的用法:
论文在“DID 格式”里给了典型 DID 语法 did:method-name:method-specific-id,并说“每个用户 ID 对应一个 DID 文档(公钥、验证方法等)”。这更符合 UserID=标准 DID 字符串 + DID 文档 的模式。 (基于区块链的物联网身份管理系统.pdf)
而示例凭证里也出现了 uiid: "did:cpp:..." 这种字段,明显就是 DID 字符串。 (基于区块链的物联网身份管理系统.pdf)
论文在系统架构里直接写“每个用户都持有一对 DID(MainID,UserID)”,并在算法 CreateDID 里把 DID = (MainID, UserIDs) 当作输出。也就是说,他们把“用户的身份标识符 DID”定义成一个包含主标识 MainID + 若干假名标识 UserID 的组合结构。 (基于区块链的物联网身份管理系统.pdf)
所以总结:UserID 更贴近标准 W3C DID(可公开、配 DID 文档);MainID 是系统为了“可监管/抗 Sybil”额外引入的“主锚点”,并通过承诺隐藏;GeneralDID 把二者组合起来当成它的 DID 体系。 (基于区块链的物联网身份管理系统.pdf)
如果你愿意,我可以结合论文里的示例凭证字段(miid/uiid/token)把“一次完整的出示与验证”里 MainID/UserID 各自出现在哪一步,按时序画成 6~8 步的流程图式文字版。
给我这个结合论文里的示例凭证字段(miid/uiid/token)把“一次完整的出示与验证”里 MainID/UserID 各自出现在哪一步,按时序画成 6~8 步的流程图式文字版
下面给你按“一次完整的出示与验证”画成 8 步时序(带你点名 miid / uiid / token 分别在什么时候出现、对应 MainID / UserID 哪一块)。
前置:系统里把用户标识符定义成
DID = (MainID, UserIDs)(基于区块链的物联网身份管理系统.pdf);样例 VC 里在basicdata放了miid / uiid / token,在claim里也有muid / uuid / token(基于区块链的物联网身份管理系统.pdf),并且文中明确说basicdata加入了miid与uiid(基于区块链的物联网身份管理系统.pdf)。
(从命名与样例格式上,uiid/uuid 对应 UserID(did:...),miid/muid 对应 MainID(十六进制/承诺相关标识);token 对应监管可用的公开令牌 Tk,见下文。)
1)验证者发起验证(Challenge)
验证者生成挑战 chal 并下发给用户(同时带上访问策略/要验证的属性集合)。验证算法输入里就包含 chal 与 DID (基于区块链的物联网身份管理系统.pdf)。
2)用户选定本次要用的“假名身份”UserID
用户从自己的一组 UserIDs 中挑一个来对外出示,把它写进样例里的 uiid(DID 字符串那种:did:cpp:...) (基于区块链的物联网身份管理系统.pdf)。
basicdata.uiid(以及后面 claim 里的 uuid) (基于区块链的物联网身份管理系统.pdf)。3)用户把“主锚点”MainID 以 miid/muid 的形式带上(用于可监管/抗 Sybil 的那条线)
在样例里,basicdata 里带了 miid (基于区块链的物联网身份管理系统.pdf),claim 里带了 muid (基于区块链的物联网身份管理系统.pdf)。论文的设计目标是“唯一 MainID + 多 UserID”,所以这一步你可以把它理解为:对外主要用 uiid(UserID),但同时携带一个与 MainID 相关的字段作为可监督锚点(通常会是 MainID 的承诺/映射相关数据)。(基于区块链的物联网身份管理系统.pdf)
basicdata.miid、claim.muid(样例字段)。4)用户生成公开令牌 token(Tk),随凭证/声明一起出示
论文在“身份验证”里专门定义了公开可验证令牌:Tk = (pk)^r,并说“只要用户公开令牌,监管者就可以打开承诺,而无需存储随机数 r” (基于区块链的物联网身份管理系统.pdf)。样例凭证中 basicdata.token、claim.token 就是这个 token 字段 (基于区块链的物联网身份管理系统.pdf)。
basicdata.token + claim.token(样例)。5)用户对本次要出示的 claim/凭证材料签名(绑定“我确实控制这个 DID”)
文中创建声明时:用户签名 ξU = Sign(skU, claim),并明确说明:未申请 UserID 时用 MainID 私钥;使用 UserID 身份时用 UserID 私钥 (基于区块链的物联网身份管理系统.pdf)。
6)用户 → 验证者:提交“可验证凭证/出示包”
把以下东西打包发给验证者:
basicdata{miid, uiid, token} + claim{muid, uuid, token, 属性…} + proof/签名…(样例结构就是这么组织的) (基于区块链的物联网身份管理系统.pdf)。
7)验证者做链上/链下验证:验签 + 验策略 + 验凭证有效性
验证算法 VerifyCredential(chal, DID, pkI, cred, T):验证者根据树结构/策略 T 检查凭证有效性,通过则输出 1 (基于区块链的物联网身份管理系统.pdf)。
同时,凭证侧会涉及发行者/委员会签名与摘要证明:cred = {pkU, claim, ξ},以及发行者签名的 (sc, ξI) 之类(文中给了创建凭证与证明结构)(基于区块链的物联网身份管理系统.pdf)。
8)(可选)触发监管/审计:监管者用 token 去“打开/核验”MainID 承诺
当需要追溯或审计时,监管者利用 Tk=(pk)^r 与承诺 Com=Comm(v,r)=g^v h^r 进行证明/核验;文中给了“无需 r 也能证明”的思路(对数等式证明) (基于区块链的物联网身份管理系统.pdf)。
如果你希望我把 miid vs muid、uiid vs uuid 在样例结构里更“对齐”成一张小表(哪个字段更像“元数据层”,哪个更像“声明层”),我也可以按论文的样例 JSON 直接给你标注。
也就是说这里面的DID其实不是W3C里面的标准,而是用户自己定义的一个,包括一个main id和user id的?
另外,刚刚上面你给我的内容,给我画个流程图
结论是:它一部分“像 W3C DID”,一部分是作者为监管/抗 Sybil 额外加的扩展。 (基于区块链的物联网身份管理系统.pdf)
UserID 基本就是 W3C DID 的用法
论文先给了标准 DID 语法 did:method-name:method-specific-id,并说“每个用户 ID 对应一个 DID 文档(公钥、验证方法等)”;样例里 uiid/uuid 也确实是 did:cpp:... 这种 DID 字符串形式。(基于区块链的物联网身份管理系统.pdf)
MainID 不是 W3C DID 里那个“字符串 DID”的典型形态
它是系统为了可监管/抗 Sybil引入的“主标识符锚点”,且用 Pedersen 承诺形式表示(Com = Comm(v,r))并随凭证随机数变化。(基于区块链的物联网身份管理系统.pdf)
作者把二者合起来,自己定义了一个“身份结构”
在系统架构里直接写“每个用户都持有一对 DID(MainID,UserID)”,并在算法里把 DID = (MainID, UserIDs) 当成输出。也就是说:对外互操作更像用 UserID(W3C DID),对内系统用 MainID+UserID 的组合来平衡隐私与监管。 (基于区块链的物联网身份管理系统.pdf)
下面这个流程严格对应论文样例 VC 结构:basicdata{miid, uiid, token} + claim{muid, uuid, token, ...} + proof{...} (基于区块链的物联网身份管理系统.pdf)
text┌──────────────────────┐ │ ① 验证者 Verifier │ │ 发起验证,生成挑战 chal│ └─────────┬────────────┘ │ chal ▼ ┌──────────────────────┐ │ ② 用户 Holder │ │ 选择本次对外身份:UserID│ │ → 样例字段:uiid / uuid │ └─────────┬────────────┘ │ ▼ ┌──────────────────────┐ │ ③ 用户带上“主锚点”MainID │ │ → 样例字段:miid / muid │ │ (用于可监管/抗 Sybil 的锚)│ └─────────┬────────────┘ │ ▼ ┌──────────────────────┐ │ ④ 用户生成公开令牌 token │ │ Tk = (pk)^r │ │ → 样例字段:basicdata.token│ │ claim.token │ │ 作用:监管方无需保存 r 也能核验/打开承诺│ └─────────┬────────────┘ │ ▼ ┌──────────────────────┐ │ ⑤ 用户组装要出示的材料 │ │ basicdata{miid, uiid, token}│ │ claim{muid, uuid, token, 属性...}│ │ proof{signature/ZKP...} │ │ 并用“所选身份”的私钥签名(用UserID则用UserID私钥)│ └─────────┬────────────┘ │ VP/VC 出示包 ▼ ┌──────────────────────┐ │ ⑥ 验证者 Verifier │ │ 验签 + 验访问策略 T │ │ 校验发行者签名/链上摘要证明等│ └─────────┬────────────┘ │ 通过/拒绝 ▼ ┌──────────────────────┐ │ ⑦ 通过:授权访问/完成认证 │ │ 拒绝:返回失败原因(策略不满足/签名不合法/凭证无效等)│ └─────────┬────────────┘ │(可选:触发审计/追责) ▼ ┌──────────────────────┐ │ ⑧ 监管者 Regulator(可选)│ │ 利用 token(Tk) + MainID 承诺逻辑做核验/打开承诺│ │ 并通过 MainID↔UserID 映射实现“可监管追溯”│ └──────────────────────┘
如果你想把 miid vs muid、uiid vs uuid 的“为什么在 basicdata 和 claim 里各放一份”也讲清楚,我可以按样例 JSON 的层级逐字段标注它们分别承担“元数据定位/声明主体/审计锚点”的角色。
介绍一下这个论文里面的3.2过程
下面按你这篇《Blockchain-based access control architecture for multi-domain environments》论文的 3.2 Access control architecture process,把“3.2 的过程”用一条主流程 + 4 个子流程(3.2.1~3.2.4)讲清楚。(多域DID.pdf)
论文把多域环境放进一个联盟链/联邦链里:各域都是链上节点;用户用 DID + 公私钥对证明身份;权限与资源都用 可验证凭证(VC)表达;大部分动作由智能合约自动执行,并把关键哈希/日志写链,便于追溯审计。(多域DID.pdf)
主线分两段:(多域DID.pdf)
目标:让用户进入多域系统时,拿到自己的 DID + 公私钥对。流程是:(多域DID.pdf)
registerReq(userInfo)(提交域要求的注册信息)sig = Sign(ska, Hash(userInfo)),并把自己的 DID、公钥等信息连同 sig 回链didu, pku, sku,生成 DID Document,并把(DID、公钥、加密后的 userInfoHash 等)写链registerRes(didu, pku, sku, userInfoHash)(用户拿到 DID 和密钥对)这里的关键点:DID 是身份标识,密钥对用于后续所有操作签名/认证。(多域DID.pdf)
这一部分分两块:CPT 创建 + 资源发布(资源凭证)。(多域DID.pdf)
CPT 可以理解为“某类凭证的 Claim 模板/字段规范”,方便不同域跨域理解数据结构。(多域DID.pdf)
createCptReq(dida, pka, ska, claimStruct)createCptRes(cpt)(后续发 VC 时按这个结构填 claim)资源发布者用 VC 把资源“声明出来”(电子资源凭证)。(多域DID.pdf)
queryCptReq(cptId) 先取模板releaseReq(didu, pku, sku, resourceInfo)(按模板组织资源数据并提交)resourceCredential(由用户私钥对 claim 签名,链上记录其哈希)resourceCredential(通常放域 registry)releaseRes(resourceCredential)目的:给用户发“电子权限凭证”(permission VC),让他能访问某些资源/服务。(多域DID.pdf)
authorizeReq(didu, pku, sku, authorityInfo)(也会先查 CPT,论文图里省略了查 CPT 的重复步骤)sig = Sign(ska, Hash(didu || authorityInfo)) 回链(证明“管理员同意授权”)authorityCredential(由管理员私钥签 claim)authorizeRes(authorityCredential)(返回凭证 ID 或凭证本体)这是“真正访问资源”的自动化闭环:认证 → 判权 → 校验资源凭证 → 返回资源 → 记日志。(多域DID.pdf)
accessReq(didu, pku, sku, credentialId, resourceId, domain)queryCredential(credentialId) 取“电子权限凭证”queryResource(resourceId) 取“电子资源凭证”accessRes(resource)(或返回失败结果)如果你愿意,我可以把这 3.2 的四个子流程(注册/资源发布/授权/访问)再压缩成一张“消息时序表”(每一步“谁 → 谁:函数(参数)”),方便你直接复述或画图。
userInfoHash ,这里面一般能包括哪些东西/
CPT资源和后面的权限有什么关联?
另外,你上面的四个子过程稍微说的有点简单,可以通俗点,然后讲清楚,用户生成什么,发给区块链什么之类的么
下面按你问的 3 个点来讲(都基于《多域DID.pdf》这篇里的 3.2 流程与伪代码)。
论文里这个名字其实有点“误导”:在注册合约 registerUser 里,userInfoHash = Encrypt(pku, userInfo)——它不是 hash,而是用用户公钥 pku 把 userInfo 加密后的密文。(多域DID.pdf)
所以它“能包含什么”,取决于 userInfo 里放了什么。论文的表述是:用户提交的是该域要求用于审核/评估的用户信息。(多域DID.pdf)
并且至少可以确定一点:userInfo 里要有 domain 字段,因为 DID 生成直接用到了 userInfo[domain]:didu = "did:" + userInfo[domain] + ":" + generateAddress(pku)。(多域DID.pdf)
更通俗地说:
一句话:CPT 就是“凭证里 claim 字段的标准模板/字段字典”,资源凭证和权限凭证都靠 CPT 来对齐结构与含义。
你可以把 CPT 理解成:“资源/权限凭证的 JSON schema + 字段含义说明书”。
我按“谁生成什么 → 发给谁什么 → 链上做什么 → 最后用户拿到什么”来写。
用户做什么 / 发什么:
registerReq(userInfo)(提交该域要求的注册信息)(多域DID.pdf)管理员做什么 / 发什么:
2) 管理员审核通过后:sig = Sign(ska, Hash(userInfo)),把签名等回传链上表示“同意注册”。(多域DID.pdf)
区块链合约做什么:
3) registerUser(...) 会:
(pku, sku);userInfo[domain] 和 pku 派生地址生成 didu;(多域DID.pdf)userInfo 用用户公钥加密成 userInfoHash(密文);(多域DID.pdf)didu, pku, userInfoHash 写链。(多域DID.pdf)用户最终拿到什么:
4) 区块链 → 用户:registerRes(didu, pku, sku, userInfoHash)(DID + 公私钥 + 加密后的注册信息备份)(多域DID.pdf)
管理员发什么:
createCptReq(dida, pka, ska, claimStruct)(把“Claim 模板/结构”提交上链)(多域DID.pdf)链上做什么 / 返回什么:
2) 区块链合约生成 CPT 并上链,返回 createCptRes(cpt);后续发 VC 时可以通过查询 CPT 获取 claimStruct。(多域DID.pdf)
用户先拿模板:
3) 用户 → 区块链:queryCptReq(cptId)(我要发布某类资源,先取对应 CPT)(多域DID.pdf)
4) 区块链 → 用户:返回 claimStruct(告诉你 claim 该怎么填)(多域DID.pdf)
用户再发资源:
5) 用户按 claimStruct 组织资源数据,连同自己的 DID/密钥 → 区块链:releaseReq(didu, pku, sku, resourceInfo)(多域DID.pdf)
链上做什么:
6) 区块链合约创建 resourceCredential(资源凭证),里面会把 claim 签名并把凭证哈希写链作为防篡改凭据(伪代码里是 uploadBlockchain(Hash(resourceCredential)))。(多域DID.pdf)
7) 资源凭证存入域 registry,返回给用户。(多域DID.pdf)
用户发什么:
authorizeReq(didu, pku, sku, authorityInfo)(“我想要某些权限”,并证明我控制该 DID)(多域DID.pdf)管理员发什么:
3) 区块链把请求转给管理员;管理员同意则签:sig = Sign(ska, Hash(didu || authorityInfo)) 回链。(多域DID.pdf)
链上做什么 / 用户拿到什么:
4) 区块链合约 authorize(...):同时认证用户与管理员、验管理员签名,通过后生成 authorityCredential(权限凭证),并存入私有/公共/域 registry。(多域DID.pdf)
5) 区块链 → 用户:返回权限凭证(或凭证 ID)。(多域DID.pdf)
用户发什么:
accessReq(didu, pku, sku, credentialId, resourceId, domain)链上做什么:
2) 先 authenticate(didu, pku, sku) 做身份认证;失败可能冻结 DID。(多域DID.pdf)
3) 向 registry 拉取权限凭证:queryCredential(credentialId),然后合约 verifyAuthority(...) 判断它是否允许访问该 resourceId(不通过会拒绝且可能冻结权限凭证)。(多域DID.pdf)
4) 通过后再去拉取资源凭证:queryResource(resourceId),合约 verifyResource(...) 校验资源凭证没被篡改,最终返回资源。(多域DID.pdf)
5) 无论成功/失败都 generateLog(...) 写链留痕便于审计追责。(多域DID.pdf)
如果你希望我把“资源凭证 claim 里一般会有哪些字段 / 权限凭证 authorityInfo 通常怎么设计(比如 RBAC/ABAC)”也接着说明,我可以结合论文 Appendix 里的 VC/CPT 示例结构继续往下拆。
那这里面的DID其实是公开的?其他所有人都知道DID/
在这篇《多域DID》的架构里,DID 基本上就是“可被别人看到/可被引用”的公开标识符——但要分清“对谁公开”。
论文把 DIDs 归为 blockchain data,并明确写了“记录在区块链里”。(多域DID.pdf)
区块链又是点对点广播、各节点共同维护账本的,所以链上参与节点都能看到这些 DID 记录。(多域DID.pdf)
因为跨域访问时,用户必须提交 DID 来证明身份与权限:论文写“用户在跨域访问资源时需要提供 DID 和凭证”。
这套方案是 consortium blockchain(联盟链) 场景。(多域DID.pdf)
所以一般不是谁都能随便读链;只有加入这条链/能访问链数据的人,以及你交互的验证方,才会知道你的 DID。
论文的思路是:DID / DID Document 公开,但不放隐私数据。
userInfoHash 再上链(其实是密文)。(多域DID.pdf)是的,这篇里的 DID 设计上就是“公开可用的身份标识符”:联盟链节点能看到、你跨域访问时也会提供给对方;但作者通过“DID Document 不含隐私 + userInfo 加密上链”来避免直接隐私泄露。fileciteturn1file10L2-L4(多域DID.pdf)
一个联盟链上可以有不同的规则么?例如有的用户请求获得DID,然后有的用户在获得DID后,在这个同一个联盟链上获取任务授权,然后有的用户获取任务授权后,可以在同一个联盟链上验证任务是否授权
可以的,但要先把“规则”分两层看:链层规则 vs 业务层规则。
这是联盟链自身的共识、交易验证、节点治理这些“底座规则”。论文里说多域环境里“每个域作为节点共同治理联盟链”,并由联盟链委员会负责部署/维护智能合约、做治理工作。(多域DID.pdf) (多域DID.pdf)
这些通常对全网一致,否则账本无法达成一致。
同一条链上可以部署不同的智能合约/同一合约不同参数来表达不同业务规则。论文明确:
所以:同链 ≠ 同业务政策。同一条链可以容纳“不同域、不同任务、不同权限策略/模板”。
你描述的三段流程,论文在 3.2 里基本都写成了智能合约驱动的步骤:
用户先向链提交注册请求,链侧合约产出 didu + (pku, sku)。(多域DID.pdf)
用户提交 authorizeReq(didu, pku, sku, authorityInfo);管理员审批后签名;链上合约生成 electronic permission credential(权限凭证) 并存入 registry。(多域DID.pdf)
这里的“任务授权”在论文模型里就是 权限凭证里 claim 的内容,它的字段结构通常由 CPT 约定(先 query CPT 再填 authorityInfo)。(多域DID.pdf) (多域DID.pdf)
访问/验权走 accessReq(didu, pku, sku, credentialId, resourceId, domain):
authenticate(didu,pku,sku) 做身份认证;(多域DID.pdf)queryCredential(credentialId);(多域DID.pdf)verifyAuthority(didu, credential, resourceId) 判断“这张权限凭证是否包含访问该 resourceId/任务的权限”;(多域DID.pdf)generateLog(...)。(多域DID.pdf)这正对应你说的:“有人拿 DID → 再拿任务授权 → 再验任务是否授权”,而且都在同一条联盟链的合约流程里完成。(多域DID.pdf)
按论文这套思路,最常见是三种“可变点”:
如果你愿意,我可以把“任务=resourceId”的映射方式讲得更具体:比如把“任务凭证/任务发布”也当成 resource credential,然后授权凭证里明确允许执行/领取哪些 taskId(对应 resourceId),这样 verifyAuthority 就能直接判断。
这样的话,论文里面的域A、域B,他们一块组成了联盟链,那他们内部,例如域A内部是区块链么?
不一定。
在这篇《多域DID》里,“域 A / 域 B”更像组织/管理边界(医院、大学、研究机构这种),它们各自运行联盟链的节点,共同维护同一条联盟链账本 (多域DID.pdf)。联盟链上记录的是 DID、CPT、智能合约、访问日志等“区块链数据” (多域DID.pdf)。
但域内部不要求再搞一条“域内区块链”。域内通常还有一个“registry(凭证/资源库)”来存放可验证数据(资源凭证、权限凭证),这个 registry 的实现方式可以很多样:** 云存储、IPFS,甚至“private chains(私有链)”**都可以 (多域DID.pdf)。
所以你可以这样理解:
如果你愿意,我可以把“联盟链上放什么 vs 域 registry 里放什么”按数据类型(DID、CPT、资源VC、权限VC、日志)列一张对照表。
那我其实可以理解为域内就是多个用户管理者构成了管理委员会,?
你的理解非常接近,但需要稍微精确一点。
在这篇 GeneralDID 论文里(《基于区块链的物联网身份管理系统》),所谓“域”并不是链本身,而是:
一个参与联盟链治理的组织单元(例如某机构、行业节点等)。
在系统架构(图 2,系统架构图)里明确写到:
📌 也就是说:
联盟链由多个“委员会节点”共同组成
每个域可以拥有一个或多个这样的节点
论文没有说域内部必须再建一条链。
它的结构是:
text联盟链(GeneralDID 主链) ↑ ├── 域 A(拥有一个或多个委员会节点) ├── 域 B(拥有一个或多个委员会节点) ├── 域 C …
域本质是:
而不是说:
域内部一定再跑一条独立区块链
你说:
域内是不是多个用户管理者构成了管理委员会?
更准确的说法应该是:
论文说:
所以:
委员会是跨域的,不是域内独立的。
换句话说:
它们一起构成 N 个委员会节点
然后用 PBFT 达成共识
这才是“管理委员会”。
域内部通常包含:
可以理解为:
text域 A ├── 用户1 ├── 用户2 ├── 设备若干 └── 区块链节点(加入联盟链)
域 ≠ 一条独立区块链
域 = 参与联盟链治理的一个组织单元
委员会 = 所有域的节点共同组成的联盟链共识层
如果你愿意,我可以给你画一张“域—委员会—联盟链”的三层结构示意图,帮你彻底理清。
那这块采用 T-Shamir 阈值方案 + PBFT 共识,其实指的是联盟链上的多个域之间采用的是这个方式?
是的,你理解得基本正确 👍
在 GeneralDID 这篇论文里:
T-Shamir 阈值方案 + PBFT 共识
指的是 ——
联盟链上的多个委员会节点(通常来自不同域)之间
采用的联合签发与共识机制。
我给你拆开讲清楚。
论文第 2.1 节系统架构中写到:
PBFT 是典型的:
多个节点之间达成一致
容忍部分恶意节点(拜占庭容错)
所以:
✔ 这是联盟链层面的共识
✔ 是多个域的节点之间的共识
✔ 不是域内部用户之间的共识
论文明确写到:
需要选择至少 t 个节点验证事务
才能完成签发或验证 (基于区块链的物联网身份管理系统.pdf)
这意味着:
这叫:
阈值签名机制
举个简单例子:
假设:
那么:
“这笔交易是否写入区块?”
“这张凭证是否有效?”
两者层级不同:
| 层级 | 机制 | 解决什么 |
|---|---|---|
| 区块层 | PBFT | 区块共识 |
| 业务层 | 阈值签名 | 多方联合签发凭证 |
✔ 是的。
更准确地说:
联盟链上的委员会节点(可能来自不同域)
共同采用 PBFT 共识
并通过 T-Shamir 阈值机制联合签发凭证。
所以结构是:
text域 A —— 节点1 域 B —— 节点2 域 C —— 节点3 域 D —— 节点4 ... ↓ 组成联盟链委员会 ↓ PBFT 共识 ↓ 阈值签名发凭证
域 ≠ 一条链
域 = 一个组织单元
联盟链 = 所有域的委员会节点组成的共识网络
T-Shamir + PBFT 是:
联盟链层的安全保障机制
而不是某个域内部的机制
如果你愿意,我可以给你画一张:
你会一下子彻底通透这个架构。
这一页里面的claim指的是啥?
这一页里的 claim 就是“凭证里的一条声明/断言”。
在你截图这段定义里,作者把身份注册阶段用到的凭证 看成由 k 条声明组成:
所以你可以把 claim 理解成“属性—值(attribute-value)对”;而 或 就是一组 claim,把用户的“身份先证/注册信息”用结构化的方式表达出来。
对应到论文后面给的可验证凭证示例里,claim 里出现的 "name":"Bob", "gender":"male" 就是典型的 claim(属性=值)实例。(基于区块链的物联网身份管理系统.pdf)
另外,这篇 GeneralDID 在后续把 claim 写得更“身份系统化”一些:它会把一条声明写成带主体关系的三元组,例如 (属性、属性值、主体U),或把属性值换成承诺 来保护隐私。(基于区块链的物联网身份管理系统.pdf) (基于区块链的物联网身份管理系统.pdf)
给我个例子
给我个例子
可以,把论文里的 claim 当成“对某个主体 的属性声明”。论文给了两种写法:明文声明 claim_i = {uprop, attv, U},以及把属性值用承诺隐藏的承诺声明 claim_i = {uprop, com, U}。(基于区块链的物联网身份管理系统.pdf)
假设主体是用户 Bob(用他的某个标识符/ID 表示为 U),他要声明两条属性:name=Bob、gender=male。
按论文的“明文声明”形式,可以理解成两条 claim:
用接近 JSON 的写法(便于看):
json{ "claim": { "U": "did:cpp:DDaF300661a5794480B6a1da38658cA867", "name": "Bob", "gender": "male" } }
这和论文给的样例凭证里 claim 段非常一致:里面就直接出现了 "name":"Bob"、"gender":"male"(同时还带了 uuid/token 等字段)。(基于区块链的物联网身份管理系统.pdf)
如果想隐藏 gender=male 这样的属性值,就把 attv 换成承诺 com:
示意:
json{ "claim": { "U": "did:cpp:DDaF300661a5794480B6a1da38658cA867", "gender_commitment": "Com = Comm(\"male\", r)" } }
如果你愿意,我也可以把样例里的 uuid/muid/token 一起纳入这个例子,解释它们分别是“主体标识/主锚点/公开令牌”在 claim 里的作用位置。
那这个claim和VC是不一样的?
对,不一样:claim 是 VC(可验证凭证)里面的一部分,VC 是“整张证书/凭证”。
GeneralDID 的样例 VC 里,整张 VC 结构是 basicdata + claim + proof,其中 claim 只是中间那一段:(基于区块链的物联网身份管理系统.pdf)
json{ "basicdata": { "miid": "...", "uiid": "...", "token": "..." }, "claim": { "name": "Bob", "gender": "male", "uuid": "...", "token": "..." }, "proof": { "...": "签名/零知识证明相关字段" } }
所以你可以记成一句话:
VC = “装着声明(claim) + 证明(proof) + 一些元数据”的完整容器;claim = 里面具体讲了什么(属性/事实)的那部分。
那DID里面只有claim和basicdata不行么?必须有proof么
我其实是不是可以把device VC改成claim?
不太行——**只剩 basicdata + claim,它就不再是“可验证凭证(VC)”了,只能算“声明数据/自述数据”。**原因是:这两篇论文都把“可验证”的关键放在 proof 上。
在 GeneralDID 这篇里,作者明确把 VC 定义为 “元数据(basicdata) + 声明(claim) + 证明(proof)”,并且说 proof 就是证书的数字签名或零知识证明。(基于区块链的物联网身份管理系统.pdf) (基于区块链的物联网身份管理系统.pdf)
所以你把 proof 去掉,验证者就少了“我怎么相信这份 claim 没被篡改/确实由某个发行者(或你)签过/确实满足ZKP”的依据——它就不满足论文里的“可验证”。
在《多域DID》那篇也一样:VC 主要由 Claim 和 Proof 构成,proof 的作用就是记录发行者对 claim 的数字签名。(多域DID.pdf)
并且他们后续在验权时会直接检查 credential[proof[publicKey]] 和 credential[proof[proofValue]] 的签名,也就是靠 proof 来验真、防伪造/篡改。(多域DID.pdf)
结论:
claim/basicdata 当业务数据用;可以分两种意思:
那你可以让设备只上送 claim(或 claim+最少元数据)到网关/服务端,然后由网关/管理员/发行者把它“封装成 VC”(补齐 proof)。
因为在论文的设计里,claim 是 VC 的内容部分,proof 才让它可验证。(多域DID.pdf)
那就等于你接受:它只是自声明,别人无法按论文的验签逻辑验证真伪;在多域访问控制里会直接卡住(验权/验资源都要验 proof)。(多域DID.pdf)
如果你告诉我你说的 “device VC” 是 设备身份凭证 还是 设备数据/任务结果凭证,我可以按你那个场景给一个“最省资源但仍可验证”的具体打包格式(比如:设备只签 challenge,网关做 VC proof,链上只存 hash)。
VC 包含 “元数据(basicdata) + 声明(claim) + 证明(proof)这是普遍做法么?
另外,我看论文里面声明是用承诺做的,那既然有承诺了,还要证明(零知识证明)干嘛?
从思想上挺普遍:一张 VC 基本都要包含三类信息——
但字段名字和拆分方式不一定统一:
所以:“三块内容”很常见,但不一定都叫 basicdata/claim/proof,也不一定都放在同一层字段里。
一句话:承诺只负责“把值藏起来”,ZKP 负责“在不打开承诺的情况下,让验证者相信你满足某个条件/你确实知道里面的值”。
更具体点分三种典型需求:
GeneralDID 里 claim 可以是承诺声明:claim_i = {uprop, com, U},com 是对属性值向量的 Pedersen 承诺(基于区块链的物联网身份管理系统.pdf)。
如果没有 ZKP,验证者要确认 com 对应的值,只能让你直接公开 (v, r) 去“打开承诺”,这就泄露隐私了(论文也说只有“必要时”才透露 v 和 r)(基于区块链的物联网身份管理系统.pdf)。
ZKP 的作用就是:不公开 v/r,也能证明“我知道 opening(或知道承诺值)”(基于区块链的物联网身份管理系统.pdf)。
比如年龄≥18、权限属于某集合、属性在某范围内。论文在 ZKP 段落里举了范围证明的例子:证明承诺值 落在 区间而不泄露 (基于区块链的物联网身份管理系统.pdf)。
承诺本身做不到“证明范围/集合成员资格”,它只保证隐藏与绑定;谓词证明靠 ZKP。
GeneralDID 明确把 proof 定义为“证书的数字签名或零知识证明”(基于区块链的物联网身份管理系统.pdf),并且在安全分析里也强调“验证过程是零知识的,不会泄露额外信息”(基于区块链的物联网身份管理系统.pdf)。
也就是说:承诺解决“内容保密”,proof(签名/ZKP)解决“可信可验证”。
如果你愿意,我可以拿你前面那段样例 VC(含 miid/uiid/token)再具体举一个“承诺 claim + ZKP proof”的例子:比如证明“gender 的承诺值属于 {male,female} 之一”但不暴露具体是哪一个。
给我个简单的例子,包括DID体系完整架构以及VC的架构
下面给你一个**“最小但完整”**的例子:先把 DID 体系的完整架构讲清楚,再给出 VC 的数据结构(用论文里的字段风格写一个示例 JSON)。
GeneralDID 的联盟链里有:委员会节点/发行者、验证者、监管者、用户(持有人),并且假设有 个委员会节点;采用 T-Shamir 阈值方案(至少 t 个节点参与)来验证/签发事务。(基于区块链的物联网身份管理系统.pdf)
每个用户持有一对 DID:(MainID, UserID),其中 MainID 监管场景唯一,UserID 用于日常应用。(基于区块链的物联网身份管理系统.pdf)
DID = (MainID, UserIDs)(一个 MainID + 多个 UserID)。(基于区块链的物联网身份管理系统.pdf)text[监管者] ←(KYC/审计/打开MainID承诺:Tk)→ [联盟链] ▲ │(PBFT共识 + t-of-N阈值签发) [用户/设备钱包] ──(注册MainID/申请UserID)───┘ │ ├─对外用:UserID (公开) → 给验证者/应用 └─对内锚点:MainID (唯一/可监管) → 需要时给监管者 [验证者/应用] ←(出示VC并验证)→ [联盟链/合约/签名验证]
论文把 VC(可验证凭证)写成三段:凭据元数据 basicdata + 声明 claim + 证明 proof,并给了样例(含 miid/uiid/token)。(基于区块链的物联网身份管理系统.pdf)
同时说明:proof 是数字签名或零知识证明。(基于区块链的物联网身份管理系统.pdf)
另外,claim 有两种:
claim_i = {uprop, attv, U}claim_i = {uprop, com, U}(把属性值用 Pedersen 承诺隐藏)(基于区块链的物联网身份管理系统.pdf)did:cpp:...)(基于区块链的物联网身份管理系统.pdf)假设设备拿到:
MainID:0xMAIN...(实际系统里经常以承诺/映射方式用)UserID:did:cpp:Thermo01下面这个 JSON 结构对齐论文样例:basicdata{miid, uiid, token} + claim{...} + proof{...}(基于区块链的物联网身份管理系统.pdf)
json{ "basicdata": { "miid": "0xMAIN... (MainID相关标识/承诺锚点)", "uiid": "did:cpp:Thermo01 (本次对外使用的UserID)", "token": "Tk = (pk)^r (给监管可打开承诺用)" }, "claim": { "uuid": "did:cpp:Thermo01", "perm": "read:hvac_status", "exp": "2026-12-31" }, "proof": { "type": "signature-or-zkp", "signatureValue": "..." } }
claim.perm/exp 只是举例;论文允许 claim 表达任意 属性-值-主体(或属性承诺)关系。(基于区块链的物联网身份管理系统.pdf)proof 必须有,因为论文把 proof 作为“可验证性材料”(签名或ZKP)。(基于区块链的物联网身份管理系统.pdf)多域DID论文更贴近 W3C 的表述:VC 主要由 Claim + Proof 构成,Proof 记录发行者对 Claim 的签名。(多域DID.pdf)
它还给了 DID Document 示例(有 id、公钥列表、serviceEndpoint)。(多域DID.pdf)
在它的“资源凭证”生成算法里,VC 里会包含 @context/id/type/claim/issuer/issuanceTime/expirationTime/proof(publicKey, proofValue, type...) 这类字段。(多域DID.pdf)
如果你想,我可以把上面的例子继续扩成一次完整交互(注册DID → 申请权限VC → 出示给验证者 → 验签/验策略 → 必要时监管用Tk审计),用 6–8 步时序把消息里到底带哪些字段写得一清二楚。
这个图详细介绍一下
这张图是在讲:信任域 A 里,一个用户 怎么拿到自己的 DID,同时又做到 (1) 委员会背书“你的身份声明是真的”、(2) 防止同一个身份重复注册(Sybil/重复注册)、(3) 不把敏感值明文写到链上(用承诺隐藏)。
claim = {a, v}
C_v = Pedersen(v, r)小提醒:图里把
claim从{a,v}改成了(a, C_v):意思是 后续查重与上链只用承诺 ,避免直接暴露 。
claim = {a, v},发给委员会(图上写“开放信道”)。接着用户做两件事:
ctx = "合法身份"C_v = Pedersen(v, r),并把 claim 改成:claim = (a, C_v)委员会收到 后:
C_v 是否属于 CBF_a这里的 CBF 从命名上很像“(计数)布隆过滤器 Counting Bloom Filter”一类的集合摘要结构:能高效做 membership 检查,用于“是否已登记过”。(仅根据图中命名推断)
查重通过后:
did:ethr:...)用户收到 DID,即完成身份注册。
假设:
流程就是:
{身份证号, 6101...} 给委员会验证(DECO),委员会 -of- 阈值签名背书CBF_身份证号,看 是否已出现过(出现过就认为重复注册风险)如果你把这张图所在论文的前后两页也截一下(尤其是对 CBF / SearchCBF / CheckCBF / DECO 的文字定义部分),我可以把“CBF 究竟是什么结构、查重失败时怎么处理、是否会更新 CBF_a(把 C_v 加进去)”这些细节也补全到实现级别。
那步骤 1:这里,其实就是委员会可以用DECO协议证明claim的真实性之后,然后再生成t份 签名,用户将t份签名和自己的合起来生成一个有效的凭据?
对,你的理解大体正确,但我帮你把“合起来”的对象说得更精确一点(按你图里的符号)。
用户先给委员会发明文声明
这里 是属性名(比如“身份证号/学号/设备序列号”), 是属性值。
委员会选出至少 个节点跑 DECO 来核验 claim 的真实性
图里写的是“选择 个委员会节点执行 DECO 协议来证明 claim”。意思就是:委员会节点先确认“你这个 是真的/符合注册要求”。
每个参与节点各自产生一份“部分签名”
这一步产生的是阈值签名方案里的 share/partial signature,不是最终签名。
用户收集到 ≥t 份部分签名后,把它们“组合”成一个可验证的阈值签名
你说的“合起来生成有效凭据”,这里更准确是:
⚠️ 关键纠正:这里不是“用户把 份签名再和自己的签名合起来”。
图里用户做的是 Comb(组合部分签名),并没有出现“用户再签一遍”的步骤。用户的参与主要是“收集 + 组合”。
ctx = "合法身份"DECO 负责“委员会确认 claim 真实”;T-Shamir 负责“至少 个委员会节点共同背书”;用户负责“收集部分签名并组合成阈值签名”,然后把 承诺化并打包成 。
如果你愿意,我也可以顺着讲你图里的步骤 2/3/4:为什么要去查 CBF_a、CheckCBF 在防什么(重复注册/Sybil),以及最后 Bchain_A 怎么生成 DID 文档。
这里面的两个联盟链的关系我怎么没看懂?为啥要有两个?
另外,根据 claim 里的属性名
a
a,去
B
c
h
a
i
n
′
Bchain
′
上查询对应的
C
B
F
a
CBF
a
这一步是干嘛的?
你这张图里把“身份注册”拆成了两类账本职责,所以画了两条“联盟链”:
看你截图的步骤 3:用户把公钥 提交到 Bchain_A 的智能合约,然后生成 DID(例:did:ethr:...)和 DID 文档,并把 、DID 写进 DID 文档里,再把 DID 返回给用户。
➡️ 也就是说 Bchain_A 负责“把公钥 ↔ DID”这件事登记下来,属于“身份登记账本”。
你截图的步骤 2:委员会在验证 后,会去 Bchain′ 查 CBF_a 并做 CheckCBF。
➡️ 也就是说 Bchain′ 不负责发 DID,而是负责提供“是否已注册过”的查询依据(更像索引/登记册)。
从设计动机上通常是三点(结合你图的流程就能解释通):
职责分离:
降低可链接性:
你图里把敏感值 先做了承诺 ,再拿 去查 CBF_a;这样做“查重”时不需要把 明文广播到发 DID 的那条链上。
系统工程上也常见多账本/多存储:很多架构会把不同数据放在不同存储/链里(例如一些数据放 registry/甚至 private chain),避免所有东西都挤在一个账本里。(多域DID.pdf)
注意:你这张图把两条都叫“联盟链”,更像是“一个全局联盟链(Bchain′)+ 每个信任域一条域链(Bchain_A、Bchain_B…)”这种多链结构。
这一步的目的就是:用属性维度做去重,防止同一个身份凭证被重复注册。
claim={a,v}: 是属性名(如身份证号/学号/设备序列号这类“强唯一属性”), 是属性值。SearchCBF:根据属性名 ,去 Bchain′ 找到对应的过滤器/集合摘要 CBF_a(可以理解为“所有用‘身份证号’注册过的条目集合摘要”)。CheckCBF:检查 是否已经在 CBF_a 里出现过。
这类“用唯一属性防止 Sybil/重复身份”是很多 DID/身份系统的核心目标之一(你之前那篇 GeneralDID 也把“防 Sybil”作为目标之一)。(基于区块链的物联网身份管理系统.pdf)
如果你愿意,我可以再把 CBF 可能是什么(Counting Bloom Filter 的概率型查重)、以及“查重命中时为什么是 可能(误判)”这块也用 3–5 句话讲清楚(一般论文会在后文解释如何处理误判/更新 CBF)。
防同一身份重复注册,是通过查属性是否有重复?那这里面假设他有多个属性,是怎么声明?然后查重的时候是只找一个关键属性来查即可?
另外,这个图片里面,是通过联盟链bchainA去上传DID,那其实这里由委员会CA直接上传也可以把?不一定必须是区块链?
你理解得对:这套“防同一身份重复注册”的思路,本质就是拿某个(些)身份属性做去重——只不过图里是用 属性名 去定位一个“去重索引”(),再用 **属性值(经处理后的表示)**去做 membership 检查。
下面把你两个问题分别讲清楚。
图里为了讲清楚流程,用了最简形式:一条声明
真实系统里一般会是一组声明(claims 列表),每条 claim 是一个“属性名—属性值”对。类似 GeneralDID 文中写的:一个证书可以包含 个声明要求 claim={claim1,...,claimm},每个 claim_i 表达一个属性及其值(明文或承诺)。(基于区块链的物联网身份管理系统.pdf)
所以对应到你这张图,直觉上就是:
然后每个 可能都会被变成承诺 。
通常是查一个或少数几个“强唯一属性”,原因很现实:
所以实践上常见两种策略:
你图里是把 变成 然后检查 。
这里要能“查出重复”,必须满足一个前提:同一个 在不同注册尝试时,映射到的“用于查重的表示”要一致(或至少可一致比较)。
否则如果每次都换随机数 ,同一个 会生成不同的 ,那 CBF 就查不出来“重复”。
所以一般会在“查重用的表示”上做成:
(你这篇图的正文如果有解释 “r 怎么处理 / CBF 存什么”,那就能确定它用的是哪一种。)
如果让 直接维护一份数据库/注册表(DID → 公钥 → DID 文档):
把 DID 文档写到链(或写哈希到链)主要带来:
如果你把这张图所在论文/章节(包含对 CBF 的定义、以及是否更新 CBF_a、如何处理误判、r 的取法)再发两页截图,我可以把“它到底查的是 Hash(v) 还是 Commitment(v,r)”和“查重命中后的处理分支”给你补成严格版。
有没有可能属性不重复,但是生成的DID(例如did:ethr:12345)这个重复了?因为他是不同域生成的
有可能理论上会重复,但要看你这个系统怎么构造 DID 的命名空间。
论文里给的 DID 语法是 did:method-name:method-specific-id (基于区块链的物联网身份管理系统.pdf)
所以 “唯一性”默认是在同一个 method-name 命名空间里谈的:
did:au:... vs did:bu:...),那它们天然就不会撞。did:ethr:...),那就要看 method-specific-id 会不会撞。它的注册算法里直接写了:
didu = "did:" + userInfo[domain] + ":" + generateAddress(pku) (多域DID.pdf)
也就是说 domain 被放在 DID 的第二段(等价于 method-name 的位置),例如:
did:DomainA:0xABC...did:DomainB:0xABC...哪怕 generateAddress(pku) 的结果一样(后面解释为什么几乎不会),只要 domain 不同,整个 DID 也不同。
所以在这篇的默认设计下,“不同域生成同一个 DID”通常不会发生。
did:ethr:12345 这种,会不会跨域撞?如果你真的让多个域都用同一个 method(都用 ethr),并且 method-specific-id 又是那种很短/可重复的编号(比如 12345 这种域内自增),那当然可能撞:
did:ethr:12345did:ethr:12345但在多域DID论文的实现里,第三段不是自增号,而是 generateAddress(pku)(从公钥导出的地址)(多域DID.pdf):
did:<domain>:<addr>)(多域DID.pdf)did:ethr:确保 method-specific-id 里带上足够的命名空间信息(至少别用短编号;通常用链/网络标识+地址这种)如果你把你说的“不同域生成 did:ethr:12345”的具体生成规则(是自增?哈希?地址?)贴一下,我可以帮你判断它在你设计下的“撞号风险”到底有多大,以及怎么改最省事。
Bchain′上面都没有DID啊,怎么会有进一步的属性之类的?
你抓到点了:Bchain′ 本来就不需要存 DID,它在这张图里承担的是“查重索引/黑名单(已用过的身份属性)”这一类功能,而不是“身份登记(DID→公钥→DID 文档)”。
从你截图的步骤 2可以看出来,委员会在 Bchain′ 上查的是 :
claim=(a, C_v) 里拿到属性名 (比如“身份证号”“学号”“设备序列号”这种属性类型)CheckCBF 去检查 是否已经“属于/存在于”这个 所以 Bchain′ 存的不是 DID,也不是完整属性值 v,而是类似下面这种结构:
(属性名 a) → (一个集合摘要/过滤器 CBF_a)
里面记录了“这个属性类型下,已经注册过的那些属性值的某种不可逆表示”(图里用的是承诺 )。
它的作用就是:给“是否重复注册”提供一个全局可查询的索引,而不是给你“解析 DID 文档”。
一句话:定位“查重集合”。
因为系统可能支持很多种可用于注册的属性(身份证号 / 护照号 / 设备 MAC / 学号……),不同属性类型各自维护一份“已使用列表”。所以要先用 找到对应那一份:
SearchCBF:按属性名 找到 对应的 CBF_aCheckCBF:判断当前这个人提交的 (对 v 的承诺)是否已经出现过
Bchain′ 并不是在存“更多属性信息”,而是存**“某类属性是否已经被用过”**的结构化索引。
顺带一提:在 GeneralDID 这类体系里,声明(claim)本身也可以是多条(一个证书含 m 个声明),每条可以是明文或承诺形式。(基于区块链的物联网身份管理系统.pdf)
所以如果一个注册场景有多个属性,设计上就有两种常见做法:
你图里用的是 去查重。要让“重复 v 能被查出来”,系统必须保证同一个 v 在查重时得到的表示是可比较/可复现的(例如固定或可派生的 r,或者查重用确定性摘要)。否则如果每次随机换 r,同一个 v 会生成不同 ,那 CheckCBF 就查不出重复了。
如果你把这张图所在论文的**“CBF / SearchCBF / CheckCBF”**文字定义那一段(通常紧挨着图)再截一页,我可以把:
那 (一个集合摘要/过滤器 CBF_a),这个是哪来的?
CBF_a 不是“凭空来的”,它一般是 系统在一开始就维护的一份“去重索引”,后续随着注册不断更新。结合你图里的写法(SearchCBF / CheckCBF),最常见、也最符合命名的解释是:
CBF_a 是什么CBF_a 可以理解为:针对某个属性名 a 的集合摘要/过滤器(常见就是 Counting Bloom Filter / Bloom Filter 一类)。v,而是存“用于去重的表示”(你图里用的是 C_v,即对 v 的 Pedersen 承诺)。通常有两种来源方式(你图的流程更像第 1 种):
A. 系统初始化时创建(最常见)
Bchain′ 上创建:
a -> CBF_aCBF_a 为空(还没人注册过)。B. 由历史注册记录“构建/重建”出来(次常见)
CBF_a 再写回链上。当某个用户注册成功(也就是查重通过、DID 发放完成)后,系统会做一件关键事(图里没画出来,但必须有,不然查重永远查不到“已注册”):
CBF_a 里C_v(或插入某个确定性摘要)。下次再有人拿同一个属性值来注册时:
SearchCBF 找到这个属性的 CBF_aCheckCBF 发现“已存在”,就拒绝或转人工复核。你图里用的是 C_v = Pedersen(v, r) 去查重。如果每次 r 都随机,同一个 v 会对应不同 C_v,那 CheckCBF 就很可能“查不出重复”。
所以实际实现里通常会保证“查重用的表示是可复现/可比较的”,常见做法是:
Hash(v) 这种确定值;承诺用于别的隐私证明环节r 可确定化(例如由 v 派生),保证同一 v 产生同一条目如果你把这张图对应论文里 CBF / SearchCBF / CheckCBF 的文字定义那段也发我(通常紧挨着图),我可以告诉你它到底采用的是哪一种。
这是后面的跨域身份认证协议过程图。根据这个图,那当用户跨域的时候,他首先在本于获得匿名凭证,然后域A把这个匿名凭证上传到联盟链bchain',域B只要查出这个匿名凭证在这个联盟链的累加器上,就认为他是可信的,就让他访问?
你理解接近了,但还差一个关键点:** 域 B 并不是“自己去链上查到某个匿名凭证就放行”**,而是——
域 B 只从联盟链 Bchain′ 取到“当前累加器值 ”(一坨摘要),然后要求用户提交一个零知识证明 ,证明“我手里那张匿名凭证对应的元素 确实被包含在 里”。验证通过后才给 token,用户再用 token 访问服务。
下面按图里的步骤把逻辑捋顺(你图的步骤 1–6)。
cred=(e,n,s)(图上写“颁布匿名凭证 cred 给 Nym”)。注意:从图上看,上链的不是 cred 本体,而是后面步骤 2 里的 累加器值 。
这步是“准备阶段”(图里也写了步骤 1、2 是准备阶段)。
所以 Bchain′ 上存的是:最新的 (以及可能的更新记录),而不是每个用户的 cred。
用户用 ServiceRequest(Nym_U^A, C^B, SP^B) 去拿到访问请求 request_s,并把请求发给域 B。
直觉上:我用假名 Nym 来申请访问域 B 的某个服务 。
域 B 取到“当前最新的 ”(图里写“获取当前的 用于跨域认证”)。
用户运行 GenNIZKProof 生成 ,发给域 B。
这个证明要表达的意思是:
我知道某个元素 (它来自我持有的匿名凭证 cred),并且我能证明 属于累加器 ,但我不把 cred / e 的细节直接暴露给你。
这就是零知识证明典型用途:证明“我知道/我满足某条件”,但不泄露秘密细节。你前面那篇 GeneralDID 也用类似表述:证明者可以生成证明,使验证者信服但不泄露信息,并可作为非交互式零知识证明附加/验证。 (基于区块链的物联网身份管理系统.pdf)
你说:
“域A把匿名凭证上传到联盟链bchain',域B只要查出这个匿名凭证在这个联盟链的累加器上,就认为他是可信的,就让他访问?”
更准确应该是:
另外也提醒一句:“在 里”通常只证明“你是域 A 认可的某个合法成员/凭证未被撤销”;至于你是否有访问 的更细权限,很多方案会把它绑定在 request / token 里,或还要叠加域 B 自己的授权策略(图里用 token 作为最终访问凭据,暗示这里还有“授权/会话控制”的意思)。
如果你愿意,我可以把这张图里的每个符号(、、、、)分别“在协议里扮演什么角色”再做一张对照表,读起来会更顺。
但是这种思路的话,域B就不能知道用户DID相关的一些内容了?例如关于用户的身份可能是匿名的,但是域B还想知道用户的某些属性,通过这种方式是否能实现呢?
是的——按你这张“累加器 + 匿名凭证 + NIZK”的跨域认证流程图来看,域 B 默认只能学到一件事:
“这个请求者持有域 A 认可的一张有效匿名凭证(对应的元素在 里)”
也就是“合法成员/未被撤销(在集合内)”这一类成员资格证明。
它并不会自动得到 DID,更不会自动读到“DID 文档里有什么属性”。(因为这套协议本身就不以 DID 为核心,而是以 Nym + 匿名凭证 cred + 证明 为核心。)
**可以,但需要在“成员资格证明”之外再加一层“属性证明/属性凭证”。**仅靠“我在累加器里”这一句,域 B 只能判断“你是 A 的合法人”,不能判断“你具备某种属性”。
常见有 3 种做法(从最贴近你图的方式开始):
把 cred 做成“属性型匿名凭证”(类似 Idemix 思路):
role=doctor、org=A-hospital、level>=3 等)。这和 GeneralDID 里“承诺隐藏属性 + ZKP 证明满足条件”的思路是一致的:承诺负责隐藏,ZKP 负责证明性质(例如范围证明、我知道承诺的 opening 等)。(基于区块链的物联网身份管理系统.pdf)
✅ 优点:域 B 能获得“你满足某条件”,但不必知道你是谁、也不必知道全部属性。
⚠️ 代价:实现复杂度与计算量更高。
也就是把“跨域认证”和“属性披露”拆成两件事:
role=doctor、licenseValid=true),域 B 验签即可。多域DID那篇就强调:VC 的 claim 记录具体业务字段,proof 记录签名;跨域时通过 CPT 让对方理解 claim 字段含义。(多域DID.pdf)如果还想保护隐私:属性 VC 也可以做成“承诺 claim + ZKP proof”(只证明必要字段/谓词),不必把全部属性摊开。(基于区块链的物联网身份管理系统.pdf)
✅ 优点:工程上最直观、最模块化(认证一套、属性/权限一套)。
⚠️ 关键点:域 B 必须信任 VC 的发行者(比如信任域 A 的委员会,或信任联盟链委员会)。
如果域 B 确实需要 DID 体系里的解析能力(比如要走 DID Document、服务端点等),但又不想把跨域行为关联回真实身份:
多域DID那篇的默认模型是“跨域要提供 DID + VC”,但同时强调 DID 文档不应泄露隐私、用户信息可加密上链。(多域DID.pdf)
✅ 优点:兼容 DID 生态(解析 DID 文档、服务发现)。
⚠️ 缺点:要额外设计“不可链接”机制(pairwise/一事一ID)。
如果你告诉我“域 B 想知道的属性”是哪一类(角色/资质/年龄范围/组织归属/设备类型等),我可以给你选一个最简单的落地组合,并把“请求里带哪些字段、域 B 具体验证哪些东西”写成 6–8 步的时序。
有个疑问,VC里面有claim和proof。那你上面提到用户只出示一些claim的关键属性,那proof用户能自己改么?例如,我的claim里面有身份证号、用户等级,然后我只想出示我的用户等级,那proof怎么弄?
不行,一般情况下你不能“只改 claim 然后自己把 proof 也改掉”——因为论文里这两类体系都把 proof 当成“发行者对 claim 的签名/证明”,它的作用就是防篡改。
论文把 VC 说成 Claim + Proof,其中 Proof 就是“发行者对 Claim 的数字签名”。(多域DID.pdf)
而它的凭证生成算法里也写得很直:proof[proofValue] = Sign(sku, Hash(claim)) ——也就是签名直接签在 Hash(claim) 上。(多域DID.pdf)
验证时会专门去验这个 proof,确保凭证没被篡改。(多域DID.pdf)
所以如果原 claim 里有:
你把“身份证号”删掉,只留“等级”,那么 Hash(claim) 变了,原来的 proof 立刻验不过。proof 你也没法“自己重算”,因为那需要发行者私钥。
✅ 在这个模型下想“只出示等级”,通常只有两条路:
GeneralDID 明确写:VC 由 basicdata + claim + proof 组成,且 proof 可以是数字签名或零知识证明。(基于区块链的物联网身份管理系统.pdf)
并且它的零知识证明部分说得很清楚:证明者可以生成 NIZK 证明,“附加到凭证中/账本中”,让任何验证者验证,同时不泄露秘密信息。(基于区块链的物联网身份管理系统.pdf)
另外它支持把属性做成承诺:claim_i = {uprop, com, U}(把属性值藏起来)。(基于区块链的物联网身份管理系统.pdf)
这意味着“只出示等级”的正确做法是:
假设发行时 claim 里变成两条承诺:
com_id = Comm(idNumber, r1)(身份证号承诺,不公开)com_level = Comm(level, r2)(等级承诺)发行者签名的是整个 claim(里面含 com_id、com_level)。
出示时你给验证者:
(level, r2) 让对方能打开 com_level 验证一致com_id(不给 (idNumber, r1))com_id 的 opening”(或证明它与同一主体绑定),但不泄露身份证号本身这样验证者能确认:
如果你把你当前 VC 的具体字段结构(claim 里有哪些字段、哪些敏感)贴一下,我可以按“最少改动”的方式告诉你:是更适合“拆成两张 VC”,还是“改成承诺+ZKP”那种呈现方式。
你给的这个例子,我有点没太看懂
不公开身份证号:只给 com_id(不给 (idNumber, r1))
再给一个 ZKP:
那这里的ZKP是用用户DID里面的私钥么?
不是同一件事:ZKP 通常不需要用到 DID 的私钥;DID 私钥更多是用来“签名”,证明你是这个 DID/凭证的持有人。
skU 来签。论文明确写了用户会用自己的私钥对声明 claim 签名,且 skU 可能是 MainID 或 UserID 对应的私钥。 (基于区块链的物联网身份管理系统.pdf)所以:
idNumber 和随机数 r1),而不是 DID 私钥。 (基于区块链的物联网身份管理系统.pdf)在 GeneralDID 这种“承诺 + ZKP”的思路里,常见做法是:
com_id = Comm(idNumber, r1)(不公开 idNumber,r1)level=VIP3com_level = Comm(level, r2),并公开 (level, r2) 让对方能打开它核对一致性(论文说“必要时可透露 v 和 r 给验证者核验一致性”)。 (基于区块链的物联网身份管理系统.pdf)com_id 的 opening(idNumber,r1)”但不泄露身份证号。这个 ZKP 用的秘密就是 (idNumber,r1),不是 DID 私钥。 (基于区块链的物联网身份管理系统.pdf)一句话记忆:
如果你把你现在 VC 的 claim 具体长什么样(字段列表、哪些想隐藏、哪些要展示)贴一下,我可以按这个论文口径给你写一个更贴近实现的“出示包 VP”结构:哪些字段原样带、哪些字段用承诺、ZKP 证明语句写成什么形式。
结合你前面给我的DID体系的完整架构,包括VC(这里的VC只需要证明设备能力:包括设备可靠等级、关键能力等级、能力边界与合规约束等信息)
给我一个低空多域异构互联场景下的DID完整体系,然后尽量在其他域使用设备的时候,可以保障DID的匿名性,同时,其他域还要知道设备的某些能力以便给他分配任务
参考这个图的形式给我分别写,
下面给你一个**“低空多域异构互联”场景下的 DID 完整体系(强调:跨域用设备时尽量匿名,但其他域仍能拿到设备能力用于派单)。我把它按你图里的 三层盒子形式分别写: DID 体系架构**、设备能力 VC 架构,并用两篇论文的机制拼起来(多域联盟链 + GeneralDID 的 MainID/UserID、承诺与 ZKP)。
多域思路:多个域(例如城市A空管/运营商A、城市B空管/运营商B、应急域C、监管域R)作为节点加入同一条联盟链;跨域访问时需要出示 DID 和 VC,由合约自动做身份与权限判断。(多域DID.pdf)
textDID体系完整架构(低空多域异构互联) ┌─────────────────────────────────────────────────────────────┐ │ 1. 标识层:DID(我是谁) │ ← 必须 │ │ │ (A) MainID:设备“根身份锚点”(可监管、抗Sybil) │ │ - 每台设备唯一;监管需要时可追溯 │ │ - 链上通常不直接放明文,而是放承诺 Com=Comm(v,r) │ │ - 用户注册/验证时可提供公开令牌 Tk=(pk)^r 供监管打开承诺 │ │ (免存 r) │ │ │ │ (B) UserID:跨域/跨任务“假名DID”(对外匿名使用) │ │ - 设备在每个域、甚至每次任务都生成一个新的 UserID_x │ │ - UserID 对网络公开,用于日常应用与跨域交互 │ │ │ │ 例:MainID(仅监管) = Com=Comm(v,r) │ │ UserID_B(在域B用) = did:lowsky-b:0x9f... │ │ │ └─────────────────────────────────────────────────────────────┘ 依据:系统定义 DID=(MainID, UserIDs),MainID唯一、UserID适用日常场景(基于区块链的物联网身份管理系统.pdf) UserID 对网络公开(基于区块链的物联网身份管理系统.pdf) Tk=(pk)^r 用于打开 MainID 承诺(基于区块链的物联网身份管理系统.pdf) ┌─────────────────────────────────────────────────────────────┐ │ 2. 文档层:DID Document(我的公钥/端点) │ ← 必须 │ │ │ - 每个 UserID_x 都有一个 DID Document: │ │ publicKeyList:该假名身份的验签公钥 │ │ serviceEndpoint:该域可用的通信/任务接口(如C2/任务API) │ │ - 跨域时,只要各域连同一条链,就能解析 DID Document 并读取内容 │ │ │ │ (示意字段,参考论文附录) │ │ { "id": "did:au:0x...", │ │ "publicKeyList":[{"type":"SM2","publicKey":"..."}], │ │ "service":[{"type":"Domain-B UTM","serviceEndpoint":"..."}] }│ │ │ └─────────────────────────────────────────────────────────────┘ 依据:DID 可解析为 DID Document,记录公钥列表与服务等(多域DID.pdf) 附录示例包含 publicKeyList 与 serviceEndpoint(多域DID.pdf) 同链可跨域映射/访问 DID Document 内容(多域DID.pdf) ┌─────────────────────────────────────────────────────────────┐ │ 3. 凭证层:VC(我的“能力属性/资质”) │ ← 可选但本场景强烈建议 │ │ │ - 域B在派任务前,需要知道设备能力(可靠等级、关键能力等级、 │ │ 能力边界、合规约束),这些用“设备能力VC”表达 │ │ - VC 的核心是 claim + proof:claim放业务字段,proof放发行者签名 │ │ - 为了匿名:claim 里不放 MainID/真实身份,只绑定当前 UserID_B │ │ 并支持“选择性披露/谓词证明(ZKP)”——只让域B看到必要能力字段 │ │ │ └─────────────────────────────────────────────────────────────┘ 依据:VC 由 Claim 和 Proof 构成,Proof 记录发行者对 Claim 的签名(多域DID.pdf) GeneralDID 也给出“元数据basicdata + 声明claim + 证明proof”,proof可为签名或ZKP3(基于区块链的物联网身份管理系统.pdf)
多域环境里,各域数据结构不一样,所以建议像论文那样用 CPT 预定义 claim 的字段结构与含义,让别的域“读得懂”。(多域DID.pdf)
text设备能力VC(DeviceCapabilityVC)结构 ┌─────────────────────────────────────────────────────────────┐ │ 1) Claim(能力声明:域B关心的字段) │ │ - subjectDid:当前跨域假名 UserID_B(只绑定“本次/本域身份”) │ │ - reliabilityLevel:设备可靠等级(例:R3) │ │ - keyCapabilityLevel:关键能力等级(例:C2:夜航/载荷/续航等级) │ │ - capabilityBoundary:能力边界(例:最大载重、航程、风速上限…) │ │ - complianceConstraints:合规约束(例:仅VLOS/禁飞区规则/频段…) │ │ - (可选) com_xxx:对某些敏感字段做承诺(不想全 раскры时) │ │ claim_i 可是明文 {uprop, attv, U},也可用承诺 {uprop, com, U} │ │ │ └─────────────────────────────────────────────────────────────┘ 依据:claim 可为明文声明或承诺声明(基于区块链的物联网身份管理系统.pdf) ┌─────────────────────────────────────────────────────────────┐ │ 2) Proof(可验证性:发行者签名 + 可选ZKP) │ │ - issuerSignature:发行者对 Hash(claim) 的签名 │ │ proofValue = Sign(sk_issuer, Hash(claim))(思想同论文算法) │ │ - zkProofs(可选):选择性披露/范围证明 │ │ 例:证明 reliabilityLevel ≥ R2、或“具备夜航能力”,但不 раскры │ │ 其他不相关字段 │ │ │ └─────────────────────────────────────────────────────────────┘ 依据:Proof 是发行者对 Claim 的签名机制(多域DID.pdf) proofValue=Sign(sk,Hash(claim)) 的签名式样在论文凭证构造中出现(多域DID.pdf) GeneralDID:proof 可是数字签名或零知识证明(基于区块链的物联网身份管理系统.pdf) ZKP 可附加到凭证/账本,做范围证明等(基于区块链的物联网身份管理系统.pdf)
subjectDid=UserID_B,不带 MainID。proof(发行者签名),并按 CPT 理解 claim 字段语义(多域DID.pdf);如果你愿意,我可以把 CPT(能力VC的 claimStructure) 也按《多域DID》附录那种 JSON 模板写出来(字段类型、是否必填、范围等),这样你直接就能用来做“低空任务派单”的能力标准。
回到你的例子:claim 里有「身份证号、用户等级」,我只想出示“用户等级”,proof 怎么弄?
这块,那我的场景下是不是可以划分为两类,一类是敏感信息,那就是做承诺+零知识证明。一类是非敏感信息,就用明文、然后发行者对整张凭证签名?
但是这里我有个问题就是,后面这个签名和零知识证明应该要有某些关联?不然验证值在不知道敏感信息的情况下怎么对整个凭证做验证?
你的划分思路是对的:敏感字段→承诺 +(必要时)ZKP;非敏感字段→明文。关键是你后面问的那句——“签名(proof)和 ZKP 要怎么关联,验证者不看敏感值怎么验证整张凭证?”——答案在于:** 发行者签名的对象不是敏感明文,而是“承诺后的 claim”**。
在多域DID论文里,VC 的 proof 本质是对 claim 的数字签名,典型就是 proofValue = Sign(sk, Hash(claim))。(多域DID.pdf)
因此,只要 claim 本身可被哈希,验证者就能验签——不需要知道 claim 里每个字段的“原始明文”,因为它验的是“claim 这份结构化数据有没有被篡改”。
GeneralDID 明确允许 claim 里用两类声明:
claim_i = {uprop, attv, U}claim_i = {uprop, com, U}(敏感值变成承诺 com)(基于区块链的物联网身份管理系统.pdf) (基于区块链的物联网身份管理系统.pdf)同时它把 VC 结构写成 basicdata + claim + proof,并说明 proof 可以是数字签名或零知识证明。(基于区块链的物联网身份管理系统.pdf)
所以核心做法是:发行者对“含承诺的 claim”签名,而不是对敏感明文签名。
你不能“改 claim 再改 proof”——因为 proof 的签名需要发行者私钥(多域DID里就是签 Hash(claim))。(多域DID.pdf)
正确做法有两条路:
你出示 VC1 即可,proof 原封不动。
假设原始信息是:{身份证号, 用户等级},你希望只透露“用户等级”。
发行时(由发行者签发)把 claim 设计成:
level:明文(非敏感)idNumber:承诺 com_id = Comm(idNumber, r1)(敏感)(基于区块链的物联网身份管理系统.pdf)proofValue = Sign(issuerSK, Hash(claim))(思想同多域DID)。(多域DID.pdf)出示时(给验证者域B):
level(本来就是明文)。(idNumber, r1),因此域B无法从 com_id 还原身份证号。这样,“签名”和“ZKP”的关联点是:ZKP 里引用的就是 VC 里那条被签名保护过的承诺 com_id。域B先验签确认 com_id 没被换过,再验 ZKP 确认你确实“拥有/满足条件”。
Hash(claim))。(多域DID.pdf)如果你愿意,把你“设备能力 VC”里哪些字段算敏感、哪些不敏感列一下(比如:可靠等级是否敏感?能力边界是否敏感?合规约束是否敏感?),我可以帮你直接把一份 CapabilityVC 的 claim 结构按“明文 + 承诺 + 对应要做的 ZKP 类型(范围/集合/知道opening)”配好。
回到你的例子:claim 里有「身份证号、用户等级」,我只想出示“用户等级”,proof 怎么弄?
这块,那我的场景下是不是可以划分为两类,一类是敏感信息,那就是做承诺+零知识证明。一类是非敏感信息,就用明文、然后发行者对整张凭证签名?
但是这里我有个问题就是,后面这个签名和零知识证明应该要有某些关联?不然验证值在不知道敏感信息的情况下怎么对整个凭证做验证?
你的划分思路基本就是论文想表达的“双凭证/双属性”路线:非敏感字段明文放 claim;敏感字段用承诺 com 放 claim,需要时再配 ZKP。GeneralDID 明确支持“明文声明/承诺声明”两种 claim 形式:claimi = {uprop, attv, U} 或 claimi = {uprop, com, U},并且必要时也允许把承诺的 (v,r) 给验证者核对一致性。(基于区块链的物联网身份管理系统.pdf)
你担心的关键点是对的:签名 proof 和 ZKP 必须“绑”在同一份 claim 上,否则验证者不知道敏感明文时就无法验证“整张凭证”的一致性/完整性。解决方式是:
在多域DID那篇里,proof 的典型生成方式就是对 Hash(claim) 做签名:proof[proofValue] = Sign(sku, Hash(claim))。(多域DID.pdf) 论文也概括了 VC=Claim+Proof,Proof 记录的是“发行者对 Claim 的数字签名”。(多域DID.pdf)
所以你把身份证号变成承诺 com_id 放进 claim 里,发行者签名覆盖的是:
验证者验签时只需要看到 claim(含 com_id),不需要知道身份证号明文,也能确认“这份 claim 没被篡改、确实由发行者背书”。
(GeneralDID里同样是“对摘要签名”,并且摘要 sc 可以是哈希或承诺,最后生成证明 ξI = Sign{skI,(pkU, sc, ξ)}。(基于区块链的物联网身份管理系统.pdf))
GeneralDID对 ZKP 的描述是:证明者掌握秘密信息(例如“承诺的初始值/opening”),可以生成非交互式零知识证明,在不泄露敏感值的情况下让验证者信服;证明还能附加到凭证/账本供任何验证系统验证。(基于区块链的物联网身份管理系统.pdf)
并且 GeneralDID 明确说 proof 可以是“数字签名或零知识证明”。(基于区块链的物联网身份管理系统.pdf)
因此“关联方式”就是:ZKP 里要证明的对象就是 claim 里的 com_id(它已经被发行者签名锁定了,换不了)。
claim 设计成混合:
level = VIP3(明文)com_id = Comm(idNumber, r1)(身份证号承诺)(基于区块链的物联网身份管理系统.pdf)Hash(claim) 签名。(多域DID.pdf)你给域B的材料里:
com_id,但没有 idNumber 明文)level 用于派单idNumber,r1 不给,因此域B无法从 com_id 反推出身份证号;同时“必要时你也可以选择透露 (v,r) 让对方核对”,但你这里不想透露。(基于区块链的物联网身份管理系统.pdf)注意:在“普通签名=Sign(Hash(claim))”这种 VC 里,如果你把 claim 的某个字段直接删掉(不发 com_id),那 Hash(claim) 就变了,签名会验不过——所以通常是“claim 不删字段,只把敏感值换成承诺”。
域B验两件事就够:
level 做业务判断/派单。如果域B除了“等级”以外,还想确认“你确实拥有那张身份证号承诺对应的秘密”(防止你随便塞个 com_id),就让你额外给一个 ZKP:
论文没有把“把 claim 哈希塞进 Fiat–Shamir challenge”写成公式,但它已经说明 NIZK 通过哈希验证且可附加到凭证中。(基于区块链的物联网身份管理系统.pdf) 工程实现里把“被签名的 claim(或其哈希)”作为 ZKP 公共输入/挑战,是最常见的绑定方式。
如果你愿意,我可以按你“低空多域设备能力VC”的字段(可靠等级、关键能力等级、能力边界、合规约束)帮你做一张“哪些明文、哪些承诺、分别配哪种ZKP(范围/集合/知晓opening)”的表,直接用于跨域派单。
上面我理解了,我还有个问题,最小披露怎么做?就是例如上面的等级,我怎么样做最小披露?
可以,你这个“最小披露(selective disclosure)”在你们讨论的 “明文+承诺混合 claim + 发行者签名 +(可选)ZKP” 体系里,最常用就两种做法——看你想不想暴露“具体等级”。
把 不想让别人看到的字段(如身份证号)做成承诺 com 放进 claim;发行者对整个 claim(含这些承诺)做签名即可——VC 结构里本来就有 basicdata/claim/proof,且 proof 可以是签名或 ZKP。(基于区块链的物联网身份管理系统.pdf) (基于区块链的物联网身份管理系统.pdf)
示意(claim 混合明文+承诺):
jsonclaim: { level_com: Comm(level, rL), id_com: Comm(idNumber, rI) } proof: issuerSignature( Hash(claim) )
(“承诺声明”这种形式在文中就是 claim_i={uprop, com, U}。(基于区块链的物联网身份管理系统.pdf) (基于区块链的物联网身份管理系统.pdf))
你把 整张 VC 原样给对方(里面有 id_com 但不含身份证明文),然后只额外给:
level 和 rL(用来打开 level_com)论文明确说“必要时,用户可以将 v 值和随机 r 透露给承诺 Com 的验证者,以确保验证者确认它们的一致性”。(基于区块链的物联网身份管理系统.pdf)
id_com)没被篡改(level, rL) 打开 level_com → 确认等级是真的(idNumber, rI),对方看不到身份证号注意:你不是“把身份证号字段删掉”;你是让它以承诺形式留在 claim 里,这样签名还能验,而值依然不泄露。
如果你只想让对方知道“够不够用”(例如任务要求 level≥3),那就不揭示 level 明文,而是给 范围证明/谓词证明:
论文里说得很直接:证明者可以在不泄露信息的情况下生成 NIZK,并且可以扩展到范围证明(如证明承诺值落在区间内),把证明附加到凭证/账本里供任何验证系统验证。(基于区块链的物联网身份管理系统.pdf)
level_com)level_com 里那个 level 满足 level ≥ 3(或属于某集合)level_com 没被换)多域DID那篇也强调 claim 可以包含一个或多个声明(Claims),proof 是对 claim 的签名。(多域DID.pdf)
所以你还可以直接让发行者拆分签发:
LevelVC(只含等级)IDVC(含身份证号承诺等)LevelVC,实现最小披露更简单。如果你把你“设备能力 VC”的字段列一下(可靠等级/关键能力等级/能力边界/合规约束里哪些算敏感、哪些必须明文),我可以帮你直接给出一份 CapabilityVC 的 claim 设计:每个字段用“明文 / 承诺 / 范围证明 / 集合证明”哪一种最合适。
这块里面的claim里面,其实是可以有多个属性的吧,claim={{a,cv}{a,cv}..}
对的——在 GeneralDID 这篇里,claim 本来就允许包含多个属性/多条声明,不是只能是单个 {a,v}。
文中明确写了:假设一个证书包含 个声明要求:
并且每条声明既可以是明文声明 claim_i={uprop,attv,U},也可以是承诺声明 claim_i={uprop,com,U}。(基于区块链的物联网身份管理系统.pdf)
在算法定义里也同样把声明写成集合:CreateClaim(...) 输出的 claim={claim1,...,claimn},其中 claim_i=(uprop,attv,U)。(基于区块链的物联网身份管理系统.pdf)
所以你写的这种形式本质上没问题,比如可以理解为:
只是论文里更常用 claim_i 这个写法。
TS.Sig(claim),看起来像“单个属性”?因为很多流程图/协议步骤会把 claim 当成“本次要被委员会背书的那份声明对象”,这个对象可以是:
{a,v}),也可以{claim1,...,claimm})也就是说:TS.Sig(claim) 里的 claim,既可以是单条,也可以是多条打包后的结构;实现里常见两种方式:
claim_i 分别做阈值签名(得到 的一组签名)它还提到可以对“属性值向量”做承诺:com = Comm(attv, r)(attv 是属性值向量)。(基于区块链的物联网身份管理系统.pdf)
这时一个 claim_i 里就能装“多个属性值的承诺”(向量承诺),再配合明文/承诺声明形式。(基于区块链的物联网身份管理系统.pdf)
无人机场景下,去重拿什么属性来弄比较好?
继续
在无人机(UAV)场景里,“去重/防同一设备重复注册(Sybil)”本质就是:选一个(或极少数几个)强唯一、难伪造、可被权威核验的属性当作 MainID 的“真实锚点”。GeneralDID 在注册时也明确要求用户/设备向监管者提交可验证的身份证明(例子给了“电子身份证、设备 MAC 地址或其他可信凭证”),由监管者核验后再生成/登记主标识 (基于区块链的物联网身份管理系统.pdf);同时强调 MainID 对每个用户/设备是唯一,用于监督与防 Sybil (基于区块链的物联网身份管理系统.pdf)。
用“设备安全元件/飞控安全芯片里不可导出的设备根密钥公钥(或其证书链)”当去重锚点。
理由:难伪造、难批量复制;最适合做“唯一身份”锚点(相当于把“设备是谁”绑定到硬件 Root-of-Trust)。
在多域系统里,设备本来也会作为“用户”进入系统注册、申请 DID 和密钥对 (多域DID.pdf),所以用硬件根来做注册核验很贴合流程。
如果你的低空体系里本来就有“监管侧的设备登记号”或“远程识别(Remote ID)模块序列号/证书”,也很适合做去重锚点。
理由:业务上天然要求“一个设备一个号”,而且容易被监管/平台核验;缺点是依赖外部登记体系的完整性。
“机身 SN/飞控 SN”这类序列号本身可被仿造,但如果你要求制造商对 SN 与设备公钥的绑定出具签名证明/证书,强度会明显上升(靠“可验证的可信凭证”思路)。这也符合 GeneralDID 所说的“其他可信凭证”这一类证据输入 (基于区块链的物联网身份管理系统.pdf)。
论文举例里提到 MAC 地址可作为可验证身份证明之一 (基于区块链的物联网身份管理系统.pdf),但在无人机场景里MAC/IMEI 很容易被改写/克隆,更适合作为“辅助校验/风控因子”,不建议作为唯一去重锚点。
可以“多属性声明”,但“查重通常只用 1 个主锚点 + 少数辅助锚点”:
claim = {claim1, ..., claimm},每条可以是明文或承诺形式 (基于区块链的物联网身份管理系统.pdf)。如果你告诉我:你们的无人机硬件条件(有没有安全芯片/远程识别模块/出厂证书体系),我可以按“可实现”的口径给你选一个主去重属性 v,再给一个“辅助属性集合”,并配一条完整注册/跨域使用流程。
这块的过程,去重用的是cv,但是我有个疑问,cv是用v,r产生的,那假如v是相同的,r不同,那cv也不同,但是v相同不就是属性值相同么?
你这个疑问完全成立:如果去重用的是 ,那么 同一个 只要 换了, 就会变成另一个值——那“查 是否已存在”就查不出重复了。
Pedersen 承诺的设计目标之一就是“隐藏性”:随机数 提供随机隐藏(perfect hiding),所以同一个 用不同 会生成不同承诺值。论文里也把它写得很明确:,并强调随机性来自 ;甚至还指出 如果 ,承诺就不再隐藏而偏“绑定”。(基于区块链的物联网身份管理系统.pdf)
同时,这篇 GeneralDID 里也提到 不同凭证会使用不同随机数 (“随不同的凭证变化”)。(基于区块链的物联网身份管理系统.pdf)
所以你直觉上会觉得“那怎么还能去重?”——这个点确实需要额外机制,否则逻辑对不上。
从你截图那段 SearchCBF / CheckCBF 的流程来看,CBF 里存的是“可比较的标记”。要想“同 必然命中”,去重用的标记必须满足:
同一个 在不同注册尝试中映射到 同一个 tag(或可被一致比较)
常见有 3 种实现路线(你可以对照看看你那篇图/正文更像哪一种):
代价:隐藏性变弱(论文也提示 时“不是隐藏的”)。(基于区块链的物联网身份管理系统.pdf)
但如果 熵很高(如身份证号/硬件根公钥哈希),实际仍可能可接受。
例如:
优点:仍保留一定“结构上的承诺形式”;缺点:如果攻击者能猜 ,仍可能离线枚举(取决于 的熵)。
也就是把“隐私承诺”和“去重标记”拆开:
这在工程上最常见:承诺负责隐私,tag 负责可比对去重,两者不冲突。
如果你把“CBF/CheckCBF”那篇论文的这一段后面两三段(通常会说明“r 怎么取 / CBF 里到底存什么”)也截出来,我可以帮你判断它到底采用了上面 A/B/C 的哪一种,并指出是否存在隐私/误判/枚举风险。
获取匿名凭证这块是怎么做的?
这一步“获取匿名凭证(cred)”本质上就是:用户先生成一个“假名/化名” ,然后域 A 的委员会 给这个 签发一张匿名凭证(可以理解成“对 的匿名签名/可证明成员资格”),以后跨域时用户用零知识证明证明“我确实拿到了这张凭证”,但不暴露真实身份。
下面按你图里的符号把它拆开讲清楚。
图里出现的 (以及后面用到的 等)一般都是系统公开参数(大家都知道)。
用户自己有一个长期秘密(图里写成 )。
用户随机选一个新随机数 ,然后计算:
直觉解释:
所以用户把 发给委员会时,即便是开放信道,别人也很难反推出 ;同时不同会话的 也不会自然关联。
图里写“颁布匿名凭证 (或你截图里写成 )给 ,其中 ”。
这通常表示委员会在做一种**“签名式凭证”**(非常像 CL 签名 / RSA 类累加器体系里那套):
你可以把它理解成:
委员会给你的凭证里包含一个“签名部件” 和一个“成员素数” ,使得别人只要看到 就能验证“这是委员会发的、结构正确的凭证”。
为啥委员会能算出 ?
通常这类方案里,委员会掌握某种“发行者秘密/陷门”(例如在 RSA 模数体系里知道 ,从而能求 次根),所以能构造出满足 的 。
你截图里写的是 或 ,但又出现了 。
在这类协议里,cred 至少要包含 (因为后面累加器要用),还通常会包含:
所以你可以先按这个最稳的理解记住:
cred = “(成员素数 e) + (签名/见证部件 p 或 n/v) + (必要的随机性信息)”
并且满足图里那条核心约束 。
所以域 B 最后通常只能学到:“你是域 A 认可的一员(集合成员)”,而不是你是谁。
如果你把这张图对应正文里对 各自含义的那一小段也截出来,我可以把“cred 的三个分量分别是什么、委员会到底发给用户哪几个数、用户后面生成 具体用哪些 witness”给你对齐到完全一致的符号级解释。
首先,第一个这个图片里面(就是你上面的第二步),他选择了c去计算p,这不是离散对数难题么?这能算出来么?
另外,接前面的,这是他完整的去重过程(末尾数字为82e.png的这个图片),我感觉这种是有问题的吧?直接拿cv检查是否重复
你这两个疑问都很关键,而且确实能看出这套方案里有“隐含假设/写法不严谨”的地方。我按你贴的两段分别说明。
不是在解离散对数,更像是在做一种“签发方可计算、其他人很难计算”的构造——典型对应两类机制:
如果目标是让 (你图里 ),那么签发方可以算:
这里用到的是 模逆 + 幂运算,不是离散对数。前提是你知道群的阶 (或等价信息),能求 。
很多匿名凭证/累加器方案里,签发方掌握“陷门”(例如知道 RSA 模数 的因子,从而知道 或能做 e 次根),才能算出满足
的那个 。
对外部攻击者来说,这相当于“求 e 次根/伪造签名”,通常是困难问题;但对签发方来说,因为有陷门,所以能算出来。
所以:它不需要解离散对数;它隐含的关键是假设“委员会/签发方有某种陷门(或知道群阶)”,否则这步确实会变得不可行。
你的直觉没错:如果 里这个 每次都是随机的,那么同一个 会产生不同的 ,结果就是:
这就是 Pedersen 承诺“隐藏性”带来的必然结果:随机性越强,越不适合拿承诺值做“确定性去重键”。
至少得满足下面三种之一:
去重阶段固定 (极端: 或固定常量)
这样同 → 同 才能命中。代价是隐藏性变弱(尤其 v 低熵时可被枚举)。
把 变成确定性的(例如 或 )
同 每次得到同 ,同样能命中;但如果 熵不够,仍可能被离线猜测。
去重根本不该用 ,而该用“确定性去重标签 tag”(工程上最常见、也最干净)
这第三种是最常见的“承诺负责隐私、tag负责去重”的分工,逻辑最顺。
你那张 Algorithm 1 里 AddCBF(Cv, CBFa) 的写法是:
CBFa[h_i(Cv)] == 1 才 ++这会导致初始为 0 的位置根本不会被写成 1(等于插入不生效)。Counting Bloom Filter 正常插入应该是无条件计数++(或至少从 0 变 1),所以这段伪代码本身就很可能写错/漏写了。
就算你解决了 “同 v 映射一致” 的问题,Bloom/CBF 也会有误判为重复的概率。
严谨的系统通常会在“命中”时走一个二次确认(例如要求额外证明/人工核验/查更精确的集合),否则可能误拒绝正常设备。
如果你把“这篇论文里对 的取法/CBF_a 的初始化与更新”那一段文字也截一下,我可以直接判断它到底隐含采用了上面哪一种(固定 r / 确定化 r / tag 分离),以及它的误判处理有没有补救流程。
所以域 B 最后通常只能学到:“你是域 A 认可的一员(集合成员)”,而不是你是谁。
接着上面的,我想让域B知道我是域A认可的一员,同时,让他知道我有那些设备能力(例如我的设备等级是大于几的,之类的),这种结合上面的要怎么做?
可以,把“域A成员资格(匿名)”和“设备能力(可最小披露)”拆成两条证明,然后在同一次会话里用同一个临时身份/上下文把它们绑定,域B就能同时得到:
下面给一个可落地的组合做法(和你《多域DID》这篇里的 DID/VC/合约流程能对齐)。
设备在进入域B时,生成一个 pairwise DID_B(一域一ID,甚至一任务一ID),并发布对应 DID Document(公钥等)。论文里 DID 可解析为 DID Document,Document 里记录公钥列表等信息,跨域连接到同一条链时可映射访问。 (多域DID.pdf)
域B用论文里的认证思路验证“你确实控制这个 DID_B 的私钥”(challenge 加密/解密那套)。 (多域DID.pdf)
沿你那张“累加器 + NIZK”的跨域认证图:域A给设备发匿名凭证,域A把“有效成员集合”的累加器值发布到链上;跨域时你给域B一个 NIZK 证明 π_member,证明“我在域A的有效集合里”。(这部分是你图里的机制,域B只学到“你是A认可成员”。)
按《多域DID》的 VC 定义:VC 由 Claim + Proof 组成,Proof 是发行者对 Claim 的数字签名;Claim 可包含一条或多条声明。 (多域DID.pdf)
并且 CPT 负责统一 claim 的结构/字段含义,便于跨域理解。 (多域DID.pdf)
能力 VC 里放你关心的字段:可靠等级、关键能力等级、能力边界、合规约束等;发行者可以是域A委员会/制造商/监管认可机构(看你信任模型)。
用一个会话绑定值(最简单就是 did_B 或 pk_B,再加一个随机 challenge)作为两条证明的共同“上下文”,让域B确认它们来自同一个请求者:
域B验这两条证明时看到的是同一个 did_B / challenge,自然就能确认“同一个会话实体”提交了两份证据。
(pk_B, sk_B),注册/发布 DID Document(只包含 pk_B、服务端点,不含真实身份)。 (多域DID.pdf)did_B(这和论文里跨域访问要提供 DID 的思路一致)。 (多域DID.pdf)did_B/challenge。keyCapabilityLevel ≥ k”,并绑定到 did_B/challenge(域B只知道“够不够”,不知道具体值)。你可以发布一个 “CapabilityCPT”,类似论文 CPT 的 claimStructure 模板(字段含义标准化)。 (多域DID.pdf)
示意字段:
did:填 did_B(只绑定本域假名身份)reliabilityLevel:可明文或承诺keyCapabilityLevel:建议支持 ≥k 的范围证明/分级证明capabilityBoundary:可以拆成若干上限字段(maxPayload、maxWind、maxRange…)按需披露complianceConstraints:按域B规则披露必要项(例如是否可夜航/是否可进入某类空域)如果你告诉我:域B派单到底用哪些规则(比如 ABAC:reliability≥R2 AND payload≥1kg AND allowZone=Z3),我可以把第 7 步具体化成一组“最小披露输出”(哪些字段明文、哪些字段做 ≥ 证明、哪些做集合成员证明),并给你一份更贴近工程实现的“出示包 VP”结构。
上面的实体不太对,应该是设备是域A的设备(域A给他分配DID、proof等),但是他要访问域B(B给他派任务)
给我重新整理一下
下面我按你纠正后的实体关系重新整理:设备归属域A(A给它发DID/VC等),设备去访问域B(B负责派任务)。整体仍然落在《多域DID》论文的“联盟链 + DID + VC + 智能合约自动验权/审计”的框架里:跨域访问需要提交 DID + 电子权限凭证(VC),合约会验证DID与凭证并写日志 (多域DID.pdf)。
论文原型里:DID 是文本串,能解析到 DID Document(公钥列表/服务等),DID持有者用公私钥对在系统里操作 (多域DID.pdf);跨域只要连同一条链,就能映射/访问对方的 DID Document 内容 (多域DID.pdf)。
textDID体系完整架构(域A设备访问域B,域B派任务) ┌─────────────────────────────────────────────────────────┐ │ 1) 标识层:DID(我是谁) │ ← 必须 │ │ │ (1) HomeDID_A:域A内“本域身份” │ │ - 设备首次进入系统时在域A申请DID,链上生成 didu + (pk,sk) │ │ 并生成 DID Document │ │ (registerUser: didu,pku,sku,...) │ │ │ │ (2) PseudonymDID_B:给域B看的“跨域假名DID” │ │ - 为了避免域B把你和域A的日常身份直接链接,设备在访问域B前 │ │ 再申请/生成一个新的DID(did_B, pk_B, sk_B)用于对外交互 │ │ - 域B只看到 did_B,不一定能从 did_B 推回 did_A(取决于你DID │ │ 命名法/文档暴露程度;见下方“最小披露”建议) │ └─────────────────────────────────────────────────────────┘ DID申请与生成:用户/设备进入系统申请DID,获得DID与公私钥对 (多域DID.pdf) 注册算法:didu="did:"+userInfo[domain]+":"+generateAddress(pku),并生成DID Document (多域DID.pdf) ┌─────────────────────────────────────────────────────────┐ │ 2) 文档层:DID Document(我的公钥/服务端点) │ ← 必须 │ │ │ - did_B 解析得到 didDoc_B:publicKeyList、serviceEndpoint等 (多域DID.pdf) │ - 域B用 didDoc_B 取到 pk_B,做身份认证(挑战-解密证明你持有sk_B)│ └─────────────────────────────────────────────────────────┘ authenticate:先verifyPk(did,pk),再random加密→用sk解密以证明持有者 (多域DID.pdf) DID Document示例含 publicKeyList、serviceEndpoint (多域DID.pdf) ┌─────────────────────────────────────────────────────────┐ │ 3) 凭证层:VC(域A给我背书的“能力属性/权限”) │ ← 强烈建议 │ │ │ - 域B派任务前,需要知道设备能力是否满足门槛;这用VC表达 │ │ - VC由 Claim + Proof:Claim记录业务字段;Proof是发行者对Claim的签名 │ │ - 通过CPT统一Claim结构/字段含义,跨域查询CPT即可“读懂”Claim │ └─────────────────────────────────────────────────────────┘ VC=Claim+Proof;Proof记录发行者对Claim的数字签名 (多域DID.pdf) CPT预定义Claim结构与含义,跨域通过查询CPT理解claim字段 (多域DID.pdf)
论文里资源VC/权限VC的 proof 典型就是对
Hash(claim)的签名(createResource里proofValue = Sign(sku, Hash(claim))) (多域DID.pdf);权限凭证也遵循“管理员签Claim段”的同构逻辑 (多域DID.pdf)。
text设备能力VC(DeviceCapabilityVC,用于域B派任务) ┌─────────────────────────────────────────────────────────┐ │ 1) Claim(能力声明:域B需要知道的最小字段) │ │ - did: did_B (把VC的主体绑定到“给域B看的假名DID”) │ │ - reliabilityLevel: 可靠等级(可用于门槛:≥R2) │ │ - keyCapabilityLevel: 关键能力等级(如夜航/抗风/载荷等级等) │ │ - capabilityBoundary: 能力边界(maxPayload/maxRange/maxWind…) │ │ - complianceConstraints: 合规约束(可进入空域类别/禁飞限制/频段等) │ │ * Claim结构由“CapabilityCPT”固定,域B通过查CPT来理解字段语义 │ └─────────────────────────────────────────────────────────┘ CPT:预定义Claim结构,发行者按CPT填充claim (多域DID.pdf) (多域DID.pdf) ┌─────────────────────────────────────────────────────────┐ │ 2) Proof(可验证性) │ │ - issuer: did_A_admin(域A管理员/机构DID) │ │ - proof.publicKey: pka(签名公钥) │ │ - proof.proofValue: Sign(ska, Hash(claim)) (对claim的签名) │ │ - expirationTime: 过期时间(避免长期滥用) │ └─────────────────────────────────────────────────────────┘ proofValue=Sign(sk,Hash(claim)) 的签名式样 (多域DID.pdf) verifyAuthority会校验:链上存在性/有效期/发行者公钥与签名 (多域DID.pdf)
下面把“谁生成什么、发什么、B怎么验”按步骤写清楚(兼容论文的 accessReq / authenticate / verifyAuthority 流程)。
did_A, pk_A, sk_A(本域身份)。(多域DID.pdf)did_B, pk_B, sk_B(假名DID,用于匿名跨域;链上可解析到 didDoc_B)。DID可解析到DID Document并记录公钥列表/服务信息 (多域DID.pdf)。did 字段填 did_B,并对 Hash(claim) 生成签名 proofValue(VC=Claim+Proof)(多域DID.pdf) (多域DID.pdf)。accessReq(did_B, pk_B, sk_B, credentialId(能力VC或其ID), resourceId(任务/任务队列), domain=B) (多域DID.pdf)。did_B(一域一ID/甚至一任务一ID),能力VC也只绑定 did_B,避免把 did_A 暴露给域B。reliabilityLevel 和某个边界字段),其余字段不进claim或另发“更细能力VC”。CPT本来就是为了让不同域对 claim 字段结构达成一致 (多域DID.pdf)。如果你还想进一步做到“只证明 level≥k 而不泄露具体level”,那需要在VC里引入ZKP一类扩展(这超出了《多域DID》论文本身的实现细节,但与你前面讨论的“承诺+ZKP最小披露”思路兼容)。
如果你把“域B派任务时用哪些门槛条件”列一下(比如:可靠≥R2、载重≥1kg、可夜航、只在某类空域),我可以把 CapabilityCPT(claimStructure) 按论文附录的格式写成一份具体JSON模板,并给出“每个任务应当要求哪些字段/阈值”。
设备为访问域B再申请/生成 did_B, pk_B, sk_B
这个我觉得不好,相当于你有多套DID,我的想法是DID文档里面只有一个DID,但是他想要访问域B的时候,可以向域A请求一个匿名凭证(这里还有claim+proof)
你这个想法完全可以做,而且不需要设备在链上再注册第二个 DID:设备只保留一个“本域 DID”,跨域去域B时,用**域A签发的“匿名能力凭证(VC)”**当作“我是谁 + 我能干啥”的可验证载体就行。
下面我把它整理成一个**“单DID + 跨域匿名VC”**的完整体系,并把它和《多域DID》论文里的组件/接口对上。
text┌────────────────────────────────────────────────────────────┐ │ 1. 标识层:DID(设备唯一、只在域A内部长期使用) │ ← 必须 │ - DeviceDID_A:域A给设备分配的唯一DID │ │ - 域A内部管理(注册、审计、吊销等)都围绕这个DID │ └────────────────────────────────────────────────────────────┘ 论文:用户/设备进入多域环境需申请DID,并得到至少一对公私钥 (多域DID.pdf) ┌────────────────────────────────────────────────────────────┐ │ 2. 文档层:DID Document(只有这一份DID文档) │ ← 必须 │ - didDoc(DeviceDID_A) 里记录公钥列表/服务等 │ │ - 用于域A侧“确认设备持有者”与密钥轮换 │ └────────────────────────────────────────────────────────────┘ 论文:DID可解析为DID Document,包含公钥列表等 (多域DID.pdf) ┌────────────────────────────────────────────────────────────┐ │ 3. 凭证层:跨域匿名能力VC(域A签发,域B用来派任务) │ ← 强烈建议 │ - 不暴露 DeviceDID_A 给域B │ │ - 让域B同时验证: │ │ (a) 你是“域A认可的一员”(匿名成员资格) │ │ (b) 你满足某些能力门槛(如level ≥ k) │ └────────────────────────────────────────────────────────────┘ 论文:VC=Claim+Proof,Proof是发行者对Claim的签名 (多域DID.pdf)
(pk_tmp, sk_tmp)(这不是第二个 DID,只是会话公钥)。pk_tmp 交给域A。这样域B从头到尾都不需要看到
DeviceDID_A,但仍可用 pk_tmp 挑战应答确认“是同一台设备在请求”。
(论文里的 authenticate 本质是“随机数加密→用sk解密证明持有者”,只是它先用 DID Doc 验 pk 属于 DID;你这里把“pk 属于 DID”替换成“pk_tmp 被域A的VC背书”。 (多域DID.pdf))
subjectPk: pk_tmp(匿名主体,不是DID)homeDomain: "A"(可选;你也可以不写,改成“issuer=域A”即可)capability(按 CPT 规范的字段):
reliabilityLevel >= R2(只给阈值结论/门槛)keyCapabilityLevel >= Ck(只证明满足任务门槛)boundary(必要时披露上限:maxPayload / maxWind / maxRange…)compliance(必要时披露:允许空域类别/禁飞区约束等)audience: "DomainB"(只允许给B用,防止拿去别的域滥用)exp: 过期时间(短有效期,降低可关联性/滥用风险)issuer: 域A管理员/委员会的 DIDproofValue: issuer 对 Hash(claim) 的签名(论文里就是 Proof 记录签名的机制) (多域DID.pdf)(pk_tmp, sk_tmp)AnonCapabilityVC(Claim+Proof)。 (多域DID.pdf)AnonCapabilityVCpk_tmp(通常 claim 已含)这时域B得到的就是:
- “issuer=域A(所以你是A认可的一员)”
- “你的能力满足任务门槛(例如 level ≥ k)”
- 但它不知道你的 DeviceDID_A 是什么。
如果你想让“域A认可的一员”更像你图里那种匿名成员资格证明(而不是简单“域A签发VC”),可以这样叠加:
pk_tmp 和能力门槛;π_member(证明自己属于域A有效成员集合),并把 pk_tmp/challenge 作为证明上下文,避免拼证;π_member + 验 VC 签名 → 成员资格更“匿名且可撤销”。(这块属于你另一篇协议图的内容;《多域DID》论文本身没有累加器细节,但它的 VC/Proof/CPT/跨域验权流程能承载这层证明。)
如果你愿意,我可以下一步把 CapabilityCPT(claimStruct) 具体写出来(字段名、类型、阈值表达方式、哪些字段建议做“只证明≥k”),让域B的派单规则能直接落到 CPT + verifyAuthority 的流水线上。
前面:一条完整流程(域B既要“你是A成员”,又要“你能力够用”)
这块改一下,注意:设备是域A的设备(域A给他分配DID、proof等),但是他要访问域B(B给他派任务)。设备在访问域B的时候,通过域A给他一个匿名凭证(注意这里的匿名凭证和前面域A发的proof要绑定),这样域B就可以知道设备是域A的成员同时满足某些能力
下面把你要的 “域A设备(A给DID/长期凭证proof)→ 访问域B(B派任务)→ 设备向A申请匿名凭证(claim+proof)且与A之前发的proof绑定” 重新整理成 8 步完整流程(并把“绑定点”写清楚)。
设备准备访问域B时,本地生成一次性的会话密钥对:
pk_anon, sk_anon(仅用于这次跨域/短时段,不上链、不生成第二套DID文档)这样你仍然只有一个长期 DID 文档(DeviceDID_A),跨域匿名性靠“会话主体 pk_anon”实现。
设备向域A提交申请(可以走域A业务系统或链上合约入口):
DeviceDID_A, pk_A, sk_A, pk_anon, targetDomain=B, capabilityPolicy(比如 level>=k), capVC_id/hash(可选)域A用 CPT 预定义匿名凭证里 claim 字段的结构与含义;跨域时域B可通过查询 CPT 来准确理解 claim 字段语义 (多域DID.pdf)
(CPT 的 claimStruct 由管理员创建并带签名,查询时会验签防篡改 (多域DID.pdf))
域A签发一个 VC(本质仍是 Claim + Proof (多域DID.pdf)),但 claim 不放 DeviceDID_A,而放:
subjectPk = pk_anon(域B看到的是匿名主体)issuer = didA_admin(域A签发方,域B据此知道“你是A认可成员”)audience = DomainB、expirationTime(短有效期)capability:只放域B派单要用的最小能力信息(例如 reliabilityLevel >= R2、keyCapabilityLevel >= k 等)bind = Hash(capabilityVC) 或 capVC_id(引用域A之前发的“能力VC/资质VC”)
然后域A对整个 claim 生成 proof(签名覆盖 claim,包含 bind 字段):
proofValue = Sign(ska, Hash(claim))(论文里就是这种“对 claim 摘要签名”的方式)(多域DID.pdf)isBlockchain(Hash(credential)) 防伪 (多域DID.pdf)✅ 这一步就实现了你说的“匿名凭证和前面域A发的proof要绑定”:
bind(capVC_id/hash)写进 claim,且被域A的签名 proof 覆盖,谁都改不了。
设备向域B发起派单/访问请求,携带:
AnonCred(含 claim+proof)cptId 或让域B按 claim 里的类型字段找到对应 CPT域B按 verifyAuthority 的思路验 VC(跨域验权的核心就是这套):
isBlockchain(Hash(credential)):确认链上有这张凭证的哈希(防伪造)(多域DID.pdf)expirationTime (多域DID.pdf)verifyPk(issuerDid, proof.publicKey):确认签名公钥确实属于 issuer 的 DID (多域DID.pdf)Verify(proof.publicKey, Hash(...), proof.proofValue):验签确认 claim 未被篡改 (多域DID.pdf)验完后,域B可得出:
因为匿名凭证里主体是 pk_anon,域B需要确认请求者真的持有 sk_anon。
可以复用论文 authenticate 的挑战方式:随机数用 pk_anon 加密 → 请求者用 sk_anon 解密返回(证明控制权)(多域DID.pdf)
通过后域B派任务(或发任务 token/授权凭证),并记录访问/派单日志到链上(generateLog)(多域DID.pdf) (多域DID.pdf)
pk_anon + “域A签发的匿名凭证”。如果你愿意,我可以把第 4 步的 **AnonCred 的 claimStruct(CPT模板)**按你无人机能力字段(可靠等级、关键能力等级、能力边界、合规约束)写成和论文 Appendix B 一样的 JSON 模板(字段类型/必填/阈值表达方式),域B就能“按模板自动派单”。
DID其实类似于一个网址,用这个网址可以找到对应的DID文档,那我现在改成匿名标识,就找不到DID文档了?会不会有问题?
你的直觉对:DID 像一个“可解析的URI”,按《多域DID》这篇的定义,每个 DID 都能解析成唯一的 DID Document,里面记录公钥列表、服务端点等信息 (多域DID.pdf),附录示例里也确实是 publicKeyList + serviceEndpoint (多域DID.pdf)。并且论文里的认证流程本来就要先 verifyPk(did, pk) 去 DID Document 里确认“这个 pk 属于这个 did”,再用挑战-解密证明你持有 sk (多域DID.pdf)。
所以如果你把“对外标识”改成一个不支持解析 DID Document 的匿名标识,会带来一个变化:
resolve DID → didDoc → verifyPk 这条链路)(多域DID.pdf)。那你完全可以不让域B解析 DID Document,而改成:
让域A给你一张跨域匿名能力/权限凭证(还是 VC 的 Claim+Proof 结构:Claim 是声明内容,Proof 是发行者对 Claim 的签名 (多域DID.pdf)),并把 pk_anon 写进 claim 里作为“匿名主体”。
域B验证时就不靠 DID Document 了,而靠论文里已经提供的 VC 验真逻辑:
authenticate 里“prove holder owns sk”那段保留下来,只是把 verifyPk(did,pk) 那段换成“issuer 的 VC 已经背书 pk_anon”。(多域DID.pdf)这样域B依然能:
level>=k、reliability>=R2)⇒ 可以派任务另外,claim 字段语义用 CPT 对齐,域B按论文方式“查询 CPT”来读懂 claim(避免异构)(多域DID.pdf)。
如果域B需要依赖 DID Document 的能力,比如:
那你有两条路:
为了替代 “DID→DIDDoc” 能力,同时做到防拼接/可验证,claim 里建议至少有:
subjectPk = pk_anon(匿名主体)serviceEndpoint(如果域B需要联络/下发任务)capability(只给派单需要的最小能力结论,比如 level≥k)audience = DomainB + expirationTime(防滥用/降低可关联性)bind = Hash(域A之前给设备签发的长期能力VC 或其ID)(你提的“要绑定域A之前发的proof”——把这个 bind 写进 claim,并被域A签名覆盖,就绑定住了)(多域DID.pdf)如果你把“域B派任务”的规则写两条样例(比如需要哪些能力门槛、是否要 serviceEndpoint),我可以把这张 **AnonCapabilityVC 的 CPT(claimStructure)**按论文 Appendix B 那种格式直接给你写出来,域B就能按 CPT + verifyAuthority 自动验与派单。
但是这样的话全域DID的意义在那?设备每次访问其他域都需要获取一个匿名标识,那就不会用到全域DID 了?
你这个担心很正常:如果跨域时都用“匿名凭证/匿名标识”,那“全域DID(全局唯一DID)”还剩什么意义?——答案是:** 全域DID仍然是“根身份锚点/生命周期锚点”,匿名凭证只是“对外出示形态(presentation)”。**两者不是替代关系,而是“护照 vs 登机牌”的关系。
在《多域DID》这套架构里,DID的核心作用是:
注意:这些价值很多发生在“域A内部 + 链上治理/审计层”,不要求域B每次都看到你的真实DID。
你可以把它理解成两条链路:
跨域时你不把 DeviceDID_A 暴露给域B,而是让域A签发一个短期匿名凭证(仍然是 VC:Claim+Proof)。域B验证它就能知道:
这和论文“跨域访问要提供DID+凭证,合约验证凭证并判权”的思想是一致的,只是你把“给B看的标识”从真实DID换成了匿名凭证里的主体字段 (多域DID.pdf)。
会少掉“用DID去解析didDoc”的那条标准路径 (多域DID.pdf),但你可以用匿名凭证把域B真正需要的信息带齐:
换句话说:域B不需要知道你的全域DID,系统仍然需要全域DID来保证这套身份体系能管得住、追得回、撤得掉。
如果你愿意,我可以把“匿名能力凭证”的 **Claim 模板(CPT)**按论文 Appendix B 那种格式写出来(比如 reliability_ge, capability_ge, boundary, compliance, audience, exp),并说明域B在派任务时应该怎么用 verifyAuthority 风格去自动验它。
我发的这个图片里面,好好理一下,我前面应该也发过
pythonfrom PIL import Image paths=[ "/mnt/data/71160e8b9ab4b92c50db975d0ff3c4fa.png", "/mnt/data/68f3ace94af70e035742ca15aea133df.png", "/mnt/data/be177d6b2fe64bf83aee9ae7c23098e3.png", "/mnt/data/36eea4db9156c55e3d047ece9c3233dc.png", "/mnt/data/59651553dd3496853870583d0b2f58e4.png", "/mnt/data/49cf87916f4a249eb381bc1e6b1636e1.png", ] imgs=[Image.open(p) for p in paths] [(p, img.size) for p,img in zip(paths,imgs)] [('/mnt/data/71160e8b9ab4b92c50db975d0ff3c4fa.png', (1322, 1016)), ('/mnt/data/68f3ace94af70e035742ca15aea133df.png', (1320, 1686)), ('/mnt/data/be177d6b2fe64bf83aee9ae7c23098e3.png', (1212, 1642)), ('/mnt/data/36eea4db9156c55e3d047ece9c3233dc.png', (1244, 1656)), ('/mnt/data/59651553dd3496853870583d0b2f58e4.png', (1278, 1728)), ('/mnt/data/49cf87916f4a249eb381bc1e6b1636e1.png', (1288, 1672))]
我按你这几张截图(3.1.3、3.2.1、图3-2/3-3/3-4、3.2.2、Algorithm 1、以及 3.3 开头那页)把整套逻辑“从对象→链上放什么→每一步干什么→为什么要两条链”理一遍。
它把跨域身份管理拆成 4 块:
你发的截图主要覆盖了 1) 身份注册 的协议细节,以及 2) 跨域匿名身份认证 的入口(3.3 开头)。
截图里写得很明确:凭证 有 个声明:
截图给出的定义:
这已经很贴近 W3C VC 的“claim + proof(签名/证明)”思路了,只是这里用数学符号写。
从图3-4可以看出分工非常清晰:
换句话说:
对应图3-4左上角(步骤1)和 3.2.2 的“身份导入”。
这里 “算 ”只是指数运算,不是离散对数;离散对数难的是“给你 让你反推 ”。
其中 在正文里写成 legal identity(合法身份)。
对应图3-4中间(步骤2)+ 你贴的 Algorithm 1。
SearchCBF(a):按属性名 去 Bchain′ 找到对应的
CheckCBF(C_v, CBF_a):检查 是否已出现
你指出的关键疑问非常对:
如果 里的 每次都随机,那么同一个 会得到不同 ,CheckCBF 就查不出“同值重复”。
所以这套“用 去重”要成立,论文必须隐含一个额外条件:
- 要么 在去重用途下是固定/可确定化的(同 得到同 ),
- 要么去重真正用的不是随机承诺,而是某种确定性去重标签(但正文/伪代码这里没写出来)。
另外你贴的 AddCBF 伪代码写法也很奇怪:它只在
CBF_a[h_i(C_v)] == 1时才++,这会导致初始为 0 的位置可能永远不会被置位/计数,很像伪代码笔误(正常 Counting Bloom Filter 插入应该是对每个哈希位置都计数++)。
对应图3-4右侧(步骤3)+ Algorithm 1 下方“DID生成”。
did:ethr:...)以及 DID 文档 DDO对应你最后那张截图里“步骤4:DID发布和DID应用”。
关键点是:用户拿到 DID 后,委员会还会用阈值签名 TS 再给一个“绑定凭证”,证明 DID 与 的关系:
其中截图注明 表示 DID 与 的关系。
并且截图最后一句很关键:
后续在跨域认证、撤销、更新等过程里可以交替使用 DID 和 ,两者同等地位。
你发的 3.3 开头只露出两条 bullet 的开头,但它已经在说:
credcred 上传到链(你前面发过那张“累加器/证明”流程图,对应这里的“链上登记成员集合摘要/累加器值”)这一步和 3.2 的关系是:
如果你想,我可以在你把 3.3 那几页(含 cred 的结构、链上上传什么、域B验证什么、是否用累加器 / NIZK )截图补齐后,把“跨域匿名认证”也像上面这样拆成:** 对象定义→上链数据→消息交互→验证逻辑**,并且顺带把“如何在匿名认证的同时最小披露设备能力(如 level≥k)”给你接成一个统一协议。
我按你这几张图(图3-5、图3-6、3.3.2参数设置、MintCred/上传累加器/GenNIZKProof/VerifyProof/GenToken)把 3.3 开始的跨域匿名身份认证从头到尾“捋直”,并把容易混淆/看起来不对劲的地方也点出来。
它把跨域认证分成两段:
所以域B最终学到的是:“你是域A认可的一员(集合成员)”,而不是你是谁(不拿到DID/真实身份)。
n / v 这种“e 次方根”(你之前问的关键点)在 3.3.2 的参数设置里(你截图那页):
params1=(N,a,b,c,g,h)。pk_C^A=(N,a,b,c),私钥写成 sk_C^A=(p',q')(本质上意味着它掌握了和 相关的“陷门信息”)。params2=(N,u),并显式写了陷门 tf=(p,q)。结论:这套方案是在 **RSA 模数 N 的群(QR_N)**里做匿名凭证/累加器;委员会掌握 的陷门(因子/相关信息),所以它能做“求 e 次根”这类发行操作——这不是离散对数问题。
用户用主秘密 和随机 生成假名:
这个 Nym 是跨域时用的“匿名身份载体”(域B看到 Nym,但不知道 sk_u)。
MintCred 里写:
并输出匿名凭证:
这一步的数学形态非常像 CL 签名/匿名凭证:发行者给你一个三元组 ,你以后可以用它做零知识证明。
你会看到两种写法:
结合 3.3.2 里 pk_C^A=(N,a,b,c)(c 是委员会公钥的一部分、应是固定参数),更合理的理解是:这里的 应该是固定的公钥元素,而不是每次签发都新抽的随机数;“随机c”很可能是笔误/符号复用导致的歧义。
关键点:上传的不是 cred,而是 cred 里的那个素数 e。
你截图里写得很明确:把 里的 e 上传到 Bchain′ 的动态累加器 GA₁,并且 GA₁“累加了所有域中的匿名凭证”。
累加器的形式(图3-6/3.3.2里):
并且链上用 GAStatus 标记“哪个区块头里装了最新 GA”(GAStatus=1 的那个区块就是最新 GA)。
所以:
用户带着假名 Nym 去找域B的委员会 请求访问 。
用 ObtainAcc 去 Bchain′ 找 GAStatus=1 的最新 GA。
用户不把 明文给域B,而是生成一个 非交互零知识证明 πₑ。
从你截图“步骤5和步骤6:认证及访问”那页可以看出,πₑ 要同时证明两件事(这是它和 cred 的“绑定点”):
这一步非常关键:域B并不是“自己查到 cred 在不在链上”;它只拿到 GA,然后靠你给的 πₑ 来验证“你对应的 e 在 GA 里”。
用 VerifyProof(阈值 t 个节点通过即可)验证 πₑ;成功则 GenToken 发 token;SPᴮ 再 VerifyToken 后放行。
你后面要问的问题(你说“仔细想一想我后面有一些问题”)大概率会落在这几个点上:
你直接把你的疑问按这三类抛出来就行,我可以按你截图里的符号和流程逐条对上解释。
你可以将我发给你的图片(包括3.2注册和3.3跨域认证),和前面的多域DID.pdf两个文件中的核心思路进行表格列举对比一下么?
下面我把你截图里这篇(3.2 注册 + 3.3 跨域匿名认证,我就叫它“方案A”)和你前面提到的 **多域DID.pdf(我就叫它“方案B”)**做一个“核心思路对比表”。
说明:方案A我完全按你截图内容整理;方案B我这边当前拿不到原PDF逐段核对(你还没把多域DID.pdf上传到对话里),所以方案B列里是基于我们前面聊天时你提到/我复述过的那套“多域DID + VC + CPT + 合约验权”的通用框架来概括的;如果你把多域DID.pdf也上传,我可以把方案B列补到“逐段对齐原文”的精确版。
| 维度 | 方案A(你截图:3.2注册+3.3跨域匿名认证) | 方案B(多域DID.pdf 核心框架:DID+VC+CPT+合约验权) | 直接影响 |
|---|---|---|---|
| 系统拓扑 | 双链/双账本职责:域内链 Bchain_A 负责 DID/DDO;联盟链 Bchain′ 负责去重索引 CBF_a + 全局动态累加器 GA1(用 GAStatus 标记最新) | 通常是一条联盟链或统一注册层:存 DID/VC/CPT/日志等,跨域通过同链可解析/可验证 | A把“登记/解析”和“去重/匿名成员集合”拆开;B偏“统一可解析/统一验证” |
| 主要目标 | 1)合法身份导入 + 防重复注册;2)跨域时匿名证明成员资格;3)链上少存凭证(用累加器) | 1)跨域互信与互操作(CPT对齐语义);2)基于 VC 的授权/验权;3)可审计日志 | A更偏隐私匿名;B更偏“可理解、可用、易落地”的跨域业务授权 |
| 跨域暴露的信息 | 默认只暴露 假名 Nym + 成员证明 πe(证明 e∈GA)+ 令牌 token;域B不知道真实DID | 多数实现会让对方看到 DID 或可解析 DID Doc,再验 VC | A天然“最小暴露”;B需要额外设计“最小披露/匿名化”扩展 |
| 维度 | 方案A(截图3.2) | 方案B(多域DID.pdf) | 直接影响 |
|---|---|---|---|
| 注册输入 | 用户/设备提交声明 claim={a,v};委员会用 DECO 验真,然后做 阈值签名 | 用户/设备提交身份信息与公钥,生成 DID、DID Doc;后续用 VC 做权限/资源描述 | A把“现实身份真实性”作为强前置;B更偏“链上身份+凭证治理” |
| 防重复注册 | Algorithm 1 Deduplication:把属性值承诺 Cv 映射进 CBF_a,CheckCBF(Cv, CBF_a) 判断是否已注册;未注册则 AddCBF 加入,并 b=1 才能发 DID | 通常不把“去重”作为核心算法(更多是域内管理/注册策略),重点在凭证授权与互操作 | A对 Sybil/重复注册更强,但实现细节要求更严谨(见下方“隐患”) |
| DID生成 | Bchain_A 智能合约基于 pk_U^A 生成 DID 与 DID文档(DDO)并写链 | DID通常按“did:域:地址/标识”生成,链上保存DID Doc/注册信息 | A把 DID 生成固定在域内链 Bchain_A;B通常更“统一可解析” |
| DID↔公钥背书 | A在“DID发布与应用”里:委员会再对消息 m={pkU, ctx, claim} 做阈值签名并合成,得到 δ^π,形成 C_π={pkU,ctx,claim,δ^π}(用于后续跨域/撤销/更新) | B里一般是“VC的 proof(签名) + DID Doc公钥”完成绑定/验签 | A显式给一个“绑定凭证”;B依赖 VC 结构与 DID Doc 解析 |
| 关键隐患(你也指出了) | A的去重用 Cv=Pedersen(v,r):若 r 每次随机,同 v 会得不同 Cv,CBF 无法查重;另外 AddCBF 伪代码也像有笔误(只在槽位==1才++) | B通常不把 Pedersen 承诺直接当“去重键”,更多靠注册规则/监管/证书链 | A在去重这块需要补“r确定化/改用确定性tag/二次校验”等工程修正,否则逻辑不闭合 |
| 维度 | 方案A(截图3.3) | 方案B(多域DID.pdf) | 直接影响 |
|---|---|---|---|
| 跨域前置准备 | 步骤1 初始化:用户在域A生成假名 Nym=a^{sk_u}b^s;域A MintCred 签发匿名凭证 cred=(e,n,s),满足类似 n^e = Nym·c 的关系;并把交易 T_cred 写入域内链(你截图显示广播到 Bchain_A 节点验证) | 多数是:用户已有 DID/VC;跨域时直接出示 DID + VC(或其ID/哈希) | A多一次“领匿名凭证”的准备动作,但换来匿名性与链上节省 |
| 链上登记方式 | 不把 cred 全量上链:只把 e 加入联盟链 Bchain′ 的全局动态累加器 GA1=u^{∏e_i} mod N,并用 GAStatus 标记最新 GA | 往往是:VC/凭证哈希、CPT、日志等按合约存证;跨域方验签/验存在性 | A链上状态更小(一个GA值);B链上更“可追溯、可解释” |
| 跨域认证交互 | 用户→域B发请求;域B从 Bchain′ 取最新 GA;用户生成 NIZK 证明 πe,证明“我的 e 属于 GA 且与 Nym/cred 结构关系成立”;域B验证成功发 token | 用户提交 DID + VC;域B解析 DID Doc 得到公钥,验证 VC 的 proof(签名),按策略授权并可能发 token | A是“成员资格证明”;B是“凭证/属性证明+授权” |
| 域B学到什么 | 只学到:你是域A认可成员(e∈GA),并得到 token;默认不知你是谁 | 通常会学到 DID(至少是对方的标识符)与 VC 中披露的属性 | A隐私强;B业务表达强 |
| 能力/属性怎么带 | A这套 3.3 本身只证明成员资格,不直接携带“能力属性”;要加能力,需要额外“能力VC/能力证明”并与 Nym/πe 绑定 | B天生就靠 VC claim 表达属性/权限(通过 CPT 对齐语义),更贴合“派任务/授权” | 如果你的目标是“匿名+派单能力”,A需要“成员资格证明 + 能力证明”的组合协议;B天然更顺 |
Nym/πe 做会话绑定(防拼证)。如果你把 多域DID.pdf 也上传到对话里,我可以把上面表格里方案B那一列改成“逐条引用原文流程/算法名/字段结构”的精确对齐版(比如具体是哪个算法负责 authenticate/verifyAuthority/CPT查询/日志上链 等),并把“如何把A的匿名成员资格证明和B的能力VC派单逻辑融合成一个统一协议”画成一张时序步骤表。
我的想法是这样的,就是未来会有很多的无人机,包括无人机所属方的,无人机制造厂商的,而这些无人机呢都可以被租用干一些事情,例如执行空中无人机任务等等。那这里面就存在很多的这种任务发送方,包括巡防、物流等等任务发送方发送任务。那在这种情况下,我就想设计一套针对低空多域多主体场景的可信认证与授权方面展开研究。具体地,我想的是,首先,所有的无人机利用DID机制,就是给每个无人机一个全域身份,给了这个身份之后,任务发送方就可以给这些无人机发送一些授权执行任务的凭据。随后这些无人机就可以执行任务了。有三个域:
• 设备域:DeviceVC(设备身份/能力等级) ——回答“这台机是什么水平/有什么能力边界”(这里面可能有专用VC和通用VC)
• 任务域:MissionVC(任务授权) ——回答“这台机被允许做什么任务”
• 监管域:临时凭证 Token(入域放行/接入许可) ——回答“这台机现在本区域能不能执行、能执行到什么程度(并可持续撤销/续证)”
那这种情况下有几个问题需要理清楚:设备域、任务域是否各自成链?主联盟链上存什么?DID直接上主链么?参考我刚发的这些图片以及前面的多域DID.pdf文件仔细想一想,那种形式最合理
我先把你这套需求翻译成一句“架构目标”,再回答你关心的 3 个落点(设备域/任务域要不要各自成链?主联盟链存什么?DID要不要上主链?),并把它和你截图里 3.2(去重+发DID)、**3.3(跨域匿名:GA累加器+NIZK)**的思路对齐。
你提出的三类凭据(DeviceVC / MissionVC / Token)非常合理:它们刚好对应 长期静态可信、任务级授权、区域级动态准入。
我的结论:不建议一开始就三域各自成链;最合理的是 “一条主联盟链(全域信任锚)+ 域内可选的账本/存储(不一定是链)”。
你截图里的方案其实已经给了一个“最小链上承载”的范式:
这背后的思想是:主链存“全域共识必须知道的最小状态”,大数据/高频状态尽量不放主链。
对你的三域也一样:
✅ 所以推荐的“链形态”是:
单主联盟链(强推荐起步)
主联盟链 +(可选)设备域账本(不一定是链)
主联盟链 + 任务域侧链(仅当任务吞吐巨大且需要域内共识)
对照你截图里的 Bchain′(“去重CBF + 全局GA”)思路,主链最适合存 6 类“全域共识最小状态”:
你在多域DID那套里强调 CPT 的意义非常大:不同域异构字段必须能被自动理解。
所以主链放:
DeviceVC_CPT(能力字段、度量、阈值表达)MissionVC_CPT(任务授权字段、范围、约束)Token_CPT(空域准入字段、撤销句柄)你截图 3.3 的“GAStatus + GA1 最新值”本质就是一种“状态根”机制。你的三类凭据都需要状态:
主链上建议存的不是每张凭据,而是:
对应你 3.2 的 Algorithm 1:主链可以存“去重索引”,但我建议你不要直接用随机承诺 Cv 做可比对键(你自己已经发现问题:同 v 不同 r 会导致 Cv 不同,查重失效)。
更稳的做法是主链存:
任务执行、放行决策、撤销事件写“哈希承诺”即可,满足追责审计但不泄露业务细节。
结论:要,但上“最小可解析版本”,不要把一切都塞进去。
原因很现实:
✅ 推荐折中:
下面给你一个“最像你截图 3.2/3.3 思路”的组合:全域DID做根身份,跨域用匿名凭证做呈现,能力与授权用VC表达,监管用可撤销Token兜底。
这块你截图 3.3 已经给了“成员资格”的强匿名方案:
要把“能力”也带上,有两种落地方式:
Hash(DeviceVC)(或其状态句柄)写进“入域Token”或“任务VC”的 claim 里并被签名覆盖,防止拼证。(你后续如果要把 3.3 的 πe 结构和 “能力阈值证明”写成统一的证明语句,我也可以帮你把绑定项设计出来。)
最合理的形态是:一条主联盟链做“全域信任锚”(DID最小解析 + 发行者/CPT注册 + 状态根/撤销根 + 审计哈希),三域凭据本体尽量链下流转;跨域匿名用你截图3.3那套“GA1+πe”证明成员资格,再叠加DeviceVC/MissionVC/Token,通过“哈希绑定+会话绑定”把成员资格、能力与授权锁在同一次访问里。
如果你愿意,我下一步可以按你三域的字段,直接给出三份 CPT/ClaimStructure 模板(DeviceVC_CPT / MissionVC_CPT / Token_CPT),以及对应的主链合约需要维护哪些状态根(类似 GAStatus 的版本指针),这样你的论文/方案会从“概念”变成“可实现的协议栈”。
但是如果是一条主联盟链,那DID就直接上链了,那做匿名凭证的意义是?因为我给你发的这个图片里面,“跨域的时候采用了匿名凭证,也就是跨域的时候是匿名的。主链上只放匿名凭证摘要值。其他域只需要知道设备的身份是域A即可。DID相关信息在域A内部”
你说得对:如果“全域 DID + DID 文档”都直接放在一条主联盟链上、而且跨域访问时也用这个 DID 作为对外标识,那确实会把“跨域匿名”削弱很多——因为可链接性会很强:同一台机每次跨域都暴露同一个全域 DID,其他域就能把它的历史行为串起来。
但关键点在于:“DID 上主链”≠“跨域必须用 DID 做呈现”。
匿名凭证的意义在于把两件事拆开:
因为 3.3 这套机制的目标不是“让对方拿到你是谁”,而是让对方验证一个更弱但足够的事实:
“我属于域A认可的集合(成员资格)”
并且把链上存储压到最小:链上只放 GA₁(集合摘要),不放 cred 明文。
这样带来的好处是:
有意义,但前提是你要采用这种分工:
所以匿名凭证的意义就是:把“全域身份”从跨域暴露面上拿掉,即使主链上存在 DID 锚点,也不必让域B拿它当外显标识。
你截图的结构本质是一个很合理的“分层账本”:
这其实回答了你前一个问题:“主链存什么?”——主链存“别人必须共同相信的最小状态”,而不是存你所有身份细节。
即便 DID 信息不对外(只在域A内部),全域 DID 依然有三类价值:
换句话说:DID 是“后台根身份”,匿名凭证是“前台通行证”。
这通常用两种办法,不需要 DID 文档也能做:
如果你要达到“跨域只让别人知道设备属于域A + 能力达标 + 可动态撤销”,同时又保留“全域 DID 做根身份治理”,那最合理的形式是:
这几乎就是你截图 3.2 + 3.3 的思路,只是把它扩展成你定义的三域凭据体系。
如果你愿意,我可以按你三类凭据把“主联盟链最小状态表”列出来(每一项链上存什么字段、谁更新、更新频率、验证方怎么查),并给一个跨域派单的完整时序:**πe(成员) + DeviceVC(能力阈值) + Token(入域可撤销) + MissionVC(任务授权)**怎么绑定到同一会话,防止“拼证/借证/重放”。
但是我的方案里想参考毕设这篇论文中的思路,跨域的时候采用匿名凭证,主链上只放匿名凭证摘要值。其他域B只需要知道设备的身份是域A即可。DID相关信息在域A内部。但是还有一个额外的,就是域B还需要指的设备的能力(就是他是匿名的,但是能力知道是大于某个层级的,例如域B可能发布了某些任务,然后域A内的设备需要向域B证明自己的能力是大于那个值的),然后域B就可以给设备发配任务了。
这个要怎么做?
可以的,而且**完全能沿用你毕设论文 3.3 的“匿名凭证 cred + 全局动态累加器 GA₁ + NIZK 证明 πₑ”这条主线;你只需要再加一条“能力证明”链路,并把两条链路绑定在同一个假名 Nym(和同一次会话挑战 nonce)**上,域B就能同时得到:
下面给两种实现方式(方式1更简单、更贴合你论文;方式2更“最小披露/更灵活”)。
保持与你图 3.6 / 3.8 一致:
DID/DDO 仍然完全可以留在域A内部;主链只要能让域B验证“来自域A的签名/断言”即可。
你论文 3.3 的成员资格链路本身已经把 πₑ 和 Nym绑定了(证明里既要证明 e∈GA₁,又要证明 cred 与 Nym 的关系成立)。
所以能力这边只要做到:
这是最贴合你毕设论文的“跨域只需知道你属于域A”的理念,同时也满足域B派单需求。
Step B0:域B发布任务需求
capLevel ≥ k(以及其他边界:载重≥x、风速≤y 等)nonceB(防重放)Step 1~2:按你论文走(域A给 cred,e 加入 GA₁)
cred=(e,n,s)(你公式 3-6)e 上传进 Bchain′ 的 GA₁(你图 3-8 / GAStatus 机制)新增 Step 2’:域A签发“能力门槛断言” CapAttest(短期)
域A基于设备在域A内部的 DID/能力档案(域B看不到)生成一个断言:
CapAttest.claim = {
Nym(必须)audience = DomainB(必须)nonceB(强烈建议)exp(短有效期)capPolicy: 例如 capLevel ≥ k(也可以把边界一起写进去)missionType / taskClass:限定用途bindGA = GAStatus版本号/GA哈希:把断言绑定到某一版GA,进一步减少重放空间
}CapAttest.proof = Sig_A(Hash(claim))(域A签名)这一步实现了“匿名但可派单”:域B只看到“域A签名担保:该匿名成员满足cap≥k”。
Step 3~6:设备去域B
设备发给域B:
Nymπₑ(你论文的 GenNIZKProof 产物)CapAttest(claim+sig)域B验证:
πₑ:确实存在某 e 属于 GA₁ 且与该 Nym 的 cred 关系成立CapAttest:域A签名有效、audience/nonce/exp 正确、capPolicy 满足任务门槛✅ 优点:实现最简单;域B得到的刚好是你想要的信息(域A成员 + 能力≥k),且不需要域B解析任何DID。
⚠️ 代价:域A需要“按任务门槛 k”在线签发(但这在你场景里通常可接受)。
如果你不希望域A每次都知道/参与具体门槛 k(或希望同一张能力凭证可复用到不同门槛),就用这一种。
C_level = Comm(level, r)跨域时:
πₑ(同方式1)DeviceVC(包含 C_level + 域A签名)C_level 里承诺的 level 满足 level ≥ k,但不泄露具体 level把 Nym 和 nonceB 作为 π_cap 的公共输入的一部分,并且 DeviceVC 里也带一个 “subject=Nym(或 Nym 的哈希)”:
Nym 在 πₑ、DeviceVC、π_cap 三者一致✅ 优点:真正的“最小披露”:域B只知道“≥k”,不知道具体等级;域A也不必为每个k重签。
⚠️ 代价:需要实现承诺+范围证明(比方式1复杂很多)。
域B最终能验证并用于派单的只有:
issuer=域A(所以你是域A成员)capLevel ≥ k(以及必要的边界/合规约束)Nym(可随访问更换以降低可链接性)域B学不到:
Nym + nonceB + exp 绑定,防拼证与重放如果你愿意,我可以按你三域凭据把“完整时序”写成一页:
1)域A内部 DID 注册与能力VC签发;2)跨域匿名 cred/GA₁/πₑ;3)能力门槛证明(方式1或方式2);4)域B签 MissionVC;5)监管域发可撤销 Token 并更新撤销根。这样你整套“低空多域多主体可信认证与授权”就闭环了。
我现在有两个思路,那个比较合理:
1、无人机在设备归属域获得DID,直接用DID去向任务域获取执行任务,任务域给他一个匿名标识
2、无人机在设备归属域获得DID,当他想去执行任务域的任务时,向归属域获得一个匿名凭证,然后任务域判断这个匿名凭证的合法性,然后再给他派任务。
就是这两种的差别是任务域是否知道无人机的真实DID,那个比较合理?
我会更偏向 方案 2 作为“默认架构”,方案 1 作为“在强监管/强合作/需要长期绑定的特殊场景下的简化版”。
原因很直接:你这个低空“多域多主体 + 可租用市场”场景里,任务域(巡防/物流/应急等)通常不需要知道无人机的真实 DID,它真正需要的是:
这三件事都可以在“匿名凭证 + 能力证明 + 监管 Token”里完成,不必暴露真实 DID。
| 维度 | 方案1:先用真实DID找任务域,再给匿名标识 | 方案2:先向归属域拿匿名凭证,任务域只验匿名凭证 |
|---|---|---|
| 隐私/可链接性 | 弱:任务域先看到真实 DID,天然可把历史行为/任务串起来 | 强:任务域默认只见“我是域A成员 + 能力满足”,不可直接串联到真实 DID |
| 任务域的信任负担 | 高:任务域要处理 DID 解析、DID 文档安全、隐私合规、数据留存风险 | 低:任务域只需要信任“域A/联盟链的验证材料”,不持有真实身份数据 |
| 市场化(租赁/多任务方) | 容易形成“平台画像/黑箱评分”,对租赁方不友好 | 更符合“隐私保护的开放市场”,按能力派单而非按身份派单 |
| 风控(限流、反滥用) | 容易:按 DID 做配额/黑名单 | 需要设计:用匿名凭证的会话绑定/短期token/撤销根来限流与封禁 |
| 追责/事故调查 | 简单:任务域本地就知道是谁 | 需要“可追溯但默认匿名”:由监管或域A在合法流程下解匿名 |
| 实现复杂度 | 相对低(但隐私差) | 相对高(要做匿名凭证合法性验证、绑定、防拼证/重放) |
因为它更贴近你参考论文的核心取向:跨域匿名,主链只放摘要(累加器/状态根),其他域只需知道“属于域A即可”,DID/DDO 留在域A内部。
同时它也更适配你三类凭据的分工:
如果你的任务域是强监管闭环、或者任务方与设备方长期固定合作,任务域确实需要长期绑定到同一实体(例如保险结算、长期信誉、长期配额),那方案 1 更省事。
方案2里建议把“匿名凭证”拆成两部分,并做绑定,任务域就能放心派单:
π_e,对应 GA₁)Nym(或同一个会话 nonce),防止“拼证/借证/重放”。这样任务域只学到:域A成员 + 能力达标 + 当前可执行,但学不到真实 DID。
默认走方案2,但加入“条件揭示/追责通道”:
这能同时满足市场化与监管可追责。
如果你愿意,我可以把你方案2写成一套“端到端时序”(含 DeviceVC、匿名凭证π_e、能力≥k证明、MissionVC、Token、撤销根更新与校验点),并明确每一步“链上存什么摘要、链下传什么材料、任务域验证什么”。这样你论文结构会非常清晰。
如果是方案2的思路,那其实就是参考我发给你的那些图片的做法了
对,方案 2 本质上就是你发的那些图(3.2 + 3.3)的路线:把“真实 DID/身份资料”留在归属域(域A)内部,跨域只让任务域(域B)验证一个匿名成员资格(用 cred → e → GA₁ → πₑ),主链只放摘要值(GA₁/状态指针),从而做到“跨域匿名”。
但你现在的研究目标比图里多了一块:域B还要按能力派任务(level ≥ k 等)。所以正确的说法是:
方案2 = 你图里的“匿名成员认证”作为底座,再叠加一条“能力门槛证明”,并把两条证明绑定到同一次会话(同一个 Nym / nonce)。
下面把它和你图里的步骤一一对齐,告诉你“需要补的是什么”。
CBF_a)、域A链上生成 DID/DDO、再发一个绑定凭证 C_π(DID↔pk 的背书)。cred=(e,n,s)(MintCred)e 更新进联盟链 Bchain′ 的动态累加器 GA₁(链上只存 GA 与 GAStatus)这一步让域B只知道:“你是域A认可的一员”。
你现在要的:域B发布任务要求 level ≥ k,域A内的设备能匿名证明“我满足这个要求”,域B就派任务。
这在你现有框架里有两种补法(从“最贴合你毕设图”到“最强最小披露”):
nonceB(防重放)和门槛 kcred(成员资格底座),再签一个短期断言:CapAttest.claim = { Nym, audience=B, nonceB, exp, capLevel_ge_k=true, (可选)边界约束 }
CapAttest.proof = Sig_A(Hash(claim))
设备去域B时同时提交:
πₑ(证明成员资格)CapAttest(证明能力≥k)绑定点:两者都包含同一个 Nym(再加同一个 nonceB 更稳),域B验:
Verify(πₑ, GA₁) + VerifySig(CapAttest) + Nym一致 ⇒ 可信且匿名。
✅ 优点:工程上最简单,完全符合你图里“跨域只需知道属于域A”的思路。
⚠️ 代价:域A需要按不同任务门槛 k 在线签发(但租赁/派单平台一般能接受)。
这更像你前面讨论的“最小披露”路线:
C_level = Comm(level, r)πₑ(成员资格)C_level + 域A签名)π_cap:证明 C_level 对应的 level 满足 level ≥ k(不泄露具体 level)绑定点:DeviceVC 的主体字段写 H(Nym) 或把 Nym/nonceB 作为 π_cap 公共输入,让域B确认三者来自同一会话主体。
✅ 优点:域A不必为每个 k 重新签;域B只得到“≥k”,最小披露。
⚠️ 代价:实现复杂(承诺+范围证明)。
cred → e → GA₁ → πₑ)作为成员资格层;如果你下一步把“域B派单规则(只看 level 还是还看边界/合规)”列个 2–3 条样例,我可以直接帮你把 **CapAttest 的 claim 结构(类似你图里那种claim+proof写法)**写成一份可放进论文的“协议定义 + 消息交互表”,并指出主链 Bchain′ 需要新增哪些最小字段(通常只需要:发行者公钥登记/撤销状态根)。
你前面这块“方式 2(更“最小披露/更灵活”):域A签“能力承诺”,设备向域B做“level≥k”的ZKP”
有个问题,DeviceVC是长期或半长期的,也就是他是提前就生成好的。而Nym是访问跨域的时候随机生成的,那Nym怎么和提前生成的deviceVC绑定呢
这个问题抓得很准:DeviceVC 是提前签出来的,Nym 是跨域时临时生成的,那要“最小披露”又要“防拼证”,就必须有一个稳定但不暴露的“绑定锚”,让你能在不透露真实 DID 的情况下证明:
“我这次生成的 Nym 的持有人 = 这张 DeviceVC 的持有人(同一台无人机)”。
做法不是把 Nym 直接写进 DeviceVC(那会固定、可链接),而是让 DeviceVC 绑定到一个长期秘密 linkSecret(或 sk_u),然后每次跨域用这个秘密生成不同 Nym,并用 ZKP 证明两者共享同一个秘密。
下面给你 3 种常用绑定方式(从最贴合你毕设 3.3 的 Nym 形式,到工程更简单的实现)。
sk_u(或 linkSecret),跨域 Nym 也由同一个 sk_u 生成(最贴合你图里的 Nym)你毕设里的 Nym 形式是类似:
其中 sk_u 是长期秘密,s 是每次会话随机数。
域A 给设备签 DeviceVC 时,在 claim 里放一个对 sk_u 的承诺(或把 sk_u 作为隐藏属性签进去):
C_sk = Comm(sk_u, r_sk) (承诺)C_level = Comm(level, r_level)(能力等级也承诺起来,支持范围证明)DeviceVC 的签名是对整个 claim(含这些承诺)签的,所以承诺值没法被换。
设备跨域时随机取 s,算出 Nym = a^{sk_u} b^s。
然后给域B一个链接证明 π_link,证明存在某个 sk_u, r_sk, s 使得:
Nym = a^{sk_u} b^sC_sk = Comm(sk_u, r_sk) (说明 DeviceVC 里那个承诺确实承诺了同一个 sk_u)同时再给能力范围证明 π_cap:证明 C_level 里的 level 满足 level ≥ k(不泄露具体 level)。
域B验证 DeviceVC 的签名(确认
C_sk, C_level没被篡改),再验证π_link和π_cap,就能确信:
同一个主体(同一个sk_u)既是这次Nym的持有人,也是 DeviceVC 的持有人,而且能力≥k。
✅ 优点:完全兼容你毕设里 Nym/cred 的“用 sk_u 做根”的风格;不需要第二个 DID。
⚠️ 代价:你需要实现一个“证明离散指数关系 + 承诺 opening 关联”的 ZKP(但这正是你已经在用的思路)。
如果你不想在域B侧处理复杂的“a^sk b^s”指数关系,也可以:
(pk_tmp, sk_tmp)pk_tmp 当匿名会话身份(或者 Nym = H(pk_tmp))绑定怎么做?
DeviceVC 里提前绑定一个 C_sk(或 linkSecret),跨域时给 ZKP 证明:
sk_u(对应 DeviceVC 的 C_sk)pk_tmp 是由我基于 sk_u 产生的(例如 PRF/派生:pk_tmp = KeyDerive(sk_u, nonce) 或 “我签了挑战证明我控制 pk_tmp” + “pk_tmp 出现在域A给我的短期断言里”)这个方式本质上是把“匿名主体”换成更工程友好的会话公钥,并用“域A背书/或ZKP关联”把它和 DeviceVC 的持有人绑定起来。
✅ 优点:域B验“持有 sk_tmp”很简单;系统实现更贴近现有密码工程。
⚠️ 缺点:你要决定 pk_tmp 是自签证明还是由域A在跨域断言里背书一次。
sk_u 派生(避免跨会话可链接)你担心的其实是“长期 VC 怎么和一次性 Nym 绑定,又不让别人关联历史”。解决要点:
你可以选择两种 Nym 策略:
Nym_B = PRF(sk_u, "DomainB")(同一域内可链接,但跨域不可链接)然后用 ZKP/证明把 Nym 与 DeviceVC 里的 linkSecret 关联即可。
把 DeviceVC 绑定到一个隐藏的长期秘密 sk_u/linkSecret,而 Nym 每次跨域由同一个秘密 + 会话随机数生成。
跨域时你不需要让 DeviceVC 里出现 Nym,只需要提供一个 ZKP 证明:
sk_u”域B就能同时得到:A成员 + 能力达标,还不会看到真实 DID。
如果你愿意,我可以按你毕设图里的符号把一个“合并证明”写成一句更标准的关系(把 π_e 的成员资格证明 + π_link 的同一持有人证明 + π_cap 的能力阈值证明合成一个 π_total),并明确每个证明的公开输入/见证是什么,这样你后面写协议会非常顺。
但是我总感觉从域A获取匿名凭证的这种做法,让DID的意义变小了,那没有DID的情况,设备也可以从域A获得匿名凭证,然后去域B获取任务
你这个感觉很正常:如果跨域永远只用匿名凭证、任务域从不见到 DID,那看起来 DID 像是“被藏起来了”,似乎可有可无。
但关键点是:匿名凭证解决的是“跨域呈现/隐私”问题;DID解决的是“根身份治理/生命周期/可追责/可互操作”问题。没有 DID 当然也能“域A发匿名凭证→去域B领任务”,但你会很快发现你不得不把 DID 的那套能力用别的名字重新做一遍。
下面把这件事说透:
如果你只用匿名凭证,你仍然需要回答这些问题:
这些本质上都需要一个“稳定的根身份锚点”和其公钥/状态/版本管理机制——你可以不叫它 DID,但做出来的东西会越来越像 DID。
你想要的效果其实是:
这时 DID 的意义一点不小,反而更清晰:
一句话:DID = 账户/档案;匿名凭证 = 临时通行证/工牌。
在你描述的租用市场里,任务域/任务平台一旦拿到真实 DID,就会天然产生:
而任务域真正需要的只是可验证的事实:
这些用“匿名凭证 + 能力证明 + 监管Token”就够了,不必暴露 DID。
如果你的系统永远只有:
那确实可以用“域A数据库ID + 匿名凭证”跑起来。
但你一旦走向你说的“多主体、多发行者、多任务方、可租用、可监管、可追责”,你就会需要 DID 这类机制来当“通用的根身份载体”,否则每个主体都要对接域A私有接口,最后会变成强中心化。
这样你既保留了 DID 的核心价值,又实现了你毕设论文那种“跨域匿名 + 主链轻量”。
如果你愿意,我可以把这段写成你论文里很常见的“必要性论证”段落结构(问题→需求→匿名凭证不足→DID作为根锚→两层身份呈现模型),并且把三类凭据(DeviceVC/MissionVC/Token)各自绑定到“根DID”和“跨域假名/凭证”的关系画成一张表。
我总结了一下我三个域的思路
无人机向设备归属域A获取DID(包括DID document和DeviceVC,其中DeviceVC中存放了与私钥sk的绑定承诺,还有某些能力的承诺)
然后,当任务域B发布某个任务时,无人机向A获取匿名凭证,A将匿名凭证摘要上链。
无人机访问域B获取任务权限时,向其发送匿名凭证+成员资格+device VC+π_cap(能力等级最小披露)
域B验证后给无人机设备发一个missionVC凭证,(该凭证与刚刚的匿名凭证绑定)
然后无人机到达某个监管域C后,无人机向C发送匿名凭证+成员资格+mission VC。C也首先判断这个匿名凭证是否在链上(他是否是合法的),然后再判断missionVC是否合法,然后再允许其放行
哪里不正确的?
你这套总体方向是对的(域A内部DID治理 + 跨域匿名成员资格 + 能力最小披露 + 任务授权 + 监管放行)。但你现在这版里有几处“概念混用/验证链条不闭合/缺了关键撤销机制”,我按点给你挑出来,并给一版更闭环的改法。
你参考的毕设图(3.3)里,主链(Bchain′)核心是维护集合摘要(动态累加器 GA 的根/状态),而不是每次把“某张匿名凭证的 hash”都上链。
更贴合毕设做法的写法应是:
cred=(e, …) 后,把 e 加入全局动态累加器,链上只更新 GA/GAStatus(根值)结论:“链上放匿名凭证摘要值”不如“链上放集合根(GA/状态根)”合理,除非你明确就是“一次性凭证 + 每次都上链 + 强可审计”的路线。
在毕设那套里:
Nym(假名)π_e(证明“我对应的 e 在 GA 里”且与 Nym/cred结构关系绑定)所以你对外消息里更像应该是:
结论:对外最好把“匿名凭证”当作持有人私有材料,对外只给 证明(π_e)。
你现在写的是:匿名凭证 + 成员资格 + DeviceVC + π_cap。
但如果不加绑定,域B会面临一个典型攻击:
要防这个,必须有一个“链接证明”让 B 确信:
生成
Nym/π_e的那台设备 = DeviceVC 的持有人
最常见的绑定方式就是你前面讨论的:
DeviceVC 里含一个对长期秘密 linkSecret/sk_u 的承诺 C_ls,而 Nym 也是由同一个 sk_u 派生出来的;然后给 B 一个 π_link 证明它们共享同一秘密。
所以对 B 的材料应当至少是:
Nymπ_e(成员资格)DeviceVC(含能力承诺、含 C_ls)π_cap(能力阈值证明 level≥k)C_ls 绑定到同一 sk_u/linkSecret)结论:你现在缺了 π_link(或把它并入 π_cap/π_total),否则拼证风险很大。
你前面三域里监管域本来应该有 Token(入域放行/接入许可,可持续撤销/续证),但你这版流程里 C 没有发 Token,而是把放行建立在 missionVC 上。
问题:
更合理的是:
π_e(成员资格)+ 验 MissionVC(任务授权)+(必要时)验关键能力约束结论:监管域最好还是回到你最初设想:C 发 Token,Token 才是可持续撤销的抓手。
至少需要三类撤销/状态:
如果不写清“链上状态根怎么更新、验证方怎么拿最新版本”,很难说服读者“可信、可控”。
C_ls = Comm(linkSecret, r)(与 sk 绑定的承诺锚)C_level = Comm(level, r2)(能力承诺)k(level≥k),给 nonceB(防重放),可选给任务类别/约束Nym(会话假名)cred,把 e 加入 GA(主链只更新 GA 根/状态)Nymπ_e(证明“我是域A成员”,e∈GA 且与 Nym 绑定)DeviceVCπ_cap(证明 level≥k)π_link(证明 Nym 与 DeviceVC 同一 linkSecret/同一主体)nonceB 绑定进 π_e/π_cap/π_link,防重放与拼证B 验证通过后签发:
Nym(或绑定 Nym 的 hash)Nymπ_e(成员资格)MissionVCπ_cap(或只验 MissionVC 中声明的约束是否满足)Nym + MissionVC_id/hash + 有效期 + 当前空域策略如果你愿意,我可以把你这套“修正版”整理成一张你毕设图那样的流程图结构(步骤1~6那种),并给每个域列出“链上存什么根/状态、链下传什么材料、验证方验什么”三列表,这样你写论文会非常顺。
无人机向设备归属域A获取DID(包括DID document和DeviceVC,其中DeviceVC中存放了与私钥sk的绑定承诺,还有某些能力的承诺)
然后,当任务域B发布某个任务时,无人机向A获取匿名凭证,A将匿名凭证摘要上链。
无人机访问域B获取任务权限时,向其发送nym(由同一个私钥sk派生得到)+成员资格+device VC+π_cap(能力等级最小披露)+π_link(nym和device VC是同一个sk)
域B验证后给无人机设备发一个missionVC凭证,(该凭证与刚刚的匿名凭证绑定)
然后无人机到达某个监管域C后,无人机向C发送nym+成员资格+mission VC。C也首先判断这个匿名凭证是否在链上(他是否是合法的),然后再判断missionVC是否合法,然后再给与其短期token
你这版已经基本成型了:成员匿名(3.3 的 cred/累加器思路)+ 能力最小披露(DeviceVC 承诺 + π_cap)+ 防拼证绑定(π_link)+ 任务授权(MissionVC)+ 监管短期准入(Token)。
真正需要改/补的主要是两处表述和两处安全绑定(否则容易被重放/拼接或被“DID/签名密钥”意外关联)。
参考你毕设图 3.3 的做法,主链更理想的是维护动态累加器根 GA(+ GAStatus 指向最新),而不是每次把“匿名凭证 hash”当作一条新记录去查存在性。
✅ 你可以继续把它口语化为“摘要上链”,但论文/协议里最好明确:
上链的是 GA 根/状态根(集合摘要),验证靠 π_e 对 GA 的验证。
你写“成员资格”没问题,但建议你定义清楚:对外给的是
Nymπ_e(证明“我对应的 e 在 GA 里”,且与 Nym/cred 结构关系绑定)而不是把 cred=(e,n,s) 明文给 B/C。否则会引入额外可链接性/泄露结构风险。
你现在写“同一个 sk 派生 Nym”,逻辑上能绑住,但工程上不建议把 DID 的认证/签名密钥直接拿来做匿名链接秘密:
因此建议你把这句改成:
Nym 由 linkSecret(ls) + 会话随机数(或 nonce)派生C_ls = Comm(ls, r)(对 ls 的承诺)π_link 证明 “Nym 与 C_ls 使用同一个 ls”这样你“DID 的意义(根身份治理)”和“跨域匿名(linkSecret)”就彻底解耦了。
否则会出现:同一份 π_e + π_cap + π_link 被转发到别的任务、别的域重复用。
建议最少加三样绑定:
nonceB(挑战随机数)π_e、π_cap、π_link 的公共输入都包含 nonceB + domain=B(或 audience=B)audience=C/执行区域 和 exp(以及绑定的 H(Nym)、Hash(GA版本) 可选)监管域 C 发 token 时同理:token 绑定 H(Nym) + missionVC_id/hash + exp + regionPolicyVersion。
DID + DID DocumentC_ls = Comm(ls, r1)(绑定用的长期秘密承诺)C_level = Comm(level, r2)(能力承诺,支持 π_cap)level ≥ k,并下发 nonceBNym = f(ls, rand/nonceB)π_e:证明 e∈GA 且与该 Nym 绑定DeviceVCπ_cap:证明 level ≥ k(对 C_level)π_link:证明 Nym 与 C_ls 同一 lsnonceB + audience=B + exp)H(Nym)(以及可选绑定 GA 版本/nonceB/exp)Nym + π_e + MissionVC(必要时 C 也可要求 π_cap,看监管是否要能力复核)π_e,验证 MissionVC(B 的签名、有效期、范围、是否匹配本域规则),通过后签发 短期 Token(可撤销/续证,绑定 H(Nym)+MissionVC)。你这版里最需要改的其实就三句话:
如果你愿意,我可以把你这套流程按“毕设图 3-5/3-6 那种样式”重新画成一张步骤图(Step1~Step6),并把每条消息的字段(Nym、π_e、DeviceVC、π_cap、π_link、MissionVC、Token)列成一个表:谁生成、谁验证、公共输入/见证是什么、绑定 nonce/exp/audience 放哪。这样你后面写论文会更顺。
给我一个device VC和mission VC的json示例,简单一点
下面给你两个尽量简单、但能覆盖你说的“承诺能力 + 绑定 + 最小披露/绑定匿名”的 JSON 示例(偏 VC 风格:credentialSubject + proof)。字段名你后面可以按 CPT/Schema 再规范化。
C_ls(绑定用的 linkSecret 承诺)、C_level(能力等级承诺)id 只是域A内部可选;你也可以不放)json{ "@context": ["https://www.w3.org/2018/credentials/v1"], "type": ["VerifiableCredential", "DeviceVC"], "issuer": "did:domainA:issuer-committee", "issuanceDate": "2026-02-24T10:00:00Z", "expirationDate": "2027-02-24T10:00:00Z", "credentialSubject": { "id": "did:domainA:drone-12345", "commitments": { "C_ls": "pedersen:0x9a3f...c1", "C_level": "pedersen:0x41b2...7e" }, "capabilitySchema": "cpt:device-capability:v1" }, "proof": { "type": "Ed25519Signature2020", "created": "2026-02-24T10:00:01Z", "verificationMethod": "did:domainA:issuer-committee#key-1", "proofPurpose": "assertionMethod", "proofValue": "z3Jm...signature..." } }
说明(口头理解即可):
C_ls承诺了设备的长期绑定秘密ls(用来和跨域 Nym/π_link 绑定)。C_level承诺了能力等级level(用来做π_cap: level ≥ k)。
nymHash(把任务授权绑定到这次跨域匿名身份 Nym)memberProofRef(比如 GA 版本/nonce)来防重放(可选)json{ "@context": ["https://www.w3.org/2018/credentials/v1"], "type": ["VerifiableCredential", "MissionVC"], "issuer": "did:domainB:mission-platform", "issuanceDate": "2026-02-24T10:05:00Z", "expirationDate": "2026-02-24T12:05:00Z", "credentialSubject": { "nymHash": "sha256:0x6d7a...90", "mission": { "missionId": "mission-20260224-0007", "taskType": "logistics", "constraints": { "maxAltitudeM": 120, "geoFence": "geohash:te5x...", "timeWindow": { "start": "2026-02-24T10:10:00Z", "end": "2026-02-24T11:50:00Z" } } }, "audience": "domainC", "memberProofRef": { "gaVersion": "GAStatus:1289", "nonceB": "0x8f1c...aa" } }, "proof": { "type": "Ed25519Signature2020", "created": "2026-02-24T10:05:01Z", "verificationMethod": "did:domainB:mission-platform#key-1", "proofPurpose": "assertionMethod", "proofValue": "z2Dk...signature..." } }
如果你想更贴你论文里的符号(比如把 C_ls/C_level 直接写成 Cv、Com 或把 issuer 换成委员会 C^A/C^B),我也可以再给你一版“论文符号风格”的 JSON。
这两块其实是在讲 同一个阈值签名(TS, Threshold Signature)体系里的两种不同操作,所以看起来像“两个公式”,但作用不一样:
δ^{Oracle} = TS.Comb(δ_i^{oracle}) 是 合成(Combine)TS.Comb(·) 做的事:把这些部分签名份额合成为一份完整的阈值签名 δ_i^{π} = TS.Sig(sk_{C,i}^A, m) 是 份额生成(Partial Sign)TS.Sig(·) 做的事:节点用自己的阈值私钥份额 产生一份部分签名 TS.Comb 合成。TS.Sig(...):每个节点各自生成“部分签名份额”( / )TS.Comb(...):用户把 ≥t 个份额合成为“完整签名”()另外你看到上标不同(Oracle vs π),主要表示它们签的消息内容/用途不同:一个是“Oracle导入/证明相关”的签名结果,另一个是“DID 与 pk 绑定关系”的签名份额与最终凭证签名。
那其实前面这个是证明claim是正确的,然后后面这个是证明DID与pk的一个绑定关系,那VC凭证是那个?后续用户使用的是那个?
你理解得很对:这两套阈值签名对应的是两类不同用途的“可验证凭证”,只是论文里没直接都叫 VC,但从结构上看它们都符合“claim + proof(签名)”的 VC 思想。
δ^Oracle 那张凭证是什么?后续干嘛用?它对应的是“Oracle/身份导入凭证”(你前面 3.2 注册里那张):
可以把它理解成:证明“你确实拥有某些已核验属性”的基础凭证。
δ^π 那张凭证是什么?后续干嘛用?它对应的是“DID–pk 绑定凭证”(论文里 ctx 表示 DID 与 pk 的关系):
可以把它理解成:证明“这个 DID 的控制权属于谁(哪个 pk)”的凭证。
如果你问“真正作为 DID 体系里通用的身份凭证是哪一个”,更像是 C_π(带 δ^π 的那张 DID–pk 绑定凭证)——因为它把 DID 体系最核心的东西(可解析标识 + 控制权公钥)锁住了,后续各种操作都能围绕它来验。
但在这个毕设方案里,严格讲有两类 VC:
C_d^Oracle(proof=δ^Oracle)
C_π(proof=δ^π)
而你在 3.3 的“跨域匿名认证”里,域B最终用的并不是这两张 VC 明文,而是你后面那套 Nym/cred/π_e(成员资格证明);这套通常是建立在你已注册(拿到 DID 与绑定关系)这个前置之上。
如果你把论文里 C_d^Oracle、C_π 在“撤销/更新/跨域”具体哪个步骤里被调用的那段也截一下,我可以帮你把“哪一步必须用 δ^Oracle,哪一步必须用 δ^π,哪一步两者都不需要(只用 π_e)”精确对齐到流程图。
你卡住的点在于:两次签名里都出现了 claim,所以看起来像“重复背书”。但它们背书的语义不一样,而且第二次签名并不能替代第一次对 claim 正确性的背书。
下面用你截图里的两步把“它到底在证明什么”说清楚。
δ^Oracle:背书的是“claim(属性)本身是真的”这一步的前提是你们跑了 DECO/Oracle 去核验属性(比如身份证号、资质号、登记信息等)确实真实,然后委员会节点给出部分签名 δ_i^{oracle},用户合成得到:
δ^Oracle = TS.Comb(δ_i^{oracle})它表达的是:
“这个 claim(或 claim 里的 v / Cv)已经被 Oracle 方式核验过,确实成立。”
这个签名的核心意义通常是入场门槛:没有 δ^Oracle,你提交的 claim 就只是你自说自话,后面的去重、注册、签发都不该继续。
δ_i^π = TS.Sig(sk_{C,i}^A, m):背书的是“DID ↔ pk 的绑定关系(顺带把 claim 一起绑定进去)”这里节点签的消息是:
m = { pk_U^A, ctx, claim },其中 ctx 明确写了“表示 DID 与 pk 的关系”。这一步更像在发一个“绑定凭证”(你前面也看到它叫 C_π):
“这个 DID(由 ctx 指代的绑定语义)对应的控制公钥是 pk_U^A,并且这次绑定关联的是这份 claim。”
关键:这一步里的委员会并不等价于重新跑一遍 DECO 来判断 claim 真不真。它更多是在做“登记/绑定/生命周期管理”的签名(把 DID、pk、以及当时那份 claim 锚定在一起,防止事后换 claim、换 pk)。
所以你看到它也把 claim 放进 m,主要目的通常是:
如果你把 δ^Oracle 删掉,只保留第二步 δ^π,就会出现一个问题:
claim(或随便构造一个 Cv),然后让委员会在“绑定流程”里对 m={pk,ctx,claim} 产生阈值签名(只要流程允许)。δ^π 会以为“这份 claim 被背书了”,但其实并没有经过 Oracle 的真实性核验。因此,δ^Oracle 负责“claim 真实”,δ^π 负责“DID–pk–claim 的绑定关系真实/不可篡改”。两者是不同层面的保证。
取决于你要证明什么:
C_d^{Oracle}(带 δ^Oracle)。C_π(带 δ^π)。如果你愿意,你把论文里 **“第二步签名时委员会节点是否再次验证 δ^Oracle / 是否检查 DECO 结果”**那一小段也截出来,我可以更精确地告诉你:作者设计上到底是“二次不验证(仅绑定)”,还是“二次也验证(可合并)”。
我有两个场景,设备域给无人机发deviceVC,任务域给无人机发mission VC,按照前面的做法,发device VC的过程是,无人机发claim,设备域核实背书,签发deviceVC。那任务域发missionVC的情况呢?关键是有个疑惑点。无人机知道自己的设备域属性,所以可以发claim,但是他知道任务属性么?能发claim么
你这个疑惑点的根源在于:“DeviceVC 的 claim” 和 “MissionVC 的 claim” 不是同一种语义。
所以:MissionVC 的 claim 不需要(也通常不应该)由无人机来“声明并证明它是真的”。
无人机做的不是“证明任务属性”,而是“证明自己有资格拿到这个授权,并同意/接收授权条款”。
无人机发的是一个“请求/申请(request)”,里面包含:
Nym(会话假名)π_e(成员资格:我是域A认可成员)DeviceVC + π_cap + π_link(能力达标且绑定同一主体)Token_C(如果你要求先入域再领任务,或任务域要看监管准入状态)这一步里无人机发的可以叫 MissionRequest VP(展示包),但它不是 MissionVC。
任务域B拿到请求后,选择/匹配任务,自己生成 MissionVC 的 claim:
subject: 绑定到 H(Nym)(匿名主体)mission: 任务ID、任务类型、地理围栏、时间窗、载荷/高度/航线限制、合规要求等audience: 监管域C(或具体空域/系统)nonceB / issueTime / exp: 防重放 + 有效期proofRef: 引用这次验证用到的材料(例如 GA 版本号、任务匹配策略版本、nonceB)然后 B 对这个 claim 签名 → 这才是 MissionVC。
为了避免“任务域给你发了你并不想接的任务VC”,可以加一步很便宜的绑定:
MissionVC_draftAccept = Sig_u(Hash(MissionVC_draft))Accept 写进最终 MissionVC(或单独存一条)这样 MissionVC 就同时证明:
无人机知道自己的设备域属性,所以可以发claim,但是他知道任务属性么?能发claim么?
{ Nym, π_e, DeviceVC, π_cap, π_link, nonceB }{ subject=H(Nym), missionTerms..., audience=C, exp, nonceB, proof=Sig_B(...) }如果你愿意,我也可以按你“匿名凭证 + 成员资格 + DeviceVC + π_cap + π_link”的符号体系,把 MissionVC 的 claim 最小字段集列出来(哪些字段必须有、哪些是可选、哪些一定要绑定 nonce/exp/audience),这样你写论文协议会更严密。
MissionRequest VP(展示包)
这个是什么意思
“MissionRequest VP(展示包)”就是:无人机向任务域 B 发起领任务/接单时提交的一揽子可验证材料。
因为 MissionVC 的 claim(任务条款:做什么、哪里、多久、限制)是任务域 B 决定并背书的,无人机不应该自己“声明任务条款是真的”。无人机能声明/证明的是:“我是谁(匿名成员)+ 我能力够(≥k)+ 是同一台机”。
你可以把它理解成一个 JSON 包:
json{ "type": ["VerifiablePresentation", "MissionRequest"], "holder": "nym:0x....", "verifiableCredential": [ { "type": ["DeviceVC"], "...": "..." } ], "proofs": { "memberProof_pi_e": "pi_e_bytes_or_object", "capProof_pi_cap": "pi_cap_bytes_or_object", "linkProof_pi_link": "pi_link_bytes_or_object" }, "challenge": "nonceB-from-domainB" }
B 收到后验证:
验证通过,B 才签发 MissionVC(任务授权凭证)。
如果你愿意,我也可以按你当前协议的字段命名(Nym、GAStatus、audience、exp)把 MissionRequest VP 和 MissionVC 的最小字段集合列成一个更规范的模板。
那如果是B给无人机发claim,那claim中的加密承诺由谁来发起做?
“承诺/加密承诺”这种字段是谁发起计算,取决于谁知道被承诺的那个值,以及你想把它对谁隐藏。
以 Pedersen 承诺为例,C = Comm(x, r) 必须同时知道:
xr所以 谁来算承诺 = 谁拥有/决定 x(并选择 r)。
MissionVC 的 claim 里大部分字段(任务类型、地理围栏、时间窗、限高、载荷约束等)是任务域 B 决定的任务条款,因此:
C_geofence = Comm(geofence, r1),C_time = Comm(timeWindow, r2)注意:很多时候 MissionVC 根本不需要承诺——B 直接把条款明文写进去签名就行。承诺的价值主要在“选择性披露/对第三方隐藏细节”。
MissionVC 里也可能包含一些与无人机相关、B不需要知道明文的字段,比如:
Nym(或 H(Nym))这时可以用持有人先算承诺、B 只负责签的方式(类似 CL/盲签/隐藏属性签发思路):
C_nym = Comm(Nym, r) 或直接给 nymHash = H(Nym)C_nym / nymHash 放进 claim 一起签这样 MissionVC 仍然是 B 的授权,但“主体绑定值”由无人机控制随机性,更利于隐私。
很多同学会把下面两种混叫:
x 的那方(上面讲的)如果你要让 监管域 C 能看到任务细节,但不想让其他人看到,可以:
这不叫承诺,而是加密;也可以“承诺 + 加密”同时用(承诺用于可验证绑定,加密用于机密传输)。
nymHash = H(Nym)(无需承诺,足够绑定)Enc_pkC(terms)(加密),必要时再附承诺做“不可篡改锚”如果你告诉我:MissionVC 里哪些字段你希望 对谁隐藏(对B隐藏?对C隐藏?对公众隐藏?),我可以给你一个最小字段集的 MissionVC 结构:哪些明文、哪些承诺、哪些加密、以及承诺开封(opening)由谁持有/何时出示。
MissionVC 绑定匿名身份:用 nymHash = H(Nym)(无需承诺,足够绑定)这个的意思是只要绑定匿名nym即可,无需对其claim中的任务等等做加密承诺?
对,你理解得对。
“MissionVC 绑定匿名身份:用 nymHash = H(Nym)” 的意思是:
MissionVC 只需要把“这张任务授权是给哪个匿名主体的”绑定住即可——用 H(Nym) 作为主体标识写进 claim,再由任务域 B 对整份 claim 签名(proof)覆盖它。
这样就能保证:
所以不需要为了“绑定身份”而对任务条款再做 Pedersen 承诺/加密承诺。
只有当你有额外目标,比如:
选择性披露:
想让监管域 C 看全部细节,但让服务商/第三方只看到“被授权即可”,这时可以对部分字段做承诺(或拆成两张VC)。
保密:
不希望任务细节被中间方看到(例如链上或转发路径),那就用加密:Enc_pkC(terms)(只有 C 能解密)。
链上存证但不泄露:
如果你把 MissionVC(或其部分)上链/广播,又不想公开任务细节,那才需要承诺/加密。
nymHash = H(Nym)(绑定匿名主体)missionTerms 明文(任务域B签名保证不可篡改)audience / exp / nonceB(防重放、限定用途)proof = Sig_B(Hash(claim))这就足够让域C验证“任务域确实授权给这个匿名主体”,并据此发短期 Token。
如果你告诉我:MissionVC 的任务条款你希望“对谁隐藏”,我再帮你决定哪些字段需要承诺、哪些需要加密、以及由谁持有 opening/密钥。
B 对部分敏感条款做承诺
那这里B做了之后,无人机还能知道具体的任务么?
看你**“承诺(commitment)”怎么用**——单纯把敏感条款做成承诺以后,承诺值本身是不可逆的,无人机不能仅凭承诺“还原出任务细节”。所以如果你让 B 只在 MissionVC 里放承诺,不额外给明文/解密材料,那无人机就不知道具体任务内容。
要让“对外隐藏细节,但无人机仍然知道任务”,一般有 3 种常见做法:
nymHash + 承诺(termsCommit) + B签名✅ 无人机能直接执行任务
✅ 第三方看不到细节
⚠️ 无人机拿到明文后仍可能泄露(但这是业务/合约层约束)
MissionVC 里同时放两样:
termsCommit = Comm(terms, r)(用于不可篡改锚定/可审计)termsCipher = Enc(pk_drone, terms)(无人机可解密拿到明文;别人看不到)无人机用自己私钥解密得到任务条款;监管域如果也要看,就再放一份 Enc(pk_C, terms) 或者让无人机转交给 C。
✅ 只有持有私钥的无人机/监管能看到细节
✅ 承诺保证“密文解出来的明文没被换”
⚠️ 实现稍复杂一点(需要加密体系)
nymHash + 任务类型(粗粒度) + 承诺/摘要 + 签名✅ 结构清晰、好落地
⚠️ 多一个对象需要管理/对齐
如果你告诉我“敏感条款要对谁隐藏”(对任务域内部的某些组件?对监管?对链上公众?),我可以帮你选最合适的那一种,并把 MissionVC 字段再精简成你论文里能直接用的版本。
签发deviceVC:无人机发设备claim,域A核实后,给其claim背书(shamir秘密共享多方签名)。然后对敏感信息生成承诺,非敏感信息公开,然后发送给域A,域A根据主码关键属性去重后,将其DID文档(DDO)上域A的链,返回DID给用户。同时给DID以及DDO进行背书(秘密共享多方签名,这一步证明的是DID与DDO文档是对应的,其实就是issuer签名证明DID与其公钥是绑定的)
签发missionVC:无人机发nym以及deviceVC+link,域B首先在链上验证nym是否存在,然后验证其nym以及deviceVC的绑定关系等,验证成功后然后生成一个任务claim背书后发送给无人机。
那这样的话,其实链上只需要存匿名凭证中的e了,然后无人机侧需要存储的是nym、deviceVC和missionVC以及相应的证明关系?
整体方向对,但你这段里有两处需要“纠偏”,然后再回答你最后那个“链上存什么、无人机存什么”。
你描述的两次阈值签名,本质是两类不同语义:
这两次都可能“包含 claim 字段”,但用途不同:前者是“属性真”,后者是“绑定真”。
另外你这句顺序建议微调一下表达:
“对敏感信息生成承诺、非敏感公开”这一步通常是在形成要上链/要签名的 claim 表达时就确定好(敏感→承诺,非敏感→明文)。至于是“先签再承诺”还是“对承诺后的 claim 签”,论文写法有时不严谨,但工程上你要确保签名覆盖最终对外使用的字段(承诺值/明文字段),否则会出现“签名背书的内容与后续使用内容不一致”。
按你参考的 3.3 思路(累加器 GA + NIZK π_e):
所以你给 B 的材料应更像:
Nymπ_e(成员资格:e ∈ GA 且与 Nym 绑定)DeviceVCπ_link(Nym 与 DeviceVC 同一 linkSecret/同一主体)π_cap(能力最小披露:level ≥ k)然后 B 签发 MissionVC,把 nymHash = H(Nym)(或 H(Nym||nonceB))写进 MissionVC 的 claim 里做绑定即可。
严格按累加器做法:
此外,为了让跨域验证可落地,链上通常还至少要有:
你写的“nym、deviceVC、missionVC 以及证明关系”方向对,但补两个关键点:
无人机长期存:
DeviceVC(长期/半长期)linkSecret (ls)(用于派生 Nym、做 π_link 的见证)——不要依赖 DID 的签名私钥本身cred=(e,n,s) 以及可能的累加器成员见证/witness;不同实现可能还要可更新的 witness)每次会话/每个任务临时生成:
Nym(临时假名)π_e、π_link、π_cap(这些证明是“现场算出来”的,不一定长期存)MissionVC(短期)Token(短期,可续证/可撤销)如果你愿意,我可以把你这两段(DeviceVC签发 & MissionVC签发)直接整理成一张时序表:每一步“谁发什么、链上读什么、验证什么、绑定哪些 nonce/exp/audience”,这样你写论文会非常清晰。
这样会有个问题,就是假设域B已经撤销了任务,那监管域是不知道的啊?
对,会有这个缺口:如果 MissionVC 只在 B↔无人机之间流转,而 C 完全不去查询任何“任务状态源”,那 B 撤销任务后 C 确实不知道。解决办法就是让 C 在做放行/续证时,能验证“这张 MissionVC 目前仍有效(未撤销)”。常见有三种做法,你选一种就能闭环。
做法:
missionId(或 missionHash)statusRef(撤销检查句柄,比如 revocationIndex/statusListIndex/accHandle)MissionStatusRoot_BstatusRef 检查该任务是否被撤销(有的设计是“提供未撤销证明”,有的是“查状态位”)优点: C 不用信任 B 的在线接口,完全靠链上“最新根”做一致验证;也符合你“链上存摘要/根”的路线。
代价: B 需要维护撤销根的更新机制。
做法:
MissionStatusRoot_B这样 B 撤销任务后,最多在“Token 剩余有效期”这段时间内仍可执行,之后续证就会失败。
优点: 实现代价低;撤销生效时间可控(上限=Token有效期)。
代价: 不是“秒级立即撤销”,是“有界延迟撤销”。
做法:
missionId 去问 B:是否撤销/是否仍有效AttestNotRevoked(missionId, exp)),C 以此发 Token优点: 撤销可做到更接近实时。
代价: C 依赖 B 在线可用;跨域联动复杂度更高。
你已经有“主链维护 GA 根”的思路,所以最自然的是:
π_eMissionStatusRoot_B + C 做撤销检查也就是 方案A + 方案B 组合:既不要求 C 实时在线依赖 B,又能把撤销生效时间控制在 Token 的有效期上限内。
如果你愿意,我可以把你 MissionVC 里的最小“可撤销字段”补到你之前那个 JSON 例子里(加上 missionId/statusRef/statusRootVersion),再给一个“B 更新状态根、C 校验状态根”的最小流程(两三步就讲清)。
那这样的话,其实链上
任务域A需要存匿名凭证相关的累加器根 GA,证明匿名凭证在该域中。撤销的时候删除e即可
任务域 B 在主链维护一个MissionStatusRoot_B(撤销授权列表),撤销的时候直接列到列表中
监管域C在主链维护一个StatusRoot_C(撤销让他进入列表),撤销的时候直接列到列表中
然后无人机侧需要存储的是nym、deviceVC和missionVC以及相应的证明关系?
这样是否合理?
整体方向是合理的:把“跨域可验证的最小状态”放主链(根/状态指针),把 VC/证明放链下流转;B、C 的撤销都能被别的域在链上独立验证。
但你这段里有几处需要改得更严谨,否则实现上会踩坑。
π_e)。你说“撤销的时候直接列到列表中”——概念对(撤销列表),但实现上不要真的把列表明细都上链,会炸吞吐/存储。
更合理写法是:
statusRef(比如 index 或 missionId hash),监管域 C 用 root + statusRef 做撤销检查这和你毕设里 “GAStatus 指向最新 GA 根” 是同一类“根 + 版本指针”模式。
你写:存 nym、DeviceVC、MissionVC 以及证明关系 ——方向对,但至少还要补:
linkSecret(ls)或等价长期绑定秘密
C_ls),π_link 需要它做见证。生成成员资格证明 π_e 所需的私有材料
cred=(e,n,s) 以及可能的 witness(取决于你怎么实现动态累加器证明)。π_e。另外,nym 通常是每次会话临时生成,不一定要长期存;更像是“会话状态”。
主链(或全域可查询的共识层)最少维护:
你这套“A: GA 成员根、B: Mission 状态根、C: Token 状态根 + 无人机链下持有 VC/证明”的大框架是合理的。
需要你在论文里补严谨的点主要是:
如果你愿意,我可以把这三类根的最小字段(root/version/更新者/验证输入)整理成一个小表格,顺便把 MissionVC 里必须出现的 missionId/statusRef/statusRootVersion 给你补全。
我觉得不太合理,因为,任务域B和C其实用的都是匿名nym,即使撤销了,那无人机还可以申请一个新的nym继续执行?这样怎么办
你这个担心非常关键:如果 Nym 是“随便换一个就行”的匿名标识,那 B/C 的撤销就会被绕过。解决办法是把“可换的会话假名”之上,再加一个不可轻易换、但仍不暴露真实身份的“撤销锚点(revocation handle)”——撤销针对这个锚点,而不是针对某一次 Nym。
下面给你一个最推荐、也最符合你现有设计(DeviceVC 承诺 + π_link/π_cap + 成员资格 π_e)的做法。
nym_session:每次任务/每次连接随机生成,降低可链接性。用设备的长期绑定秘密 ls 派生一个“域专用假名”:
pid_B = H(PRF(ls, "DomainB"))pid_C = H(PRF(ls, "DomainC"))(监管域也可以有自己的)特点:
你现在是:
nym + π_e + DeviceVC + π_cap + π_link改成:
nym_sessionpid_Bπ_e(成员资格,对 GA)DeviceVCπ_cap(能力≥k)π_link_total:一个合并证明,证明下面这些都绑定同一个 ls(或把它拆成两个证明也行):
DeviceVC 里的 C_ls 承诺的是同一个 lspid_B = H(PRF(ls,"DomainB"))nym_session = f(ls, rand/nonceB)(可选,但推荐绑定 nonceB 防重放)这样 B 就能把撤销对象锁定为 pid_B,而不是某次 nym。
pid_B 或 nymHashMissionVC 里建议放:
subjectPid = pid_B(用于撤销/配额/信誉)nymHash = H(nym_session)(用于会话绑定、防转发)B 撤销任务时有两类撤销:
MissionStatusRoot_B 里把 missionId 标记撤销B_BlacklistRoot 里加入 pid_B这就回答了你担心的“换 Nym 继续执行”:
只要 B 撤销的是 pid_B,你换多少 nym_session 都没用,因为你每次都必须提交能证明同一pid_B的材料。
pid_C(或 pid_B + missionId)C 发 Token 时,把 Token 绑定:
subjectPid = pid_C(或也可接受 pid_B,看你想让 C 追踪到什么粒度)missionId / missionHashexp(短期)C 的撤销根 StatusRoot_C 存的是 pid_C(封禁) 或 tokenId(撤销某次准入)。
pid_B/pid_C 的证明。pid_*(域内稳定假名),所以撤销仍然有效。不要把撤销绑在可随时更换的 Nym 上;撤销要绑在“域内稳定但跨域不可链接”的撤销锚点 pid(由 DeviceVC 承诺的 linkSecret 派生),并要求每次出示时用 ZKP 证明 nym/pid/DeviceVC 同源。
如果你愿意,我可以给你一个很简单的 pid_B 字段如何出现在 DeviceVC/MissionVC/Token 里的 JSON 示例(以及 π_link_total 需要证明的语句清单)。
域A、域B和域C分别有哪几种撤销方式?
下面按你现在的“三域三类凭据”(A:成员/设备,B:任务授权,C:准入Token)把各域常见、最合理的撤销方式列出来,并说明各自撤销的对象是什么、怎么让别的域验证。
A 的撤销对象主要是:这台无人机还能不能作为“A域成员”被外域接受、以及它的设备能力证书还有效吗。
e(对应你匿名凭证 cred 里的那个素数/成员标识),或撤销锚点 pid_*(域内稳定假名)e 从有效集合里移除(需要动态累加器支持删除 + witness 更新机制)e 加入撤销根/撤销累加器 R_A;验证时要求同时证明 e ∉ R_AGA_A_root(以及 R_A_root),验证 π_e(以及可选的非撤销证明)DeviceStatusRoot_A(类似状态列表根),撤销时更新根;VC 里带 statusRefDeviceStatusRoot_A 的状态位/证明B 的撤销对象是任务能不能继续执行,以及这台设备在 B 域还能不能接任务。
missionId / missionHash(一张 MissionVC 对应一个任务授权)MissionStatusRoot_B(撤销根/状态根),撤销=更新根并把该任务标记为 revokedmissionId/statusRef 去验证“未撤销”pid_B(不要用可换的 nym_session)BlacklistRoot_B(或写进 MissionStatusRoot_B 的另一张状态表),把 pid_B 加入封禁集合pid_B(由 linkSecret 派生)与自己绑定C 的撤销对象是:这台设备现在还能不能进入/继续在本区域执行。
tokenId(一次准入许可)TokenStatusRoot_C(撤销根/状态根),撤销某 token = 更新根pid_C(域C专用稳定假名,或监管统一 pid)BlacklistRoot_C,把 pid_C 加入集合policyVersionPolicyRoot_C(或 policyVersion 上链),Token 续证/校验必须匹配最新 policyVersion;不匹配则自动失效如果你告诉我你更倾向 “GA 删除” 还是 “撤销集合 R_A”(工程上更省事),我可以把三域的链上根(GA_root、MissionStatusRoot、TokenStatusRoot、BlacklistRoot)统一成一套“根+版本指针+证明接口”的最小规范,方便你写论文/画系统图。
我有一个问题,就是目前的方案,假设C撤销某个无人机永久飞,他要怎么做?因为监管域目前只知道是PID-C或者PID-B不知道真正的DID
这个问题本质是 “匿名但可追责 / 可永久封禁” 怎么做。
结论:C 不需要知道真实 DID 也能永久禁飞,只要你的 PID 设计是“域内稳定、不可随便换”的;但为了防止“换一套新身份重新注册”这种规避,还必须配一个 归属域A的强制约束/联动撤销(或“硬件唯一性去重”)。
下面给你一套最闭环、最符合你当前架构的做法。
前提:pid_C = H(PRF(ls, "DomainC"))(ls 是设备长期 linkSecret),并且无人机每次来 C 都必须提供能证明:
pid_C 确实由同一个 ls 派生ls 与 DeviceVC 里的 C_ls 是同一个(靠 π_link/合并证明)那 C 做“永久禁飞”就很简单:
pid_C 加入 BlacklistRoot_C(黑名单状态根)pid_C ∉ BlacklistRoot_C因为 pid_C 是由 ls 决定的,你换 Nym 没用;只要你还拿同一个 DeviceVC/同一个 ls 来证明,你的 pid_C 就不会变。
所以“C 不知道 DID”不妨碍它在自己辖区永久封禁——它封的是“域内稳定假名 PID-C”。
如果无人机能在域A重新注册、拿到新 DeviceVC(新的 C_ls),那 pid_C 就会变,确实可能绕过 C 的黑名单。
所以你需要 A 侧的不可规避约束,至少满足其一:
用你毕设 3.2 的思路做“去重/唯一注册”,但要确保去重键是确定性的(不能每次随机承诺导致查不出来)。常见做法是:
这样无人机就没法“换马甲”再拿新 DeviceVC。
当 C 永久禁飞某设备(pid_C)时,C 发送一条签名的 BanOrder给 A(链上可只存哈希/状态根):
pid_C(或 pid_A)追溯到具体 DID/档案e、撤销 DeviceVC 状态、拒绝再 mint 匿名材料这样即使无人机想重新申请凭证也拿不到。
那就不能只靠 pid_C,因为它是“域专用”。
你有两种常见设计:
让所有监管域使用同一个派生标签:
pid_R = H(PRF(ls, "REGULATOR"))
所有监管域都用 pid_R 做封禁键(仍然不暴露 DID,且跨监管域一致)。监管联盟在主链维护 RegBanRoot,封禁时把 pid_R 加进去;各监管域发 Token 必查。
总结成一句话:
pid_C 就能做到(前提是 pid_C 与 ls 强绑定,且 ls 不能随意换)。pid_R 或主链的监管封禁根。如果你愿意,我可以把“BanOrder(C→A)”和“链上根的最小字段(BlacklistRoot_C / RegBanRoot / DeviceStatusRoot_A / GA_A_root)”给你写成一个很短的接口/数据结构模板,直接能放进你的方案/论文。
还是说换种方式,链上还是只存GA,当C要撤销的时候,C告诉B,B判断无人机还能否执行其他相关任务,如果能就重新发任务。如果不能,B就找A,告诉A,该无人机不能执行任务,让A撤销其在GA上的e。同理,B想撤销无人机,就找A,让A撤销。
你这个“只在链上保留 GA,然后所有撤销最终都落到 A 去撤 e”的思路可以成立,而且能把链上状态压到很小。但要注意:** 它成立有几个前提**;否则会出现“C 根本没法让 A 知道该撤谁 / 撤销不够及时 / 责任边界很怪”。
下面我把它理清楚,并给你一个更稳的版本(仍然尽量保持“链上只存 GA”的风格)。
你现在的流程里,C 只看到 Nym(匿名),并不知道 DID。那 C 要求 A 撤销时,A 至少得知道“对应的是哪个成员 e / 哪台设备”。
所以必须有 revocation handle(撤销句柄),让 C(或 B)可以把“这次违规的匿名主体”指向 A 内部的一条档案。
常见做法(选一个就行):
cred=(e,...) 的同时生成 tag = PRF(k_A, e)(或对 e 的承诺/加密)tag + 证据 + 自己的签名 发给 A,A 就能定位并撤销对应 epid_R = H(PRF(ls,"REGULATOR"))(监管统一)pid_R,并把 pid_R 发给 A;A 内部能把 pid_R 映射回设备档案(靠注册时绑定的 ls / 或映射表)没有这类句柄,你的“C 找 B,B 找 A”最后还是会卡在:A 不知道撤哪个 e。
更稳的职责划分是:
也就是说:
即使 A 很快撤 e,也会有传播/检查周期。为了避免“撤了但还能飞一段时间”,你需要:
这样 A 一旦撤 e,下一次续证就会失败,延迟上限≈Token 有效期。
很多动态累加器里“删除”很麻烦,而且可能要求 witness 更新。
工程上更推荐:
e ∈ GA 且 e ∉ R_A你想极简到“链上只存 GA”也行,但那你就只能“重建 GA”(把所有未撤销成员重新算一遍根),不现实。
链上最小状态:
GA_A_root (+ version):A 域成员集合根R_A_root (+ version):A 域撤销集合根(或监管封禁根)撤销流程:
BanRequest = {tag/pid_R, evidenceHash, action=permanentBan, sig_C}R_A(或更新 GA)B 的撤销:
tag/pid_R 发给 A,请 A 做全局封禁可以,但必须补:
如果你愿意,我可以帮你把 BanRequest、tag/pid_R、以及 A 更新撤销根的最小字段写成 3~5 行协议定义,这样你论文里“监管永久禁飞”就闭环了。
那种思路比较好
两种思路都能跑起来,但适合的“安全假设”不一样。放到你这个低空场景(监管强、实时性强、域多主体多、还要能跨域验证)里,我更推荐一个分层的混合方案:** 本域立即可控 + 全局最终封禁**。它兼顾你想参考的“主链尽量只存 GA/摘要”的风格,又不会被“链下联动失效/延迟”拖死。
下面先把你提的两条思路对比清楚,再给我建议的选型。
优点
缺点
优点
致命风险/缺点(低空场景里很关键)
MissionStatusRoot_BGA_A_root(+version),设备出示 π_e 证明成员。R_A_root 或 RegBanRoot(封禁集合根),撤销针对 e 或 pid_R(不是 Nym)。BlacklistRoot_C(封禁 pid_C/pid_R),续证必重验(成员 + 任务 + 政策)。MissionStatusRoot_B 上链;如果你告诉我你更偏向:
我就能帮你把 B 的那块(MissionStatusRoot_B 要不要、怎么更新频率才不炸)定成最简、最能写进论文的版本。
我没看懂在线和离线的区别
“在线/离线”的区别,指的是 监管域 C 在做放行/续证/检查时,需不需要实时去问别人(B 或 A)拿一个“最新答复”。
C 不需要和 B/A 建立实时通信,只靠:
GA_root、MissionStatusRoot_B、TokenStatusRoot_C)就能判断:
例子:
C 检查任务是否撤销:从链上取最新 MissionStatusRoot_B,用 MissionVC 里的 statusRef/missionId 验“未撤销”。不需要问 B。
优点: 不依赖网络/对方服务;更稳、更适合无人值守/断网环境。
缺点: 需要 B 把撤销状态以“根/版本”的形式上链维护。
C 在做放行/续证/检查时,必须去问 B(或 A)要一个“当前状态”的回执,比如:
AttestNotRevoked(missionId, exp)),C 依据该回执放行/续证。例子:
C 收到 MissionVC 后,拿 missionId 调 B 的接口查询;B 回复“未撤销 + 签名 + 有效期5分钟”,C 才发 Token。
优点: 不用把撤销根上链,链上更省;状态更新可更实时。
缺点: 依赖网络和 B/A 在线服务;一断网就麻烦。
很多方案会用折中:
如果你告诉我你更偏“必须断网可用”还是“始终联网”,我可以帮你把 B 的撤销设计成最简的两套版本(离线上链根版 vs 在线回执版)。
我觉得这个把:如果你考虑 基站/边缘检查点可能断网、或希望监管“独立可控”,选 离线(更像监管要求)。
明白,那你选“离线可验证”这条路线很对,尤其贴合低空监管的真实约束(断网/弱网、无人值守检查点、监管要独立可控)。
在你现有框架里,“离线”意味着一句话:
C 在放行/续证/检查时,不需要实时问 B/A,只靠「无人机带来的材料 + 主链上的最新状态根」就能判断“任务是否撤销、成员是否有效、是否被封禁”。
GA_A_root (+ GA_A_version)
RevRoot_A 或 RegBanRoot (+ version)
MissionStatusRoot_B (+ version) ✅(你已经认同离线就需要这个)
TokenStatusRoot_C (+ version)(可选但很实用)
这些根都是“很小的状态”,链上只存根值+版本,不存明细列表。
无人机到 C 时给:
Nym(会话假名)π_e(成员资格证明:e ∈ GA_A)MissionVC(B 签发)Token_C_old(续证时)π_cap(如果 C 也要能力复核)C 离线验证链条:
GA_A_root,验 π_e ✅RevRoot_A/RegBanRoot,检查“未被封禁” ✅MissionVC 的签名 ✅MissionStatusRoot_B,检查 missionId 未撤销 ✅Token_C(短期),并按需写入/更新 TokenStatusRoot_C这样 B 撤销任务后,C 不用联网问 B,照样能拒绝放行/拒绝续证。
MissionVC 至少要带:
missionId(或 missionHash)statusRef(在 B 的状态结构里对应的索引/句柄)statusRootVersion(便于快速定位版本)这样 C 才能拿 missionId/statusRef 去对 MissionStatusRoot_B 做撤销检查。
你之前担心“换 Nym 逃避撤销”,离线版用 封禁锚点解决:
RegBanRoot这样换 Nym 没用,封的是 pid_R(稳定且不可随意换)。
这就是离线监管里最经典的“根驱动”架构:谁签发谁维护状态根,监管查根即可独立裁决。
如果你愿意,我可以按你现在的字段体系,把这 4 个 root 各自的“更新事件”(mint/revoke/suspend/renew)和“验证接口输入”(missionId/statusRef/GA_version 等)整理成一张非常小的表,你后面写论文/画架构图会特别清晰。
GA_A_root (+ GA_A_version)
A 域成员集合摘要(你毕设那套 GA/GAStatus)
RevRoot_A 或 RegBanRoot (+ version)
这两的关系我没看懂,既然已经有了累加器,那A域撤销设备的时候,直接删除累加器相关的e值不就可以了么?为啥还要RevRoot_A 或 RegBanRoot (+ version)
你这个问题问到点子上了:“既然有累加器 GA,撤销时把 e 从 GA 里删掉不就行了?为什么还要 RevRoot/RegBanRoot?”
答案是:理论上可以只用一个 GA 做“有效成员集合”,但工程上/安全上通常还要一个“撤销根”,原因主要有 3 个。(你也可以二选一,我把两种路线讲清楚)
GA_A_root:表示一个集合的“摘要根”。常见两种语义:
RevRoot_A:A 域维护的“撤销集合根”(哪些 e 被撤销了)。通常是只增不减的结构(状态列表根/撤销累加器根/梅克尔根都行)。
RegBanRoot:监管(或监管联盟)维护的“封禁集合根”(哪些设备被永久禁飞)。它不一定由 A 管,通常更符合监管权责。
验证时就变成:
e ∈ GA_Ae ∉ RevRoot_A(或 pid_R 不在 RegBanRoot)很多累加器(尤其 RSA 累加器)支持添加很容易,但删除往往需要:
所以如果你把 GA 定义成“有效集合”,每撤销一次就删 e:
工程成本很高。
离线监管最怕两件事:断网 + 状态不同步。
如果撤销靠“从 GA 删除”,那监管检查点必须确保拿到最新 GA_root,否则就会把已撤销成员当成有效。
而“撤销根/封禁根”做成只增不减(append-only)有两个好处:
监管的“永久禁飞”有时不是让它“退出 A 域成员”,而是:
这类权力通常不应该完全依赖 A 去删 e(否则变成“监管要靠归属域配合才能执法”)。
所以会引入 RegBanRoot 这种监管侧的独立封禁根:监管自己说了算,离线也能验。
优点:链上状态最少(一个根)。
缺点:删除与 witness 更新复杂,系统实现更难。
RevRoot_ARegBanRoote ∈ GAe ∉ RevRoot_A 且 pid_R ∉ RegBanRoot优点:撤销是追加更新、同步稳、离线友好、职责清晰。
缺点:链上多一个根(但仍是“根级别”非常轻量)。
因为在“离线可验证 + 多域监管 + 可追责封禁”的要求下,把撤销做成一个独立的、只增不减的状态根更稳、更好实现、更符合监管权责;而“从 GA 删除 e”虽然理论可行,但会引入删除与 witness 更新的复杂度,并且监管封禁不一定应该完全依赖 A 的成员集合变更。
如果你告诉我你更倾向:
主链上至少要有这些“根/版本指针”
把上面的这块再理一下
好,我把“主链上至少要有哪些根/版本指针”这块按离线可验证的目标重新捋一遍(每个根:代表什么、谁更新、别人怎么用)。
“根/版本指针”可以理解成:链上只存一个很小的 root 值(比如 Merkle root / accumulator root)+ 一个 version/状态指针(类似你毕设里的 GAStatus 指向最新那条)。验证方只要拿到“最新 root”,就能离线验证某个东西是否有效/是否被撤销。
监管域 C 在放行/续证时 不问 B / 不问 A,只靠:
所以链上必须有“能离线判断状态”的 root。
GA_A_root (+ version)用途:证明“这台设备是归属域 A 认可的成员”(匿名成员资格底座)
e 的集合摘要(你毕设 3.3 的动态累加器 GA)π_e)这一步对应你毕设:链上存 GA + GAStatus(version指针),外域验
π_e。
这里你之前卡住了:为啥有了 GA 还要撤销根。离线场景下,通常需要一个“撤销/封禁 root”来表达 谁被拉黑/永久禁飞,而且最好是追加式、同步稳。
RevRoot_A (+ version)(A 域撤销根)用途:A 撤销某设备(例如资质失效、设备被盗、严重违规),让它以后在哪都过不了(或过不了 A 成员检查)
e(或 A 能映射到 e 的撤销句柄)e ∉ RevRoot_A(或查状态位/非成员证明)这适合“撤销是归属域管理职责”的情况。
RegBanRoot (+ version)(监管封禁根,推荐用于“永久禁飞”)用途:监管对设备做“永久禁飞/跨空域封禁”,不依赖 A 配合即可生效(离线也能验)
pid_R(由设备的 linkSecret 派生,跨监管域一致,但不泄露 DID)pid_R ∉ RegBanRoot这解决你之前的担心:C 不知道 DID 也能永久封,而且换 Nym 没用。
✅ 最低配离线监管:我建议你至少要 RegBanRoot(因为你讨论的核心就是“永久禁飞”)。
MissionStatusRoot_B (+ version)用途:离线判断“这张 MissionVC 对应的任务是否被撤销/暂停/替代”
missionId(或 missionHash / statusRef)missionId + statusRef(最少这俩)MissionStatusRoot_B,离线检查该任务“未撤销”你选了“离线”,那这一项基本是必需的,否则 C 只能在线问 B。
TokenStatusRoot_C (+ version)(可选但很实用)用途:监管对已签发的短期 Token做紧急撤销(秒级/分钟级生效)
tokenId(或 token 的哈希)如果你把 Token 设计得很短(比如 5–10 分钟)且不强调“秒级撤销”,这项可以弱化;但现实监管通常很喜欢有它。
不然 B/C 根本不知道该信谁的签名:
这些不是“root”,但属于离线验证的必要前提。
如果你目标是离线可验证 + 可永久禁飞 + 可撤销任务,主链最小需要:
GA_A_root (+ version):成员集合根RegBanRoot (+ version):监管永久封禁根(按 pid_R)MissionStatusRoot_B (+ version):任务撤销/状态根TokenStatusRoot_C (+ version):token 紧急撤销根如果你愿意,我可以按你现在的数据流,把 **C 放行/续证时的“离线检查顺序”**写成 6 行(取哪些 root、验证哪些 VC/证明、哪些字段必须放进 MissionVC/Token),你就可以直接搬到方案章节里。
Token 状态根,这个我觉得意义不大,直接验证方快速验证token即可,无需链上信息。监管域的封禁根有必要
就是我觉得下面这三个是必要的
GA_A_root (+ version):成员集合根
RegBanRoot (+ version):监管永久封禁根(按 pid_R)
MissionStatusRoot_B (+ version):任务撤销/状态根
但是我有疑问,首先
1、这三种具体操作方式应该类似,那大概是怎么做的?
可以,把这 3 个“根 + 版本指针”当成同一种通用模式来实现:链上只保存最新 (root, version);链下由对应域维护一份“状态表/集合”,每次变更就重算 root 并把新 root 上链。验证方离线取最新 root,用**证明(proof)**去校验某个键的状态。
下面分别说 GA_A_root、RegBanRoot、MissionStatusRoot_B 的“怎么做”,并尽量让三者的操作方式看起来“统一”。
链上合约给每个 root 一个槽位:
rootName:GA_A / RegBan / MissionStatus_BrootValue:最新根version:单调递增updatedAt:时间戳updater:授权更新者(A/B/C)更新接口类似:
UpdateRoot(rootName, newRoot, newVersion, metaHash)newVersion = oldVersion + 1。验证方离线做的事就是:拿到链上最新 (root, version) 来验你给的 proof。
A 维护成员集合 S = {e1, e2, ...}(每个成员对应一个素数 e)。
累加器值(根):
GA = u^(∏ ei) mod N(或等价形式)发放/登记成员(Add)
e_newGA' = GA^(e_new) mod N(等价于把 e_new 乘进指数)(GA', version+1) 上链撤销成员(你现在选了 RegBanRoot,所以 GA 不需要删)
无人机向 B/C 给 π_e(成员资格证明),B/C 从链上取最新 GA_A_root 验证:
监管侧维护一个键值状态表:
k = H(pid_R)(监管统一 PID 的哈希做键)0=未封禁 / 1=封禁用 Sparse Merkle Tree(稀疏默克尔树) 计算根 RegBanRoot。
(SMT 的好处:同一个 proof 既能证明 value=1(在黑名单)也能证明 value=0(不在黑名单),非常适合离线验证。)
永久封禁(Ban)
pid_R 的 value 置为 1RegBanRoot'(RegBanRoot', version+1)解封(Unban,可选)
无人机向 C 出示:
pid_R(或其承诺形式)π_link:证明 pid_R 由其 linkSecret 派生且与 DeviceVC 绑定ProofBan:SMT 证明该 k=H(pid_R) 在最新 root 下对应 value=0C 离线取最新 RegBanRoot 验 ProofBan,不需要问任何人。
B 维护任务状态表:
k = H(missionId)(或 missionHash)0=有效/1=撤销/2=暂停/3=完成用 SMT 算根 MissionStatusRoot_B。
撤销任务(Revoke mission)
(MissionStatusRoot_B', version+1)任务变更/替换
MissionVC 里必须包含:
missionId(或 missionHash)statusRootHint/versionHint无人机进 C 时提交 MissionVC + ProofMissionStatus(SMT 证明该 missionId 的 value=0 仍有效)。
C 从链上取最新 MissionStatusRoot_B 验证即可。
如果你愿意,我可以下一步把这三类根各自的最小链上记录格式(合约里存哪些字段)和无人机需要携带的 proof(π_e / ProofBan / ProofMissionStatus)列成一个小表,你就能直接拿去画系统架构图和流程图。
这三个不能用相同的方式么
非常好的问题 👍
答案是:
可以用相同的方式。
而且从系统工程角度讲,统一成一种“状态树 + 根上链 + Merkle 证明”的模式是更干净、更容易实现的方案。
你现在之所以觉得它们不一样,是因为:
但从系统设计角度看,这三者本质都是:
链上存一个 root,链下维护一个集合/状态表,验证时给出 membership / non-membership 证明。
完全可以统一。
对每一种“可验证状态”,都定义为:
key -> value
然后:
原来你是:
GA_A_root + π_e(累加器成员证明)
你可以改成:
A 域维护成员状态表:
textkey = H(memberId) (memberId 可以是 e 或 pid_A) value = 1 表示有效成员
用 SMT 算出:
MemberRoot_A
上链:
MemberRoot_A + version
无人机提交:
C/B 从链上取 MemberRoot_A 验证即可。
完全相同模式:
textkey = H(pid_R) value = 1 表示被封禁
链上存:
RegBanRoot + version
验证:
同样结构:
textkey = H(missionId) value = 0 有效 value = 1 撤销
链上:
MissionStatusRoot_B + version
验证:
| 类型 | key | value | root |
|---|---|---|---|
| 成员 | memberId | 1=有效 | MemberRoot_A |
| 封禁 | pid_R | 1=封禁 | RegBanRoot |
| 任务 | missionId | 0/1 | MissionStatusRoot_B |
全部都是:
状态树 + 根上链 + Merkle 证明
因为累加器:
但在工程系统里:
如果你是写论文 + 需要工程合理性:
全部统一用 SMT
全部同一种结构
这样:
主链只需要:
textMemberRoot_A RegBanRoot MissionStatusRoot_B
每个:
{ root, version, updatedAt }
监管域 C 放行流程:
完全离线。
如果你愿意,我可以下一步帮你:
这样你整个系统就非常清爽了。