前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >去中心化数字身份DID简介——四、用户属性的零知识证明

去中心化数字身份DID简介——四、用户属性的零知识证明

作者头像
深蓝studyzy
发布2022-09-19 15:45:30
1.1K0
发布2022-09-19 15:45:30
举报
文章被收录于专栏:深蓝居深蓝居

上一篇文章中,我们介绍了用户具有多个身份属性时,选择性的把其中的一个属性暴露出来,而不会造成其他信息的暴露。更进一步的情况,某些时候我们只需要验证用户的年龄达到多少岁,或者小于多少岁,但是并不关心用户的具体年龄和出生日期,比如在购买烟酒时,商家需要验证用户的年龄大于18岁。除了年龄,住址、民族等都可能会有对某个断言进行验证的情况。比如某旅游景点,对本市所有居民免费,所以居民只需要证明自己身份证上的住址在某市,而不需要暴露具体的居住地址。这些只给出证明的答案,而不暴露其他任何身份信息的情况,都是零知识证明的范畴。

传统的零知识证明算法很复杂,难以理解,也难以实现,而且就算实现了,也不能很好的满足我们数字身份中关于身份属性验证的问题,因为这里涉及到三方:发证方、持证方、验证方。在发证方将证件(可验证声明VC)发给持证方时,发证方并不知道持证方以后会遇到验证大于18岁,还是验证大于65岁,另外持证方在生成亮证(可验证表达VP)时,只需要持证方和验证方进行交互,不应该在此时引入发证方。所以我们可以认为:

1.生成VC和生成VP是两个独立的事件,生成VP时不应该有发证方参与。

2.验证方信任的是发证方,而不是持证方,所以持证方只是简单的证明自己大于18岁,但是这个证明没有发证方的背书,是不可信的。

基于以上条件,本文提出了一种身份证明的零知识证明方法,该方法将VC和VP独立,生成VP时发证方不需要参与,而且VP中给出的证明具有零知识性,而且有发证方背书。

0x0. Issuer:根据采样粒度与采样范围进行数据的断言构建

发证方Issuer要对某个属性做出证明,首先需要在该数据所在的作用域进行采样,采样包括采样的粒度和范围。以用户的生日属性为例,其作用范围虽然可以是历史上任意一天,但是我们考虑实际情况,可以将采样范围定义在1900-1-1到2020-1-1,然后是采样粒度的问题,如果我们以年为粒度,也就是说我们只关心用户出生的那个年份来确定年龄,如果我们以年月粒度,那么就可以根据具体出生在几月来确定年龄,最细的粒度就是到天。这里简单起见,我们就以年为采用粒度,这样我们就建立了一个从1900到2020的数组:

代码语言:javascript
复制
[1900,1901,1902,…,2019,2020]

然后我们还可以增加下区间”<1900”和上区间”>2020”两个元素,从而覆盖年份的所有取值范围。

我们有了年份采样的数组,接下来是根据用户的实际情况,为每个元素增加断言,这里我以当年用户是否已经出生为断言,所以我们的数组变为,以小明1985年出生为例:

<1900未出生, 1900未出生,1901未出生,1902未出生,…1984未出生,1985已出生,1986已出生,…,2019已出生,2020已出生,>2020已出生

有了这么一个断言数组,我们可以简化断言为更简洁一些的形式:

代码语言:javascript
复制
Min=1900,Max=2020,Step=1,OtherRange=Both,Assert=[0,0,0,0,……,0,1,1,1,…,1,1],Format=“{0}:{1}"

这里定义了数组的范围,采样粒度,边界处理,以及断言的结果。Format是定义了断言字符串的格式。

0x1. Issuer:断言默克尔树的构建

现在我们已经构建好了断言数组,接下来就只需要将断言数组作为默克尔树的叶子节点,并采用上一篇文章中说的加盐方法,防止哈希碰撞,从而构建一个加盐断言默克尔树。

0x2. Issuer:默克尔根签名,VC生成

这棵树构建好了,得到了默克尔根,发证方接下来使用自己的私钥对这个默克尔根进行签名,并将签名、默克尔树生成办法、随机种子等信息放到VC中,以供用户认证。以下是公安部门针对用户生成的身份证VC,并在其中包含了出生年份的断言。

代码语言:javascript
复制
{
  // VC内容所遵循的JSON-LD标准
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://studyzyexamples.com/identity/v1"
  ],
  // 本VC的唯一标识,也就是证书ID
  "id": "vc511112200001010015",
  // VC内容的格式
  "type": ["VerifiableCredential", "Identity"],
  // 本VC的发行人
  "issuer": "did:公安部门ID",
  // 本VC的发行时间
  "issuanceDate": "2010-07-01T19:73:24Z",
  // VC声明的具体内容
  "credentialSubject": {
    // 被声明的人的DID
    "id": "did:cid:511112200001010015",
    // 声明内容:姓名、性别、生日、民族、住址等
    "name":"小明",
    "gender":"男",
    "birthdate":"2000-01-01",
    "nation":"汉",
    "address":"A省B市C区D街道xxx号",
    //接下来是种子数、默克尔根、公安的签名
    "seed":"23523865082340324",
    "merkleRoot":"ea59a369466be42d1a4783f09ae0721a5a157d6dba9c4b053d407b5a4b9af145",
    "rootSignature":"3066022051757c2de7032a0c887c3fcef02ca3812fede7ca748254771b9513d8e266",
    "signer":"did:公安部门ID#keys-1"
    //接下来是对出生年份断言默克尔树的构建和签名
    "birthYearAssert":{
      "min":1900,
      "max":2020,
      "step":1,
      "otherRange":"Both",
      "assert":[0,0,0,0,0,0,......0,1,1,1,1,1.......1],
      "format":"{0}:{1}",
      "seed":"9013492332268116070",
      "merkleRoot":"806de4a868682738bb328a4801c09d88a93ce1301e3dbff08f5b0881be01fddb",
      "rootSignature":"3077022051757c2de7032a0c887c3fcef02ca3812fede7ca748254771b9513d8e255",
      "signer":"did:公安部门ID#keys-1"
    }
  },
  // 对本VC的证明
  "proof": {
    "creator": "did:公安部门ID#keys-1",
    "type": "Secp256k1",
    "signatureValue": "3044022051757c2de7032a0c887c3fcef02ca3812fede7ca748254771b9513d8e2bb"
  }
}

0x3. Verifier:生成断言请求

现在卖烟酒的商家Verifier要求顾客证明自己大于18岁,换句话说,以当前2020年来说,就是要证明18年前 2002年已经出生。所以商家需要顾客证明的断言是:

代码语言:javascript
复制
2002:1

商家将这个断言生成断言请求,并发送给顾客的数字身份APP中,比如商家可以把断言请求生成二维码,让所有顾客都扫码,生成VP。

0x4. Holder:生成零知识证明VP

现在顾客Holder已经得知了Verifier的断言请求,于是根据断言请求,找到该断言在断言默克尔树中的位置,并形成:断言内容、断言位置、默克尔验证路径、Salt、默克尔根、公安机关DID和签名的验证判断所需的全部元素,而这一切都是基于之前公安机关颁发给用户的VC生成的,并不需要联网,更不需要公安机关在本次验证过程中的参与。

代码语言:javascript
复制
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://studyzyexamples.com/identity/v1"
  ],
  "type": "VerifiablePresentation",
  // 本VP包含的VC的内容
  "verifiableCredential": [{
    "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://studyzyexamples.com/identity/v1"
  ],
  "id": "vc511112200001010015",
  "type": ["VerifiableCredential", "Identity"],
  "issuer": "did:公安部门ID",
  "issuanceDate": "2010-07-01T19:73:24Z",
  "credentialSubject": {
    "id": "did:cid:511112200001010015",
    //以下是断言的内容,意思是2002年已经出生
    "assert":"2002:1",
    //以下是验证披露字段有效性的数据
    //数据在默克尔树中的索引
    "dataIndex":103,
    //本数据加盐的值
    "salt":"5ff63326ca055a6dca267985c8ca03732b907b4197eb16a60c723bd567883650",
    //默克尔验证路径
    "merklesibling":"b6234c998b586914c76ccabd35c97be779074ea2ea7d03e81b25dc80547ee799 02a9c8c6a60eaab5765f526b4a1792f37e3b399cdab2a9492653dac432f2ccd3 5109396c42763abe94aa92acf11e9b2a034cdd1a63a4493ae0cce9fffb632f81 5bd2b306f156bdab383e352dc31c62cb2e18ada75957398fdd0c369ef3850d97 73af5df5f4c36d1377bd976a4b7be2b88878befd21b75962863d22299d3023a6 537ad98582a606ef422881bf766550bf22dbd8f06eb91d6ea59a57643f02c22a 4b590775b2fddd7fa7b6fe428e5ff83256dfbf6a15fa2c30b643a41785c245a0",
    //默克尔根哈希
    "merkleRoot":"806de4a868682738bb328a4801c09d88a93ce1301e3dbff08f5b0881be01fddb",
    //公安机关对默克尔根的签名
    "rootSignature":"3077022051757c2de7032a0c887c3fcef02ca3812fede7ca748254771b9513d8e255",
    //用的公安机关哪个Key进行的签名
    "signer":"did:公安部门ID#keys-1"
  },
  
  }],
  // Holder小明对本VP的签名信息
  "proof": {
    "type": "Secp256k1",
    "created": "2010-07-02T21:19:10Z",
    "proofPurpose": "authentication",
    "verificationMethod": "did:cid:511112200001010015#keys-1",
    // challenge和domain是为了防止重放攻击而设计的
    "challenge": "1f44d55f-f161-4938-a659-f8026467f126",
    "domain": "4jt78h47fh47",
    "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5
      XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqs
      LfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh
      4vGHSrQyHUGlcTwLtjPAnKb78"
  }
}

0x5. Verifier:验证VP

商家在收到顾客生成的VP后,可以直接通过签名验证默克尔根是否是公安机关签名的,然后通过默克尔验证来证明”2002:1“这个断言是正确的。具体验证的细节我在上一篇文章中已经讲过,这里也是一样的过程,就不再重复了。

0x6. 小结

本文提出的零知识证明方法基于范围数据构建和加盐默克尔树验证,对于无法定范围的场景,可能并不是很适用。比如对于姓名字段,我们可以拆分成姓和名,姓字段是有一个范围的,大概率都在百家姓里面 ,而名字段就太广泛了,基本上所有的汉字都可以作为名,而且名有多个字,排列组合的情况是天文数字,所以我们可以对姓字段建立零知识证明,而对于名字段无法使用。除了生日外,民族是一个可数的范围(56个民族+其他),住址的省、市、县都是一个可数的范围,我们都可以使用本文中的零知识证明方法。

本零知识证明还有个局限性,就是只能证明范围数据构建时的取值,而无法证明中间的取值。比如我们对家庭年收入字段建立范围取值,每10W一个值,所以默克尔树叶子节点就是:0,10W,20W,30W …...

比如小明的实际家庭年收入是38W,我们可以基于这个取值来证明家庭年收入大于30W,但是我们无法证明家庭年收入大于35W。如果想要证明,我们就需要将划分范围的粒度变细,比如变成每一个范围是1W,这样构建了一个新的长了很多的叶子节点列表0,1W,2W,3W…….如果我们将范围上限定在1000W,那么就需要1000个叶子节点,但是我们也只能证明年收入大于35W,无法证明更细的粒度,比如年收入是否达到38.5W?

基于前面几篇文章介绍的数字身份DID技术的基础知识,下一篇我们将介绍DID的应用场景。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-12-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x0. Issuer:根据采样粒度与采样范围进行数据的断言构建
  • 0x1. Issuer:断言默克尔树的构建
  • 0x2. Issuer:默克尔根签名,VC生成
  • 0x3. Verifier:生成断言请求
  • 0x4. Holder:生成零知识证明VP
  • 0x5. Verifier:验证VP
  • 0x6. 小结
相关产品与服务
分布式身份
腾讯云分布式身份TDID(Tencent Cloud Decentralized Identity)为可信数字身份和数据交换服务提供基础设施。TDID以区块链为底层,提供了一种分布式生成、持有和验证身份标识符 DIDs(Decentralized Identiflers) 和身份数据VCs(VerifableCredentials)的机制,使您能以加密安全、保护身份隐私的方式,在互联网上可信地表达和应用现实世界各种类型的身份。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档