加密货币交易所偿付能力的零知识证明

2023-09-20 12:02:54

如何检测下一个 FTX 和 Mt. Gox

加密货币交易所 FTX 的内爆导致数十亿客户资金流失,这是加密货币历史上交易所破产的最新例子。历史可以追溯到 2014 年,当时处理 70% 比特币交易的历史最悠久、规模最大的交易所 Mt. Gox 丢失了用户的 850,000 个比特币。

如今,许多用户更喜欢将他们的加密货币资产存储在集中式交易所中,以便于使用,类似于网上银行,以避免自己管理加密密钥的困难和风险。

不幸的是,将资产存储在交易所会使用户面临因外部或内部盗窃而在交易所丢失资产的风险。

我们展示了一种交易所以加密方式证明偿付能力的方法,这意味着它的资产覆盖了它的负债。该证明不披露任何私人信息,包括其客户、其控制的地址和总负债。所提出的方法可以附加受信任的审计,这可能是昂贵的,或者是独立应用的。

原始的方法

交易所证明其偿付能力的一种基本方法是公开披露所有用户负债及其控制的所有比特币地址的。任何一方都可以计算其总负债和资产,从而检查其是否具有完全偿付能力。

每个用户都可以独立验证他是否在负债数据集中。如果遗漏任何用户,则可以发现交易所作弊。

交易所可以通过数字签名或将余额转移到新地址来证明其拥有任何地址的私钥。

这种完全透明的方法显然是有问题的,因为它会泄露有关交易所及其用户的商业敏感信息。我们需要一种保护隐私的替代方案。

密码学基础

佩德森 (Pedersen) 承诺

Pedersen 对消息 x 的承诺定义为:

GH 是椭圆曲线的独立生成元。 r 是一个随机值,称为致盲因子。

与基于哈希的承诺(例如 SHA256)相比,Pedersen 承诺是 加法同态 的。这意味着在不知道 xy 这两个值的情况下,可以将它们相应的承诺相加以计算其总和的承诺。

零知识范围证明 (ZKRP)

ZKRP 是一种特殊类型的零知识证明,它显示一个数字在一定范围内,而不公开数字。Bulletproof 是一种高效的 ZKRP 结构。

资产证明

在资产证明(又名储备证明)中,交易所充当其总资产的证明者,任何一方都可以扮演验证者的角色。

为防止交易所隐私数据泄露,采取了以下措施。

  1. 更多的匿名地址被添加到完整的资产集中,交易所不知道其私钥。这混淆了交易所拥有的地址集。

  1. 诸如 zk-SNARK 之类的 ZKP 用于为每个地址证明以下陈述:

“要么我知道地址对应的私钥,承诺就是地址的余额

或者

我不知道私钥,承诺的值为 0。”

  1. 由于其同态性质,总资产余额可以通过对步骤 2 中证明的所有个人 Pedersen 承诺求和来获得。请注意,未披露专有且敏感的总资产,仅披露其 Pedersen 承诺。

最终结果是 Pedersen 对总资产 commit(assets) 的承诺,即交易所知道全套比特币地址子集的私钥。

负债证明

接下来,交易所证明它欠所有客户的硬币总数。每个客户都确认自己被包括在内。

求和默克尔树

为此,交易所将所有用户组织成 Merkle 树的变体。每片叶子代表一个用户和她的余额。与规范的 Merkle 树相比,求和 Merkle 树进行了两个修改。

  1. 除了散列之外,每个节点中还添加了一个余额字段。节点的余额是其两个子节点的总和。
  2. 使用 Pedersen 承诺代替 SHA256 等哈希。

树的根包含总负债的承诺。交易所签署根并将其发布在例如比特币上。每个客户都可以根据已发布的根请求包含他们的 Merkle 证明。如果有足够数量的客户独立验证,则大概率可以抓到作弊交易所。

范围证明

不诚实的交易所可以通过包含负余额的假用户来欺骗,从而减少他们的总负债。为了防止这种攻击,交易所还提供了一个 ZKRP,叶节点的每个客户都有一个非负余额,但没有透露余额本身。请注意,交易所没有动力添加具有正余额的虚假用户,因为这会增加他们的负债。

偿付能力证明

一旦交易所完成资产和负债证明,我们就可以计算其余额的承诺。

commit(balance) = commit(assets) — commit(liabilities)

交易所有两种方式来证明余额是非负的,即交易所是有偿付能力的。

  1. 直接打开承诺。
  2. 给定承诺,使用 ZKP 证明余额是非负的。

讨论

我们的偿付能力证明只是交易所提高透明度和提高客户信心的初步步骤。要在实践中采用它还有许多其他措施,交易所会定期发布证明。

例如,一群资不抵债的交易所可以串通一气,通过用它们的集体资产来覆盖每个交易所的个人负债。从本质上讲,没有什么能阻止单个比特币地址的资产被用于各种交易所的偿付能力证明。为了对抗这种攻击,交易所的资产证明需要额外证明其使用的地址集与另一个交易所的地址集不相交。

参考

[1] 为比特币交易所提供隐私保护的偿付能力证明 Real World Crypto 2016:幻灯片

[2] 基于 ZK-SNARK 的比特币交易所资产证明协议

更多推荐

Spring Boot 如何配置 Hikari 数据库连接池

目录一、SpringBoot介绍二、什么是数据库连接池三、Hikari介绍四、配置Hikari一、SpringBoot介绍SpringBoot是一个开源的Java框架,它简化了基于Spring的应用程序的开发和部署。它提供了一种快速、方便的方式来创建独立的、可扩展的、生产级别的Spring应用程序。SpringBoot

Matlab--微积分问题的计算机求解

目录1.单变量函数的极限问题1.1.公式例子1.2.对应例题12.多变量函数的极限问题3.函数导数的解析解4.多元函数的偏导数5.Jacobian函数6.Hessian矩阵7.隐函数的偏导8.不定积分问题的求解9.定积分的求解问题10.多重积分的问题求解1.单变量函数的极限问题1.1.公式例子%%%3.1.1.单变量函

Springboot 实践(21)服务熔断机制

在微服务架构中,服务众多,通常会涉及到多个服务层的调用,一旦基础服务发生故障,很可能会导致级联故障,继而造成整个系统不可用,这种现象被称为服务雪崩效应。服务熔断引入熔断器概念,熔断器如果在一段时间内侦测到许多类似错误,就会强迫其以后的多个调用快速失败,不在访问远程服务器,从而防止应用程序不断地尝试执行可能会失败的操作,

sed & awk使用简介

简介本文主要介绍Linux系统的两个神级工具:sed和awk,他们是Linux高手们必备的技能,很值得我们去研究的东西。这里是我在网上书上收集的相关资料,因为这两个工具很有名也很重要,所以这些资料会帮助我更好的了解和熟悉它们。什么是sed在《sedandawk》一书中(1.2AStreamEditor)的解释是:Sed

Text-to-SQL小白入门(六)Awesome-Text2SQL项目介绍

项目介绍项目地址GitHub地址:GitHub-eosphoros-ai/Awesome-Text2SQL:CuratedtutorialsandresourcesforLargeLanguageModels,Text2SQL,andmore.项目首页欢迎大家围观参与、使用、贡献。项目理念这个项目主要收集了针对大型语言

vite和webpack的区别

vite和webpack的区别1、前言2、Webpack2.1Webpack简述2.2Webpack常用插件3、Vite3.1Vite简述3.2Vite插件推荐4、区别4.1开发模式不同4.2打包效率不同4.3插件生态不同4.4配置复杂度不同4.5热更新机制不同5、总结1、前言Webpack和Vite是现代前端开发中非

笔记1.5:计算机网络体系结构

从功能上描述计算机网络结构分层结构每层遵循某个网络协议完成本层功能1.基本概念实体:表示任何可发送或接收信息的硬件或软件进程。协议是控制两个对等实体进行通信的规则的集合,协议是水平的。任一层实体需要使用下层服务,遵循本层协议,实现本层功能,向上层提供服务,服务是垂直的。下一层协议的实现对上层的服务用户是透明的同系统的相

Mysql 数据库基础介绍

Mysql数据库基础介绍一、数据库介绍1.1、数据库的发展史1.1.1、文件管理系统的缺点1.1.2、数据库系统发展阶段1.3、DBMS数据库管理系统1.4、数据库管理系统的优点1.5、数据库管理系统的基本功能1.6、数据库系统的架构1.7、各种数据库管理系统1.7.1、层次数据库1.7.2、网状数据库1.7.3、RD

TCP/IP协议栈各层涉及到的协议

21/tcpFTP文件传输协议22/tcpSSH安全登录、文件传送(SCP)和端口重定向23/tcpTelnet远程连接80/tcpHTTP443/tcpHTTPS计算机各层网络协议五层:应用层:(典型设备:应用程序,如FTP,SMTP,HTTP)DHCP(DynamicHostConfigurationProtoco

动态规划问题

看一遍就理解:动态规划详解-什么样的问题可以考虑使用动态规划解决呢?如果一个问题,可以把所有可能的答案穷举出来,并且穷举出来后,发现存在重叠子问题,就可以考虑使用动态规划。比如一些求最值的场景,如最长递增子序列、最小编辑距离、背包问题、凑零钱问题等等,都是动态规划的经典应用场景。-动态规划的解题思路动态规划的核心思想就

面试:C++ 11 智能指针

查询内存泄露方法啥是内存泄露内存泄露在维基百科中的解释如下:在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。在C++中出现内存泄露的主要原因就是程

热文推荐