
2.1 序列密码
2.1.1 序列密码介绍
序列密码的起源可追溯到1917年Vernam提出的“一次一密”(One-Time Pad)密码体制。“一次一密”密码体制是理论上最安全的加密方法,要求密钥流与密文长度相同且完全随机,同时密钥流不能重复使用。这也导致“一次一密”在实际应用时存在明显的缺陷,主要是密钥流的生成、分配和管理变得异常困难。为了克服这些缺陷,研究者们设计了各种序列密码算法。其主要思想是使用一个较短的密钥(称为“种子”)通过特定的算法来产生一个长的伪随机序列用于加解密,从而只需要生成、管理较短的密钥,简化了密钥管理。
在20世纪中叶,随着有限域和线性移位寄存器理论的成熟,以及晶体管的出现和广泛应用,基于线性移位寄存器的序列密码逐渐成为发达国家保密通信系统中的主要装备。到了20世纪80年代,序列密码的研究开始一步步走出黑屋,多个序列密码研究项目推动了相关技术的发展。
1)2000年,欧盟启动NESSIE项目,征集序列密码算法并进行评估和公开讨论,第一次在学术界掀起了序列密码研究热潮。但由于过于苛刻和严谨的评估准则,所有序列算法候选方案都未能胜出。
2)2004年,欧盟启动ECRYPT计划,其中包括eSTREAM项目,主要是面向全球征集适合广泛应用的高效、紧凑的序列密码算法。eSTREAM项目共征集到34个算法,经过多次安全和性能评估,并按照不同应用需求进行分类,最终选出满足高吞吐量要求的软件应用和适用于资源受限(如有限的存储、门数、功耗等)的硬件应用的算法。到2008年活动结束,最终评选出7种算法,包括4种面向软件应用的算法(Salsa20/12、SOSEMANUK、Rabbit、HC-128),与3种面向硬件应用的算法(Grain v1、Trivium、MICKEY v2)。
根据密钥流生成方式的不同,序列密码分为同步序列密码与自同步序列密码。同步序列密码(见图2-1)使用种子密钥k和初始向量IV,根据密钥流生成算法生成密钥流序列z=z0z1z2…,然后使用密钥流序列依次对明文序列m=m0m1m2…加密:

其中,密钥流序列对明文加密的过程通常为异或运算,即依次将每个密钥流与明文流异或运算得到密文:。

图2-1 同步序列密码示意图
相应解密过程只需使用同一密钥k和相同的初始向量IV,采用相同的密钥流生成算法生成同样的密钥流序列z=z0z1z2…,然后依次对密文序列c=c0c1c2…解密:

其中,D为E的逆过程。当E为异或运算时,D也为异或运算,即。
同步序列密码算法具有加解密速度快、便于软硬件实现等特点,适用于大量数据加密场景,广泛应用于数据通信领域,例如互联网通信、VPN通信和无线通信等。
与同步序列密码不同,自同步序列密码(见图2-2)在生成密钥流的过程中,密文流会参与后续的密钥流生成。这种特性使得即使密文流的部分比特出现错误,当一定数量的正确密文流被反馈回密钥流生成器后,加解密仍然能够重新同步,系统将回到正确的状态。这种能力在通信中尤其有用,因为它允许系统在不稳定的信道环境中运作,即便存在信号干扰、传输错误或数据丢失等情况,仍能保持一定程度的加密能力。自同步序列密码能够容忍一定程度的错误。然而,为了实现这种错误容忍特性,系统可能会变得更加复杂,而且可能需要更多的计算开销。在实际应用中,我们通常使用分组密码结合一些工作模式来构造自同步序列密码。
2.1.2 序列密码的设计原理
序列密码的设计关键在于如何利用较短的密钥生成具有长周期、高复杂度和良好统计特性的伪随机序列。这些序列不仅需要具备长的周期和高的复杂度,还应能有效隐藏生成过程中的中间状态,确保即使攻击者获得输出序列,也难以推测内部状态或密钥。换言之,即使攻击者获取了较长的序列,也无法获取序列的未来或过去的值,更无法确定密钥。

图2-2 自同步序列密码示意图
1.线性反馈移位寄存器
线性反馈移位寄存器(LFSR,Linear Feedback Shift Register)因其理论成熟、易于硬件实现、可以产生大周期序列、统计特性良好且易于分析等优点,在序列密码设计中被广泛应用。LFSR由寄存器单元和反馈函数组成,其中,寄存器单元的数量被称为“移位寄存器的级数”,反馈函数为寄存器单元的线性组合。
LFSR的工作原理是通过特定的特征多项式来定义反馈逻辑,从而生成序列。例如,一个n级LFSR的状态由n个寄存器中的值组成,每个时刻的状态变化依赖于反馈函数的计算结果。LFSR生成的序列被称为“n级LFSR序列”,其特征多项式完全描述了该序列的特性。图2-3展示了一个以f(x)=xn⊕cn-1xn-1⊕…⊕c0为特征多项式的n级LFSR。n个寄存器中的值组成的向量(ak+n-1,ak+n-2,…,ak)被称为“LFSR的第k时刻的状态”,特别地,(an-1,an-2,…,a0)被称为“LFSR的初始状态”。对任意k≥0,LFSR状态做如下变化。
1)计算ak+n=cn-1an+k-1⊕…c1ak+1⊕c0ak;
2)寄存器中的值依次向右移位,并将最后一个寄存器中的值ak输出;
3)将ak+n放入最左侧寄存器。
LFSR所产生的序列a=(a0,a1,a2,…)被称为“n级LFSR序列”。特征多项式f(x)完全刻画了该序列。需要注意的是,LFSR的特征多项式并不唯一,但次数最小的特征多项式是唯一的,被称为“该序列的极小多项式”。

图2-3 线性反馈移位寄存器示意图
易知,当LFSR的状态出现重复时,其输出序列也将出现重复。给定LFSR序列a=(a0,a1,a2,…),若存在非负整数k和正整数T,使得对任意i≥k,都有ai+T=ai,则称a为准周期序列,并将最小的T称为a的周期。特别地,若k=0,则称a是(严格)周期序列。设ma(x)为a的极小多项式,则a是周期序列当且仅当ma(0)≠0。
注意,LFSR总是将某时刻全0状态转化成之后所有时刻全0状态,因此,对于一个n级F2上(即每个寄存器的值为0或1)的LFSR,输出序列的最大可能周期为2n-1。若LFSR序列a的周期为2n-1,则称其为F2上的n级m序列。LFSR序列a为n级m序列,当且仅当a的极小多项式是n次本原多项式。
m序列是最重要的LFSR序列,不仅其周期可以达到最大,而且具有较好的统计特性,满足信息理论和编码理论的先驱Solomon W.Golomb提出的3条随机性假设规则。
• 均匀性规则:对于一个理想的伪随机二进制序列,0和1出现的数量应当是相等的或相差极小。
• 游程规则:游程是序列中连续的同样符号(例如连续的0或1)的最大长度。此规则描述了不同长度的游程出现的频率。在理想情况下,长度为1的游程应该占总游程数的1/2,长度为2的游程应该占1/4,长度为3的游程应该占1/8,依此类推。这反映了一个好的伪随机序列在短的时间尺度上有很好的均匀性,而在较长的时间尺度上则可能会出现不均匀性。
• 自相关规则:这是一个描述伪随机序列的自相关特性的规则。理想的伪随机序列应该具有低的自相关,除了在0位移(或说零延迟)上,其自相关函数的值应该接近于零。这意味着序列与其自身的一个版本(该版本经过一定数量的位移)之间的相似度非常低。
LFSR序列a的极小多项式的次数被称为“该序列的线性复杂度”,记为LC(a)。线性复杂度用来衡量生成LFSR序列的最小代价。1969年,研究者提出的Berlekamp-Massey算法(简称B-M算法)解决了求序列极小多项式的问题。对于线性复杂度为L的LFSR序列a,B-M算法在已知序列a连续2L比特的条件下,可以还原出整条序列,且计算复杂度仅为O(L2)。
目前,LFSR已作为基础部件广泛应用于序列密码设计。考虑到算法实现中的软硬件资源和运算效率,我们通常选择更大有限域Fq上的LFSR,即寄存器中的元素均为Fq中的元素,运算也为Fq上的运算。Fq上的LFSR生成的序列几乎保持了传统的F2上的LFSR序列的所有性质,如周期性、伪随机性等。
2.密钥流生成器
在序列密码设计中,我们通常使用LFSR生成的m序列作为序列源,再结合非线性部件生成密钥流序列。m序列具有大周期、理想的统计特性、高效性等特点,而非线性部件用于提高安全性与复杂性,用于抵抗密码攻击。经典的非线性改造方式有非线性组合、非线性过滤和钟控等,其中非线性组合与非线性过滤生成器均在统一时钟下控制LFSR的状态更新,而钟控生成器通过一个LFSR控制另外一个或多个LFSR的状态更新。由于基于钟控生成器设计的密码算法相对较少,下面仅简要介绍非线性组合与非线性过滤生成器。
非线性组合生成器的思想是将多个m序列通过非线性的方式合并成一条密钥流。如图2-4所示,n个LFSR分别生成m序列a1,a2,…,an,记ai=(ai,0,ai,1,ai,2,…),1≤i≤n,然后将此n个序列经组合函数F组合生成密钥流序列z=(z0,z1,z2,…),其中,组合函数F为n元非线性函数,zk=F(a1,k,a2,k,…,an,k),k≥0。若m序列a1,a2,…,an的线性复杂度分别为m1,m2,…,mn,且互不相同,则组合序列z的线性复杂度为F(m1,m2,…,mn)。

图2-4 非线性组合生成器示意图
非线性过滤生成器的思想是对单个m序列进行非线性运算得到密钥流序列。如图2-5所示,LFSR的输出序列为a=(a0,a1,a2,…),F=F(x1,x2,…,xn)为一个n元函数,被称为“过滤函数”,密钥流序列z=(z0,z1,z2,…),其中zt=F(at,at+1,…,at+n-1),t≥0。若函数F(x1,x2,…,xn)=xixi+δ…xi+(k-1)δ⊕G(x1,x2,…,xn),其中gcd(δ,2n-1)=1,G的代数次数小于k,则输出序列z的线性复杂度不小于。

图2-5 非线性过滤生成器示意图
3.其他反馈移位寄存器
线性反馈移位寄存器序列容易受到相关攻击与代数攻击的影响,非线性序列生成器逐渐受到研究人员的关注。常见的非线性序列生成器有带进位的反馈移位寄存器(FCSR,Feedback with Carry Shift Register)与非线性反馈移位寄存器(NFSR,Nonlinear Feedback Shift Register)。
FCSR由A.Klapper和M.Goresky于1993年首次提出,其原理是利用整数的进位运算生成一类二元非线性序列。设q为正奇数,,q+1=q12+q222+…+qr2r,qi∈{0,1},且qr=1,以q为连接数的FCSR如图2-6所示。图2-6中Σ表示整数加法,mn是进位(也称“记忆”),(mn;an+r-1,an+r-2,…,an)表示FCSR在时刻n的状态。FCSR的状态转换过程如下。
1)计算整数和;
2)r个寄存器依次右移一位,输出最右侧寄存器的值an;
3)计算an+r≡σnmod 2,并放入最左侧寄存器;
4)计算,并使用mn+1更新进位寄存器。
记FCSR的输出序列a=(a0,a1,a2,…),q被称为“序列a的连接数”,若q是序列a所有连接数中的最小值,则称q为a的极小连接数。若序列a是以q为极小连接数的FCSR序列,则序列a的周期为ordq(2)。因此,FCSR序列的周期的最大值为ϕ(q),并称周期为ϕ(q)的FCSR序列为l序列。与B-M算法类似,1995年研究者提出的2-adic有理逼近算法可在较低复杂度内还原FCSR序列,因此,l序列本身不能直接作为密钥流序列,需结合非线性部件共同生成密钥流序列。

图2-6 进位反馈移位寄存器示意图
NFSR是序列密码设计的一类重要部件。在2008年,欧洲eSTREAM项目胜选的3个面向硬件设计的序列密码算法Trivium、Grain v1和Mickey v2均基于NFSR设计。NFSR往往具有较低的硬件实现代价,常用于轻量级密码设计。
一个n级NFSR示意图如图2-7所示。该寄存器由n个寄存器和一个反馈函数构成,记初始状态为(a0,a1,…,an-1),对任意k≥0,其状态更新过程如下。
1)计算ak+n=f1(ak,ak+1,…,ak+n-1);
2)n个寄存器向右移位,并输出最右侧寄存器中的值ak;
3)使用ak+n更新最左侧寄存器中的值。

图2-7 n级NFSR示意图
记NFSR的输出序列为a=(a0,a1,a2,…),f1(x0,x1,…,xn-1)为反馈函数,f(x0,x1,…,xn-1,xn)=f1(x0,x1,…,xn-1)+xn为NFSR的特征函数。一个n级NFSR序列的最大可能周期为2n。若NFSR序列a的周期为2n,则称a为n级De Bruijn序列。De Bruijn序列具有最大周期及良好的伪随机性质,一直以来都是NFSR序列的研究热点。近年来,一些基于NFSR设计的序列密码逐渐出现,但由于NFSR序列的复杂性,人们对相关算法的安全性还存在一些疑虑。
2.1.3 常见的序列密码算法
1.SNOW 3G
在2000年启动的NESSIE计划中,SNOW 1.0算法作为一种新型序列密码算法被提出,其设计目标是在保证安全性的同时优化性能。然而,研究者很快发现SNOW 1.0算法存在多个缺陷,这促成了SNOW 2.0算法的诞生。它对原算法进行了改进并修复了已知缺陷。在2006年,ETSI/SAGE基于SNOW 2.0进行了进一步改进而发展出了SNOW 3G算法。与SNOW 2.0相比,SNOW 3G抵抗代数攻击的能力更出色,安全性得到进一步提升。之后,SNOW 3G便被3GPP(第三代合作伙伴计划,3G Partnership Project)采纳为加密标准,并在4G/5G移动通信中作为机密性算法和数据完整性算法的核心算法之一。SNOW 3G以其实现简单、性能高以及资源消耗低等特点,在物联网等资源受限环境中具有广阔的应用前景。
SNOW 3G是一种以字为单位的序列密码算法,其结构如图2-8所示。其中,符号⊕表示按位异或操作,符号表示整数模232加法操作。该算法主要由一个线性反馈移位寄存器(LFSR)和一个有限状态机(FSM,Finite State Machine)组成。LFSR由16个32比特寄存器(s0,s1,…,s15)和一个反馈电路(反馈函数)组成。FSM由3个32比特寄存器(R1,R2,R3)和2个32~32比特的S盒S1与S2组成。算法的运行过程主要分为两个阶段:初始化阶段和密钥流生成阶段。
在初始化阶段,算法首先将128比特的密钥Key和IV分成4个32比特字K0、K1、K2、K3和IV0、IV1、IV2、IV3,并将LFSR的各个寄存器按如下方式初始化。

将寄存器R1、R2、R3初始化为0,其中,1表示0xFFFFFFFF,0表示0x00000000。然后重复执行以下计算过程32次完成算法初始化:
1);
2);
3)(R3,R2,R1)=(S2(R2),S1(R1),r),其中,S2、S1分别为对应的S盒字节代换操作;
4)s16=(s0,1‖s0,2‖s0,3‖0x00)⊕MULα(s0,0)⊕s2⊕(0x00‖s11,0‖s11,1‖s11,2)⊕DIVα(s11,3)⊕F;
5)(s15,s14,…,s0)=(s16,s15,…,s1)。

图2-8 SNOW 3G算法结构
下面依次介绍SNOW 3G算法初始化过程涉及的运算。
设w=w0‖w1‖w2‖w3为32比特输入,S1(w)=r0‖r1‖r2‖r3为32比特输出,则S盒S1如下:
r0=MULx(SR(w0),0x1B)⊕SR(w1)⊕SR(w2)⊕MULx(SR(w3),0x1B)⊕SR(w3)
r1=MULx(SR(w0),0x1B)⊕SR(w0)⊕MULx(SR(w1),0x1B)⊕SR(w2)⊕SR(w3)
r2=SR(w1)⊕MULx(SR(w1),0x1B)⊕SR(w1)⊕MULx(SR(w2),0x1B)⊕SR(w3)
r3=SR(w0)⊕SR(w1)⊕MULx(SR(w2),0x1B)⊕SR(w2)⊕MULx(SR(w3),0x1B)
S盒S2如下:
r0=MULx(SQ(w0),0x69)⊕SQ(w1)⊕SQ(w2)⊕MULx(SQ(w3),0x69)⊕SQ(w3)
r1=MULx(SQ(w0),0x69)⊕SQ(w0)⊕MULx(SQ(w1),0x69)⊕SQ(w2)⊕SQ(w3)
r2=SQ(w1)⊕MULx(SQ(w1),0x69)⊕SQ(w1)⊕MULx(SQ(w2),0x69)⊕SQ(w3)
r3=SQ(w0)⊕SQ(w1)⊕MULx(SQ(w2),0x69)⊕SQ(w2)⊕MULx(SQ(w3),0x69)
其中,MULx表示将16比特输入映射成8比特输出,设(V,c)为两个8比特的输入,MULx(V,c)具体如下:

注:≪nt表示在n比特内左移t比特。
SR与SQ为两个8比特输入、8比特输出的S盒,分别如表2-1与表2-2所示。当输入信息为8比特值x=x0·24+x1时,S盒的输出值为第x0行x1列的值。
表2-1 SNOW 3G算法中S盒SR的值

表2-2 SNOW 3G算法中S盒SQ的值

(续)

函数MULα、DIVα分别将8比特输入映射成32比特输出。设c为8比特输入,则
MULα(c)=(MULxPOW(c,23,0xA9)‖MULxPOW(c,245,0xA9)‖
(MULxPOW(c,48,0xA9)‖MULxPOW(c,239,0xA9)
DIVα(c)=(MULxPOW(c,16,0xA9)‖MULxPOW(c,39,0xA9)‖
(MULxPOW(c,6,0xA9)‖MULxPOW(c,64,0xA9)
其中,MULxPOW(V,i,c)根据整数i将16比特的输入(V,c)映射成8比特的输出值,具体如下:

当SNOW 3G初始化完成后,以如下方式生成密钥流,每次产生32比特密钥流zt(t≥1),具体过程如下:
对t=0~n,计算
1);
2);
3)(R3,R2,R1)=(S2(R2),S1(R1),r);
4)zt=F⊕s0;
5)s16=(s0,1‖s0,2‖s0,3‖0x00)⊕MULα(s0,0)⊕s2⊕(0x00‖s11,0‖s11,1‖s11,2)⊕DIVα(s11,3);
6)(s15,s14,…,s0)=(s16,s15,…,s1)。
注,z0舍弃,z1为第一个密钥流。
2.Trivium
Trivium是欧洲序列密码发展计划eSTREAM获选算法之一,是一种面向硬件应用的基于移位寄存器的序列密码算法。
Trivium算法结构如图2-9所示,内部由F2上3个寄存器构成[分别为(s1,s2,…,s93)、(s94,s95,…,s177)、(s178,s179,…,s288)],密钥Key=(K1,…,K80),初始向量IV=(IV1,…,IV80)的长度均为80比特,可以生成不超过264比特的密钥流。Trivium算法包含初始化阶段与密钥流生成阶段。填充密钥和初始向量后,经4×288轮运算完成初始化,具体过程如下:
1)(s1,s2,…,s93)=(K1,…,K80,0,…,0);
2)(s94,s95,…,s177)=(IV1,…,IV80,0,…,0);
3)(s178,s179,…,s288)=(0,…,0,1,1,1);
4)对i=1到4×288,计算
a)t1=s66+s91·s92+s93+s171;
b)t2=s162+s175·s176+s177+s264;
c)t3=s243+s286·s287+s288+s69;
d)(s1,s2,…,s93)=(t3,s1,s2,…,s92);

图2-9 Trivium算法结构
e)(s94,s95,…,s177)=(t1,s94,s95,…,s176);
f)(s178,s179,…,s288)=(t2,s178,s179,…,s287)。
其中,“+”和“·”均为F2上的运算,即“异或”和“与”运算。
当初始化完成后,Trivium算法密钥流生成阶段每次产生1比特密钥流zi,所能产生的密钥流总数N不大于264,具体过程如下。
对i=1到N,计算
1)t1=s66+s93;
2)t2=s162+s177;
3)t3=s243+s288;
4)zi←t1+t2+t3;
5)t1=t1+s91·s92+s171;
6)t2=t2+s175·s176+s264;
7)t3=t3+s286·s287+s69;
8)(s1,s2,…,s93)=(t3,s1,s2,…,s92);
9)(s94,s95,…,s177)=(t1,s94,s95,…,s176);
10)(s178,s179,…,s288)=(t2,s178,s179,…,s287)。
3.ZUC
祖冲之序列密码算法(简称“ZUC算法”)是一个面向字设计的序列密码算法。2009年5月,ZUC算法获得3GPP安全算法组SA立项,正式加入3GPP LTE第三套机密性和完整性算法标准的竞选。2011年9月,ZUC正式被3GPP SA全会通过,被称为“3GPP LTE第三套加密标准核心算法”,也成为我国首个国际密码标准算法。ZUC算法于2012年成为密码行业标准,并于2016年成为我国国家标准。
ZUC算法由LFSR、比特重组(BR)和非线性函数F三部分组成,如图2-10所示。其中,LFSR序列为GF(231-1)上的m序列,非线性函数采用有限状态机设计,内部包含R1和R2两个记忆单元,并使用扩散与混淆性质良好的线性变换与S盒。Z U C算法的初始密钥k和初始向量iv均为128比特,包含初始化阶段与密钥流生成阶段。
记初始密钥k=k0‖k1‖…‖k15,初始向量iv=iv0‖iv1‖…‖iv15,LFSR单元变量为s0,s1,…,s15,其中,ki、ivi均为8比特,si为31比特,则初始化过程如下。

图2-10 ZUC算法结构
1)对0≤i≤15,si=ki‖di‖ivi;
2)令R1=R2=0;
3)对i=1到32,计算
a)X0=s15H‖s14L;
b)X1=s11H‖s9L;
c)X2=s7H‖s5L;
d)X3=s2H‖s0L;
e)(
为模232加法);
f);
g)W2=R2⊕X2;
h)R1=S[L1(W1L‖W2H)];(H表示高16比特,L表示低16比特)
i)R2=S[L2(W2L‖W1H)];
j)W=W≫1;
k)v=215s15+217s13+221s10+220s4+(1+28)s0mod(231-1);
l)s16=(v+W)mod(231-1);
m)如果s16=0,则置s16=231-1;
n)(s0,s1,…,s14,s15)=(s1,s2,…,s15,s16)。
其中,密钥装载时所用到的16个15比特常数di的取值如下:
d0=100010011010111,d1=010011010111100
d2=110001001101011,d3=001001101011110
d4=101011110001001,d5=011010111100010
d6=111000100110101,d7=000100110101111
d8=100110101111000,d9=010111100010011
d10=110101111000100,d11=001101011110001
d12=101111000100110,d13=011110001001101
d14=111100010011010,d15=100011110101100.
32比特线性变换L1与L2定义如下:
L1(X)=X⊕(X<<<2)⊕(X<<<10)⊕(X<<<18)⊕(X<<<24)
L2(X)=X⊕(X<<<8)⊕(X<<<14)⊕(X<<<22)⊕(X<<<30)
32比特S盒由4个8比特S盒并置构成,即S=(S0,S1,S0,S1)。对于8比特x=24x0+x1输入,S0与S1的输出取值分别为表2-3与2-4中第x0行x1列的值。
表2-3 ZUC算法中S盒S0的输出取值

(续)

表2-4 ZUC算法中S盒S1的输出取值

当初始化完成后,ZUC算法每次产生32比特密钥流Zi,设生成的密钥流字的个数为L,则密钥流生成过程如下:
对i=0到L,计算
1)X0=s15H‖s14L;
2)X1=s11H‖s9L;
3)X2=s7H‖s5L;
4)X3=s2H‖s0L;
5);
6);
7)W2=R2⊕X2;
8)R1=S[L1(W1L‖W2H)];
9)R2=S[L2(W2L‖W1H)];
10)Zi=W⊕X3;
11)v=215s15+217s13+221s10+220s4+(1+28)s0mod(231-1);
12)如果s16=0,则置s16=231-1;
13)(s0,s1,…,s14,s15)=(s1,s2,…,s15,s16)。
注:舍弃Z0,输出的第一个密钥流字为Z1。