做硬件密码实现的朋友应该都体会过一件烦心事:AES的加密通路调通后,一看解密逻辑的面积,心凉了半截。S盒要逆的,列混合要逆的,轮密钥加法虽然不用逆,但整套逆变换摆在版图上,硬生生多出一块芯片面积。更烦的是时序和功耗的平衡,解密这条路径不是白送的,它是拿工程师的头发换的。所以当我第一次读到ICEBERG这个分组加密算法的论文时,第一反应是:还有这种操作?它把一个在数学里很出名、但在密码工程里不太常用的性质——对合结构——用到了极致,让解密电路和加密电路共用同一套轮函数逻辑。简单说,加密和解密对ICEBERG来说几乎是同一个操作,只是子密钥的流动方向变了。
这篇东西我会从对合概念讲起,把ICEBERG的轮函数构造、子密钥编排、硬件面积账、安全权衡一次性聊透。适合三类人读:做嵌入式安全或RFID芯片的硬件工程师,对分组密码设计感兴趣的进阶学习者,以及在轻量级密码算法里做选型的技术负责人。读完你至少能明白,为什么有些密码天生"解密便宜",以及"数学性质换来工程优势"这件事在密码设计里到底怎么落地。
1. "对合结构"到底是个啥:不搞懂这个性质,后面都没法聊
1.1 对合的定义:一个函数是自己逆函数这件事
对合(involution)的定义其实特别简单:一个函数 (f),如果对定义域里的任意 (x),都有 (f(f(x)) = x),那 (f) 就是对合函数。说白了,这个函数就是它自己的逆函数,同一个函数用两遍,所有东西恢复原样。
生活里的例子很多。镜子就是最典型的:现实里的你照一次镜子,镜像里出现一个反向的你,再照一次,这个"反向的反向"又变回正向。数学上,取负号 (f(x) = -x) 也是,负负得正。翻书页、拧瓶盖再拧回去、把口袋内衬翻出来再翻回去,全都符合这个模式。
密码学里最常见的对合操作是异或:(f(x) = x \oplus K),连续异或同一个密钥两次,(x) 原封不动地回来了。这个性质是分组密码里轮密钥加法的基石——没有它,密钥加法这一层在解密的时候就要重新设计一套逻辑。
但要注意,对合是个"全局性质"和"局部性质"要分清的概念。两个对合函数复合在一起,结果不一定还是对合。举个简单例子:(f(x) = -x) 是对合,(g(x) = 1-x) 也是对合,但 (f(g(x)) = x - 1) 用两遍得到的是 (x - 2),不是 (x)。所以设计一个整体对合的密码算法,比简单地把几个对合操作叠起来要难得多,你必须处理层与层之间的相互作用。这一点后面讲ICEBERG的轮函数构造时,是理解它的关键。
1.2 从Feistel到SPN:分组密码里的对合家族史
分组密码的两大经典骨架——Feistel结构和SPN结构——在对合这件事上的待遇截然不同。
Feistel结构的代表是DES。它的每一次迭代只改分组的一半,另一半原样拿着做轮函数输入。这个结构有一个非常著名的数学性质:不管轮函数 (F) 本身是什么,整个Feistel网络天然是对合的,只要把子密钥的使用顺序反过来。这就是为什么DES的解密可以直接复用加密的硬件数据通路,只是密钥调度的读序不同。Feistel是"天生就对合",解密路径白送。
SPN结构的代表是AES。它的每一轮同时对整个分组做替换和扩散,扩散效率比Feistel高得多——每一轮里所有比特都能互相关联上。但代价就是,轮函数里的S盒、行移位、列混合这些操作都必须单独构造逆操作。AES的解密需要逆S盒、逆行移位、逆列混合,一套完整的"反向"轮函数。虽然工程上有技巧可以让正逆变换共用一部分电路,但本质上,SPN的加解密路径是不对称的,解密就是要比加密贵。
这个矛盾就是ICEBERG出现的背景:能不能造一个既保留SPN优秀扩散性能、又让解密路径像Feistel一样白送的算法?对合结构就是这个问题的答案。
1.3 "解密免费"的工程红利,比省面积更值钱
很多人第一次听到对合结构,第一反应是"解密省电路"。对,这是最直观的好处,但不是全部。我实际做项目之后发现,加解密路径完全一致这件事,在工程上的连锁收益比想象中多得多。
首先是掩码方案可以复用。搞侧信道防护的同学都知道,做一套掩码(masking)设计的验证工作量有多大。如果加密和解密是两套数据通路,掩码就得做两遍,每个中间值都要重新算掩码表示。ICEBERG这种对合结构,掩码变换在加解密两边是同一套逻辑,验证工作量直接减半。
其次是设计周期。一次实现两遍功能,综合、布局布线、时序收敛都只需要做一遍。在项目工期紧的时候,这一个优势可能比省那几千个门电路还关键。
最后是个容易被忽略的点:加解密路径的功耗对称性。很多侧信道攻击会利用加密和解密过程中功耗曲线的差异来"校准"模板攻击的模板特征。如果加解密走的是同一条物理路径,攻击者能用来做区分的信息维度就少了一个。这不是安全证明,但确实在实践中让某些攻击路径变得更麻烦。
2. 在SPN里塞进对合结构:ICEBERG的轮函数与密钥编排
2.1 先把参数底牌亮出来
ICEBERG是2004年前后由几位韩国学者提出的分组加密算法,目标平台从一开始就是低成本硬件。它的基本参数如下:
- 分组长度:64比特
- 密钥长度:128比特
- 轮数:16轮
- 结构:SPN结构
- S盒:4比特S盒,两个交替使用
- 扩散层:基于Hadamard矩阵/线性码构造的二元矩阵
- 核心卖点:加密路径与解密路径共用同一套轮函数
这个参数组合放在今天看并不惊艳,甚至有点复古。64比特分组在现代密码学标准里已经不够看了(得需要至少128比特分组才能抗住生日攻击)。但在它提出的那个年代,RFID标签和传感器节点的计算资源极其有限,64比特分组配合轻量级的轮函数,换来的是电路面积和功耗的可控性。理解一个算法的设计目标,一定要把它放回当时的历史场景里看,而不是用今天的标准去审判它。
2.2 轮函数三层拆解:每一层都努力做"对合层"
ICEBERG的轮函数由三个子层复合而成:密钥加层、S盒替换层、线性扩散层。我们来逐一拆解每个子层是怎么处理对合性问题的。
密钥加层最简单,就是异或轮子密钥。异或天然对合,加了一次再加密钥就回到原位,这一层零成本满足对合。
S盒替换层是第一个技术难点。ICEBERG用的是4比特S盒,而不是AES那种8比特S盒。4比特S盒的好处是面积极小,一个盒只有4个输入比特,组合逻辑非常省,但代价是4比特S盒的差分均匀度和线性逼近优势可能不如8比特S盒,所以需要从代数构造上多花心思。ICEBERG的论文里设计了两个不同的4比特对合S盒,每个S盒都满足"自己是自己的逆映射"。这两个S盒在一轮内部交替使用——比如奇数位置用S1,偶数位置用S2——既保证了每一层的对合性,又通过混用两个代数表达式的替换来抑制简单S盒在连续迭代中的代数规律。
那么4比特对合S盒怎么构造?我记得论文里的思路是从有限域上做文章。在一个特征为2的有限域里,取一个元素的乘法逆元这个映射本身是"逆运算",而逆运算的逆运算是它自己,所以直接把 (x \mapsto x^{-1}) 这个映射拿来用,天然就是自逆的。再在这个基础上复合一些保序的仿射变换,只要仿射变换选取得当,整个S盒仍然能保持对合。这种构造方式和AES的S盒同源(AES也是用有限域逆加仿射变换构造的),只不过AES没有刻意去保持对合性,ICEBERG在设计取舍里把"自逆"当成了硬约束。
线性扩散层是第二个技术难点。ICEBERG的扩散层用了基于Hadamard矩阵构造的二元矩阵。这类矩阵的好处在于:合适的Hadamard矩阵天然满足"矩阵乘自己等于单位阵"或者"转置等于自己"的性质。意思是一个比特的变化经过这一层扩散,能同时影响多个输出比特(扩散性能好),而且这个线性变换的逆变换恰好就是它自己(对合性满足)。
所以从单层角度看,ICEBERG的三个子层全部是对合的。但前面已经说过,两个对合函数的复合不一定对合。如果只是简单地"对合S盒 + 对合扩散矩阵 + 异或密钥层"叠加,解密的时候密钥加层的顺序、S盒与扩散层的交互都会出问题,整体结构依然没法直接复用加密电路。ICEBERG真正的工程巧思,在于它用子密钥编排的对称性解决了层与层之间的"对合复合"问题。
2.3 子密钥编排的镜像对称:解决复合对合的真正钥匙
ICEBERG的密钥编排,据我看到的设计思路,是先通过非线性的密钥扩展算法从128比特主密钥生成一个中间密钥相关的量,再从中间量派生出16轮子密钥。最关键的地方在于:第1轮到第8轮的子密钥序列与第9轮到第16轮的子密钥序列,围绕整个调度表的中心呈镜像对称关系。
这个设计解决了一个看似绕不开的难题:如果轮函数整体对合,解密时数据流反向流动,每一轮遇到的子密钥应该和加密时对应位置的子密钥是什么关系?答案在普通SPN里是"要用逆子密钥",在Feistel里是"把子密钥倒序",但ICEBERG因为子密钥序列本身镜像对称,解密时不需要重新生成一套反序的子密钥序列,只需要改变子密钥轮数的读取方向——硬件上就是改了一个指针或者计数器。
更深一层看,为什么要用镜像对称而不是更简单的完全对称或完全独立?因为如果16轮子密钥完全一样,安全性会出大问题(轮间独立性不足);如果完全独立,解密时数据通路虽然能用,但密钥调度器必须支持"反向生成",那就得要么把所有子密钥都存储下来(费寄存器),要么在硬件里再实现一套反向调度逻辑(费电路)。镜像对称正好卡在中间:既保证了前后轮子密钥不同,又让调度器只需一套硬件就能正反两向供钥。
这个"前后轮子密钥不同但是对称"的思路,本质上是用代数上的弱约束换工程上的强收益,是理解ICEBERG设计哲学的钥匙。
2.4 加密与解密对照:一张表看清"哪里一样、哪里不一样"
我用一张表来总结ICEBERG加解密时的各个操作:
| 操作步骤 | 加密流程 | 解密流程 | 硬件是否共用 |
|---|---|---|---|
| S盒替换 | 用S1/S2交替替换 | 同样用S1/S2交替替换(因为S盒对合) | 完全共用同一套查表电路 |
| 线性扩散 | Hadamard矩阵乘法 | 同一个Hadamard矩阵乘法(矩阵自逆) | 完全共用同一套组合逻辑 |
| 密钥加层 | 与第i轮子密钥异或 | 同样与第i轮子密钥异或(异或自逆) | 完全共用同一套XOR门 |
| 子密钥生成 | 正向读取轮密钥 | 反向读取轮密钥 | 同一套密钥调度逻辑,仅读序改变 |
如果你把加密轮函数和解密轮函数的所有模块名称摆在一起对比,会发现模块列表一模一样,唯一的区别是子密钥的读取顺序和数据的流向。这就是"对合结构"带来的最大工程红利——不是省了某个模块,而是整个反向轮函数逻辑根本不存在。
3. 解密免费?硬件实现里的面积账、功耗账和时序账
3.1 一个真实对比:AES加解密实现里的"面积税"
要说清楚ICEBERG省了什么,得先知道普通SPN密码(比如AES)在"同时支持加解密"时付出了什么代价。
假设你在ASIC上实现一个AES核心,加密需要SubBytes、ShiftRows、MixColumns、AddRoundKey四个操作。如果只做加密,S盒查找表(或组合逻辑)一套,MixColumns矩阵乘一套,面积是很紧凑的。但一旦要支持解密,事情就变了:
- InvSubBytes是逆S盒,要么单独做一套查找表,要么对S盒查找表做反向索引(后者延迟更大);
- InvMixColumns是一套完全不同的矩阵乘法,和MixColumns不能共用,只能单独画逻辑;
- 虽然ShiftRows的逆操作只是换了个移位方向,但那也得有额外的布线或Mux控制。
我记得业界给过一个粗略的估算:一个同时支持加解密的AES核心,面积大约比纯加密核心多出20%到30%。别小看这二三十个百分点的面积税,对于一颗小尺寸RFID芯片来说,这可能就卡在产品能不能塞进指定封装的关键线上。
3.2 ICEBERG把面积省在哪几个具体环节
ICEBERG的对合结构,几乎把上面提到的每一条"面积税"都规避掉了:
- S盒面积省一半:普通SPN正逆S盒各一套,ICEBERG只放一套,因为正逆是同一个映射。4比特S盒虽然单价比8比特S盒便宜,但省掉一套的含义是一样的。
- 扩散层面积省一套:Hadamard矩阵自逆,加密和解密用的是同一个矩阵乘法,组合逻辑只画一遍。反过来想,如果一个SPN算法的扩散矩阵不是自逆的,解密就得额外挂一套逆矩阵乘法的逻辑,这就是纯面积开销。
- 密钥调度面积省一套:ICEBERG子密钥镜像对称,硬件上只需要正向生成参数,反向读取时只需要控制读序。很多普通SPN密码解密时要么预先存好全部轮密钥(要一堆寄存器放着),要么调度器里再实现一套反向扩展(逻辑面积翻倍)。ICEBERG两种坑都避开了。
- 控制逻辑保持极简:加解密切换就相当于"数据从这头进还是从那头进"的方向切换,控制状态机简单得多。
我记得论文里给出的ICEBERG硬件实现面积,和同期的轻量级密码在同时支持加解密的条件下做对比,非常有竞争力,数量级上比AES那种完整加解密内核要省不少。具体数字这些年我已经记不太清,建议以论文报告为准,但趋势肯定是明确的:对合结构在面积指标上确实能换来实打实的收益。
3.3 面积之外的三笔隐性收益
除了面积,我在实际工程里还尝到了另外三个甜头。
第一个是时序收敛变简单了。解密路径共享加密路径后,关键路径只有一条,综合工具不需要同时约束两条路径的时序,时钟频率的收敛难度显著下降。对于追求低功耗的芯片来说,这意味着可以在更低的电压下跑,功耗还能再省一笔。
第二个是验证成本大幅降低。加解密共用一个数据通路,功能验证只需要证明"正向走一遍再反向走一遍能回到原文",比分别验证两套独立逻辑的等价性要省事得多。在密码模块的安全性验证(比如抗故障注入验证)里,这个优势更明显——需要覆盖的攻击路径少了一半。
第三个是硬件随机掩码的实现更顺畅。前面提到过,掩码方案在加解密两边共用时,中间值的随机化表达是一致的。我曾经在一个嵌入式安全项目里切过算法,原来用普通SPN时加解密掩码逻辑要做好几套变体,换成对合结构后,掩码生成、掩码更新、掩码移除的逻辑直接统一了,代码量肉眼可见地缩水。
3.4 什么场景最吃这个特性
坦白说,如果你只想做单方向的加密,比如存数据的时候算个校验密文、或者做一次哈希式操作,那对合结构的好处不大。ICEBERG这类算法的甜区在于"双向通信"和"资源受限"同时成立的场景。
RFID标签是最经典的例子:标签要响应读写器的查询,加密回数据,解密命令,加解密都得有。同时标签芯片的面积和功耗受到严格限制,很多RFID标签连电池都没有,靠射频场供电,每一纳安功耗都在预算表里。ICEBERG这类对合结构算法在标签里实现,一套硬件搞定双向加解密,面积和功耗都省下来了。
传感器网络、智能卡、NFC支付模块、物流溯源芯片,这些场景的逻辑一样:低成本设备,既要加密发出去,又要解密收进来,对成本极其敏感。每次我看到讨论轻量级密码选型的文章都爱提AES-128的最小面积能压到多少门,却很少提"同一颗芯片还要把解密做进去"这半个隐性需求。ICEBERG的思路提醒我们,有时候更聪明的做法不是把单方向做小,而是让另外一个方向直接归零。
4. 对合不是免费的午餐:安全代价与设计权衡
4.1 密码设计的一条铁律:结构越规整,攻击面越顺手
密码算法设计有个绕不开的悖论:为了让硬件好做、面积小、功耗低,你希望结构整齐、对称、规律强;但攻击者最喜欢的就是整齐、对称、规律强的东西。
对合结构相当于给算法强加了一套全局代数对称性。攻击者看到"加密路径等于解密路径",第一反应就是:那我可以把正反两个方向的差分特征连起来用。典型的两类攻击就来了。
一类是飞去来器(boomerang)攻击。这类攻击的基本操作就是把明文加密一段,做修改,再解密回来,利用的是顶半段和底半段的独立差分特征。如果算法加解密路径对称,攻击者的差分特征设计空间会更宽裕,因为下半段的特征可以直接借用上半段路径的性质来构造。
另一类是代数攻击。对合结构本质上是给代数方程组添加了冗余约束,攻击者在构建布尔多项式系统时,这些冗余约束可能让方程求解变得更容易。这就是为什么很多密码算法论文里,光说"结构巧妙"是不够的,你还得证明"这些巧妙的结构不会给攻击者送子弹"。
4.2 ICEBERG怎么应对:轮数、S盒交替和扩散强度
ICEBERG对安全性的应对,从我读过的公开分析来看,主要靠三根支柱:
第一根是足够的轮数。ICEBERG是16轮。对比一下,AES-128的标准轮数是10轮,PRESENT是31轮(但PRESENT的轮函数极其简单),ICEBERG选16轮,说明设计者很清楚"对合结构的规整性需要用更多的迭代轮数来稀释"。多几轮意味着差分特征和线性逼近的传播路径更长,单轮特征再好也较难拼出一条覆盖全轮的实用路径。
第二根是双S盒交替混用。前面提到,S1和S2在每一轮交替排列。这不仅仅是给对合性服务的,它更大的安全意义在于:两个不同代数结构的S盒交替使用,会让攻击者试图用统一的代数表达式描述整个替换层时遇到"非齐次"的痛苦。对于基于代数攻击和插值攻击的判断来说,这种交替设计能明显提高分析难度。
第三根是Hadamard扩散层的扩散速度。ICEBERG的扩散层一次能影响多个输出比特,单个比特的扰动经过一两轮就能覆盖整个分组。对于不可能差分攻击和飞去来器攻击来说,扩散快的算法意味着要构造一条长路径的差分特征更难,因为中间截断的比特位置会迅速蔓延开,很难维持"截断差异"的清晰结构。
从我看到的公开文献记录来看,ICEBERG在提出之后并没有出现实质性的、可复现的全轮攻击结果。它是安全的,但也别因此就把"安全"当成它的最大卖点——它的最大卖点始终是对合结构带来的工程优势。
4.3 用"约束条件下的最优解"眼光评价ICEBERG
如果拿ICEBERG和AES拼"每轮安全性强度",ICEBERG会输;拿它和现代轻量级算法拼"软件实现速度",它也不占优。但拿它和一个默认前提比——"低成本硬件上,加密解密都得做,面积预算在几千门级别"——它就呈现出一种我说不清道不明的优雅感。
我见过不少人评价ICEBERG时把它当做一个"失败的AES挑战者",这让我有点哭笑不得。ICEBERG从来没打算跟AES在通用处理器上抢地盘。它是带着特定的工程约束出场的,它的价值不是取代谁,而是证明了"在SPN结构里也能实现对合路径"这个设计思路是走得通的。
5. 站在ICEBERG肩膀上:轻量级密码的对称路径传承
5.1 同时代的"省钱密码"各显神通
2000年代中后期,轻量级密码设计迎来了一波井喷。各家算法省钱的方向不太一样,可以拉一个表直观对比:
| 算法 | 分组/密钥 | 轮数 | 结构 | 省钱核心思路 |
|---|---|---|---|---|
| ICEBERG | 64/128 | 16 | 对合SPN | 加解密共用轮函数,解密路径近乎免费 |
| PRESENT | 64/80或128 | 31 | SPN | 4位S盒查表极小,置换层布线省电,轮函数简单 |
| HIGHT | 64/128 | 32 | ARX | 纯异或、加法、循环移位,无S盒查表,面积极小 |
| PRINCE | 64/128 | 12 | 对称轮结构FX构造 | 解密=加密+固定常量操作,路径几乎完全对称 |
你看,ICEBERG不是唯一一个往"对称路径"方向使劲的。PRINCE更是把这个理念推到了极致——它的解密实现只需要加密实现加一个固定的alpha常量处理,轮函数部分完全共用。这进一步验证了ICEBERG当初选对合结构作为核心设计约束,是踩在了一个正确的技术方向上。
5.2 "解密路径也省"的设计思想,在后续算法里越走越远
晚近一点的轻量级算法里,你可以明显看到对合思想的变体在延续。比如Midori和SkINNY这类面向深度低功耗场景设计的算法,都在刻意追求"解密轮函数与加密轮函数尽量同构"。SkINNY的官方文档里甚至直接把这一条列为设计目标之一。
更广义地说,很多AEAD(认证加密)方案的硬件实现里,底层的分组密码如果天然对合或者加解密路径对称,认证加密的整体电路就会紧凑得多。因为认证加密在解密方向上本来就要同时做解密和认证两个操作,底层分组密码的"解密代价"越低,整个方案的硬件成本就越可控。
我甚至见过一些做白盒密码和混淆实现的团队,会优先考虑加解密路径对称的底层密码,因为对称路径可以让加解密变换的嵌入表示保持一致,从而减小混淆表的总规模。这说明对合结构的应用范围,早就超出了"RFID芯片省钱密码"这个小圈层。
5.3 从ICEBERG里我学到的三件"密码工程之外"的事
第一件,数学性质是有工程价格的。对合、自逆矩阵、有限域逆映射,这些词听起来像是纯数学对象,但它们背后直接对应的是芯片上省掉的一堆逻辑门。做密码工程的人如果能多从代数结构层面理解算法,很多"性能问题"其实在算法选择阶段就可以避免。
第二件,评估一个密码不能脱离它的目标场景。ICEBERG跟你说"我安全"是没意义的,你要问的是"在面积预算两千克门、加密解密都要、功耗不能超过多少微瓦的前提下,ICEBERG是网安全性和成本之间最好的折中吗?"把约束条件列清楚,选择自然就浮出水面了。
第三件,对称性在密码学里是双刃剑。对合结构给了你面积和功耗的优惠券,但也给了攻击者代数结构上的抓手。设计者必须用轮数、S盒多样性、扩散强度这些手段把安全漏洞补回去。看到任何一个"免费"性质,第一反应应该是"这个免费背后谁买单"。
最后说点我自己的体会
我对ICEBERG的兴趣从第一眼看到它的轮函数图就产生了——十几年前第一次在FPGA上复现它的时候,代码量比我预想的小得多,因为加解密真的只有一套逻辑。我记得当时在仿真波形里看到解密出来的明文和原始明文完全对上的那一刻,觉得一个看似抽象的数学性质(对合)变成芯片上实实在在的面积优势,这个转化链路的魅力是很多复杂算法给不了的。
如果你也想深入研究这个算法,我建议别光读论文,亲手去写一轮加解密的实现。ICEBERG的轮函数结构足够简洁,用任何一门语言写一个软件验证模型都不难。等你写完加密,再把解密函数写出来,你会发现解密函数几乎可以复制粘贴——区别只有子密钥的读序。
那一下的触动,比看十篇论文摘要都管用。密码设计的精妙之处,往往不是多了什么,而是恰到好处地少了一样东西。