有几种使用SIMD操作在恒定时间内实现AES的方法,主要基于快速字节改组(例如Hamburg和Kasper / Schwabe)。是否有任何类似的方法允许仅使用标准C操作来实现恒定时间AES?我所看到的最接近的东西是这种面向字节的AES实现,但是它使用依赖于输入的循环来计算sbox的对数和指数。

#1 楼

一般来说,可以通过将查找表当作硬件电路来在恒定时间内实现。

考虑一个多路复用器:这是一个接受三个输入$ a $,$ b的电路$和$ c $,并产生一个输出$ d $,如果$ c = 0 $则等于$ a $,否则为$ b $(我在这里谈论的是单位值)。多路复用器可用于实现$ 1 \ rightarrow1 $查找表:将$ a $设置为“ 0”输入的表的值,$ b $设置为“ 1”输入的值,并设置$ c $到要转换的实际输入。

如果将单个位值存储在变量中,则相应的C代码如下所示:

d = (a & ~c) | (b & c);




如果您知道如何使用恒定时间代码实现$ n \ rightarrow1 $查找表,则通过隔离最后一个$ n + 1 \ rightarrow1 $查找表位:您考虑两个$ n \ rightarrow1 $子表,第一个是通过将最后一位分别设置为0或1而获得的表。然后,将这两个子表的输出用作$ a $和$ b $输入,用于由最后一个输入位控制的额外多路复用器。这意味着$ n + 1 \ rightarrow1 $表只是一对$ n \ rightarrow1 $表和多余的位,它决定了我们实际上在谈论的两个表中的哪一个。

通过这种构造,一个$ 8 \ rightarrow1 $表可实现为255个多路复用器的树,就像上面的树一样。 AES S-box是一个$ 8 \ rightarrow8 $表,在每个回合中并行应用于16个值,因此您最终不得不评估每回合$ 128 \ times255 $个多路复用器。

但是,使用上面的C代码,您实际上是在并行计算几个多路复用器。如果C变量是64位值,则您正在同时执行64个多路复用器:索引0的位与索引0的其他位对话,索引1的位与索引1的位对话,依此类推,直到索引63的位这称为位切片。由于AES中结构的相似性,您可以使用它来将多路复用器评估的数量减少至每轮$ 4 \乘以255 $:仅需数千个...

使用这种技术,您可以结束使用AES的固定时间纯C实现,应该在例如20000个时钟周期内评估一个块。这确实很慢,但仍然可行。但是,这仅仅是开始。有许多优化可以应用于这种结构(例如,您可以用不完全是一个多路复用器的结构“ a ^ (b & c)”替换多路复用器,该结构在$ a $和$ a \ oplus b $($ a $ xor之间选择$ b $),并且足以实现查找表;而且,树的多路复用器的第一行通常可以折叠,因为其输入的已知值为0或1)。对于DES S盒(八个不同的$ 6 \ rightarrow4 $表),Matthew Kwan早在1998年就设计了非常优化的位片实现。此外,AES S盒具有内部代数结构,可以进一步利用它。 />
谷歌搜索“ bitslice实现AES”链接到一些研究论文,但显然没有一个可以公开下载。

#2 楼

只是为了补充托马斯的答复,这里有几篇不依赖SIMD寄存器来实现位片化AES的论文:




我们可以在x64处理器上走多远? (附录中的源代码)

AES的快速且耐缓存定时的实现(源代码)


#3 楼

补充托马斯的答案:在AES S盒的深度16电路中,Joan Boyar和Rene Peralta以布尔操作的形式紧凑地表示了AES表,这对于位片/ SIMD实现很有用。