针对SPHINCS的嫁接树故障攻击

嫁接树:针对SPHINCS框架的故障攻击

摘要

由于基于哈希的签名除了要求哈希函数的抗原像性或抗碰撞性外无需任何假设,因此它们是一类独特且极具吸引力的后量子原语。其中,sphincs家族的方案可以说是目前最实用的无状态方案,并可在现场可编程门阵列或智能卡等嵌入式设备上实现。这自然引发了人们对其抵抗实现攻击能力的关注。

在本文中,我们提出了首个针对sphincs、gravity-sphincs和sphincs+底层框架的故障攻击。我们的攻击只需一次故障消息即可伪造任意消息签名。此外,该故障模型非常合理,且故障后的签名仍保持有效,这使得我们的攻击既隐蔽又实用。由于攻击涉及不可忽略的计算成本,我们提出了一种细粒度的权衡方法,通过略微增加故障消息数量来降低计算成本。我们的攻击具有通用性,不依赖于所使用的底层哈希函数。

1 引言

基于哈希的签名仅依赖于寻找哈希函数碰撞或(第二)原像的困难性来保证其安全性,而无需任何额外假设。这一显著特性使其即使在其他后量子方案中也脱颖而出。从严格的安全性假设角度来看,几乎无法期望有更好的方案,因为Rompel[Rom90]已经证明,当且仅当单向函数存在时,安全的签名才存在,而Song[Son14]已将该结果扩展到量子对手。此外,基于哈希的签名易于分析,且其安全性不依赖于底层原语的选择。

自从兰波特[Lam79]提出首个基于哈希的签名方案——该方案只能对一条消息进行签名——以来,人们提出了多种构造方法以提高其效率。这些方法可分为两类:有状态和无状态构造。默克尔[Mer90]提出的有状态签名限制了签名者需要维护其已使用密钥的记录。这种要求可能会产生操作问题,特别是在多个服务器使用同一密钥时。无状态签名(由Goldreich[Gol86]提出)消除了这一要求,但代价是签名时间和签名大小大幅增加。

直到最近才提出了实用的无状态构造。2015年,Bernstein等[BHH+15]提出sphincs,一种基于哈希的签名方案,通过结合Goldreich和默克尔的构造,并使用少量次签名方案,实现了无状态性以及合理的效率(在运行时间和签名大小方面)。2017年,向美国国家标准与技术研究院(NIST)后量子密码方案征集提交了sphincs的两种变体[NIS16]:Aumasson和Endignoux提出的gravity-sphincs[AE17b],以及Bernstein等提出的sphincs+[BDE+17]。

哈希函数可以在资源受限的设备上高效实现,因此已提出多个在微控制器上的基于哈希的签名实现[RED+08,HBB12],包括一种ARM实现[HRS16]的sphincs。然而,嵌入式设备众所周知容易受到物理攻击,例如侧信道分析或故障攻击。

自从Boneh等人[BDL97]的开创性文章发表以来,故障攻击已被证明是针对嵌入式设备最强大的密码分析手段。在故障攻击中,我们假设攻击者足够强大,能够在算法执行期间破坏其内部状态。尽管这假设了攻击者具有相当强的能力,但这些条件在现实生活中通常可以实现,并且往往导致毁灭性的攻击。

然而,据我们所知,目前尚未公开提出针对基于哈希的签名的故障攻击。

1.1 我们的贡献

从高层次来看,sphincs框架(在本文中,这一概念涵盖原始的sphincs方案以及gravity-sphincs和sphincs+)通过在树形数据结构内结合哈希树和多个一次性签名方案(OTS),实现了一种无状态签名方案。我们提出了首个针对sphincs框架的故障注入攻击。该攻击分为两个步骤:故障注入部分和嫁接部分。

  1. 故障步骤 。对同一消息查询两个签名。在第二次签名计算过程中,引发一个故障,使得sphincs框架内的某个一次性签名方案最终签署的值与第一次不同。通常情况下,一次性签名密钥仅用于签署单个值,但我们的故障攻击迫使其执行其他操作。
  2. 嫁接步骤 。我们证明,可以利用这两个签名——正确的签名和被故障影响的签名——来恢复受到故障影响的一次性签名方案的部分私钥,从而部分攻破该方案。随后,攻击者将利用这个被攻破的一次性签名方案来认证一棵不同于其本应认证的树。

然后,攻击者生成一棵完全由其控制的树,并利用被攻破的一次性签名方案将该树嫁接到sphincs树上,这正是我们将此步骤称为嫁接步骤的原因。嫁接树由攻击者选择,且独立于私钥,同时允许为某些消息生成有效签名。

我们证明,这足以使攻击者具备通用伪造能力,并解释了她如何实现这一目标。该攻击对攻击者所需的资源很少——使其具有实用性——并且能够产生有效签名,从而使其尤为隐蔽。

尽管每次伪造攻击都伴随着不可忽略的计算成本,但我们提出了权衡方案,通过略微增加攻击者可获得的故障签名数量来降低该成本。我们的攻击具有通用性,因为它针对的是sphincs框架:无论使用何种底层哈希函数,攻击均能成功,并且对原始的sphincs、gravity-sphincs或sphincs+的具体特性无依赖。

1.2 路线图

首先,我们将介绍与树相关的概念。在第2节中,我们将简要概述基于哈希的签名构造。然后在第3节中描述我们的攻击。嫁接步骤将先于故障步骤进行介绍,因为它仅需要同一一次性签名生成的两个签名,并且不关心这些签名是否通过故障攻击获得。随后我们将在第3.4节讨论对策。第4节将总结本文并提出一些开放性问题。

1.3 相关工作

我们的嫁接技术依赖并扩展了Bruinderink和Hülsing [GBH16]关于一次性签名在双消息攻击下的安全性的研究成果。

由于后量子密码方案相对较新,其抵抗故障攻击的能力直到最近才被研究。针对基于格的方案,已有大量攻击被研究,详见[BBK16],文献[EFGT16]中还展示了一种循环中止攻击。对于基于超奇异同源的方案,文献[BG15、Ti17、GW17]研究了循环中止攻击和点解压缩攻击。虽然目前我们尚未知晓任何针对基于哈希的签名的故障攻击,但相关对策已在[MKAA16]中进行了研究。

哈希函数在其密钥操作模式上已成为故障攻击的目标。特别是Hemme和Hoffmann[HH11]提出了一种差分故障分析方法,使攻击者能够通过大约1000个发生故障的哈希值恢复SHA-1实例的内部状态,其中故障针对计算过程中的特定变量。在2015[BGS15]中提出了一种针对SHA-3的类似攻击。该攻击通过对80条消息引入随机单比特故障来恢复大部分SHA-3内部状态。相比之下,我们的攻击仅需一次故障,且攻击者成功所需的精度非常低。

2 预备知识

2.1 符号与约定

我们用λ表示签名方案的安全参数。H:{0, 1}∗ →{0, 1}λ表示一个密码学哈希函数。我们将用粗体小写字母表示向量。当我们考虑对向量v的值进行故障攻击时,用v′表示v的故障值。

2.2 树形符号

我们回顾与树相关的概念。假设(平衡)二叉树、父节点、子节点、兄弟节点、根、叶节点和内部节点的定义是已知的。

我们用&f表示叶节点f的地址。树的高度是从根到任意节点的最长路径的长度。如果两个节点到根的距离相同,则称它们处于相同的高度(相应地,同一层,或同一级)。

在本文中,我们还涉及超树,即其节点本身也是树的树。超树的高度是每一层中最大高度的和。为了避免超树与节点树之间的混淆,我们将超树的结构称为层,而将节点树的结构称为层级。

例如,图3展示了一个sphincs超树的简化版本。该示例具有2层高度2,因此其总高度为4。sphincs-256具有12层高度5,因此其总高度为60。

2.3 签名方案的安全性模型

我们简要回顾一下签名方案的一些经典安全性概念。

定义21。存在性伪造 ——如果存在一个消息m,使得对手能够提供一个有效的(消息,签名)对(m, σ∗),其中σ∗并非由合法签名者生成,则该对手能够进行存在性伪造。

定义22. 通用伪造 –如果对手能够对任意消息m生成有效签名σ∗,则称其具有通用伪造能力。

任何能够实现通用伪造的攻击者都能够实现存在性伪造。关于更形式化表示,我们建议读者参考例如[GBH16]。

2.4 基于哈希的签名

基于哈希的签名源于一个非常简单的思想:公钥是私钥的承诺,而消息的签名则包含揭示部分信息,验证者可据此重新计算出该承诺。

一种构建基于哈希的一次性签名(OTS)的简单方法可定义如下。给定一个哈希函数H,设私钥为S=(S1, S2),消息空间为{0, M −1},其中M为整数。公钥为

P=(P1, P2)=(HM(S1), HM(S2)).

消息m的签名∈{0, M −1}是

σ=(σ1, σ2)=(Hm(S1), H M−m(S2)).

验证者只需检查

(σM−m 1 , σ2m)=(P1, P2).

如果H具有抗原像性,则该方案是一次性的。然而,它不是两次安全的,因为一旦获得消息m1<m2的签名,就可以计算任意m1<m3<m2的签名,从而破坏存在不可伪造性。

我们提醒读者注意,在我们提出的方案中,公钥可以从任何有效签名中计算得出。这是基于哈希的签名中的一个常见特征,也是本文所考虑的所有方案实际上都会具备的特点。由于这一特性,只要能够验证其真实性,就不需要事先拥有公钥。

这使得可以通过计算签名树,从一次性签名构建出可多次使用的签名方案。

在本节的其余部分,我们将介绍一种一次性签名(OTS)、两种少量次签名(FTS)以及两种多次签名,其中一种是有状态的,另一种是无状态的。

2.4.1 一种一次性签名:WOTS

wots是一种一次签名,其原理由默克尔[Mer90]基于温特尼茨的思想提出。它由三个值进行参数化:
– w:wots使用的字的大小
– 1:待签名消息中大小为w的字的固定数量
– 2:签名算法中使用的奇偶校验值中大小为w的字的固定数量

设= 1+ 2为签名中大小为w的固定字数。现在我们可以详细说明wots。

密钥生成()
1. 设私钥sk为=(si)i=1,…,,其中si是均匀随机的w位字;
2. 对于1 ≤ i ≤ , pi ← Hw−1(si);
3. 公钥:pk ←(p1,…, p),私钥:sk。

Sign(m,私钥)
1. 将m表示为w进制:m=(m1m2 … m1)w;
2. 计算校验值C ←∑ (w −1 −mi);
3. 将C表示为w进制:C=(C1 C2 … C2)w
4. b=(b1, b2,…, b) ←(m1,…,m1, C1,…, C2)——我们之后将其称为m的b-向量;
5. 对于1 ≤ i ≤ , σi ← Hbi(si);
6. 签名: σ ←(σ1,…, σ)。

验证(m, σ,公钥)
1. 按照签名算法中的步骤计算消息m的b-向量(步骤1–4);
2. 当且仅当∀i ∈ {1, }, pi= Hw−1−bi(σi)时接受。

备注1. gravity-sphincs实现了上述描述的无掩码版本wots,但sphincs(+)将wots替换为一种变体wots+,该变体使用随机掩码以将抗碰撞性替换为第二抗原像性。由于我们的攻击对掩码的存在与否无动于衷,因此我们仅针对无掩码方案(wots)提出攻击,以便简化说明。

参数: 实际上,sphincs-256(它是sphincs中提出的[BHH+15]的实际实例化),gravity-sphincs并且sphincs+设置:
⎧ ⎨
⎩ 1= 64, 2= 3, w= 16.

这些参数在大小和速度之间提供了良好的权衡,通常在最新的构造中被选择。

在[GBH16的第5]节中,作者研究了(除其他场景外)抵抗存在性伪造的双随机消息攻击的能力。他们认为,在已知两条随机消息m1和m2的签名的情况下,伪造另一条随机消息m3签名的概率大致等于:对于所有0 ≤ i< ,,消息m3的b-向量的第i个坐标小于消息m1或m2的b-向量的第i个坐标的概率。

我们将在第3.1节看到,这种对wots的存在性伪造可以扩展为对sphincs框架的通用伪造。

2.4.2 FTS

为了将一次性签名(OTS)构造扩展为FTS签名方案,可以生成多个OTS,使用认证树链接公钥,并将该树的根作为公钥。签名者在签名消息时,只需选择生成的一次性签名子集,并使用每个一次性签名对消息进行签名。验证者仅需从签名中恢复各个公钥,并检查该公钥是否等于与公钥及其对应的认证路径相关联的认证值。

基于sphincs框架的三种算法使用了不同的FTS。在我们攻击的背景下,只需牢记两点:
– 就像wots一样,FTS系统完全是确定性的;
– 在每个这些FTS系统中,公钥可以从有效签名直接计算得出。

2.4.3 一种有状态构造:默克尔方案

默克尔的方案[Mer90]基于哈希树,这些哈希树是(通常为平衡的)二叉树,其中每个内部节点定义为其两个连接后的子节点的哈希值。在默克尔的构造中,哈希树的每个叶节点都是一次性公钥:这样的哈希树被称为Merkle树。默克尔方案的公钥是Merkle树的根,而私钥则是与一次性公钥配对的所有一次性私钥的集合。

对于Merkle树的一个叶节点f,我们用A(f)表示并称之为f的认证路径,即(除根节点外,每层一个节点)的一组唯一节点,使得Merkle树的根可以从f和A(f)重新计算得出。

要签名消息,签名者在Merkle树的一个叶节点中选择一个未使用的OTS密钥对(ski,pki):他使用ski对消息m进行签名,并将签名连同pki及其认证路径A(pki)一并发送。接收者验证:(1)使用OTS对该消息的签名是有效的;(2)可以从pki和A(pki)重新计算出总公钥(即Merkle树的根)。

该方案有两个主要缺点。首先,由于每次签名时都必须存储或重新计算整棵树,因此签名时间(或内存需求)随树高呈指数级增长。1其次,签名者必须跟踪已使用的OTS密钥对,这使得该方案为有状态的。

2.4.4 一种无状态构造:Goldreich的签名

Goldreich的提议[Gol86]解决了上述两个问题:它仍然基于一棵二叉树,其叶节点为一次性公钥,但内部节点现在是一次性密钥对。树中的每个节点都由一个比特串唯一索引,该比特串与作为整体私钥一部分的种子一起,用于伪随机生成该节点的密钥对。

该方案的公钥是根节点的公钥,其私钥由根节点的私钥和上述种子组成。

要签名消息时,随机选择一个叶节点,然后使用该密钥对对该消息进行签名。此后,从该叶节点到根节点路径上的每个节点(具体指其中的公钥)及其兄弟节点,均由其父节点进行签名。验证者仅当所有签名均为有效时才接受该签名。

这种方案的缺点是签名大小。对于128位的前量子安全性,需要一个256层树;例如,使用参数为w= 16的Winternitz一次性签名(见第2.4.1节)和具有256位输出的哈希函数,签名大小达到1.65MB。

2.5 SPHINCS

sphincs的目标有两个:实现适中的签名时间和签名大小,并消除任何类型的状态。

为了实现这一目标,sphincs树被设计为一种节点为Merkle树的戈德赖希树。

H H
H0
H00
pk000 pk001
H01
pk010 pk011
H1
H10
pk100 pk101
H11
pk110 pk111

图1. 一个Merkle树。两条合并箭头表示“父节点是两个子节点的哈希值”。f= pk000的认证路径将是A(f) = {pk001, H01, H1}.

H H
H0
H00
pk000 pk001
H01
pk010 pk011
H1
H10
pk100 pk101
H11
pk110 pk111

图2. 一个戈德赖希树。除了图1中的符号外,虚线箭头表示“叶节点对下方的根进行签名”。

在这种新配置中,Merkle树中的每个叶节点用于对下一层Merkle树的根进行签名。这种结构也可在GMSS[BDK+07]和XMSS[BDH11,HRB13]中找到。

此外,一棵sphincs树的叶节点对一个少次签名(FTS)方案的公钥进行签名,该方案的密钥对在少量不同消息上重复使用时其安全性不会受到损害。这在图3中进行了总结。

为了快速了解sphincs,可以将其视为三种类型树的组合。具体如下:
1. sphincs超树:高度为h(在sphincs-256中为60)的戈德赖希树,分为d层(在sphincs-256中为12层)。每一层的叶节点对一个Merkle树的根进行签名。
2. 大小为h/d(在sphincs-256中为5)的Merkle树,其叶节点为在戈德赖希构造中使用的一次性签名wots的公钥。
3. 用于对消息进行签名的FTS由超树的最后一层进行签名。

我们现在更深入地探讨一下sphincs的机制。

高度为h的sphincs树可被视为具有d层的戈德赖希树,其中每层由高度为h/d的默克尔树代替节点。在[BHH+15]中,对第2.4.3节所述的默克尔树构造进行了一些修改。其中一项对我们工作至关重要:在sphincs的默克尔子树的叶节点中,所有wots公钥均被压缩,方法如下:将其部分视为二叉哈希树的叶节点;然后通过以下规则计算该树的根:若某节点没有兄弟节点,则将其提升至树的更高层,直到拥有兄弟节点为止。该树的根即作为压缩后的wots公钥。

PK
H0 H0 H1 H1
pk00
H00
H000 H000 H001 H001
pk0000
FTS
pk0001
FTS
pk0010
FTS
pk0011
FTS
pk01
H01
H010 H010 H011 H011
pk0100
FTS
pk0101
FTS
pk0110
FTS
pk0111
FTS
pk10
H10
H100 H100 H101 H101
pk1000
FTS
pk1001
FTS
pk1010
FTS
pk1011
FTS
pk11
H11
H110 H110 H111 H111
pk1100
FTS
pk1101
FTS
pk1110
FTS
pk1111
FTS

图3. 一个高度为4的超树,可以看作是在节点位置具有高度为2的Merkle树的两层戈德赖希树。除了图1和2中的表示外,灰色圆盘表示FTS实例(horst对应原始的sphincs,porst对应gravity-sphincs,fors对应sphincs+)。

与戈德赖希构造类似,每个节点都有索引,每个叶节点在sphincs中都有一个地址,该地址包含其在超树中的层、所在层中Merkle树的编号以及其在Merkle树中的位置。

我们现在描述原始的sphincs签名方案(为了将其与sphincs框架区分开来,我们将称其为o-sphincs)。

密钥生成() 随机选取一对种子(S1, S2) ∈{0, 1}λ ×{0, 1}λ,并生成顶层默克尔树(位于层d−1的树),其根为整体公钥pk。私钥为sk ←(S1, S2)。

Sign(m, sk)
1. 根据m和S2生成2个伪随机值(R1, R2) ∈({0, 1}λ)2;
2. 计算D= H(R1||m);
3. 取R2的最左侧h位作为索引idx;
4. 生成索引为idx的密钥对;
5. 使用该密钥对对D进行σH=签名;
6. 使用第0层的密钥对对horst公钥进行σ0=签名,该密钥对(压缩形式)位于索引为&f0= d||idx的叶节点f0中;
7. 对包含fi−1的Merkle树的根进行1 ≤ i< d, σi=签名,使用第i层相应叶节点fi中的wots密钥对;
8. 签名:σ=(idx, R1,σH,σ0, A(f0), σ1, A(f1) …,σd−1, A(fd−1))。

验证(m, σ,公钥)
1. 计算D= H(R1||m);
2. 假设σH是有效的,计算公钥;
3. 对于0 ≤ i< d:
(a) 假设签名σi是有效的,并根据它以及前一步计算出的根推导出一个公钥wots;
(b) 假设A(fi)是正确的,并计算其Merkle树的根;
4. 将最后一个根与公钥进行比较:sphincs当且仅当两者相等时接受。

2.6 gravity‐sphincs和SPHINCS+的修改

gravity-sphincs在[AE17b]中被提出,对o-sphincs进行了多项修改,旨在提升其性能和签名大小。与我们攻击相关的修改如下:
1. 超树的顶层现在被缓存,因为它在签名算法中始终被使用,其高度从5增加到20(从而减少了超树的层数)。因此,最上层Merkle树的叶节点数量从32增加到2^20。
2. FTS实例的索引现在直接由消息和签名者从其私钥计算出的公有盐值推导得出(这在[AE17a,图3]中有很好的总结)。因此,验证者可以验证该索引,攻击者无法再选择该索引——但我们会发现,绕过这种保护很容易。

独立地,sphincs+在[BDE+17]中被提出。与我们的攻击相关的修改是,消息摘要md和FTS索引idx的计算方式如下:

(md‖idx) ← H(r, pk, m), (1)

其中r是由签名者根据消息和私有种子生成的公有盐值。这种索引生成方式的改变与gravity-sphincs中的类似。为简化起见,本文档将仅关注针对NIST安全等级1的参数集。

我们将看到,这些修改虽然在理论上增加了我们攻击的成本,但实际上对攻击效率的影响非常有限。

参数。 o-sphincs, gravity-sphincs和sphincs+提出了参数以提供针对存在性伪造的128位量子安全性(假设为256位消息)。表1总结了这些参数。

方案 安全性 w 1 2 h d 签名大小(kB)
o-sphincs 128 16 67 6 60 12
gravity-sphincs 128 16 67 6 60 20 17
sphincs+‐128f 128 16 67 6 64 8
sphincs+‐128s 128 8

我们注意到[AE17b]提出了效率与签名大小之间的多种权衡,以及在上下文中允许的签名数量的不同变体。

3 针对SPHINCS框架的嫁接攻击

在本节中,我们提出了一种针对sphincs框架超树结构的新攻击方式。该攻击的目标是将一个由我们控制的分支插入到顶层的某个叶节点fd−1(即一次性公钥)下方。为了实现这一点,攻击者必须能够为该分支的根节点提供一个对该密钥fd−1有效的签名。一旦该根节点通过验证并成功嫁接分支,攻击者便完全控制了该分支,并可通过修改生成该分支所用的种子以及随机化无法验证的值,轻松修改分支内的任意节点。

在本节的其余部分,我们将详细阐述嫁接攻击的原理及其对安全性的影响。最后,我们将提供一种导致对sphincs框架实现通用伪造的实际故障攻击,并讨论不同的复杂性权衡。最后,我们将简要概述针对该攻击可能采取的对策。

3.1 在SPHINCS超树中嫁接一个分支

让我们针对超树顶层的一个叶节点fd−1。我们假设对应的wots密钥已对两个不同的值进行了签名,攻击者知道这些值及其签名。根据[GBH16],她能够以概率wots生成一个pw ≈ 2−34。我们将这种针对wots的存在性伪造能力转化为对任意sphincs类方案的通用伪造能力。为了找到一个可伪造的消息m,我们按如下步骤进行:

  1. 随机生成一个种子,使得要使用的FTS索引落在目标wots实例之下。该情况发生的概率为pf,其中pf在o-sphincs时为1,在2−20时为gravity-sphincs,在2−8(分别对应2−3)时为sphincs+‐128f(分别对应‐128s)。
  2. 基于该种子和消息m,计算签名直至超树的倒数第二层。以概率pw,攻击者能力可以对相应wots签名的该层根进行签名。
  3. 使用签名者已知的合法认证路径完成签名,该认证路径来自任意消息的合法签名,且该消息在超树中的认证路径经过fd−1。

将上述存在性伪造转化为通用伪造的简单方法是随机选择种子(该种子用于生成签名过程中使用的一次性签名和所有FTS),以满足以下两个要求:
1. 所使用的FTS位于目标wots实例之下:这种情况发生的概率为pf第3.1节中所述。
2. 攻击者能够使用目标wots私钥对倒数第二层中使用的默克尔树的根进行签名:这种情况发生的概率为pw。

为了找到同时满足这两个要求的种子,攻击者需要为每条消息尝试大约1/pfpw个种子。这些尝试可以完全离线进行。我们注意到,所需的哈希计算次数甚至更高,因为每次尝试大约消耗215次哈希。然而,有可能做得更好。

确实,即使诚实的签名者使用私有种子生成(对应于Merkle树叶节点的一次性签名私钥),验证者也无法检查这是否真正执行。因此,为倒数第二层寻找合适的默克尔树(所谓合适,是指其根可以用目标wots密钥进行签名)可以与寻找合适FTS索引的过程去关联。这使得尝试次数从1/pfpw降至1/pf+ 1/pw。

此外,签名不包含完整的默克尔树,而只是对每棵树包含一个叶节点fi及其认证路径A(fi);这减少了签名大小以及验证时间。然而,这也使得攻击者能够加快伪造速度,因为攻击者无需生成合适的默克尔树,而只需生成一个看起来像是在合适默克尔树中的叶节点fd−2和认证路径A(fd−2)即可。为此,攻击者可以简单地随机选择A(fd−2)中的所有值(最后一个除外),然后尝试该最后一个值的多个可能取值,直到从fd−2和A(fd−2)计算出的根可以用fd−1进行签名为止。通过这一改进,每次新的尝试现在仅耗费one哈希而非215哈希。

通过这些改进,对任何sphincs方案进行伪造的成本从最多215/pfpw哈希降低到1/pf+ 1/pw哈希。举例来说,对于gravity-sphincs,这代表成本从269降至234。

3.2 针对SPHINCS框架的故障注入

正如我们之前所见,整个攻击依赖于攻击者获取同一私钥下两个不同的wots签名的能力。在sphincs框架的背景下,超树的整体构造是确定性的,且签名完全取决于消息和私钥。这一特性导致一次性签名无法对不同的消息进行签名,从而确保了该方案的安全性。

下文中,我们将展示一种故障注入攻击,该攻击允许攻击者使用相同的wots密钥恢复两条不同消息的签名。

记sk=(s1, s2,…, s)为对应于wots的私钥,以及由该私钥认证的Merkle树根fd−1。我们请求对一条消息m进行签名,不失一般性,假设在最后一步需要对δ进行签名。记δ对wots的签名σd−1=(σd−1,1,… σd−1,)。我们收到整体签名

σ=(idx, R1,σH,σ0, A(f0),…,σd−1, A(fd−1)).

下一步,我们将再次请求对相同消息m的签名。由于该算法是完全确定性的,生成的签名应与σ相同。但我们将干扰在计算认证路径A(fd−2)时执行的操作。这种故障将导致计算出的Merkle树根δ′与δ不同。由此生成的wots签名σ′d−1使得δ′攻击者能够发起如前所述的嫁接攻击。故障的概览见图4。

故障模型的一个优点是它非常弱。实际上,它满足以下特性:
– 每次签名仅需一次单次故障,因为在倒数第二层Merkle树的计算中引入一次单次故障即可满足所需的修改;
– 故障条件非常宽松,因为我们并不使用故障变量的实际值:只需要该变量发生改变,而无需知道其具体变化值;
– 故障可在较宽的时间范围内实施。实际上,由于验证算法使用A(fd−2)来计算δ′,因此必须对认证路径进行故障注入:否则,攻击者将从中推导出合法的根δ而非故障后的根δ′。这意味着不能直接对签名验证者会重新计算的节点进行故障注入,但对所有其他节点进行故障注入均可导致攻击成功。换句话说,可以对认证路径“下方”的任意节点进行故障注入,而对“上方”的节点进行故障注入则对我们的目的无意义。实际而言,在o-sphincs中,最终可能有33227次哈希计算成为故障目标,而在gravity-sphincs中,参数如表1所示时,有273352次哈希计算可作为故障目标。

这些数字大致占整个o-sphincs计算的6%和整个gravity-sphincs的18%。

示意图0

3.3 故障签名与计算能力之间的权衡

我们已经看到,可以通过一次故障签名对sphincs系列的现有方案实现通用伪造。然而,每次伪造的签名都需要付出不可忽略的计算成本,因为需要尝试大约 1/pw ≈ 2³⁴个倒数第二层Merkle树根的值(见第3.1节),才能利用wots上的容量。在本节中,我们将提供攻击者允许的故障签名数量与伪造签名所需的计算成本之间的权衡。

3.3.1 对WOTS的TotalBreak攻击

首先,我们估算需要多少个故障签名才能恢复整个wots私钥。

将H建模为随机预言是安全的。根据这一假设,当δ的计算发生故障时,δ′将在0到2λ −1之间取一个均匀随机值。因此,每个bi(对于1 ≤ i ≤ 1)以概率1/w为0。

然后,校验和C服从1= 64个随机变量(r.v.)的和的分布,这些随机变量在{0, w−1}上服从均匀分布,根据中心极限定理,我们将其近似为具有参数μ= 1(w−1)/2和σ²= 1(w² −1)/12的正态分布。

让我们按照大端约定将C写成以w为基的形式。那么,对于1< i ≤ ,bi= 0表示j= i−1条件下的C mod wʲ < wʲ⁻¹。该事件的概率为:

P(C mod wʲ < wʲ⁻¹)= ∑ {q=0}^{⌊1(w−1)/wʲ⌋} ∑ {z=qwʲ}^{qwʲ+wʲ⁻¹−1} P(C= z),

其中P(C= z)= ρμ,σ(z)/∑_{n∈Z} ρμ,σ(n),且ρμ,σ(x)= exp(−(x−μ)²/(2σ²))。

我们得到P(b₆₅= 0) ≈ 1/w, P(b₆₆= 0) ≈ 0.098, P(b₆₇= 0) ≈ 2⁻³⁰.⁷。最后一个值需要特别说明。这意味着我们平均需要请求2³⁰.⁷个签名才能得到s₆₇,这个数量很大,但与此同时,我们需要s₆₇以概率2⁻³⁰.⁷对一个根进行签名。因此,相对于s₆₇,我们只能寻找H(s₆₇)。鉴于找到该值的概率非常高(P(b₆₇= 1) ≈ 0.80),我们可以假设恢复s₁,…, s₆₆所需的平均签名数量足以以压倒性概率找到H(s₆₇),因此我们不再关心s₆₇。稍后我们将看到这在实践中是成立的。

最后,我们依赖于P(b₆₅= 0)和P(b₆₆= 0)的值来证明此后将进行的近似:b₁, b₂,…, b₆₆被视为{0, w −1}中的66个均匀偏差。

现在让我们考虑执行该攻击所需的平均签名数量。设X为建模请求签名数量的随机变量,用于查找sk(不包括s₆₇)。那么我们的问题就归结为计算E(X)。

设{σ(1)′,σ(2)′,…,σ(n)′}为攻击过程中某一时刻请求获得的n个故障签名。我们定义:V(n)ⱼ := {σ(i)′d−1,j | 1 ≤ i ≤ n},即当攻击者收集到n个故障签名时,所有接收到的σ(i)′d−1的第j个坐标的取值集合。我们还定义事件Bₙ:={∃1 ≤ j< ,使得sj∉ V(n)ⱼ}。可以证明P(X= n)= P(Bₙ₋₁ ∩ Bₙ),并且这将导致:

P(X= n)= P(Bₙ)− P(Bₙ₋₁). (2)

由于σ′d−1的坐标在假设下是成对独立的,并且在{0, w −1}上服从相同的均匀分布,因此我们有:

P(Bₙ)= ∏_{j=1}^{−1} P(sj ∈ V(n)ⱼ)=(1 −((w −1)/w)ⁿ)^{−1}. (3)

组合公式2和3,并结合sphincs方案中设置的参数,我们估计E(X) ≈ 74.5。注意,这导致找到H(s₆₇)的概率大于1 −2⁻¹⁷⁰,这确实已经足够了。

因此,对于所使用参数的方案,平均只需查询74.5个故障签名即可恢复整个wots私钥。

3.3.2 权衡

我们已经看到,该攻击只需一个故障签名即可实施,但每次伪造签名都需要较高的计算成本;或者攻击者可以制造约75个故障签名,以确保自由选择默克尔树根。现在,我们将逐步增加攻击者可获得的故障消息数量,来研究所能实现的各种权衡。

为此,我们扩展了Hülsing和Groot Bruinderink的[GBH16]推理。设δ为我们要伪造其签名的根,wots表示该根的签名,δ(1)、δ(2)、⋯⋯、δ(n)为从同一私钥获得有效签名的均匀随机根。令b=(b₁,…, b)为b的δ-向量,b(i)=(b(i)₁,…, b(i))为所有1 ≤ i ≤ n对应的δ(i)的b-向量。那么,当且仅当以下表达式成立时,我们才能为δ伪造一个有效的签名:

{j=1}^ ∨ {i=1}^n {bj ≤ b(i)ⱼ}.

为了估计该事件的概率,我们假设均匀随机字的b-向量的坐标在{0, w − 1}中成对独立且均匀分布。虽然这一假设对于前1个坐标显然成立,但对于最后的2个坐标显然不成立。然而,我们稍后将看到,由此得到的理论概率与仿真获得的概率非常接近。因此,为简便起见,我们采用这一假设。

此外,我们假设随机根δ(i)是成对独立的,即对应的b-向量是成对独立的。根据坐标独立性假设:

P(∧ {j=1}^ ∨ {i=1}^n {bj ≤ b(i)ⱼ}) = ∏ {j=1}^ P(∨ {i=1}^n {bj ≤ b(i)ⱼ}) = ∏ {j=1}^ (1−P(bj < b(1)ⱼ)ⁿ) = (1− 1/(wⁿ⁺¹) ∑ {a=0}^{w−1} aⁿ)^ ,(4)

第二个等式来源于b向量的独立性假设,最后一个等式来源于同分布假设。表2展示了攻击者在不同数量的故障签名下,需要尝试的平均根数以找到一个可伪造签名的根——注意,攻击者除了故障签名外还拥有合法签名。这些数值由公式4得出,并通过实验验证。

我们可以观察到,伪造消息m的计算复杂度本质上是三个操作复杂度的和:

– 尝试为消息分配满足条件的索引的种子数量 – 从o-sphincs到2²⁰对于gravity-sphincs;
– 在能够伪造wots签名之前,需要尝试的Merkle树根值的数量 – 取决于故障签名的数量,参见表2;
– 签名的复杂度⁸。

根据这一观察,我们可以说,只需3条故障消息,即可以大约2²⁰次哈希计算的代价对gravity-sphincs实现通用伪造。

故障签名 1 2 3 4 5 10 20
尝试的树的数量 2³⁴.⁹ 2²⁴.⁰ 2¹⁸.⁰ 2¹⁴.² 2¹¹.⁷ 2⁵.⁵ 2².⁰

3.4 对策

通用对策(例如通过冗余计算来实现签名计算)可能会使我们的攻击变得更加复杂,但它们可能带来显著的开销(对于冗余而言,时间和空间上的开销因子为2)。实际上,在我们的情况下,简单的签名验证并不高效,因为该攻击产生的签名是有效的。此外,只有执行过程中的一小部分会被注入故障,因此必须对每个默克尔子树的根进行冗余检查。然而,冗余计算是一种有效的方法,可显著限制攻击者,迫使其需要更强大的攻击模型,因为故障必须在两次执行中完全一致地复现。由于通用对策已有充分的文档记录,我们的讨论将集中在针对sphincs框架特有的对策上。

在[MKAA16]中,作者提出了一种特定的重计算方法,用于避免默克尔树中的故障,称为节点交换重计算(RESN)。尽管该对策通过轻量级流水线电路以可接受的开销提供了高效的安全性,但它并未涵盖戈德赖希构造。与经典重计算方法相比,对我们的攻击产生的主要影响是,它将故障限制为仅针对默克尔树根的根计算,因为任何其他故障哈希计算都将被RESN检测到。我们注意到,在这种情况下,故障签名将不再是一个有效的签名,且结果可以通过额外的开销进行验证。

一种抵御我们攻击的简单方法是从公开值而非秘密值计算FTS索引。事实上,如果从消息和公钥计算索引,则攻击者将无法再选择要签名消息的FTS索引。

然而,这样做的补救措施将比问题本身更糟糕。事实上,尽管我们的攻击会被这种修改所阻止,但现在恶意用户可以通过尝试多条消息来在FTS的索引idx上引发多碰撞。

在所研究的方案中,FTS叶子的数量上限为2⁶⁴。这意味着,给定固定的索引idx,攻击者可以通过大约k × 2⁶⁴的计算代价找到k条导致该索引的消息。因此,这种修改将导致目标方案的普遍可伪造性而无需任何故障。

一种有效的防御措施是通过某种方式将超树的不同层关联起来,使得在树的计算过程中出现故障时会导致生成无效签名,即根值与公钥不同。在返回签名之前简单检查其有效性即可防止任何故障攻击。然而,为了关联这些层,无法仅从索引和私钥计算出一次性签名密钥,因此每次签名时都必须重新计算整个超树,这将导致签名时间的巨大开销。

4 结论与开放问题

在本文中,我们提出了首个针对sphincs家族签名方案的故障攻击。在初始付出单次故障消息的代价后,该攻击允许以每条消息2³⁴次哈希运算的(离线)成本为任意消息伪造签名。

我们提出了几种权衡方案,以在略微增加故障消息数量的同时降低计算成本。对于任何目标方案,我们只需知道3条故障消息,即可以约2²⁰个哈希函数的代价伪造任意消息。此外,该故障模型非常宽松。

尽管我们的攻击可以通过一些通用的(但可能代价较高)故障攻击防御措施来抵御,但我们并未找到任何特定的防御措施。

正如本研究所展示的,多种基于哈希的签名及其内部使用的一次性签名的确定性特性可能使其在面对故障攻击时成为弱点。从防御方面来看,一个有趣的研究方向是提出能够对故障攻击提供一定内在弹性的基于哈希的构造。

在攻击方面,这项工作的一个自然延伸是在实践中实现所提出的故障攻击。我们的攻击针对sphincs框架,但将其扩展到其他多树结构(如多树XMSS或GMSS)也将是有趣的。人们还可以设计一种替代方法(而非故障注入)来恢复同一密钥下的两个不同wots签名,从而能够应用我们的嫁接攻击。我们将此留给未来工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值