aesimc 指令给出不正确的结果

发布于 2024-10-22 04:35:44 字数 1437 浏览 5 评论 0原文

我正在尝试使用 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:
enter image description here

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

是伱的 2024-10-29 04:35:44

字节是向后的。如果您希望 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文