验证过程

开发者可以通过MAGIC ID SDK将MAGIC ID作为交易(Web3)或请求(Web2)的一部分进行集成:

  • 通过应用内选项或由第三方应用程序呈现的QR码触发验证过程。扫描QR码会打开应用程序。验证请求包含上下文、消息和目标。上下文唯一标识Sybil保护的范围(例如第三方应用程序、特定提案的投票等)。消息编码了与交易相关的特定于应用程序的业务逻辑。目标标识了索赔的接收方(即回调)。

  • 用户检查验证详情并决定是否使用MAGIC ID进行进一步操作。用户了解上下文是预期的内容以避免中间人攻击非常重要。

  • 为了生成ZKP,应用程序需要来自合约的最新Merkle包含证明。可以通过从合约获取树来以分散的方式完成,但对于十亿用户来说,这需要下载数十GB的数据,对于移动应用程序来说是不可行的。为了解决这个问题,开发了一个索引服务,代表应用程序检索最新的Merkle包含证明。

  • 为了使用该服务,应用程序提供其公钥,索引器回复一个包含证明。由于这允许索引器将请求者的IP地址与其公钥关联起来,这构成了对隐私的轻微侵犯。缓解这个问题的一种可能方法是通过匿名化网络使用这些服务。索引服务今天是注册序列基础设施的一部分,并且是开源的,任何人都可以运行自己的实例。

  • 现在,应用程序可以使用当前的Merkle根、上下文和消息作为公共输入来计算ZKP;使用nullifier哈希作为公共输出;使用私钥和Merkle包含证明作为私有输入。请注意,身份信息不是公共输入的一部分。证明有三个保证:1)私钥属于公钥,从而证明了密钥的所有权;2)包含证明正确地显示了公钥是由根标识的Merkle树的成员;3)nullifier正确地从上下文和私钥计算出来。然后,将证明发送给验证者。

  • 验证者dApp将接收到的证明转发给自己的智能合约或后端进行验证。当在Web2的情况下从后端进行验证时,后端通常会与链中继服务联系,因为需要使用链上数据验证证明输入。

  • 验证者合约确保上下文是正确的操作。如果未能这样做,将导致重放攻击,其中证明可以在不同的上下文中重复使用。然后,验证者将联系MAGIC ID合约以确保Merkle根和ZKP是正确的。如果根是当前根或最近的根,则根是有效的。允许稍微过时的根非常重要,这样树就可以在不使当前正在进行的交易无效的情况下进行更新。在纯追加的集合中,根原则上可以无限期地保持有效,但出于两个原因,这是不允许的:首先,随着树的增长,匿名集合也增长。通过强制每个人使用类似的最新根,可以最大程度地保护匿名性。其次,将来可能会实施密钥恢复、轮换和撤销,这将使追加的假设无效。

  • 此时,验证者确信一个有效的用户打算执行此特定操作。剩下的就是检查用户以前是否已经执行过此操作。为此,将证明中的nullifier与之前看到的nullifier进行比较。此比较在开发者端进行。如果nullifier是新的,则检查通过,并将nullifier添加到已经看到的集合中。

现在,验证者可以使用消息作为输入执行操作。他们可以有信心地这样做,因为启动是由已确认的人类完成的,该人以前在此上下文中没有执行过操作。

正如上述过程所示,存在相当多的复杂性。其中一些复杂性由钱包和MAGIC提供的服务和合约处理,但其中很大一部分将由第三方开发的验证者处理。为了使集成MAGIC ID变得简单和安全,开发了一个易于使用的SDK,其中包含示例项目和可重用的GUI组件,以及更低级别的库。从概念上讲,对于新开发人员来说,最困难的部分是nullifiers。这是创建匿名性的标准解决方案,但在密码学之外很少为人所知。Nullifiers提供了用户以前未执行过操作的证明。为了实现这一点,应用程序跟踪之前看到的nullifiers并拒绝重复项。重复项表示用户尝试两次执行相同的操作。Nullifiers被实现为私钥和上下文的密码伪随机函数(即哈希)。可以将Nullifiers视为上下文随机化的身份,每个用户每个上下文都会获得一个全新的身份。由于操作只能执行一次,这些身份之间不存在相关性,保持匿名性。可以想象设计中不拒绝重复项而以其他方式处理重复项的情况,例如限制为三次尝试或每个时期一次。但是,由于这种设计相关联了用户的操作,因此不建议这样做。可以通过使用不同的上下文(即为每个时期提供三个上下文或一个上下文)来实现相同的结果。

例如,假设目标是让所有人每天都能够索取一些代币。为此,部署了一个验证者合约,该合约还可以发送代币。作为上下文,使用验证者合约地址和舍入到月份的当前时间的组合。这样,每个用户每天都可以创建一个新的索取。作为消息,使用用户希望接收代币索取的地址。为了使其可扩展,它部署在以太坊L2上并使用了MAGIC ID状态桥接。

Last updated