QcBits:基于小密钥的码基密码实现

QcBits:基于常数时间小密钥的码基密码学

摘要

本文介绍了一种基于准循环中等密度奇偶校验码(QC‐MDPC)加密方案的恒定时间实现。在 280安全级别下,该软件解密一条短消息需要 14 679 937个Cortex‐M4周期和1 560 072个Haswell周期,而此前的记录分别为18 416 012和3 104 624(非常数时间)Haswell周期。这一速度是通过结合两种技术实现的:1)使用一系列“恒定时间旋转”在 F2[x]/(xr − 1)和 Z[x]/(xr − 1)中执行每个多项式乘法;2)位切片。

关键词 :麦克里斯 · Niederreiter · QC-MDPC codes · Bitslicing · 软件实现

1 引言

2012年,Misoczki 等人提出将QC‐MDPC码用于基于编码的密码学[3]。使用 QC‐MDPC码的主要优势在于它们允许较小的密钥尺寸,这与原始McEliece 论文中提出的使用二元戈帕码的方法不同[1]。自那以后,已针对各种平台发布了多篇实现论文;参见[4,5](针对现场可编程门阵列和AVR)[7,9](针对 Cortex‐M4)以及[11](针对Haswell,包含来自[4,5,7]的结果)。

QC‐MDPC码的一个问题是,当最广泛使用的解码算法被简单实现时,会通过时间泄露秘密信息。尽管解码仅用于解密,但如果密钥生成和加密不是恒定时间的,同样可能产生此问题。不幸的是,唯一解决时间攻击问题的软件实现论文是[7]。[7]在没有缓存的平台(针对可写内存)上提供了恒定时间的加密和解密。

本文介绍了QcBits(发音为“quick‐bits”),即一种基于准循环中等密度奇偶校验码(QC‐MDPC)加密方案的完全恒定时间实现。QcBits提供恒定时间的密钥对生成、加密和解密,适用于包括带缓存的平台在内的多种平台。QcBits 遵循 McBits 论文 [17],采用了一种混合型(KEM/DEM) Niederreiter 加密方案的变体,该变体在 [13,14] 中提出。(此变体并未完全遵循 KEM/DEM 构造,因为从 KEM 到 DEM 多传递了一个“KEM 失败”位;见 [17])作为 KEM/DEM 加密方案的一个特性,该软件能够抵御自适应选择密文攻击,而普通的麦克里斯或 Niederreiter [2] 加密方案则不具备此能力。

代码使用 C语言 编写,易于理解和验证。此外,QcBits 的性能结果优于所有先前的实现论文所达到的结果;见下文。

读者应注意,QcBits在当前版本中使用了来自 280 的 [3] 安全参数集。请注意,经过一些小的修改后,QcBits也可用于 2128安全性。然而,我尚未找到适用于 2128安全性的解码器的良好“阈值”,这些阈值能够实现较低的失败率,因此决定不在当前版本中包含 2128安全性的代码。此外,所使用的密钥空间小于 [3] 中描述的密钥空间。但这一点对于所有先前的实现论文 [4,5,7,9,11] 同样成立。做出这些设计选择是为了达到较低的解码失败率;更多讨论请参见第 2.1和 7节。

性能结果

表1。性能结果: QcBits、 [7,9],以及在 [11] 中的向量化实现。 “密钥对”列显示生成密钥对的周期计数。“加密”列显示加密操作的周期计数。“解密”列显示解密操作的周期计数。对于 Qcbits 的性能数据,使用 59 字节明文以遵循 eBACS [16] 约定。对于 [9] 32 字节明文被使用。标有 * 的周期计数表示该操作的实现在此平台上不是恒定时间的,这意味着最坏情况下的性能可能要差得多(特别是对于解密)。请注意,所有结果均针对 280 安全级别(r= 4801, w= 90, t= 84;参见第 2.1 节)。

平台 密钥对 加密 解密 参考实现 方案
Haswell 784 192
20 339 160
*14 234 347
82 732
225 948
*34 123
1 560 072
2 425 516
*3 104 624
(new) QcBits
(new) QcBits
[11]
clmul
ref
桑迪桥 2 497 276
44 180 028
151 204
307 064
2 479 616 3 137 088 (new) QcBits
(new) QcBits
clmul
ref
Cortex‐A8 61 544 763 1 696 011 16 169 673 (new) QcBits ref
Cortex‐M4 140 372 822
*63 185 108
*148 576 008
2 244 489
*2 623 432
7 018 493
14 679 937
*18 416 012
42 129 589
(new) QcBits
[9]
[7]
no-cache

在Haswell微架构上,QcBits的解密速度约为[11]的两倍,在密钥对生成方面则快一个数量级,即使[11]的实现并非恒定时间。QcBits在加密时消耗的周期数要多得多。这主要是因为QcBits使用了较慢的随机性来源;更多讨论见第3.1节。另一个次要原因是KEM/DEM加密本质上比McEliece加密需要更多的操作,例如哈希。

在Cortex‐M4上的测试使用STM32F407进行QcBits和[7], ,而[9]使用 STM32F417。请注意,这些设备上的可写内存(SRAM)没有缓存。QcBits 在加密和解密方面比[9]更快。与[7]相比,差异更为显著。ST M32F407/417产品线提供从512千字节到1兆字节的闪存。[9]报告的闪存使用量为16千字节,而包含对称原语时,无缓存 实现使用62千字节闪存,不包含对称原语时使用38千字节。有关对称原语的更多讨论,请参见第2.3节。

需要注意的是,由于解码算法是概率性的,每种解密实现都带有一定的失败率。对于QcBits在 108次试验中未发生解密失败。我尚未找到能够在相同安全级别下达到同等失败率的解码算法阈值,因此 QcBits 使用了 2128安全级别的参数集。对于 280,在 [11],次试验中未发生解密失败。对于 107,失败率未明确指出,但其解码器似乎与 [9]相同。目前尚不清楚 [11]所达到的失败率水平。有关失败率的更多讨论,请参见第7节。

表2显示了128位安全的性能结果。使用从[3,第A节]中的公式推导出的阈值,在进行12次解码迭代时会导致失败率为 6.9·10−3。实验表明,存在一些阈值集合,在使用19次解码迭代时可实现约 10−5的失败率,但这仍然远未达到 10−8;有关阈值,请参见第6节。注意,[9,11]并未说明他们在128位安全下所达到的失败率,而[7]没有128位安全的实现。据[3]报道,在论文中提出的所有参数集(包括用于表1和2的参数集)的次试验中均未发生解密失败,但他们未提供细节,例如需要多少次解码迭代才能实现这一点。

表2。QcBits、[9],以及[11]中针对128位安全的向量化实现的性能结果(r= 9857, w= 142, t= 134;见第2.1节)。QcBits解密的周期计数已加下划线,以表示这些是 单次解码迭代的周期计数。实验表明,QcBits使用19次解码迭代可实现约10−5的失败率 (见第6节)。

平台 密钥对 加密 解密 参考实现 方案
Haswell 5 824 028
*54 379 733
196 836
*106 871
1 363 948 *18 825 103 (new) QcBits
[11]
clmul
Cortex‐M4 750 584 383
*251 288 544
6 353 732
*13 725 688
7 436 655 *80 260 696 (new) QcBits
[9]
no-cache

与其他后量子公钥系统的比较

2013年,我与伯恩斯坦和施瓦布共同提出了 McBits(参见[17]),一种使用二元Goppa码的KEM/DEM加密方案的常数时间实现。在 2128安全级别下,该软件解密仅需60493个Ivy Bridge周期。看起来QcBits似乎比McBits慢得多。然而,读者应牢记,McBits依赖外部并行性来实现如此速度:周期数是将256个解密实例并行运行的时间除以256得到的结果。而QcBits的速度仅依赖于内部并行性:表1中给出的时间均为仅运行一个实例的结果。

基于格的系统以高效著称,而遗憾的是QcBits无法与其中最优者相竞争。例如,eBACS网站报告指出,在 2128安全级别下,ntruees439ep1的加密需要54940 Haswell周期(非常数时间),解密需要57008 Haswell周期(非常数时间)。此外,最近发表的用于后量子密钥交换的“Newhope”论文[32],在针对 2128量子安全级别时,报告了服务器端密钥生成需要115414 Haswell周期(恒定时间),服务器端共享密钥计算需要23988 Haswell周期(恒定时间),以及客户端密钥生成加上共享密钥计算共需144788 Haswell周期(恒定时间)。

值得注意的是,使用QC‐MDPC码替代二元戈帕码可以实现更小的密钥尺寸。[3] 报告称,对于 280‐安全参数集(即表1中所用参数集),公钥大小为601字节;对于 2128‐ 安全参数集(即表2中所用参数集)为1233字节;对于 2256‐安全参数集则为4097字节。[17]报告称,对于 280‐安全参数集为74624字节,对于 2128‐安全参数集为221646字节,而对于 2256‐安全参数集则达到1046739字节。ntruees439ep1的公钥大小为609字节。Newhope的“消息大小”为1824字节(服务器到客户端)和2048字节(客户端到服务器)。

二元戈帕码的使用由McEliece于1978年在[1]中提出,同时提出了 McEliece密码系统。将近40年过去了,该系统的实际安全性并未发生实质性改变。NTRU密码系统至今已有近20年历史。然而,基于QC‐MPDC码的密码系统仍然相当年轻,因此需要一些时间来获得公众的信任。

2 预备知识

本节介绍后续章节所需的预备知识。第2.1节简要回顾QC‐MDPC码的定义。第 2.2节描述用于解码QC‐MDPC码的“比特翻转”算法。第2.3节给出了由 QcBits实现的KEM/DEM加密方案的规范。

2.1 准循环中等密度奇偶校验码

“MDPC”代表“中等密度奇偶校验”。顾名思义,MDPC码是一种在线性码的奇偶校验矩阵 H中具有“适度”数量非零元素的线性码。为便于讨论,本文假设 H ∈Fr×n 2 ,其中 n= 2r,尽管某些参数集[3]使用 n= 3r或 n= 4r。H被视为两个方阵的连接,即 H= H(0)|H(1),其中 H(i) ∈ Fr×r 2 。

“QC”代表“准循环”。所谓准循环,是指每个 H(i)都是“循环”的。为了便于讨论,可以认为这意味着

H(k) (i+1) mod r,(j+1) mod r= H(k) i,j,

尽管原始论文允许对 H进行行置换。请注意,准循环意味着 H具有固定的行权重 w。以下是具有 r= 5, w= 4的小型校验矩阵:

⎛ ⎜⎜⎜⎜⎝
1 0 1 0 0 0 1 0 0 1 0 1 0 1 0 1 0 1 0 0 0 0 1 0 1 0 1 0 1 0 1 0 0 1 0 0 0 1 0 1 0 1 0 0 1 1 0 0 1 0

⎟⎟⎟⎟⎠.

一种编码能够纠正的错误数量通常表示为 t。由于目前没有很好的方法来确定给定的准循环中等密度奇偶校验码的最小距离, t通常只是一个估计值。

Qcbits使用 r= 4801, w= 90, 和 t= 84匹配 280在 [3]中提出的 ‐安全参数集。然而,Qcbits进一步要求 H(0)和 H(1)具有相同的行权重,即 w/2。这并非新做法,因为所有先前的实现论文 [4,5,7,9,11]也以这种方式限制 H。对于QcBits而言,这是为了实现低失败率而做出的决定;有关此问题的更多讨论,请参见第7节。先前的实现论文并未解释为何以这种方式限制 H。

2.2 解码(QC‐)MDPC码

与许多其他允许高效确定性解码的线性码不同,(QC‐)MDPC码最流行的解码器—— “比特翻转”算法是一种概率性的算法。比特翻转算法采用了相同的思想使用所谓的“统计解码” [19,21]。(“统计解码”这一术语在历史上晚于“比特翻转”出现,但“统计解码”更能准确体现该算法背后的思想。) 给定一个最多与码字相差 t个错误的向量,该算法旨在通过一系列迭代输出该码字(或等价地,输出错误向量)。每次迭代会统计判断输入向量 v的 n个位置中哪些位更有可能出错,并翻转这些位置上的比特。翻转后的向量将作为下一次迭代的输入。在该算法的最简单形式中,当 Hv变为零时,算法终止。

每个位置出错的概率由未满足的奇偶校验次数表示。次数越高,该位置被认为出错的概率就越高。换句话说,位置 i出错的概率由

ui= |{i | Hi,j=(Hv)i= 1}|.

在本文中,伴随式 Hv将被称为私有伴随式。

现在剩下的问题是,给定向量u,应该翻转哪些位?在[3]中给出了两种可能性:

  • 翻转所有违反至少 max({ui}) 个奇偶校验的位置,其中 δ 是一个较小的整数,例如 5。
  • 翻转所有违反至少 Ti个奇偶校验的位置,其中 Ti是为第 i次迭代预计算的阈值。

在之前的研究中,人们发明了若干变体。例如,一种基于第一种方法的变体在解码失败时,若在10次迭代内未能成功,则使用新的 δ重新启动解码。

QcBits 使用预计算阈值。解码迭代次数设置为6,且阈值为 29, 27, 25, 24, 23, 23. 这些阈值是通过交互实验获得的。我并不声称这些是最优的阈值。使用此阈值列表,在 108次解码试验中未发生迭代失败。有关实验的更多细节,请参见第6节。

先前的实现论文[4,5,7,9,11]中取得的最佳结果是通过预计算阈值方法的一种变体实现的。在该变体的每次迭代中,按顺序计算 ui’s。如果当前 ui大于或等于预计算阈值,则翻转 vi,并通过将 i‐th列的 H加到校正子上来直接更新校正子。采用这种变体,[11]报告平均迭代次数仅为2.4。

QcBits 始终执行 6 次解码迭代,这远多于 2。4。然而,接下来几节中介绍的算法使得 QcBits 能够非常快速地执行每次迭代,尽管是恒定时间的。因此, Qubits 在解密方面仍然实现了更好的性能结果。

2.3 用于QC‐MDPC码的混合Niederreiter加密系统

KEM/DEM加密使用Niederreiter加密方案作为KEM。Niederreiter加密用于加密一个随机向量 e,其权重为 t,然后将其输入密钥派生函数以获得对称加密和认证密钥。密文随后是Niederreiter密文、对称密文以及对称密文的认证标签的拼接。解密的工作方式与加密类似;详见 [17]以获取更详细的描述。默认情况下QcBits使用以下对称原语:Keccak [23], Salsa20[25],和Poly 1305[24]。更准确地说,QcBits使用具有512位输出的Keccak来哈希 e,对称加密密钥和认证密钥定义为哈希值的前半部分和后半部分。对于对称加密和认证,QcBits使用nonce 0的Salsa20和Poly1305。注意QcBits并未实现 Keccak、Salsa20和Poly1305;它仅提供调用这些原语的接口。对于表1中的实验结果,对称原语的实现来自SUPERCOP基准测试工具包。用户可以使用自己实现的原语,甚至使用其他对称原语(在这种情况下,用户必须更改硬编码参数,例如MAC的密钥大小)。

私钥是随机奇偶校验矩阵 H的一种表示形式。由于首行 H已包含生成整个矩阵的足够信息,因此只需使用{j | H(0) 0,j= 1}中的索引数组和{j | H(1) 0,j= 1}中的索引数组来表示 H即可。每个数组中的索引不应重复,但不需要排序。

QcBits将每个数组表示为长度为w的字节流,其中第 i个双字节是以小端格式表示的数组中第 i个索引。私钥即定义为这两个字节流的连接。

公钥是 H的行简化阶梯形式的一种表示。该行简化矩阵记为 P。尼德雷特要求 P(0)必须是单位矩阵 Ir,否则密钥对应被拒绝。(先前的论文如[7]使用 P(1)= Ir,但使用 P(0)= Ir在安全性上是等价的。)换句话说, P(1)包含了 P的全部信息(如果 P有效)。注意 P也是准循环的;因此QcBits将公钥定义为长度为 (r+7)/8的字节流,其中字节值为

(P(1) 7,0 P(1) 6,0 … P(1) 0,0)2,(P(1) 15,0 P(1) 14,0 … P(1) 8,0)2,…

加密过程首先生成一个重量为t的随机向量 e。 e的密文随后是公共伴随式 s= P e,它被表示为长度为 (r+ 7)的字节流/8,其中字节值为

(s7s6… s0)2,(s15s14… s8)2,....

对于哈希, e以类似于公共伴随式的方式表示为长度为 (n+ 7)/8的字节流。32字节对称加密密钥和

32字节认证密钥由字节流的64字节哈希值的前半部分和后半部分生成。明文 m使用对称密钥进行加密和认证。整个KEM/DEM方案的密文是公共伴随式、对称加密下的密文以及标签的拼接。总体上,密文占用(r+ 7)/8+ |m| + 16字节。

当接收到输入流时,解密过程将其解析为公共伴随式、对称加密下的密文 以及标签的连接。然后通过将公共伴随式输入解码算法来计算错误向量 e′。如果 Pe′= s,则解码成功。否则,发生解码失败。然后通过对 e′进行哈希生成对称密钥,以执行对称解密和验证。当且仅当验证失败或解码失败时, QcBits报告解密失败。

3 密钥对生成

本节展示 QcBits如何使用 F2[x]/(xr − 1) 中的乘法执行密钥对生成。第3.1节展示私钥的生成方式。第3.2节展示密钥对生成如何被视为F2[x]/(xr−1) 中的乘法。第3.3节展示 F2[x]/(xr−1) 中的乘法如何实现。第3.4节展示 F2[x]/(xr −1) 中的平方运算如何实现。

3.1 私钥生成

私钥定义为一个包含 w随机16位索引的数组。 QcBits通过首先从随机性来源读取32字节,然后使用 Salsa20 将这32字节扩展到所需长度来获取随机字节。 QcBits允许用户选择任意随机性来源。为了在表1中的Ivy Bridge、桑迪桥和Cortex‐M4上生成性能数据,使用 /dev/urandom作为随机性来源。为了在表1中的Cortex‐M4上生成性能数据,使用了板载的真随机数发生器,如 [9]所示。RDRAND指令被 [11]所使用,但由于对该指令存在安全担忧,因此未予考虑; 参见 RDRAND[26]的维基百科页面。有人可能会争辩说,目前没有证据表明 RDRAND存在后门,但我决定不冒这个风险。

3.2 多项式视图:公钥生成

对于任意矩阵 M,令 Mi,: 表示向量 (Mi,0, Mi,1,…),类似地定义M:,i。在第2节中,公钥被定义为表示P(1) :,0 的字节序列,其中 P 是校验矩阵 H 的行简化阶梯形式。因此,实现恒定时间公钥生成的一种简单方法是从私钥生成H, 然后执行高斯消元法。使高斯消元法实现恒定时间并不困难;例如参见 [17]。

然而,当将公钥生成视为多项式运算并利用准循环结构时,可以使其在时间和内存上更加高效。

对于任意长度为 r 的向量 v,令 v(x) = v0+ v1x+···+ vr−1xr−1。由于 H(0)是循环的,我们有

H(i) j,:(x)= xjH(i) 0,:(x) ∈ F2[x]/(xr −1).

高斯消元法诱导了 H(0)行的线性组合,从而得到 P(0) 0 ,:。换句话说,存在一组索引 I,使得

1=∑
i∈I
xiH(0) 0,:(x)=(∑
i∈I
xi)H(0) 0,:(x),
P(1) 0,:(x)=∑
i∈I
xiH(1) 0,:(x)=(∑
i∈I
xi)H(1) 0,:(x).

换句话说,公钥可以通过找到 H(0) 0的逆元来生成: (x) 在 F2[x]/(xr − 1) 中的逆元,然后将该逆元乘以 H(1) 0 :)(x)。先前的实现论文[4,5,7,9,11]使用扩展欧几里得算法计算逆元。该算法在原始形式下具有高度的非恒定时间特性。[30]提出了一种使扩展欧几里得算法实现恒定时间的方法;到目前为止,尚不清楚他们的算法是否比直接使用幂运算(见下文)更快。

为了实现恒定时间,QcBits 通过执行固定序列的多项式乘法来计算逆元。要理解这一点,首先考虑将 xr − 1 ∈ F2[x] 分解为 ∏i(f(i)(x))pi,其中每个 f(i) 都是不可约的。此时,F2[x]/(xr −1) 等价于


i
F2[x] /(f(i)(x)) pi

由于

∣ ∣ F2[x]/(f(i)(x)) pi) ∗ ∣ ∣ ∣ ∣
= 2deg(f (i))·pi ·(2deg(f (i)) −1)/2deg(f (i))
= 2deg(f (i))·pi −2deg(f (i))·(pi −1),

可以通过将其提升至幂来计算 F2[x]/(xr − 1) 中元素的逆元

lcm(2deg(f ( 1 ) )·p1 −2deg(f ( 1 ) )·(p1−1), 2deg(f ( 2 ) )·(p2−1) −2deg(f ( 2 ) )·(p2−1),…)−1.

QcBits 使用 r= 4801。多项式 x4801 −1 可以分解为

(x+ 1)f (1)
f
(2)
f
(3)
f
(4) ∈ F 2[x], 其中每个f (i) 都是一个1200次 的不可约多项式。因此,QcBits 通过将多项式提升到 lcm(2 −1, 2 1200 −1) −1= 21200 −2 次幂来计算其对模 x 4801 −1 的逆元。

在 F2[x]/(x4801 −1) 中将一个元素提升到 21200 −2 次幂可以通过一系列平方运算和乘法来实现。最简单的方法是使用平方‐乘算法,这需要1199 次平方运算和1198 次乘法。QcBits 通过为 21200−2 寻找一条优良的加法链来实现更优的性能。首先注意到,对于形如 2k −1 的整数,存在一种系统的方法来寻找良好的加法链。以 211 −1 为例,该加法链如下

1 → 102 → 112 → 11002 → 11112 → 111100002 → 111111112 → 11111111002 → 11111111112 → 111111111102 → 111111111112.

这需要10次倍增和5次加法。使用相同的方法,很容易找到一个用于 2109 − 1的加法链,该加法链需要108次倍增和10次加法。QcBits随后将 211 − 1和 2109 − 1的加法链组合起来,形成一个用于 211·109−1= 21199−1的加法链,该过程需要 10·109+108= 1198次倍增和 5+10= 15次加法。一旦计算出(21199−1)次幂,就可以通过一次平方运算计算出(21200−2)次幂。总共计算(21200−2)次幂 需要在 F2[x]/(x4801−1)中进行1199次平方运算和15次乘法。

最后,利用逆元, P(1) 0 ,:(x) 可通过一次乘法运算得到。公钥定义为 P(1):,0 的表示形式,而非 P(1) 0 ,:。因此,QcBits 通过注意到 P(1):,0 来推导出 P(1) ,:

P(1) 0,j={P(1) 0,r−j if j> 0
0,0 if j= 0.

从 P(1):,0 到 P(1) 0 ,: 的转换不需要是恒定时间的,因为它可以从公开数据轻松逆转。

3.3 在 F2[x]/(xr − 1) 中的通用乘法

此处的任务是计算 h= fg,其中 f, g ∈ F2[x]/(xr −1)。在 QcBits 中,多项式使用 r/b b 位字的数组以自然的方式表示。以 f 为例(同样适用于 g 和 h),这些 b 位的值为:

(fb−1fb−2… f0)2,(f2b−1f2b−2… fb)2,....

用户可以选择 b为32或64,但为了获得最佳性能, b应根据机器架构来选择。

令 y= xb。可以将这种表示视为使用一个 b位整数来存储f的基数‐y表示中的每个系数。本文中,这种表示称为“稠密表示”。

使用该表示方法,我们可以通过对 f和 g的 b‐比特字进行无进位乘法运算, 来计算 h的基数‐y表示中的系数(每个系数为一个 2b‐比特值)。一旦获得 2b‐ 比特值,便可经过少量后处理计算出 h的稠密表示。具体而言,

给定两个 b 位的数 (αb−1αb−2 ··· α0)2 和 (βb−1βb−2 ··· β0)2,,无进位乘法会计算出一个 2b 位的值(实际上只有 2b−1 位)


⎝ ⊕
i+j=2b−2
αiβj ⊕
i+j=2b−3
αiβj ··· ⊕
i+j=0 αiβj
⎞ ⎠
2
.

换句话说,输入值被视为F2[x]中的元素,输出则是 F2[x]中的乘积。

实现clmul使用PCLMULQDQ指令对两个64位值执行无进位乘法。对于实现ref和no‐cache,使用以下C语言代码来计算 2b位值的高位和低位 b位:

low= x*((y>> 0)& 1); v1= x*((y>> 1)& 1); low^= v1<< 1; high= v1>>(b-1); for(i= 2; i< b; i+=2) { v0= x*((y>> i)& 1); v1= x*((y>>(i+1))& 1); low^= v0<< i; low^= v1<<(i+1); high^= v0>>(b-i); high^= v1>>(b-(i+1)); }

3.4 在 F2[x]/(xr − 1) 中的通用平方运算

在 F2[x]/(xr−1) 中的平方运算可以作为乘法来执行。然而,显然平方运算的代价要低得多,因为只需要 r/b 次无进位乘法(实际上是平方运算)。

实现 clmul再次使用 PCLMULQDQ指令来执行64位多项式的无进位平方运算。根据肖恩·埃隆·安德森的“位操作技巧”中关于交错位的章节,[12],实现 ref和 无缓存 使用以下C代码两次来计算表示为32位字的32位多项式的平方:

x=(x | (x<< 16))& 0x0000FFFF0000FFFF; x=(x | (x<< 8))& 0x00FF00FF00FF00FF; x=(x | (x<< 4))& 0x0F0F0F0F0F0F0F0F; x=(x | (x<< 2))& 0x3333333333333333; x=(x | (x<< 1))& 0x5555555555555555;

通过使用该代码两次,我们还可以计算一个64位多项式的平方。

4 KEM加密

本节展示 QcBits如何通过 F2[x]/(xr − 1) 中的乘法实现KEM加密。第4.1节 说明错误向量的生成方法。第4.2节说明

4 KEM加密

本节展示 QcBits如何通过 F2[x]/(xr − 1) 中的乘法实现KEM加密。第4.1节 说明错误向量的生成方法。第4.2节说明公伴影计算如何被视为 F2[x]/(xr −1) 中的乘法运算。第4.3节说明这些乘法运算的实现方式。

4.1 生成错误向量

错误向量 e的生成方式与私钥基本相同。唯一的区别在于,对于 e,我们需要 t 个从 0 到 n −1 的索引,并且只有一组索引而不是两组。请注意,在进行哈希时,仍然需要生成 e的稠密表示。

4.2 多项式视图:公伴影计算

此处的任务是计算公共伴随式 Pe。令 e(0) 和 e(1) 分别为 e的前半部分和后半部分。则公共伴随式为

s= P(0)e(0)+ P(1)e(1)
=∑
i
P(0) :,i e(0) i+∑
i
P(1) :,i e(1) i.

由于 P是准循环的,我们有

s(x)=∑
i
xiP(0) :,0(x)e(0) i+∑
i
xiP(1) :,0(x)e(1) i
= P(0) :,0(x)e(0)(x)+ P(1) :,0(x)e(1)(x)
= e(0)(x)+ P(1) :,0(x)e(1)(x).

换句话说,私有伴随式可以使用在F2[x]/(xr − 1)中的一个乘法运算来计算。这种乘法并 非通用类型,因为 e(1)(x)是稀疏的。有关该乘法在QcBits中的实现方式,请参见下文。

4.3 F2[x]/(xr − 1) 中的稀疏‐稠密乘法

该任务可以形式化为计算 f(0)+ f(1)g(1) ∈ F2[x]/(xr −1),其中 g(1)采用稠密表示。 f(0)和 f(1)一起使用 I={i | f(0)i = 1}∪{i+ r | f(1)i = 1}中的索引数组 表示,其中 |I| = t。

当然可以以通用方式执行 f(1)和 g(1)之间的乘法运算,如第3.3节所示。实现clmul实际上会生成 f(1)的稠密表示,然后使用PCLMULQDQ指令计算 f(1)g(1)。[11]基本上采用了相同的技术。实现ref和no‐cache 然而利用了 f(0) 和 f(1) 中的稀疏性;详见下文。

现在考虑计算 h= fg ∈ F2[x]/(xr−1) 这一稍简单的问题,其中 f 以 I={i | fi= 1} 中的索引数组表示,而 g 采用稠密表示。 тогда我们有

fg=∑
i∈I
xig.

因此,ref和no‐cache实现首先设置 h= 0。然后,对于每个i ∈ I,计算 xig并 将其加到 h中。注意, xig被表示为由 r/b b位字组成的数组,因此将 xig加 到 h可以通过在 b位字上使用 r/b条按位异或指令来实现。

现在剩下的问题是如何计算 xig。显然, xig可以通过将 g旋转 i位得到。为了实现恒定时间旋转,实现 ref利用了桶形移位器 [27]的思想。该思想是首先将 i用二进制表示

(ik−1ik−2 ··· i0)2.

由于 i r−1,只需使用 k= lg(r−1)+1。然后,对于 j从 k−1到lg b,执行 一个 2j位的旋转。以恒定时间方式选择未移位向量和已移位向量中的一个,并作为下一个 j的输入。在处理完所有 ik−1, ik−2,…, ilg b之后,使用一系列逻辑指令执行(ilg b−1ilg b−2 ··· i0)2位的旋转。

为了阐明这一思路,以下是一个针对 n= 40, b= 8 情况的示例。多项式 g是

(x8+ x10+ x12+ x14)+(x16+ x17+ x20+ x21)+(x24+ x25+ x26+ x27)
+(x36+ x37+ x38+ x39),

表示为一个5字节数组

000000002, 010101012, 001100112, 000011112, 111100002.

目标是计算 xig,其中 i= 0100112。由于 lg(40 −1)+ 1= 6,算法首先计 算 1000002= 32 位的旋转,这可以通过移动字节来实现。结果是

010101012, 001100112, 000011112, 111100002, 000000002.

由于最高有效位未设置,因此选择未移位多项式。接下来我们对 0100002= 16位执 行旋转操作。结果是

000011112, 111100002, 000000002, 010101012, 001100112.

由于第二高有效位被置位,我们选择已旋转多项式。然后将该多项式左移 0010002= 8位。然而,由于第三最高有效位未被置位,因此选择未移位多项式。为了处理 i的最低有效lg b= 3位,使用一系列逻辑指令来组合字节的最高有效 0112位和最低有效 1012位, 从而得到

011000012, 111111102, 000000002, 000010102, 101001102.

注意 [3] r需要是一个素数(这意味着 r不能被 b整除),因此该示例展 示了一个较简单的情况。大致来说,实现 ref执行一次旋转,就好像向量长度 为 r −(r mod b),然后使用更多指令来补偿 r mod b额外位的影响。实现 no-cache本质上执行一次 ik−1ik−2 ··· ilg b0··· 0)2位的旋转,然后再执行一次 ilg b−1ilg b−2 ··· i0)2位的旋转。

通过恒定时间旋转,我们现在可以处理计算 f(0)+ f(1)g(1) ∈ F2[x]/(xr −1) 的 原始问题。QcBits 首先设置 h= 0。然后对于每个 i ∈ I,根据 i< r 是否成立, 选择 1 或 g(1) 中的一个,这必须以恒定时间方式执行,以隐藏关于 i 的所有信息。选定的多项式随后被旋转 i mod r 位,并将结果加到 h 上。请注意,这意味着 实现 ref 和 no‐cache 会执行虚拟多项式乘法,以隐藏关于 f(0) 和 f(1) 的信息。

5 KEM解密

本节展示了QcBits如何使用在 F2[x]/(xr −1)和 Z[x]/(xr −1)中的乘法运算来执 行KEM解密。KEM解密本质上是一种解码算法。每次解码迭代都会进行计算

  • 私有伴随式 Hv和
  • 未满足奇偶校验计数,即向量 u,使用私有伴随式。

中的位置 v然后根据计数进行5.1节展现了私有伴随式计算如何在 F2[x]/(xr −1) 中通过5.2节展现了计数未满足的奇偶校验如何被视为在 Z[x]/(xr − 1) 中的5.3节展现了这些在Z[x]/(xr−1) 中的5.4节展现了位翻转如何实现。

5.1 多项式视图:私有伴随式计算

公共伴随式和私有伴随式是相似的,因为它们都是通过矩阵‐向量乘积计算得到 的,其中矩阵是准循环的。对于公共伴随式,矩阵是 P,向量是 e;对于私有 伴随式,矩阵是 H,向量是 v。因此,私有伴随式的计算可以像公共伴随式一 样被视为多项式乘法。也就是说,私有伴随式可以被视为

H(0) :,0(x)v(0)(x)+ H (1) :,0(x)v(1)(x) ∈ F 2[x]/(x r −1).

公共伴随式和私有伴随式的计算仍然略有不同。对于加密,矩阵 P是稠密 的,而向量 e是稀疏的。对于解密,矩阵 H是稀疏的,而向量 v是稠密的。然而,乘法 H(i) :,0(x)v(i)(x)仍然是稀疏‐稠密乘法。QcBits因此使用 第4.3节中描述的技术来计算私有伴随式。4.3。

由于私钥是 H(i) 0 ,:的稀疏表示,我们不能直接得到 H(i):,0。这种情况类似 于公钥生成过程中, P(1):,0是从 P(1) 0 ,:推导而来。因此,QcBits通过在恒定时 间内调整稀疏表示中的每个索引,从 H(i) 0 ,:计算出 H(i):,0。

5.2 多项式视图:计数未满足的奇偶校验

设 s= Hv。未满足奇偶校验计数的向量 u可以被视为

uj=∑
i
Hi,j · si ∈ Zn,

其中Hi,j和 sj被视为整数。换句话说,

u=∑
i Hi,: · si ∈ Z n.

Let u(0)和 u(1)分别为 u的前半部分和后半部分。现在我们有 :

(u(0)(x), u(1)(x))=(∑ i
xiH(0) 0,:(x)· si,∑
i
xiH(1) 0,:(x)· si)
=(H(0) 0,:(x)· s(x), H(1) 0,:(x)· s(x)) ∈(Z[x]/(xr −1)) 2.

换句话说,向量 u 可以使用 Z[x]/(xr − 1) 中的 2 次乘法计算得出。注意这些乘法并非通用: H(i) 0 ,:(x) 始终是稀疏的,且 H(i) 0 ,:(x) 和 s(x) 的系数只能为 0 或 1。有关此类乘法在 QcBits 中的实现方式,请参见下文。

5.3 Z[x]/(xr − 1) 中的稀疏‐稠密乘法

该任务可以形式化为计算 fg ∈ Z[x]/(xr−1),其中 fi, gi ∈{0, 1}对所有 i成立,且 f的重量仅为 w。 f用I f ={i|fi= 1}中的索引数组表示。 g通常自然地 表示为一个由 r/b b‐bit值组成的数组。然后我们有

fg=∑
i ∈ I f
x i g.

尽管所有操作现在都在 Z[x]/(x r −1) 中而不是在 F2[x]/(x r −1) 中,每个 x i g仍然 可以使用第4.3节中所述的恒定时间旋转来计算。4.3。

| 1011012|
| —|
| 1010002|
| 0001012|
0000002
......
非位切片 位切片
| 0… 1012|
| —|
| 0… 0002|
| 0… 1012|
| 0… 0112|
| 0… 0002|
| 0… 0112|
8位
b
b比特
6

因此,QcBits 首先设置 h= 0,然后对于每个 i ∈ I,使用恒定时间旋转计算 xig,并将其添加到 h 中。在处理完 I 中的所有元素后,我们得到 h= fg。注意, xig 被表示为由 r/b b 位字组成的数组。

现在剩下的问题是如何将 xig加到 h中。表示h的一种直接方法是使用一个 包含 r字节的数组(当w/2< 256时,每个系数使用1字节即可,这对于[3]中 所有满足 n= 2r的参数集都成立),每个字节存储一个 r系数。为了将 xig加 到 h中,最简单的方法是对 h的每个系数,使用一条按位与AND指令并最多一 条移位指令从相应的 b位字中提取所需比特,然后使用一条加法指令将该比特 加到字节上。换句话说,平均大约需要3条指令来更新 h的每个系数。

QcBits通过位切片 h的系数来实现更优性能:QcBits并未使用 b字节,而 是采用多个 b‐位字来存储一组 b个系数,其中第 i个 b‐位字存储这 b个系数的 第 i低位。由于 H的列权重为 w/2,因此使用 lg w/2+1 b‐位字已足够。为了更新 h的 b个系数,需对 lg w/2+1个b‐位字以及 xi g中对应的 b‐位字执行一系 列逻辑操作。这些逻辑指令模拟了 b个将1位数加到(lg w/2+ 1)‐位数上的电 路副本。此类电路大约需要 lg w/2+ 1个半加器,因此更新 b个系数大约需 要在 b‐位字上执行2(lg w/2+ 1)条逻辑指令。

图1说明了当 b时系数的存储方式。在非位切片方法中,使用 b字节。在 位切片方法中,使用 lg(90/2)+1= 6 b‐位字,相当于 6b/8 字节。注意这意味 着位切片节省内存。关于指令数量,平均需要 (6 · 2)/b条逻辑指令来更新每个 系数。对于 b= 32或 b= 64,(6 · 2)/b远小于 3。因此,位切片也有助于提 升性能。

McBits 所实现的速度也依赖于位切片。然而,读者应注意QcBits与 McBits 不同,利用了单个解密实例中固有的并行性。

5.4 翻转位

每个解码迭代的最后一步是根据计数进行位翻转。由于QcBits以位切片格式存 储计数,因此位翻转也是以位切片方式进行的。在每次解码迭代开始时,生成 b份 −t的位切片形式,并存储在 lg w/2+ 1 b‐bit字中。一旦计算出计数,便 通过在 b‐bit字上使用逻辑指令并行地将 −t加到计数中。这些逻辑指令模拟了 用于相加(lg w/2+ 1)‐bit数的电路的多个副本。这样的电路需要(lg w/2+ 1) 个全加器。因此,每个 ui+(−t)大约需要5(lg w/2+ 1)/b条逻辑指令。

加法用于为所有 ui − t 生成符号位,这些符号位存储在两个由 r/b b 位 字组成的数组中。为了翻转位,QcBits 简单地将两个数组中 b 位字的补码与 v(0) 和 v(1)进行异或运算。然后大约需要 1/b 条逻辑指令来更新每个 vi。

对于 w= 90,我们有 5(lg w/2+ 1)/b+ 1b= 31/b,其值小于 1,无论 b= 32 还是 b= 64。相比之下,当使用非位切片格式时,朴素的方法是对 每个 ui − t 至少使用一条减法指令,以及一条异或指令来实现位翻转。有人可 能会认为,对于非位切片形式,可能存在更优的方式来计算 u 并执行位翻转。例如,可能在一条指令中并行执行多个字节的加法/减法。然而,由于需要在比 特序列和字节之间进行格式转换,这种方法的实际开销似乎远高于预期。

6 解码的实验结果

本节展现了在不同参数集下QC‐MDPC解码的实验结果。所使用的解码算法是 第2.2节中介绍的预计算阈值方法。编码受到限制: H(0)和 H(1)必须具有相 同的行权重。r、w、t 的含义与第2.1节中相同。sec 表示安全级别。T 是阈值 列表。除非另有说明,阈值均通过[3,附录A]中的公式获得。S 是一个表示测试 所进行迭代次数的列表。S 中数字的总和即为测试总数,在前三种情况下设为 108 ,最后一种情况设为 106 。 108(106) 次测试包含对 104(103) 个密钥对 中的每一个进行 104(103) 次解码尝试。列表中的第一个数字表示在 #T 次迭代 内未能完成解码的测试次数(即,总迭代次数内)。第二个数字表示成功解码 所需的迭代次数

在1次迭代后成功的测试次数。第三个数字表示在2次迭代后成功的测试次数; 依此类推。avg表示成功测试的平均迭代次数。

r= 4801w = 90t = 84sec= 80T =[29, 27, 25, 24, 23, 23]S =[0, 0, 752, 69732674, 30232110, 34417, 47] 平均值= 3.30
阈值通过交互实验获得。QcBits 使用此设置。

r= 4801w = 90t = 84sec= 80T =[28, 26, 24, 23, 23, 23, 23, 23, 23, 23]S =[40060, 0, 9794, 87815060, 12079266, 51387, 3833, 519, 70, 10, 1]平均值= 3.12

r= 9857w= 142t= 134sec= 128T =[44, 42, 40, 37, 36, 36, 36, 36, 36, 36, 36, 36]S =[689298, 0, 0, 86592, 53307303, 42797368, 2856446, 235479, 24501, 2651, 333, 26, 3]avg= 4.46

r= 9857w= 142t= 134安全级别= 128T =[48, 47, 46, 45, 44, 43, 42, 42, 41, 41, 40, 40, 39, 39, 38, 38, 37, 37, 36]S =[12, 0, 0, 0, 0, 0, 142, 78876, 578963, 290615, 43180, 6363, 1309, 336, 108, 54, 27, 7, 4, 4]平均值= 8.33
阈值是通过交互实验获得的。

7 基于准循环中等密度奇偶校验码的密码系统的未来

QcBits提供了一种在具有缓存的平台上实现恒定时间QC‐MDPC解码的方法。此外,QcBits中的解码速度远快于以往的工作。然而,比特翻转算法是概率性 的这一事实可能带来安全性问题。在[13,14]中的安全性证明假设密钥封装机制 能够以“压倒性概率”成功解密一个KEM密文。由于目前尚无有效方法来估计 给定QC‐MDPC码的失败率,人们所能做的最好方式就是进行大量实验。

QcBits在 108次试验中实现了无解码失败。实际上, 108并不是一个微不足道 的数值,但如此级别的失败率是否足以保证系统安全仍不明确,更不用说这仅 针对80位安全。有关失败率的更详细实验结果,请参见第6节。

人们或许可以通过降低失败率来缓解这一问题。这可以通过改进解码算法 或设计更优的参数集来实现。然而,一个尚未解决的更根本问题是,为了确保 安全,失败率应低到何种程度。

另一个可能不那么严重的问题是,QcBits 及所有之前的实现论文 [4,5,7,9,11]强制校验矩阵 H在 H(0) 和 H(1) 中具有相等的权重,这与 [3] 中描述的情况不同。QcBits 通过这种方式限制密钥空间以降低失败率。当然, 有人可能会争辩说,即使不限制密钥空间,在极大概率下 H(0) 和 H(1) 仍然 会具有相同的权重。然而,这种论点仅在攻击者只能针对一个系统时才成立。对于旨在攻破多个系统中任意一个的攻击者而言,目前尚不清楚此类限制是否 会影响安全性。希望研究人员也能花时间研究这一问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值