aesimc 指令给出不正确的结果
我正在尝试使用 AES 机器指令实现 AES 加密(基于英特尔的白皮书 )可以在我的桑迪桥上找到。不幸的是,我在生成用于解密的轮密钥的阶段停止了。具体来说,指令aesimc
(应用逆混合列操作)返回不正确的结果。
他们在论文中举了一个例子:
因此,通过输入:
48 69 28 53 68 61 79 29 5B 47 75 65 72 6F 6E 5D
我使用 _mm_aesimc_si128()
得到以下内容:
2D BF F9 31 99 CD 3A 37 B7 C7 81 FD 7D E0 3D 8E
它应该返回:
62 7A 6F 66 44 B1 09 C8 2B 18 33 0A 81 C3 B3 E5
结果不同。 为什么会这样?
如果你想重现它,我用下面的代码测试了它(记住编译时的参数-maes -msse4
):
#include <wmmintrin.h>
#include <iostream>
using namespace std;
void print_m128i(__m128i data) {
unsigned char *ptr = (unsigned char*) &data;
for (int i = 0; i < 16; i++) {
int val = (int) ptr[i];
if (val < 0xF) {
cout << "0";
}
cout << uppercase << hex << val << " ";
}
cout << endl;
}
int main() {
unsigned char *data = (unsigned char*)
"\x48\x69\x28\x53\x68\x61\x79\x29\x5B\x47\x75\x65\x72\x6F\x6E\x5D";
__m128i num = _mm_loadu_si128((__m128i*) data);
__m128i num2 = _mm_aesimc_si128(num);
print_m128i(num2);
return 0;
}
编辑:英特尔白皮书中的例子是错误的。正如汉斯所建议的,我的芯片是小端字节序,因此需要来回字节交换。
I'm trying to implement AES cryptography using the AES machine instructions (basing it on Intel's white paper) available on my Sandy Bridge. Unfortunately, I've come to a halt in the phase of generating the round keys for decryption. Specifically, the instruction aesimc
(applying the Inverse Mix Columns operation) returns an incorrect result.
In their paper they have an example:
So with input:
48 69 28 53 68 61 79 29 5B 47 75 65 72 6F 6E 5D
I get the following using _mm_aesimc_si128()
:
2D BF F9 31 99 CD 3A 37 B7 C7 81 FD 7D E0 3D 8E
It should have returned:
62 7A 6F 66 44 B1 09 C8 2B 18 33 0A 81 C3 B3 E5
Not the same result. Why is this the case?
If you want to reproduce it, I tested it with the code below (remember the arguments -maes -msse4
when compiling):
#include <wmmintrin.h>
#include <iostream>
using namespace std;
void print_m128i(__m128i data) {
unsigned char *ptr = (unsigned char*) &data;
for (int i = 0; i < 16; i++) {
int val = (int) ptr[i];
if (val < 0xF) {
cout << "0";
}
cout << uppercase << hex << val << " ";
}
cout << endl;
}
int main() {
unsigned char *data = (unsigned char*)
"\x48\x69\x28\x53\x68\x61\x79\x29\x5B\x47\x75\x65\x72\x6F\x6E\x5D";
__m128i num = _mm_loadu_si128((__m128i*) data);
__m128i num2 = _mm_aesimc_si128(num);
print_m128i(num2);
return 0;
}
EDIT: The example in Intel's white paper was wrong. As Hans suggested, my chip is little-endian so byte-swapping is necessary - to and fro.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
字节是向后的。如果您希望 0x5d 成为最低有效字节,那么它必须位于第一位。这是一个小端芯片。在VS中,使用Debug + Windows + Registers,右键+勾选SSE即可查看寄存器值。
The bytes are backwards. You want 0x5d to be the least significant byte, it has to come first. This is a little-endian chip. In VS, use Debug + Windows + Registers, right-click + tick SSE to see the register values.