第7章 故障分析自动化
萨扬迪普·萨哈和德布迪普·穆克吉帕迪亚
7.1 简介
物联网(IoT)和信息物理系统的发展极大地推动了智能设备的设计,这些设备通常嵌入了电子元件、软件、传感器、执行器和网络连接功能,以实现便捷的通信与交互。尽管这一趋势为物理世界与计算系统的融合创造了大量机遇,并带来了更大的经济效益,但也要求将敏感信息置于设备内部。这一事实引发了严重的安全漏洞问题,近年来这些问题已开始被视为智能系统的设计目标。通常,密码学被选为标准解决方案,以抵御各种形式的攻击并提供可证明安全。然而,密码算法的资源密集型特性导致了社区致力于为资源受限环境设计轻量级密码系统。
实际攻击(例如侧信道攻击和基于故障的密码分析)在密码学界已为人所知相当长一段时间。然而,最近这些攻击的相关性显著增加,主要是在上一段所述场景的背景下。过去几年中,提出了多种面向资源受限环境的新密码算法(例如轻量级分组密码)。为了确保这些算法的实际可用性,保障每个算法的安全性至关重要,这就要求对每个算法及其实现都进行全面的实际攻击分析。此外,考虑到市场竞争因素,人们无法承受花费数年时间来完成此类分析。遗憾的是,以目前密码学界的状况来看,此前主要依赖严格的数学证明和人工分析,要在合理时间内完成这一任务似乎相当不可能。
综合考虑所有这些需求,对攻击的密码分析技术进行完全自动化似乎是唯一的出路。最近,故障攻击和侧信道分析研究群体已开始关注此类自动化工作。然而,即使对于本质上相当系统的实际攻击,这一任务仍面临诸多挑战。其中首要挑战是通用性。理想情况下,一个自动化工具应适用于任何给定的密码算法或密码协议。但在密码算法的实际应用中,这一点极难实现。另一个主要挑战是评估针对所有可能攻击类别的安全性。在本章中,我们将探讨在该自动化方向上的一些早期努力,主要集中在分组密码上的故障攻击。
最近,故障攻击领域在自动化方面取得了一些显著进展。这些工作主要围绕所谓的代数故障分析(AFA)展开,研究发现AFA在分组密码背景下具有足够的潜力来支持这一趋势。AFA的核心思想源自代数密码分析,后者是经典密码分析的一种替代形式,在过去十年中得到了广泛推广。在过去六年中,AFA借助基于通用方程的表示以及现成求解器(如布尔可满足性求解器(SAT)),在针对不同轻量级密码算法的新的攻击发现方面取得了显著成功。本章的目标是使读者熟悉AFA的概念及其所带来的自动化特点。出于明显的原因,讨论将仅限于分组密码的范围内。AFA的整体概念在数学上较为复杂。考虑到这一点,我们试图在有限的范围内提供一些必要的数学背景知识。通过阅读本章,读者将能够全面理解这一概念,并能够在SAGE [62]等数学软件系统上编写相应的代码。
本章结构如下。我们首先在第7.2节概述代数密码分析。对于AFA至关重要的代数密码分析中的一些重要概念将在第7.3、7.4和7.5节中介绍。最后,在第7.6节中,我们将详细引入AFA的概念,并对其近期发表的研究成果进行总结关于该主题的最新研究成果。由于本章的主题是故障攻击自动化,在第7.7节中,我们将简要回顾在此背景下的其他一些相关工作。最后,本章将在第7.8节进行总结。
7.2 代数密码分析:概述
代数故障分析(AFA)是另一类被称为代数密码分析的攻击类别的延伸,该类别在21世纪初获得了广泛关注[17, 51,54, 56]。因此,在深入探讨AFA之前,有必要对该类攻击进行简要介绍,这类攻击在本质上与所有其他已知的经典密码系统攻击形式有很大不同。然而,对此主题的严格论述超出了本章的范围,感兴趣的读者可参考[17]了解相关内容。本节将仅通过触及一些关键概念,尝试提供一个较为非正式的描述。与AFA相关的概念将在后续章节中更详细地介绍。
从非常简单的意义上讲,代数密码分析旨在通过求解表示密码算法的一组代数方程来提取密钥。此类攻击的动机源于克劳德·E·香农关于1949[165],的开创性论文,其中预测“破解一个良好的密码算法所需的工作量应等同于求解一个包含大量未知数的复杂联立方程组”(参见[165])。通常,将密码算法表示为一组非线性多元代数方程并不困难,正如我们将在本章后面展示的那样。然而,求解这样的方程组却是一项艰巨的任务,因为求解该系统的计算问题被证明是NP完全的。因此,过去人们并不认为利用密码方程的攻击会构成重大威胁——至少在20世纪90年代之前是如此。这一障碍最终从20世纪90年代中期开始被打破,随着SAT、格罗布纳基等机器求解器的成功应用,这些求解器已经发展得足够成熟,能够利用其复杂的启发式方法处理大规模问题实例。突破首先出现在公钥密码学领域,例如帕塔林对松本‐今井密码系统的密码分析[140],以及库尔图瓦对基本HFE密码系统的攻击[53]。随后,人们逐渐将注意力转向对大型分组密码的代数密码分析。然而,最近代数密码分析已被应用于公钥密码学领域,用于求解椭圆曲线离散对数问题[145]。
正如上一段所指出的,代数密码分析中的主要挑战在于求解密码方程系统。通常情况下,分组密码会生成规模过大而难以处理的有限域上的多元多项式方程系统,这些系统通常被发现是超定且稀疏的。尽管一般来说该求解相关的计算问题是难处理的,但如果底层系统具有足够的稀疏性,则问题会变得相对容易,这一事实成为对分组密码进行代数攻击的一个重要推动因素。然而,诸如用于求解有限域上多项式系统的格罗布纳基技术等主要方法,由于所考虑系统的规模过于庞大,大多无法有效应用。因此,代数密码分析的早期尝试主要集中在开发替代技术来处理此类系统,通过利用其低次数和稀疏性。在2000年欧洲密码学会议上,Courtois等人[51],提出了一种称为XL的通用技术,用于求解定义在大有限域上的超定多元多项式方程组。随后在2002年,库尔图瓦提出了XL的改进版本,称为XSL[56]。XL和XSL都使用了一个非常简单的关键步骤,称为线性化。非正式地说,给定一个非线性(实际上是二次;将在后续章节中解释)多项式系统,线性化方法将每个次数为>1的单项式替换为一个新的变量,从而使得到的系统完全线性化。可以证明,原始多项式系统的解集确实是所得线性系统解集的一个子集,且线性化不会丢失原始系统的任何解。原始解可以通过试错法从线性系统的解中找到。然而,整个过程的成功与否关键取决于所得线性系统的变量数和秩。通常情况下,如果变量数几乎等于秩,则预期解的总数较少,从而简化了后续通过试错法寻找原始解的步骤。为了高效地构造线性系统,XL提供了一个额外的步骤,即在进行线性化之前,先提升系统的次数至立方或更高,并添加一些额外方程。通过XL方法构造的线性系统通常具有较少的解,使得上述求解过程非常有效。XSL算法以更复杂的方式做了类似的操作,以适当地保持线性系统的变量‐秩比接近1。
XSL攻击的结果令人惊讶,因为人们原本预计,对于像Rijndael、Serpent等大型分组密码,只要S盒可以表示为低次数的稀疏多项式方程,则基于XSL的攻击其攻击复杂度将随着加密轮数的增加而线性增长。这一结果可能对传统的分组密码设计原则产生巨大影响,因为它与来自线性和差分密码分析的标准认知相悖。在同一论文中,库尔图瓦进一步推测(未提供证明),有可能以大约 2^100,的复杂度攻击Rijndael,该复杂度低于穷举搜索复杂度2^128。尽管XSL在声称能够攻破高级加密标准时引发了一些争议(包括科珀斯密特和莫认为此类攻击无法奏效),但它促进了人们对分组密码多项式系统的知识积累和深入理解,并描述了这些系统可能易于求解的情形。此外,还提出了对XL/XSL的改进方法,从而产生了MutantXL[42],、ElimLin[54]等技术。然而,随着SAT求解器的巨大成功,研究社区逐渐转向使用SAT求解器。我们在此中断对这些定制化求解器的研究,并在本章后续部分采用SAT求解器。
尽管求解器在代数密码分析中起着重要作用,但它们并不是唯一重要的因素。密码方程的恰当表示也极为关键。其中最具挑战性的部分是S盒的表示。研究发现,所谓的S盒不当表示甚至可能导致攻击失败。更糟糕的是,目前尚无确定何种表示方式最适合攻击的方法,通常只能通过试错法来实现。在他们的论文[54],中,库尔图瓦提出了一些表示DES的有效方法S盒并找到了一些最适合其用途的表示方法。对于Rijndeal和Serpent,类似的工作已在[56]中完成。然而,为任意给定的密码算法找到最佳的S盒表示仍然被认为是一门艺术!在接下来的章节中,我们将介绍一种基于S盒表格表示生成S盒方程的通用策略。需要注意的是,我们并不声称通过该策略生成的S盒方程是最优的。事实上,可以证明Rijndeal S盒的最佳表示无法通过该策略生成。
在接下来的章节中,我们将详细描述代数密码分析中的一些关键概念。第7.3节将专注于有限域上多项式方程组的系统性理论处理。我们通常将此类多项式系统表示为 MC 或 MQ(当系统为二次时)。在第7.4节中,将提供生成 S盒 多项式的技术。最后,在第7.5节中,我们将介绍将MQ系统从代数正规形(ANF)转换为合取范式(CNF)的算法。
7.3 有限域上的多项式方程组
有限域上的多项式方程组是一个在纯数学、密码学、通信和计算机科学中具有广泛应用的主题。该课题几乎从公元3世纪起就以各种形式被数学家广泛研究。关于多项式系统存在丰富的理论和工具,尤其是在代数几何领域(格罗布纳基、理想和簇与多项式系统直接相关)。格罗布纳基求解器也因理论上的严谨性而被应用于代数密码分析领域[57]。然而,它们的应用被发现是有限的,因为它们无法处理非常庞大的系统。感兴趣的读者可参考科克斯、利特尔和奥谢所著的书籍 Ideals, Varieties, and Algorithms [57],以获得关于格罗布纳基的严格论述。
本节的主要目标是研究有限域上的多元多项式系统——更具体地说,是在GF(2)及其扩域上。需要注意的是,在讨论此类系统的解时,必须明确指出所期望的解所在的基域。例如,给定一个在GF(2^n)上的多项式方程组,人们可能只关心位于GF(2^n)中的解。但如果他/她希望求解同一方程组在GF(2^m)上的解,且满足n|m,则必须明确说明。在整个本书中,我们都尽量遵循这一约定。
在所有代数攻击的变体中,GF(2)上的多项式都具有特殊的重要性。从数学上讲,GF(2)上的每个n变量多项式都属于如下形式的多项式理想:
GF(2)[x1, x2,… xn]/(x²₁ −x₁, x²₂ −x₂,…, x²ₙ −xₙ)
该表示形式显然表明,这些多项式中不会出现单变量的平方、立方甚至更高次项。为完整起见,需要说明的是,GF(2)上的一个多项式是包含最多d项的单项式的异或和,其中d是该多项式的次数。其系数为0或1,因此无需显式指定这些系数。例如,考虑在3个变量x₁, x₂, x₃中的多项式:
f: x₁x₂+ x₁+ x₃+ 1
该多项式包含4个单项式:一个次数为2,两个次数为1,一个次数为0。另外请注意,次数为0的单项式的系数是1。
在本章中,我们处理多项式方程。在GF(2)多项式的背景下,可以通过令其等于0或1来构造方程。例如,可以写成:
x₁x₂+ x₁+ x₃+ 1= 0 or x₁x₂+ x₁+ x₃+ 1= 1
然而,对于第二个方程,注意右边的1可以移到左边,与原本就在左边的另一个1相消。得到的方程如下:
x₁x₂+ x₁+ x₃= 0
在代数攻击领域,通常将多项式方程表示为“等于0”的形式。此外,在大多数情况下,表示方程时会省略“= 0”部分。读者不应对此标准做法感到困惑,因为我们在本章中也将采用这一做法。
7.3.1 多项式次数约简算法
在求解多项式方程组时,方程的数量、变量的数量以及最高次数是衡量难度的一些关键指标。我们将在本节后面讨论前两个因素。在本小节中,我们展示如何处理多项式系统中的高次方程。幸运的是,可以证明:给定一个多项式方程组(注意,该结论不仅限于有限域,对于其他代数结构上的多项式同样成立),总存在另一个多项式方程组,其解集与原方程组的解集构成双射,且新方程组中所有方程的次数至多为2。此外,为实现这一转换而在原系统中新增的变量和方程的数量,对于任意固定的原系统最高次数而言,是原变量数量的多项式函数。
实现这一点的基本算法非常简单且直观。我们通过一个例子来说明。考虑以下包含5个变量的方程:
f: d+ e+ ac+ ae+ bc+ be+ cd+ de+ ade+ ace+ abd+ abc
该方程的最高次数为3。然而,可以很容易地观察到,通过添加两个额外变量 α 和 β,可将其降至2,如下所示。
d+ e+ ac+ ae+ bc+ be+ cd+ de+ dβ+ cβ+ αd+ αc
α= ab
β= ae
请注意,我们在此有意省略了“= 0”项,这是遵循标准做法。这个简单示例改编自[17],,该文献还提供了一种简洁的降次算法及其复杂度评估。该算法的关键思想是将系统中次数d ≥ 3的单项式替换为二次单项式。让我们考虑这样一个单项式w=xa₁xa₂…xad,其中a₁,a₂,… ad是范围在[1, n]内的指标。该算法引入d −2个新变量r₁, r₂,… rd−2作为哑变量,并引入以下方程:
r₁= xa₁ xa₂
r₂= r₁xa₃
r₃= r₂xa₄
…
…
rd−3= rd−4xa d−2
rd−2= rd−3xa d−1
w= rd−2xa d
必须按照上述策略替换所考虑系统中的每个单项式。还可以精确估计在所得系统中新增的变量和方程的总数。我们以以下定理的形式给出该算法的全部关键结果,而不陈述证明。
定理7.1 设 f₁(x₁,x₂,…,xₙ) = 0, f₂(x₁,x₂,…,xₙ) = 0, …, fₘ(x₁,x₂,…,xₙ) = 0 是一个包含 n 个变量和 m 个方程且最大次数为 d ≥ 3 的多项式系统。则存在另一个次数至多为 2 的方程组 g₁(x₁,x₂,…,xₙ′) = 0, g₂(x₁,x₂,…,xₙ′) = 0, …, gm′(x₁,x₂,…,xₙ′) = 0,其解与 f 系统的解之间存在双射关系。进一步,设 z 为 f 系统中次数大于等于 3 且具有非零系数的单项式的数量,所有这些单项式的次数之和为 D。则有 m′ ≤ m + D −2z 且 n′ ≤ n + D −2z。
不幸的是,对于任意 n 变量系统,该简单降次算法的复杂度在系统最大次数 Δ 不固定时为 Θ(e^(n/2)n^(n/2))[17],。然而,若将 Δ 固定为某个预定义值,则运行时间为 Θ(n^Δ),这确实是多项式时间。值得一提的是,该算法存在一种贪心变体,通过谨慎选择用于替换的单项式来减少虚拟变量的数量,从而进一步提升性能。感兴趣的读者可参考 [17] 以了解详细信息。
7.3.2 多项式系统求解的NP完全性
本小节从计算角度具有重要的理论意义。与前一小节和后一小节不同,它本身并未提供任何用于处理多项式系统的算法工具。然而,本节所得到的结果促使人们采用SAT求解器来求解多项式系统,迄今为止这已被证明是该领域中最有效的工具。与前一节类似,我们仅在此陈述关键结果,而不给出显式的证明。不过,将提供一些非正式的证明思路。
在有限域或有理数上求解多项式方程组的问题是NP完全的。如上一小节所示,可以轻松地将一个最高次数 d ≥ 3的系统转换为一个最大次数为 2的系统。我们将求解最大次数为2的系统的计算问题记作MQ。类似地,对于任意最大次数至少为2的一般系统,我们将其记作MP,而对于三次系统,则记作MC。此外,相应的判定问题分别命名为MQD、MPD和MCD。接下来,我们将本节的主要结果以定理形式陈述如下:
定理7.2 判定任意定义在GF(2)上的三次多项式系统(MC)在基域中是否存在解是 NP完全的。
在给出该定理证明的非正式概述之前,我们首先来看一下它的推论。证明在 GF(2)上的MC决策问题为NP‐完全,直接也证明了在GF(2)上的MP问题同样如此,因为任何在GF(2)上的MP问题都可以通过次数降低算法转换为在GF(2)上等价的MC问题。同样的结论也适用于MQ问题。为此,假设在GF(2)上的 MQ问题可在多项式时间内求解。由于任何MC或MP实例都可在多项式时间内转换为某个等价的MQ实例,因此MQ的多项式时间可解性将直接意味着MC和 MP的多项式时间可解性,这与该定理的断言相矛盾。最后,该结果可推广至除 GF(2)以外的任意有限域GF(q)。其证明思路是将任意在GF(q)上的多项式系统视为从GF(q)到{0,1}的一个映射。可以证明,从一个有限集到另一个有限集的所有此类映射都可以用在GF(p)上的多项式系统来表示,其中p为任意素数。取p=q即可实现我们的目的。
现在,让我们给出定理7.2的证明概要。与其他NP完全性证明一样,我们首先假设存在某个多项式时间算法,该算法能够求解MC决策问题的任意实例。现在,我们将利用这一多项式时间算法来求解一个已知为NP完全的3‐CNF SAT问题实例。这将导致矛盾,从而最终证明定理7.2。唯一还需要证明的是,存在一种从任意3‐CNF SAT实例到某个 MC实例的多项式时间转换策略。我们通过以下改编自[17]的例子来说明这一步骤。我们从一个合取范式子句(a ∨b ∨c)开始,并最终将其转换如下所示。
(a ∨ b ∨ c) ⇔((a ∨ b) ∧ c)⊕(a ∨ b)⊕ c
⇔((a ∧ b) ∨(a ∧ c))⊕(a ∨ b)⊕ c
⇔((a ∧ c ∧ b ∧ c)⊕(a ∧ c)⊕(b ∧ c))⊕((a ∧ b)⊕ a ⊕ b)⊕ c
⇔(a ∧ b ∧ c)⊕(a ∧ c)⊕(b ∧ c)⊕(a ∧ b)⊕ a ⊕ b ⊕ c
⇔(abc+ ac+ bc+ ab+ a+ b+ c)= 1
⇔ abc+ ac+ bc+ ab+ a+ b+ c+ 1= 0
如果a在3‐CNF中被否定,则可以在多项式表示中将其替换为 1+ a。因此,每个3‐CNF子句都可以表示为一个多项式方程。这种多项式的表示形式通常称为代数正规形(ANF)。在本章中,我们将广泛使用这一术语。
7.3.3 稀疏性在MQ求解中的作用
本节的最后阶段提出了一项非常重要的指标,用于理解多项式系统求解的难度。我们在此节开头已经指出这一点。一个多项式系统(不失一般性,可仅讨论MQ系统)可以用两个参数来刻画,即其中的变量数(n)和方程数(m)。我们特别关注这两个参数是如何调节求解难度的。然而,由于这是一个NP完全问题,无法给出精确的度量方法。尽管如此,人们发现这两个参数在决定难度方面仍具有一定作用。从历史角度来看,[51, 102]沙米尔曾指出,即使MQ问题是NP难的,当其为超定情况时,其复杂度会显著降低。库尔图瓦在[56],关于稀疏性的背景下也提出了类似的论断。
让我们考虑比率 γ=m/n。我们还用术语 β 表示系统的稀疏性。当 γ> 1 时,该系统被称为 超定。通常情况下,如果 γ ≈ n(也就是说 m ≈ n²),包括 SAT求解器 在内的大多数求解器普遍认为该系统更容易求解。然而,完整的图景仍未完全揭示。人们还发现,稀疏性 β在涉及求解难度时具有重要作用。但定义稀疏性并非易事。通常,人们可能仅将其视为系统中出现某个单项式的期望概率。让我们更详细地讨论这一点。给定一个包含 m个方程和 n个变量的 MQ系统,如果它仅包含 αlog(n) 个唯一的二次单项式,其中 α 是一个常数。注意,此处暂不考虑这些单项式出现的次数。直观上讲,如果选择将这些单项式替换为新的虚拟变量,从而将系统转化为线性系统(此过程称为线性化,如第7.2节所述),那么这些虚拟变量总共具有 2^αlog(2)= n^α 种可能取值。对于这些二次单项式的一组特定取值,可以通过简单的高斯消元法求解剩余的线性系统,其复杂度为 Θ(mn min(m, n)),适用于包含 m 个方程和 n 个变量的系统。将猜测步骤与随后的高斯消元步骤相结合,总运行时间为 Θ(mn^(α+1) min(m, n)),这确实是关于 m 和 n 的多项式时间。这一看似简单的策略很好地说明了稀疏性在MQ系统求解中的作用。
仅包含 αlog(n)个单项式的系统确实是合理的。然而,我们仍未考虑这些单项式在系统中的多次出现情况。现在让我们考虑系统中每个唯一的二次单项式的出现次数。显然,一个单项式在单个方程中不会出现超过一次,我们只需考虑跨方程的出现情况。如果系统有n个变量,则总共可能存在(n²+ n)/2个二次和线性单项式,外加一个常数单项式。如果我们假设特别地,每个方程中会随机出现3/4的唯一 αlog(n)个单项式,那么该系统的稀疏性结果为:
β= 4n+ 3α log(n) / (2n²+ 2n+ 1) ≈ 1 / 2n (7.1)
此处稀疏性通过系统中出现的单项式总数与可能的单项式总数的比率简单计算得出,本例中该值相当低。显然,稀疏性可作为度量求解难度的一个指标。这一简单的研究由G. 巴德在其优秀的著作中完成[17]。
尽管通常认为稀疏性是系统可解性的强有力指标,但两者之间的关系仍不十分明确。可以类比线性系统的情况:通常发现,相同规模的稀疏线性系统比稠密系统更容易求解。由于许多求解工具(包括XL、格罗布纳基)都使用线性代数方法,因此稀疏系统预期也更易于这些工具处理。此外,在考虑格罗布纳基算法时,求解的主要限制因素是内存。若处理的是稀疏系统而非稠密系统,内存效率可得到显著提升。最后还发现,SAT求解器在处理稀疏系统时的表现明显优于稠密系统,但其原因尚不十分清楚。
7.4 S‐盒多项式的生成
到目前为止,本章讨论了与有限域上的多项式相关的一些基本性质和工具。迄今为止,尚未提供能够为最先进的分组密码编写方程系统的方法。请注意,此处所说的密码方程仅指GF(2)上的多项式系统。尽管可以为某些分组密码在扩域上写出紧凑的方程(最好的例子是高级加密标准;请参见[47]),但目前我们尚无有效手段求解此类系统。严格来说,不存在编写分组密码方程的最佳方式。正如我们在第7.2节中已提到的,确定某种特定的方程表示为最佳方式仍是一个开放性问题。然而,这方面仍存在一些希望,并且有一些标准实践值得提及。毫无疑问,S盒是构造密码方程中最棘手的部分。例如,给定一个已知明文,完整的高级加密标准方程系统可表示为大约4000个多变量二次(MQ)方程组成的方程组。Courtois 等人已在[56],中表明,高级加密标准中的逆运算可用一组非常紧凑的二次方程表示。尽管实际上已证明高级加密标准难以攻破,但对于某些分组密码、流密码和公钥密码,已有成功利用此类代数攻击实现破解的积极成果——这主要归因于它们的S盒表示稀疏且次数较低。Courtois 进一步在[54],中指出,在差分密码分析背景下被认为“构建良好”的DES S‐盒,若考虑轮数减少(最多6轮)的DES版本,则在代数攻击下是脆弱的。本章稍后我们将看到这一结果在对DES的AFA攻击中的影响。
Courtois 等人提出了 [54], 中对代数攻击有用的 DES S‐盒 的多种表示方法。这些表示方法被广泛地分为三类。第一类涉及低次多变量输入输出方程。输入输出次数定义为形如 g(x₀, x₁,…,xₙ₋₁; y₀,y₁,…,yₘ₋₁) = 0 的关系的最小次数,其中 (x₀, x₁,…,xₙ₋₁) 和 (y₀,y₁,…,yₘ₋₁) 是某个 n × m S盒 的输入和输出变量。只有当这些关系对其对应的 S盒 以概率1成立时,才被视为输入输出关系。Courtois 进一步指出,对于任意 n ×m S盒,这样的输入输出关系均存在,并且可以通过非常高效的方式进行计数和获取。我们在此不提供具体结果,但可在 [54] 中找到。尽管通过这种方法可以获得足够数量的线性无关的完全三次或四次方程,但发现这些方程非常稠密,且方程数量庞大。作为补救措施,提出了另一类相对稀疏、但可能次数较高的方程(第二类)。第二类方程的构造方式使其最高次数保持为 ≤4,同时每个方程的单项式数量通常保持在4到5个之间。然而,在这些情况下,方程的线性无关性无法得到保证。在满足所有这些约束条件下,每个 DES S‐盒 大约可获得500–700个四次方程。最后,在第三类中获得了可能最适合的方程。该方法从任何 DES S‐盒 的标准三次表示出发,通过添加额外变量来降低次数并提高稀疏性。研究发现,对于 DES,每个 S盒需要约52个变量来实现高度稀疏的表示。此外,次数变为二次,且每个方程实际上包含0或1个非线性单项式。这种表示方式与DESS盒的最小硬件表示一致。
引入额外变量以降低次数并增加稀疏性的思想似乎是构造优质方程的一个巧妙技巧。然而,我们仍然缺乏一种通用的S盒方程构造方法。在本段中,我们介绍一种由Knudsen和Miolane [103]提出的技术,该技术在AFA社区中获得了广泛的关注。该方法用于构造一个n ×m比特S盒的方程,其最高次数d是先验确定的,其中n和m均以比特为单位。该方法的核心是构造一个二进制矩阵A,其具有 2ⁿ行和∑ᵈᵢ₌₀(n+m i)列。S盒的输入作为行元素,而所有次数小于或等于d的∑ᵈᵢ₌₀(n+m i)个有序单项式(依据某种分级单项式序;有关格罗布纳基中的单项式序,请参见[57])作为列元素。当S盒的输入i使得第j列对应的单项式取值为1时,矩阵aij处的元素被置为1。所有次数小于或等于d的确定性S盒方程均可通过计算矩阵A零空间的基得到。此过程可确保总共获得∑ᵈᵢ₌₀(n+m i) −2ⁿ个方程。
上一段中描述的过程可以通过计算所得方程的格罗布纳基进一步增强。这种做法通常被发现是有用的。值得一提的是,通过上述方法获得的方程的质量,关键取决于所选择的单项式排序。通常发现,分级逆字典序能提供最紧凑的表示形式。然而,这并不总是成立。人们仍然可以手动计算出更优的 S盒表示形式。例如,使用此技术永远无法获得高级加密标准S盒的最紧凑表示。DES的情况也是如此。高级加密标准S盒的二次方程是通过考虑有限域求逆的性质得到的,而DES的二次方程则是特别设计的,正如我们之前所述。
正如本段开头提到的,格罗布纳基和单项式排序在S盒表示中起着重要作用。然而,对该主题的严格讨论已超出范围。我们强烈建议读者阅读[57],的前3章,以正确理解这一主题。
尽管我们已经精确描述了如何构建S盒方程,但关于系统中的线性方程部分尚未提及。通常我们认为线性方程非常容易描述。一旦我们描述一个密码算法的完整方程系统,这一点就会变得清晰。然而,在处理定义在有限域上的密码算法(如高级加密标准或LED)时,会涉及一些技术细节。在这种情况下,线性层通常是在字级别上描述的,且大多数情况下涉及MDS矩阵。为这类系统编写 GF(2)上的方程较为复杂,因为需要将所有扩散层操作有效地转换为在GF(2)上表示的比特矩阵。幸运的是,至少对于在相对较小扩域上表示的密码算法(如高级加密标准),存在标准的方法来进行此类转换。卡洛斯·西德的专著[47],系统地描述了针对高级加密标准的转换过程。有关通用方法论,请参考[17]的第15章。
7.5 MQ到CNF转换
求解多元多项式系统有多种方法。事实上,代数密码分析最初的科研目标就是为了为此目的设计出最佳的求解器。然而,人们很快开始转向使用SAT求解器,这不仅因为其高效性,还因为其易于使用。现代SAT求解器可能是计算机科学和应用数学领域中最广泛使用的工具。SAT求解器在搜索启发式方面的持续改进使其变得极为强大且稳健。如今,标准的SAT求解器可以轻松处理数百万个变量和子句。但作为这种极高效率的代价,深入理解其内部机制确实非常困难。尽管理解现代SAT求解器的工作原理需要专业知识,但将其作为黑箱使用却极为简单。就我们的目的而言,我们仅需将其作为黑箱使用。因此,在本章中,我们有意略去SAT求解器的工作策略。感兴趣的读者可参考现有文献。此外,著名CryptoMiniSAT求解器作者马特·索斯的博客[168],也提供了一些关于现代SAT求解器工作原理的见解。
尽管可以安全地跳过SAT求解器的细节,但我们仍需了解如何将密码方程系统输入给它们。通常,SAT求解器接受合取范式(CNF)格式的输入。Conjunctive NormalForm(CNF)公式是由子句(clauses)通过合取(AND)构成的,而每个子句是称为文字(literals)的正变量或被否定变量的析取。将处于ANF形式的密码方程转换为CNF需要大量的算法工作量,接下来我们将对此进行描述。本节内容主要基于巴德的著作[17],以及巴德、库尔图瓦和杰斐逊的相应论文[18]。
7.5.1 稀疏性再探
在第7.3.3节中,我们指出多项式系统的稀疏性是决定其求解难度的关键因素。然而,此前并未恰当地给出稀疏性的定义。在此,我们以一种简洁的方式定义稀疏性,因为本章后续内容将多次用到这一概念。方程组的稀疏性(β)定义为非零系数的比率与可能系数总数之比。例如,在一个包含m个方程和n个未知数且定义在GF(2)上的MQ系统中,稀疏性可定义如下:
β= κ / (m((n²)+(n¹)+(n⁰))) (7.2)
其中, κ是系统中非零系数的数量。
稀疏系统,尤其是超定系统,被发现非常易于由SAT求解器处理。通常,如果 β ≤ 1/100,求解会变得容易得多对于MQ系统而言,比穷举搜索更快。由于实际原因,密码方程系统通常具有稀疏性,因为稀疏性意味着低门数,这无疑是可取的。或许,SAT求解器最引人注目的优势在于其相对较低的内存需求。像MAGMA [37]和SINGULAR [60]等大多数标准格罗布纳基实现会因内存需求过高而崩溃,而SAT求解器却能够成功运行。然而,只有在妥善处理某些问题的情况下,才能充分发挥SAT求解器的最佳性能。在接下来的几个小节中,我们将讨论这些问题。
7.5.2 GF(2)上的MQ系统
我们在这里首先讨论MQ系统,这是显而易见的。考虑一个具有n个变量和m个二次方程的代数正规形。将该系统直接表示为代数正规形意味着它位于GF(2)上。可以将该代数正规形表示为如下方程组:
f₁(x₁,…, xₙ)= y₁
f₂(x₁,…, xₙ)= y₂
…
fₘ(x₁,…, xₙ)= yₘ
这里每个 fi是一个二次多项式。通过调整常数,只需考虑 yⱼ= 0, ∀j。
这里,比率 γ= m/n可用于衡量系统是否超定。因此,如果 γ= 1,系统是恰好确定的,而如果 γ> 1,系统是超定的。设 M为单项式的总数,其中 M=(n²)+(n¹)+ 1,因为我们只考虑二次多项式。
7.5.3 代数正规形到合取范式转换算法
代数正规形到合取范式的转换过程包含三个主要步骤。在第一步中,可能会进行一些预处理以使系统更加适用于这种转换。接下来,对该系统进行线性化,引入新的哑变量以表示次数为 ≥2 的单项式。最后,将该线性系统转换为等价的子句系统。首先,我们忽略预处理步骤,描述该过程的第二和第三步。本节后续部分将补充预处理步骤。
通常,合取范式中不可用常数(0 和 1),而在代数正规形中它们至关重要。可以通过添加一个额外的合取范式变量T来表示 1,从而解决这一微小的技术问题。如有需要, ∼T随后可用于表示 0。这种简单技巧效果良好,并且在需要此类转换时被广泛使用。一旦我们确定了常数的表示方式,就可以直接进入代数正规形到合取范式的转换过程的第二步——即线性化。
多项式系统到线性系统
不失一般性,我们仅考虑MQ系统。每个MQ代数正规形中的多项式方程都是线性和二次项的和。对于出现在方程组中的每个次数为d> 1(本例中为 d= 2)的单项式,我们添加一个新的哑变量。例如,考虑一个二次项,a=wx。这里的哑变量是a。注意,这等价于以下三个子句:
1. (w ∧x) ⇒ a ≡ C₁: a ∨¬w ∨¬x = 1
2. ¬w ⇒ ¬a ≡ C₂: ¬a ∨w = 1
3. ¬x ⇒ ¬a ≡ C₃: ¬a ∨x = 1
我们可以安全地省略此处的“= 1”项,从而得到合取范式表达式 (a ∨¬w ∨¬x)(¬a ∨w)(¬a ∨x)。这可以很容易地推广到任意d次项(单项式),以表明其会产生(d+ 1)个子句,且所有子句的总长度为(3d+ 1)。
如果一个单项式出现多次,则可以重复使用相同的哑变量及相应的子句。我们只需对单项式进行频率分析即可。通常在大型超定系统中,每个可能的单项式至少出现一次,通过变量重用的线性化会带来较大的节省。另一方面,对于极端稀疏且非超定的系统,这种方法略显悲观。尽管如此,仍可安全地将此线性化步骤用于我们所掌握的所有系统。
线性系统到合取范式
线性化后,每个多项式现在都变为变量的和,或等价于一个逻辑异或。因此,将逻辑和视为 a + b + c + d = 0。这可以表示为8个子句:
C₁ : (a ∨¬b ∨¬c ∨¬d),
C₂ : (¬a ∨ b ∨¬c ∨¬d),
C₃ : (¬a ∨¬b ∨¬c ∨d),
C₄ : (¬a ∨¬b ∨¬c ∨d),
C₅ : (¬a ∨b ∨ c ∨d),
C₆ : (a ∨¬b ∨c ∨d),
C₇ : (a ∨b ∨¬c ∨d),
C₈ : (a ∨b ∨c ∨¬d)。
显然,如果我们将此技巧应用于长度为l的异或,则子句总数将为 $\binom{l}{1} + \binom{l}{3} + \cdots = 2^{l-1}$,其随 l 呈指数增长。因此,通常的做法是将异或最优地切割成长度为 c(通常为 4 或 6)的块或子和。c 被称为切割数。假设将其切割为长度为 4 的子和,则得到如下结果:
x₁+ x₂+ x₃+ y₁= 0
y₁+ x₆+ x₇+ y₂= 0
… … …
yᵢ+ x₄ᵢ₊₂+ x₄ᵢ₊₃+ yᵢ₊₁= 0
… … …
yₕ+ xₗ₋₂+ xₗ₋₁+ xₗ= 0
假设l ≡ 2 mod c(对于l ≠ 2 mod c的情况,最后一个求和所需的子句更少,以偶数l为例,分别为4和8)因此,可以有h= ⌈l/c⌉ −2。此外,共有h+ 1个子和,每个需要 $2^{c−1}$ 长度为c的h是虚拟变量的数量,由y₁,…,yₕ给出。找到切割数的最优值对最佳性能至关重要。实验发现c= 6是切割数[18]的最有效选择。
预处理
ANF系统中变量(n)的数量对于确定哑变量、子句数量以及子句总数起着关键作用,我们很快将对此进行说明。在牢记n作用的前提下,可以考虑在线性化步骤之前应用一种预处理方案。该方案类似于高斯消元法,由Bard等人[17]提出。其思想是将MQ系统中任意特定多项式的项按如下方式重新排序:
xₐ₀ = xₐ₁ + xₐ₂ + ⋯ + xₐₙ + (quadratic terms) + 1
其中+1项是可选的,每个aᵢ ∈ {1, 2, …, n}。我们将该方程添加到系统中每个包含xₐ₀的多项式中,除了第一个多项式之外。由于SAT求解器通常倾向于选择出现频率最高的变量进行分支决策,xₐ₀将不会被计算,直到所有其他变量都被赋值。现在,如果有t个这样的方程,则在预处理后,这t个变量将仅出现在它们的基本定义中(甚至不会相互引用)。就主系统而言,在SAT分支过程中现在只有n −t个变量参与。发现这一简单步骤大约可使SAT性能提高一倍。值得一提的是,仅选择长度为 ≤4或 ≥10的多项式进行这些替换。发现这种长度限制能够最小化过程中 β的增长。这种行为的原因归因于预处理算法类似高斯消元法的特性。此处省略更多细节。
值得一提的是,先验地固定一些变量会导致问题规模显著减小。这一技巧在代数密码分析领域也经常被使用。尽管从原则上讲,这在某种程度上违反了基本假设,但在实际中可能存在这种情况完全合理的情形(例如,如果有人在进行代数攻击之前使用侧信道分析来提取某些密钥比特时)
7.5.4 测量难度
测量一个合取范式表达式的难度,如果不显式地求解它,则是一项非常困难的任务。然而,仍然可以进行一些经验性估计。通常,变量总数、子句数量以及子句的总长度可以粗略估计该合取范式的求解难度。在本小节中,我们将尝试从对应的代数正规形表达式来估计所生成的合取范式的难度。在实践中,这可能有助于快速判断使用SAT求解某个多项式系统是否合理。
不失一般性,我们从MQ系统开始。设n为变量的总数,M为二次 ANF系统的单项式总数。令β表示单项式在多项式中出现的概率,即系统的稀疏性。在线性化步骤中,转换单个单项式的代价是1个哑变量和3个总长度为7的子句。这需要对系统中的总共M −n −1个二次单项式进行。常数单项式需要1个哑变量,对应的子句长度为1。
线性化之后的代数正规形到合取范式的转换步骤需要估算每个方程的预期长度。对于M个可能的系数,该长度将等于Mβ。假设暂定切割数为c= 4,则每个方程将有Mβ/2 −1个子和,需要引入Mβ/2 −2个虚拟变量,以及总长度为16Mβ/2 −32的4Mβ −8个子句。因此,总体上应得到以下结果:
-
Number of Variables
: n + 1 + (M − n −1)(1) + m(Mβ/2 −1)
-
Number of Clauses
: 0 + 1 + (M − n −1)(3) + m(4Mβ −8)
-
Length of all Clauses
: 0 + 1 + (m − n −1)(7) + m(16Mβ −32)
其中m是方程的数量。代入,m= γn和M= n²/2 + n/2 + 1,
-
Number of Variables
: n²/2 + γn³β/4
-
Number of Clauses
: 3n²/2 + 2γn³β
-
Length of all Clauses
: 7n²/2 + 8γn³β
此外,只要 β > 1/m,每个表达式的第一项都可以忽略。另一种情况,即 β < 1/m,会导致每<方程>(n+ 1)/2γ个<单项式>,只要 γ不太大,这确实是稀疏的。无需考虑这种情况。
需分别讨论该情况。然而,合取范式难度度量会随着切割数的变化而变化。有关此问题的更多细节,请参见[17, 18]。
到目前为止,我们仅考虑了用于合取范式难度分析的MQ系统。同样也应研究三次(MC)系统,因为在许多情况下(例如DES方程),考虑到稀疏性和超定性,三次方程是最自然的选择。然而,三次系统需要大量的手动预处理(参见上一节以及Bard [18]的论文)。三次系统的主要问题在于单项式的数量远多于其二次对应项。此外,还存在一个问题:系统中是否会出现所有可能的单项式。直观上可以认为,在非常大的概率下,许多单项式将不存在。但在 β固定之前,这并不是问题,因为根据定义, β是任意单项式出现在方程中的概率——与其次数无关。考虑m个方程时,单项式出现在系统中的概率为 1 −(1 − β)^m。现在有趣的是计算出β的一个合适估计值,使得系统中存在的单项式数量不超过预期单项式总数的一个分数r,即:
1 −(1 − β)^m ≤ r
由于在实际中, β(< 1/2)是一个小量,因此可将上述不等式近似为 mβ ≤ r。出于实际考虑,仅当系统中实际缺失的单项式达到3/4或更多(即r< 1/4)时才值得考虑。现在可以较为准确地估算二次‐立方情况下的 β值。
对于一个三次系统,总共(n³) ≈n³/6 个三次单项式是可能的,每个需要 1 个虚拟变量,4 个子句且总长度为 10。注意,二次单项式在此仍然相关。因此,可能的单项式总数为 M=(n³)+(n²)+(n¹)+(n⁰) ≈n³/6。任意多项式的预期长度为 Mβ ≈ βn³/6。考虑切割数为4的情况,这将需要 ≈ βn³/12 个虚拟变量以及 ≈ (2/3)βn³ 个子句,总长度为 ≈ (8/3)βn³,用于每个 m方程。因此,三次情况在各个方面都与二次情况类似。
到目前为止,我们主要讨论了一些重要的概念和数学工具,这些工具主要是为代数密码分析而开发的,同样也适用于AFA。通过上述概念,现在可以将任意给定的密码算法表示为代数正规形中的方程组,并最终转换为合取范式,以便由SAT求解器求解。从下一节开始,我们将主要关注AFA。值得一提的是,Sage工具[62],包含了本文所讨论的大多数算法的优化版 Python实现。鼓励读者动手使用该工具,以更好地理解这一主题。
7.6 代数故障分析
代数密码分析为经典密码分析开辟了一个全新的方向。尽管代数密码分析比其他最先进的密码分析方法更具系统性和形式化,但迄今为止其成功案例仍然有限。除了在缩减轮版本中,尚无任何标准密码算法被代数密码分析攻破。即便结果相对悲观,代数密码分析在与其他攻击手段结合时(例如侧信道分析(SCA)或故障分析(FA))仍被认为极为有用。事实上,代数侧信道分析(ASCA)通常被认为是迄今为止设计出的最高效的侧信道技术之一 [138, 153, 184]。ASCA的主要思想是将侧信道轨迹(例如功耗轨迹)以方程的形式编码,并将其添加到密码方程系统中。研究发现,即使对于AES等大型密码算法,加入这些泄露信息后,原本无法求解的方程系统可在几秒内被求解[153],。已有大量工作针对ASCA的不同方面进行了研究[138, 153, 184],此处不再详述。然而,ASCA相较于其他侧信道技术的关键优势在于其极低的数据复杂度(在低噪声场景下,仅需几条轨迹即可)。此外,它能够并行地利用轨迹中的所有数据点。尽管噪声的存在会引发一些问题,但赵等人已表明可通过引入额外变量来处理这些问题[184]。
然而,本章的主要重点是AFA,它是一个比ASCA相对较新的概念。AFA最初由库尔图瓦在[55],中提出,并应用于DES。研究发现,在DES的第13轮引入单个2比特故障并已知24个密钥比特的情况下,可在0.01h内恢复剩余的密钥比特,比穷举搜索快10倍。关于AFA的下一项重要工作是由约瓦诺维奇等人完成的,他们以LED为例,展示了针对轻量级分组密码的首个AFA攻击[85]。赵等人 [181],在此方向上取得了进一步进展,他们对多种分组密码(主要是轻量级密码)实施了AFA。研究发现,AFA同样适用于AES[181]和Twofish[180]等大型密码算法。然而,其涉及的计算成本极高(例如,对于Twofish,使用280 MB的攻击脚本耗时24小时[180]),相较于常规的DFA并无显著优势。相比之下,对于 LED、PRESENT、Piccolo、LBlock等轻量级密码算法,AFA在大多数情况下可在数秒内恢复完整密钥[185]。
然而,AFA 的主要成功之处在于其他方面。人们可以将该方法视为一种用于故障分析攻击和安全评估的通用框架。尽管大多数最先进的 DFA(差分故障分析)需要大量的人工干预,而 AFA 仅需提供密码算法以及构建额外的故障方程,这一过程具有足够的系统性,且易于实现自动化。考虑到 AFA 的这一特性,张等人构建了一个用于密码算法抗故障攻击的评估 [180] 框架。我们接下来关于 AFA 的讨论将主要围绕这一主题展开。
7.6.1 通用故障攻击框架
对于任意密码算法,存在多个可以注入故障的点。然而,并非所有注入的故障都会导致成功攻击。我们将能够实现成功攻击的故障称为可利用故障。在实际中,由于密码算法整体故障空间的多样性,难以确定哪些故障是可利用的。即使故障注入的轮次保持固定,人们仍可能考虑在状态的各个不同位置注入故障。密钥调度是另一个可能引发成功攻击的位置。此外,还可以考虑修改密码算法的轮计数器,通过减少轮数来有效降低其安全性。最终将证明, AFA的基于方程的框架能够高效地编码上述所有场景。在此之前,为了进行数学分析,我们需要提供一个故障攻击的形式化模型。该模型应能够精确地编码任何给定密码算法的所有可能故障场景。尽管此类模型可能存在多种描述方式,但此处我们采用张等人在[180]中提出的方法。
故障的形式化模型可以描述为一个五元组:
F= 〈X, λ, w, t, f 〉.
此处X是一个中间状态,故障将被注入于此,而X ∗表示故障注入后的错误状态。在整个讨论中,X被称为故障的位置。Xᵢ是X的单元,用于确定状态的组织方式。实际上,X可以是密码算法在某一特定轮次r的某个状态寄存器,或密钥寄存器,甚至是轮计数器状态。注意,当考虑在状态或密钥调度中进行故障注入时,轮次信息与X本身密切相关;在这种情况下,可以将X表示为Xᵉⁿʳ或Xᵏˢʳ。 alternatively,如果故障被注入到轮计数器中,则无需考虑注入的轮次。 λ表示状态X的宽度,通常以比特为单位。
在我们的形式化构造中,注入的故障用 f 表示。在描述故障时,必须说明其所遵循的故障模型。本例中的故障模型由故障宽度 w 概括。w 的典型值为 1、4 或 8,分别表示位故障、半字节故障和字节故障模型。唯一剩下的参数是 t,它指的是状态 X 中的故障位置。参数 t 根据故障宽度 w 指定故障要注入的 X 中的单元。通常情况下,对于给定的 X, λ(λ= |X|) 和 w,t ∈{0, 1, 2, . . . , ⌈λ/w⌉}。此外,根据场景的不同,t 可能是已知的或未知的。
现在可以利用上述形式化构造来描述密码算法中的不同故障注入。通常在AFA中,由于注入的故障而产生的额外关系也被编码为代数正规形中的多项式方程。我们将这些方程称为fault equations。需要注意的是,术语上的表述可能具有误导性,因为在故障攻击领域,相同的术语fault equations常常指的是跨S盒构建的故障差分方程。在本章中,我们将使用该术语仅指代代数正规形中的故障关系。故障方程与原始密码方程组结合后,显著降低了密钥搜索复杂度,最终导致成功攻击。接下来的两个小节将通过轻量级分组密码PRESENT [33],及其对应的故障方程作为案例研究,详细介绍其完整的代数正规形描述。对于其他密码算法的扩展也相当直接。
7.6.2 案例研究:PRESENT的代数正规形方程系统
我们简要回顾一下,PRESENT是由博格达诺夫等人在CHES 2007[33]上提出的一种轻量级分组密码。它采用SPN结构,具有64位分组大小和31轮,密钥长度为80或128位。其中80位密钥版本被广泛研究,我们的工作也采用此版本。
PRESENT的每一轮包含三个主要操作:首先是addRoundKey(AK),即将一个64位轮密钥与状态进行异或;其次是sBoxlayer(SL),该层通过16个相同的 4 × 4 S盒执行替换操作;最后是pLayer(PL),即一个64位置换操作。
PRESENT‐80的密钥调度由简单的位旋转、S盒查找和轮计数器异或操作组成。PRESENT的S盒和置换操作已在第4章中描述,因此此处不再赘述。
轮密钥加法方程
轮密钥加法生成PRESENT方程系统中最简单的方程。设x₀|| x₁… || x₆₃为一个64位状态,k₀||k₁… ||k₆₃为轮密钥,y₀||y₁… ||y₆₃为轮密钥加法后的输出变量。则对应的方程可表示为:
xᵢ + kᵢ + yᵢ = 0, 0 ≤ i ≤ 63
S盒方程
PRESENT的S盒可以通过第7.5节中描述的方法转换为以下代数方程。S盒的输入表示为x₀|| x₁|| x₂|| x₃,,输出表示为y₀||y₁||y₂||y₃。值得注意的是,确实可能存在更简单的表示形式。然而,从AFA的角度来看,以下S盒表示效果最佳。该表示使用变量的次数逆字典序排列,并且计算了格罗布纳基以增加方程数量。阿尔布雷希特和西德在[4]中也采用了类似的表示方法。应注意,该表示仅包含一个三次项,大多数非线性单项式本质上是二次的。但这并不能完全解释为何这种S盒表示对PRESENT最为有效。事实上,最近Courtois 等人[52]提出了一种对PRESENT更优的实现方式S盒,其中仅包含14个门电路,使用中间变量。这种表示方式在此上下文中可能效果更好,但尚未经过测试。
y₂x₃ + y₃x₃ + x₁x₃ + x₂x₃ + x₃ = 0
y₀x₃ + y₀ + y₃x₃ + y₃ + x₁x₃ + x₁ + x₂x₃ + x₂ + x₃ + 1 = 0
y₃ + x₀ + x₁x₂ + x₁ + x₃ = 0
y₀ + y₁ + y₃x₃ + y₃ + x₀x₂ + x₀ + x₁x₃ + x₂x₃ + x₂ + y₃ = 0
y₀ + y₁ + x₃y₂ + x₃y₃ + x₃ + x₀ + x₁x₃ + x₂ + y₃ = 0
x₀y₂ + x₁y₂ + x₁y₃ + y₁ + x₃x₃ + x₀ + x₁ + y₂ + 1 = 0
y₁ + y₂ + x₃x₃ + x₀x₁ + x₁x₃ + x₁ + x₂x₃ + x₂ + x₃ + 1 = 0
y₁ + y₂ + y₃x₁ + y₃x₃ + y₃ + x₀ + x₁ + x₂x₃ + x₂ + 1 = 0
y₀ + y₂x₁ + y₂x₂ + y₃x₃ + x₀x₃ + x₀ + x₁x₃ + 1 = 0
y₀ + y₁x₁ + y₁x₃ + y₁ + y₂x₂ + y₂ + y₃ + x₀x₃ + x₁x₃ + x₂ + x₃ = 0
y₀x₁ + y₁x₂ + y₁x₃ + y₁ + y₂ + y₃ + x₀x₃ + x₀ + x₁ + x₂x₃ + 1 = 0
y₀ + y₁x₂ + y₁x₃ + y₁ + y₂x₂ + y₂ + y₃x₀ + y₃x₃ + x₀x₃ + x₁ + x₂x₃ + x₃ = 0
y₀ + y₁x₂ + y₁ + y₂x₀ + y₂ + x₀x₃ + x₁ + x₂ + x₃ = 0
y₀ + y₁x₀ + y₁x₃ + y₂ + y₃ + x₀x₃ + x₀ + x₁x₃ + x₁ + x₂x₃ + x₃ + 1 = 0
y₀x₀ + y₀ + y₁x₃ + y₁ + y₂x₂ + y₃ + x₀ + x₁x₃ + x₃ = 0
y₀ + y₁x₃ + y₁ + y₂y₃ + y₂ + y₃x₃ + y₃ + x₀x₃ + x₀ + x₂x₃ = 0
y₁y₃ + y₁x₂ + y₁x₃ + y₁ + y₂x₂ + y₃x₃ + y₃ + x₀x₃ + x₁x₃ + 1 = 0
y₀y₃ + y₀ + y₁x₃ + y₂ + y₃x₃ + x₀x₃ + x₁x₃ + x₁ + x₃ + 1 = 0
y₀ + y₁y₂ + y₁x₃ + x₀x₃ + x₀ + x₁x₃ + 1 = 0
y₀y₂ + y₁ + y₃ + x₃ + 1 = 0
y₀y₁ + y₀ + y₁x₃ + y₁ + y₂ + x₀x₃ + x₂x₃ + x₂ + x₃ + 1 = 0
y₁x₂x₃ + y₁x₂ + y₃x₃ + y₃ + x₀x₃ + x₀ + x₁x₃ + x₁ + x₂x₃ + x₂ = 0
置换层的方程
表示PRESENT置换层最简单的方法是使用以下方程,其中xᵢ和yᵢ(0 ≤ i ≤ 63)分别表示输入和输出变量。
xᵢ + y_P(i) = 0, 0 ≤ i ≤ 63
完整的方程系统
PRESENT的完整方程表示需要为每一轮引入新变量集。同时,还需要写出密钥调度方程,否则各轮次之间的密钥变量将被视为相互独立,从而显著增加搜索的复杂度。我们在此不提供密钥调度方程,将其作为练习留给读者。
至于数据路径方程,每一轮将通过置换层方程与下一轮的变量相连接。完整的方程系统包含13642个方程,涉及4172个变量。值得注意的是,在为单个明文‐密文对构建方程系统时,必须将相应的方程一并添加。如果有多个明文‐密文对,则必须为每一对分配新的变量集和方程。最近,[181]中的作者声称使用解密方程而非加密方程可使AFA运行更快。这一说法在某些情况下已通过实验得到支持。然而,在许多情况下(如PRESENT),加密方程同样有效。因此,究竟哪种选择最优仍是一个开放性问题。
一旦构建了密码方程系统,下一步显然就是将故障表示为ANF方程。这部分专用于AFA,并显著降低了密钥的搜索空间复杂度。从下一节开始,我们将分析故障对密码算法的影响。
7.6.3 故障方程的构造
AFA中的故障方程构建比DFA更为通用。给定一个故障F(X, λ, w, t, f),我们首先添加额外变量来表示系统中的错误值。通常情况下,对于在r轮次密码算法第r轮的故障注入,需要为第r轮及之后所有轮次分配附加变量,以表示错误值。设Y表示第r轮的错误状态,X表示正确状态。如果状态大小为 λ‐比特,则可将其分别表示为Y = y₁||y₂|| … ||y_λ和X = x₁||x₂|| … ||x_λ。现在给定故障宽度w,故障注入可能的位置共有m = λ/w种。需要注意的是,此处讨论的是每次在状态中仅注入单个故障实例的情况。
设Z= z₁||z₂|| … ||z_λ表示X与Y之间的差值。实际上,它们可以用以下方程表示:
zᵢ + xᵢ + yᵢ = 0, 1 ≤ i ≤ λ (7.3)
给定故障注入的 m个可能位置,我们将 Z划分为 m个块Z₁||Z₂… ||Z_m,具体如下:
Zᵢ = z_{w×(i−1)+1}||z_{w×(i−1)+2}|| … ||z_{w×i}, 1 ≤ i ≤ m (7.4)
在实际场景中,攻击者可能知道也可能不知道t的确切位置。根据这一信息,故障方程可能有不同的表示。如果t已知,则Z可以表示如下:
Zᵢ = 0, 1 ≤ i ≤ m, i ≠ t (7.5)
and
u_t = (1 + z_{w×(t−1)+1})(1 + z_{w×(t−1)+2})…(1 + z_{w×t}) = 0, (7.6)
其中 u_t是一个比特变量,用于表示 Z_t存在故障。利用公式(7.5)和(7.6),故障通过 w+ 1个变量和 w(m+ 1)+ 2个CNF方程表示。
第二种情况是,攻击者不知道故障在目标轮次 r 中的确切位置。在这种情况下,我们引入变量 u_i 1 ≤ i ≤ m,用于表示每个 Z_i数据块的故障状态。
u_i = (1 + z_{w×(i−1)+1})(1 + z_{w×(i−1)+2})…(1 + z_{w×i}), 1 ≤ i ≤ m (7.7)
如果u_i= 0,Z_i将是与w比特位故障相关联的变量。假设只有一个且必须有一个 Z_i数据块发生故障,则应仅存在一个为0的u_i。该约束可通过以下方程表示:
(1 + u₁) ∨(1 + u₂) ∨⋯ ∨(1 + u_m) = 1
u_i ∨ u_j = 1, 1 ≤ i < j ≤ m (7.8)
方程(7.7)和(7.8)产生m(w+ 2)个变量和m(2w+ 0.5m+ 1)个合取范式方程。
这些方程可以通过w、m和 λ的故障进行参数化。注意,在方程构建的任何阶段都不需要故障值f。对于PRESENT,典型的 λ、w和m值可分别取为64、4(半字节故障模型)和16。比特和字节故障模型在此情况下同样适用。可以很容易地观察到,整个方程构建过程完全是通用的,这使得AFA成为自动故障分析的一个强大工具。
7.6.4 AFA流程
一次成功的AFA通常需要多个故障密文才能成功。其主要思想是将密钥搜索空间的大小减少到一个非常小的值。通常情况下,每次注入都会在一定程度上降低搜索复杂度。尽管这种减少可以从数学上进行分析,但对于通过 AFA成功恢复主密钥而言并非必需。在本节后面,我们将展示一种自动化的计算方法来估计搜索空间的大小。
算法8给出了AFA的完整伪代码。它改编自[180],,并做了一些小的修改。目前,我们假设故障注入在加密算法的数据路径上。对于密钥调度和轮计数器中的故障,也可以构建类似的过程。参考算法8,从在第r轮加密中插入N个w比特故障开始。位置t可能因场景不同而未知。该算法的输出是求解主密钥所需的时间(t_sol)。需要注意的是,根据具体场景,该算法可能无法在合理时间内求解问题实例。对此场景的标准处理方法是设置一个合理的超时时间t_out。如果算法未能找出密钥,则输出t_sol= t_out。需要注意的是,算法8 被设计为一种验证机制,密钥在其内部生成。但也可以很容易地提供明文和密文,使用某个故障实例和未知密钥加密,将此算法构造成一个真正的攻击算法。
算法8 AFA数据路径故障处理流程
输入: N,r,w,b_t,t_out
t_sol
1: 随机明文 (P)
2: K = KS (K,L)
3: 对于 rc= 1到r_max do
4: GenKSRdES (rc, K_rc+1) #1
5: 结束循环
6: 对于 i= 0 到 N −1执行
7: C_i= Enc(P_i,K)
8: 对于 rc= r −1到 r_max −1 do
9: GenEnRdES (X_rc+1, X_rc, K_rc+1) #2
10: end for
11: GenInputES (C_i)
12: C∗_i= InjectFault (Enc (P_i, K), X_r)
13: 对于 rc= r −1到 r_max −1 do
14: GenEnRdES (X∗_rc+1, X∗_rc, K_rc+1) #3
15: 结束循环
16: GenInputES (C∗_i)
17: Gen故障ES ( f= X_r+ X∗_r) #4
18: 结束循环
19:RandomPT (P_v)
20: C_v= Enc (P_v, K)
21: 对于 rc= 0到r_max −1 do
22: GenEnRdES(X′_rc+1, X′_rc, K_rc+1) #5
23: 结束循环
24: GenInputES (P_v,C_v) #6
25: t_sol=运行AFA() #7
在算法8中,P 和 K 分别表示明文和密文空间。KS 和 Enc 分别表示密钥调度和加密函数。RandomPT 生成一个或多个随机明文,InjectFault 引发一次故障。生成方程组的函数以 Gen 开头,以 ES 结尾。在攻击过程中,攻击者选择 N 对明文/密文,并开始构建方程。首先,构建密钥调度的方程(算法中的#1)。接着,对每个 N 次加密执行一次故障注入,并从注入轮次(r)开始构建相应的正确和错误方程,同时在注入轮次构建相应的故障方程(见算法中的#2、#3和#4)。该系统若求解返回多个解,则除其中一个外其余均为错误解。候选密钥来自故障注入后缩小的密钥搜索空间。根据注入故障的参数不同,候选密钥的数量会有所变化。正如我们将在本节后面看到的,候选密钥的数量可能从1到 2^s不等,其中 s ≤ λ_s 可以是不超过密钥长度 λ_s的任意数值。在最坏情况下,可能无法显著缩小密钥搜索空间。
为了自动消除虚假解,需将一对明文‐密文验证对(P_v,C_v)添加到方程系统中。需要构建一个包含该验证对的完整加解密方程组。此步骤的目标是确定正确的密钥并返回该密钥。但需要注意的是,如果故障注入后剩余密钥空间的大小仍然显著较大,则加入该验证对后可能导致求解时间急剧增加。
一旦构造出方程系统,便会将其转换为合取范式(CNF),并输入给SAT求解器。在AFA社区中最常用的选择是CryptoMiniSAT [168],,它专门针对异或子句进行了优化。正如我们所见,异或子句在密码学问题中非常常见,这使得CryptoMiniSAT成为该任务的理想选择。
在给出了AFA攻击的一般流程后,我们来研究其对PRESENT数据路径的影响。关于结果的全面分析可参见[180],此处仅提供简要总结。需要注意的是,攻击仅针对PRESENT‐80进行。同时,针对第28轮和第29轮在不同故障宽度下的攻击也进行了研究。研究发现,在第28轮注入故障比第29轮更高效。事实上,在大多数情况下,只需在第28轮注入2个故障(w= 1,位故障),即可在三分钟内恢复密钥。进一步假设攻击者已知t。对于其他故障模型w= 4,8,16,32,性能有所下降,其中32比特故障的表现最差。对于半字节故障,在某些情况下,同一轮次的攻击可能需要长达9000秒;实际上,某些情况下即使

被折叠的 条评论
为什么被折叠?



