编者注:关于 “trusted” 一词,常见的翻译是 “可信”,例如 “trusted third party” 翻成 “可信第三方”,“trusted setup” 翻译成 “可信初始化”。然而我以为,翻译成 “可信” 恰恰错失了这个词原本的意思,因为 “trusted” 一词表达的并不是一种价值判断(不是 “creditable”、不是 “reliable”、不是 “trustworthy”),而是一种事实判断,即协议的运行需要信任;作为一种修辞,它的作用是标记信任的锚点。举例而言,带有 trusted third party 的协议,意味着协议的安全性依赖于一些第三方,他们的作为会影响协议的安全性,用户在使用协议时也实质上信任了这些第三方不会违反协议。正因为如此,在翻译尼克·萨博的 《Trusted Third Parties are Security Holes》一文时,我就把 “trusted” 翻译成 “受信任的”。同样地,在这篇文章中,我们同样使用被动语态(或者名词形态)来翻译 “trusted”。
如果你没有做好准备,那就是准备失败。——《圣经世界》,1919
当你想要了解一个去中心化系统时,必须搞清楚的问题之一是:这个系统有要被信任的初始化阶段(trusted setup phase)么?
一个问题随之而来:比特币和以太坊有要被信任的初始化阶段么?
许多分布式计算和密码学协议都设计了一个初始化阶段。对于一个多阶段协议(multi-phase protocol)而言,被信任的初始化设置有其特殊性。我们称第一个阶段为初始化阶段(setup phase),第二个阶段为主阶段 (main phase)。通常有两个性质将初始化阶段与主阶段区分开来。
主阶段通常会执行许多重复的任务。而初始化阶段只需执行一次,就能开启重复运行许多实例的主阶段。
初始化阶段通常都是 输入无关的,也就是说,它根本不会使用来自各参与方的私有输入。此外,有时候初始化阶段甚至是 函数无关的,跟主阶段各参与方想要计算什么函数根本无关;这一阶段每个参与方都只知道自己想要计算某些函数。因此,我们通常将初始化阶段和主阶段分别称为离线阶段(或预处理阶段)和在线阶段(即,当各参与方意识到在未来的某个时间点他们可以基于尚且未知的输入运行某些函数时,就会愿意运行离线阶段。)
你可以将初始化阶段看作一个由完全可信的实体 T 运行的理想函数,理想到我们觉得无可挑剔。例如,假设公钥基础设施(PKI)的安全性就意味着:我们假设存在一个完全可信的实体(completely tursted entity),每个参与方都向该实体提交自己的公开加密(及验证)密钥,然后该实体会把这些公钥广播给所有的参与方。在本文中,我们将通过研究各种初始化假设所用的理想函数,来回顾一下信任初始化的常见类型。
可以这样来建模被信任的实体:存在一组初始的参与方 P1,...,Pn 和被信任的实体 T 交互。这些参与方可以发送输入 x1,...,xn 给 T(xi 代表 Pi 的输入),而 T 反过来运行一些函数 F(r,x1,...,xn )(其中 r 是一个均匀的随机字符串),产生输出 y1,...,yn ,并将 yi 发送给 Pi。这一过程可能是 “交互性” 的,也就是说它可能重复许多次。由于这是在描述一个理想中的世界,因为我们总是假设各参与方与受信任的实体之间的通信信道是安全的。
在下文中,我们认为绝大多数函数都属于以下五种类型之一:
没有设置(No setup):这是最简单的一种情况,我们实际上并不需要信任某些实体或某些初始化设置。最小通信假设是参与方可以访问某种类型的通信媒介。不过,没有设置很多时候也指代参与方的身份是全局知晓的这种设定。
成对设置(Pairwise setup):在这种设置下,我们假设存在一些初始的参与方 P1,...,Pn,并且每两个参与方之间都有可靠的通信信道。特别是,在最简单的成对设置假设中,当参与方 Pi 在通道(i,j)中收到一条消息时,它可以确认这条消息来自参与方 Pj 。
广播设置(Partially public setup):在这类设置中,我们假设不需要用到秘密(secret)。PKI 设置就是一个典型的例子,它只需要用广播来传递公钥。
部分公开设置(Partially public setup):经常被称为公共参考串(Common Reference String,CRS)模型。许多密码学协议都利用这一设置来提升效率。其中一个特殊的例子就是随机信标。
完全私有设置(Fully private setup):在安全多方计算(MPC)协议的语境中通常被称为 离线阶段。这一类型中的初始化阶段需要计算一个相当复杂的依赖各参与方的输出。在 SPDZ-2 中创建 OT 和 乘法三元组(multiplication triplets) 的阶段就是一个例子。
我们来详细介绍一下这五种设置的变体,举出一些案例并讨论其优缺点。最后,我们也会讨论一些初始化阶段的潜在替代方案。我们使用 n 来表示系统中的参与方数量,使用 f 来表示故障(或拜占庭)的参与方(或行为完全任意的人)数量。
1. 没有设置
当一个协议没有需要被信任的初始化设置时,也就没什么需要担心的了。这类协议比较容易取得我们的信任。但另一方面,它们也存在固有的局限性。
没有设置的环境有两种形式:1)假设参与方之间彼此一无所知,有时也被称为匿名通道模型,2)假设所有参与方的身份信息都是全局知晓的,这个假设在许多现实世界的应用中是完全可以接受的。但是,这两种方式都缺乏经过认证的信息通道,敌人可以随意地发起中间人攻击。
在传统的密码学中(敌手的资源是多项式有界的),这类模型的开创性研究是由 Dolev、Dwork 和 Naor 提出的,用于不可延展的加密算法(non-malleable encryption)和零知识等特定任务,后来被 Barak 等人 推广到了任意计算(后者假设了全局身份已知)。
匿名模型的另一个研究方向基于对敌手能力的更精确假设,也就是说,该假设限制了敌人和诚实参与方的计算能力(例如,哈希算力)比例。已有研究证明,在这样的模型中,从头开始构建一个有限的 PKI 模型是有可能的。案例可以参见 Aspnes, Jackson 和 Krishnamurthy ,以及少数直接受到比特币类型谜题启发的方法(参见 Katz、Miller 和 Shi、Andrychowicz 和 Dziembowski,以及 Garay、Kiayias、Kiayias 和 Panagiotakos)。
2. 成对设置
在成对设置中,我们假设每一对参与方之间的通信信道是经过认证的。这是分布式密码学和分布式计算中的经典假设。Fisher、Lynch 和 Merritt 在 1985 年研究了在这种设置下,参与者数量相对于敌手数量的下界:当 n <= 3f 时,即便使用了这种设置,即便敌手的资源假设是传统的多项式有界假设,也不可能达成哪怕是弱形式的拜占庭共识。
而另一方面,当 n > 3f 时,成对设置可以完美实现任何函数。这是 Ben-Or、Goldwasser 和 Widgerson 在 1988 年发表的著名研究成果,详细的证明请看 Asharov 和 Lindell 。
3. 广播设置
广播意味着即便可信实体是 “透明的”,也就是说,该实体所 接收/发送 的所有 输入/输出 以及它的随机字符串都是公开的,系统的安全性也不会受到损害。典型的例子就是那些使用一个被信任的实体来广播所有参与方公钥的协议。
使用 PKI 既可以提高异步拜占庭协议的复杂性(案例参见 Cachin、Kursawe 和 Shoup),也可以将同步拜占庭协议的容错能力提升至 n = 2f + 1(案例参见 Katz 和 Koo)。
请注意,此处存在循环论证的风险:有了 PKI 设置,就可以分别在 n=2f+1 时实现同步模型中的拜占庭共识,还能在 n = f+1 时实现拜占庭广播(参见 Dolev 和 Strong)。但如果没有 PKI 设置(标准模型),那么初始化 PKI 的广播环境需满足 n > 3f。
优点:完全公开设置的一个重要优点就是它相对简单,并且可以减少受攻击面。
风险:这类设置的失败通常会导致模棱两可。给不同的参与方提供不同的密钥可能会导致未来的协议失败。
4. 部分公开设置
部分公开意味着来自受信任实体 T 的输出对所有参与方都公开,然而可能要求参与方的输入 x1,...,xn 和 T 的随机字符串 r 应当保密。例如,设想一个持续接受用户消息、并需要在未来那么某个时间 t 将所有消息一次性全部显示出来的系统。这样一个系统可以使用如下初始化设置:函数 F 不接收任何来自参与方的输入,并执行如下操作:生成用于加密机制的密钥对(sk,pk),然后生成一个 Rivest、Shamir 和 Wagner 时间锁谜题 p,用于在到达时间 t 之前隐藏 sk;最后,向各参与方输出谜题 p 和加密密钥 pk,从而结束初始化阶段。在主阶段,用户可以使用 pk 加密他们的消息并广播。此外,他们开始解决谜题以在时间 t 内获得解密密钥 sk,从而解密所有消息。请注意函数 F 的所有输出都是对参与方公开的,但这个被信任的实体的内部状态(也就是说,用于生成密钥对(sk,pk)的随机字符串)必须保密。
信任一个带有秘密值的预计算流程通常效益显著。此类设置的风险是,系统的属性现在依赖于初始化阶段的隐私性。而在初始化过程中想要检测信息泄漏事件是非常困难的(在执行初始化设置过程中获得机密信息的攻击者可以不让他人获知自己获得了机密信息)。
要求初始化过程公开一个公共值的好处是更容易确保这一属性(比起向各参与方发送私有值而言)。这一模型通常被称为公共参考串(Common Reference String,CRS)模型。这里我们举两个例子:
针对高效可验证秘密共享(Secret Sharing)的设置 —— Kate、Zaverucha 和 Goldberg 提出了一种机制,该机制要求一个信任初始化阶段来生成一个随机的公开生成器 g 和一个私钥 α。然后,初始化阶段以 g(ai) 的形式广播幂。使用这一设置,可以获得最高效的异步可验证秘密共享机制。
针对高效零知识证明的设置 —— 少数高效的零知识协议要求 CRS 设置。要让这种初始化过程值得被信任,通常需要一些难度较大(non-trivial)的 MPC 协议。比如,参见 Bowe、Gabizon 和 Miers。实际上,仅仅运行一个 MPC 协议是远远不够的,通常来说,必须进行一个完整的初始化仪式才能建立公开的可验证性。
5. 完全私有设置
这是最通用的一种初始化形式,即便是函数发送给各参与方的输出也是彼此保密的。显然,该设置最大的优点就是允许在它们之上运行强大的协议。此类初始化的实例化(或实现)相当复杂,并且面临更大的受攻击面。
我们在这里集中讨论两种实例:分布式密钥生成和安全多方计算的离线阶段。
分布式密钥生成和门限签名设置
门限签名机制通常在降低词语复杂度(word complexity)和减少总计算开销(案例参见此处)上表现突出。而门限签名的问题在于该机制要求有个初始化过程,通常被称为分布式密钥生成(DKG)初始化。
DKG 函数只从每个参与方那里接收随机的比特,生成一个密钥对(sk,pk),然后输出 pk 给所有人并单独分享 sk 给每个参与方,使得参与方 Pi 收到 ski,sk 在每个参与方之间必须保密。
风险:在这一初始化过程中,有两个地方可能会失败。一是当共谋者数量达到门限值时秘密将会泄漏,二是某些参与方可能会收到错误的 sk。参与方有多种方式来验证其收到的 sk 的有效性,因此主要的风险发生在参与方掉线时。
安全计算的可信设置
安全多方计算协议允许一组数量为 n 的参与方 P1,...,Pn 基于他们私有输入 x1,...,xn 去计算一个(布尔或算术)电路 C,然后只显示输出 y = C(x1,...,xn )(假设所有的参与方都应该得到相同的输出)。例如,电路 C 可以计算所有输入之和。
最新的 MPC 协议都被设计成 离线-在线 两阶段运作,其中离线是用于初始化阶段的,通常是完全保密的。一个常见的例子就是向各参与方共享乘法三元组(也叫,Beaver 三元组)的信任初始化阶段。具体来说,该初始化过程随机将 ai 、bi 和 ci 发给参与方 Pi,且 (a1 +…+ an )·(b1 +…+ bn) = (c1 +…+ cn )。然后,在协议的主阶段(也叫在线阶段),参与方分享他们的输入,也就是说,参与方 Pi 通过向 Pj 发送 x'j 使得 x'1 +...+ x'n = x' 来分享他的输入 x'。现在,各个参与方都可根据被共享的数值进行任何算术运算,也就是说,给定一个共享的秘密值 x 和 y,如果参与方 Pi 持有 xi 和 yi 使得 x1 +...+ xn = x 且 y1 +...+ yn = y,那么各参与方可以执行以下流程(我们在以下描述中省略了一些细节) :
开始 —— 给定一组共享的 x1,...,xn ,使得每个参与方都可以获得 x = x1 +...+ xn。
加法/减法 —— 各参与方 Pi 通过在本地计算 zi = xi + yi ,可以计算出一个共享的 z = x + y。因为这遵循 z1 +...+ zn =(x1 +...+ xn )+(y1 +...+ yn)。
缩放 —— 给定一个所有参与方都知晓的值 c,他们就可以通过每个参与方在本地计算 zi = cxi 来计算一个共享的 z = cx。同样的,它也遵循 z1 +...+ zn =(cx1 +...+ cxn )= c(x1 +...+ xn )= cx。
乘法 —— 各参与方通过放弃来自初始化阶段的单个乘法三元组可以计算出一个共享的 z = xy。简单起见,我们用 [x] 来表示(x1 +...+ xn )。参与方都拥有共享的 [x]、[y] 和来自初始化阶段的三元组 [a]、[b]、[c](别忘了c = ab)。各参与方分别计算 [s] = [x] - [a] 和 [t] = [y] - [b]。由于 a 和 b 的值是由初始化设置统一选择的,因此 s 和 t 的值也是统一的,所以该过程不会泄漏任何关于 x 和 y 的信息。然后,这些参与方计算 [xy] = s[y] + t[x] + st − [c]。此过程仅包括缩放和加/减法计算,因此可以由每个参与方在本地计算来获得共享的 [z] = [xy]。
风险和优势:如上所述,这样一个初始化阶段的受攻击面极大。初始化阶段的输出必须保密,也就是说,在上面的乘法过程中,要注意如果一些持有 t 的参与方结盟,获得了所有参与方共享的 a1,…,an,那么他们就可以通过计算 [x] = [s] - [a] 算出秘密值 x。请注意,在此类初始化阶段中并不是只要做好保密就万事大吉了,我们还必须确保三元组都是正确的,也就是说,ab 必须等于 c,否则计算的输出就会出错。保护三元组不被泄漏以及不受到恶意参与方的影响是一项艰巨的任务,因此会给 MPC 协议带来巨大的成本。另一方面,由于初始化阶段已经输出了乘法三元组,因此协议的主阶段将变得非常快。
存在对被信任的初始化阶段的替代方案么?
在最后,我们提及几种潜在的替代方案:
(信任初始化等于是)一次性将大量的信任从系统中的在线阶段转移到了某个历史性的离线阶段。这引入了新的风险和安全漏洞。一种潜在的替代方案是使用一个永不停歇的初始化阶段。在此类机制中,存在一种不断可更新的 CRS。最近的一个案例是 SONIC。
另一种方案是使用多次初始化来生成多个公共参考串。在这种方案中,我们只假设一部分设置是忠实完成的。参见 Groth and Ostrovsky。