为什么SSE中的AES不能提供全部功能?

时间:2017-10-01 13:30:32

标签: assembly x86 aes sse instruction-set

Rijndael key schedule procedure涉及RotWordSubWordXOR,这些都受到{ _mm_aeskeygenassist_si128

X3[31:0] ← SRC [127: 96];
X2[31:0] ← SRC [95: 64];
X1[31:0] ← SRC [63: 32];
X0[31:0] ← SRC [31: 0];
RCON[31:0] ← ZeroExtend(Imm8[7:0]);
DEST[31:0] ← SubWord(X1);
DEST[63:32 ] ← RotWord( SubWord(X1) ) XOR RCON;
DEST[95:64] ← SubWord(X3);
DEST[127:96] ← RotWord( SubWord(X3) ) XOR RCON;
DEST[VLMAX-1:128] (Unmodified)

但是,它不会返回完整的圆键。例如,而不是简单地执行

DEST[31:0] <- SubWord(X1)

我想我们应该实际执行

DEST[31:0]<-RotWord(SubWord(X3)) XOR RCON XOR X0

因此,在_mm_aeskeygenassist_si128之后,我们的开发人员必须在完全生成轮密钥之前做一些额外的工作。

为什么SSE不提供完整的AES密钥生成程序?

1 个答案:

答案 0 :(得分:6)

请参阅英特尔AES-NI白皮书中的Key Expansion Using AESKEYGENASSIST (page 23)。他们指出该指令可以用作不同密钥大小的构建块:128/192/256。它们仅显示128b的示例,在您描述的每个aeskeygenassist指令之后执行函数调用的额外工作。

AESKEYGENASSIST已经进行了微编码(例如Skylake上有13次uop,AESDEC / AESENC只有1次(http://agner.org/optimize/)),因此使用不同的指令执行最后几步对于不同的密钥大小而言,它们的不同之处并不能使其以当前实施的方式运行得更快。

Skylake每12个周期aeskeygenassist吞吐量为1,但Nehalem每2个周期有1个,与aesenc相同。所以在Nehalem中,我猜他们确实在专用硬件中实现了它。这可能是解释的另一部分:更多的步骤将在第一代实现中采用更多的硬件,或者使该指令微编码(它可能不是在Nehalem中)来做额外的更多uops的步骤。

英特尔显然不认为密钥设置对性能至关重要,因为我说他们在Nehalem之后降低了aeskeygenassist的性能。 (即使是Sandybridge,它每8个时钟吞吐量就会有1个微编码。)

对不同的密钥大小有不同的指令会占用更多的操作码。那时,英特尔还没有引入VEX前缀,因此在AES指令上花费更多的操作码空间会减少未来扩展的空间。 (VEX有大量可用的编码空间,仅使用当前指令使用的现有强制前缀组合的几个多位代码。)