C 使用_mm_AESKYGENAssist_si128匹配参考值

C 使用_mm_AESKYGENAssist_si128匹配参考值,c,encryption,cryptography,aes,aes-ni,C,Encryption,Cryptography,Aes,Aes Ni,我正在尝试使用Intel SI使EAX正常工作。使用位于的纸张,我有一个输入键: Cipher Key = 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c 我试图匹配第二个扩展键,看起来应该是: rk[1] = A0 FA FE 17 88 54 2C B1 23 A3 39 39 2A 6C 76 05 我从网上抓取了使用Intel Intrinsic的各种代码片段,例如:。它们都集中在一个不同的值上: rk[1] = C0 7F 9F 93

我正在尝试使用Intel SI使EAX正常工作。使用位于的纸张,我有一个输入键:

Cipher Key = 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c
我试图匹配第二个扩展键,看起来应该是:

rk[1] = A0 FA FE 17 88 54 2C B1 23 A3 39 39 2A 6C 76 05
我从网上抓取了使用Intel Intrinsic的各种代码片段,例如:。它们都集中在一个不同的值上:

rk[1] = C0 7F 9F 93 E8 D1 4D 35 43 26 58 BD 4A E9 17 81
下面是我正在使用的一个示例片段:

#include <wmmintrin.h>
#include <emmintrin.h>
#include <smmintrin.h>

void dump(const char *banner, __m128i v) {
    printf("%s: ", banner);
    uint16_t *v64val = (uint16_t*) &v;
    for (int i =0; i < 4; ++i) {
        printf("%02X\n", *(v64val+i*2+1));
        printf("%02X\n", *(v64val+i*2));
    }
}

__m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) { 
    __m128i temp3; 
    temp2 = _mm_shuffle_epi32 (temp2 ,0xff); 
    temp3 = _mm_slli_si128 (temp1, 0x4);
    temp1 = _mm_xor_si128 (temp1, temp3);
    temp3 = _mm_slli_si128 (temp3, 0x4);
    temp1 = _mm_xor_si128 (temp1, temp3);
    temp3 = _mm_slli_si128 (temp3, 0x4);
    temp1 = _mm_xor_si128 (temp1, temp3);
    temp1 = _mm_xor_si128 (temp1, temp2); 
    return temp1; 
}

void AES_key_expansion_raw(uint32_t key[], __m128i *ret) {
    __m128i rkey, tmp2;
    ret[0] = rkey = _mm_loadu_si128((__m128i*)key);

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[1] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x2);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[2] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x4);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[3] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x8);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[4] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x10);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[5] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x20);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[6] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x40);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[7] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x80);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[8] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1b);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[9] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x36);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[10] = rkey;
}

int main() {
    printf("INTEL:\n");
    __m128i rdkeys[11];
    uint32_t key[] = {0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c};
    AES_key_expansion_raw(key, rdkeys);
    for (int i = 0; i < 11; ++i) {
        dump("RK", rdkeys[i]);
    }


    return 0;
}
#包括
#包括
#包括
无效转储(常量字符*横幅,_m128i v){
printf(“%s:”,横幅);
uint16_t*v64val=(uint16_t*)&v;
对于(int i=0;i<4;++i){
printf(“%02X\n”,*(v64val+i*2+1));
printf(“%02X\n”,*(v64val+i*2));
}
}
__m128i AES_128_辅助(uuu m128i temp1,uuu m128i temp2){
__m128i-temp3;
temp2=_mm_shuffle_epi32(temp2,0xff);
temp3=_mm_slli_si128(temp1,0x4);
temp1=_mm_xor_si128(temp1,temp3);
temp3=_mm_slli_si128(temp3,0x4);
temp1=_mm_xor_si128(temp1,temp3);
temp3=_mm_slli_si128(temp3,0x4);
temp1=_mm_xor_si128(temp1,temp3);
temp1=_mm_xor_si128(temp1,temp2);
返回temp1;
}
无效AES键扩展键原始(uint32键[],m128i*ret){
__m128i rkey,tmp2;
ret[0]=rkey=_mm_loadu_si128((_m128i*)键);
tmp2=_mm_aeskeygenassist_si128(rkey,0x1);
rkey=AES_128_辅助(rkey,tmp2);
ret[1]=rkey;
tmp2=_mm_aeskeygenassist_si128(rkey,0x2);
rkey=AES_128_辅助(rkey,tmp2);
ret[2]=rkey;
tmp2=_mm_aeskeygenassist_si128(rkey,0x4);
rkey=AES_128_辅助(rkey,tmp2);
ret[3]=rkey;
tmp2=_mm_aeskeygenassist_si128(rkey,0x8);
rkey=AES_128_辅助(rkey,tmp2);
ret[4]=rkey;
tmp2=_mm_aeskeygenassist_si128(rkey,0x10);
rkey=AES_128_辅助(rkey,tmp2);
ret[5]=rkey;
tmp2=_mm_aeskeygenassist_si128(rkey,0x20);
rkey=AES_128_辅助(rkey,tmp2);
ret[6]=rkey;
tmp2=_mm_aeskeygenassist_si128(rkey,0x40);
rkey=AES_128_辅助(rkey,tmp2);
ret[7]=rkey;
tmp2=_mm_aeskeygenassist_si128(rkey,0x80);
rkey=AES_128_辅助(rkey,tmp2);
ret[8]=rkey;
tmp2=_mm_aeskeygenassist_si128(rkey,0x1b);
rkey=AES_128_辅助(rkey,tmp2);
ret[9]=rkey;
tmp2=_mm_aeskeygenassist_si128(rkey,0x36);
rkey=AES_128_辅助(rkey,tmp2);
ret[10]=rkey;
}
int main(){
printf(“英特尔:\n”);
__m128i-rdkey[11];
uint32_t key[]={0x2b7e1516、0x28aed2a6、0xabf71588、0x09cf4f3c};
AES_key_expansion_raw(key,rdkey);
对于(int i=0;i<11;++i){
转储(“RK”,rdkeys[i]);
}
返回0;
}
通过阅读_mm_aeskeygenassist_si128的文档,我不太明白我应该如何使用它来生成圆键,我甚至对我看到的各种实现更为困惑,这些实现似乎生成了与AES规范不匹配的圆键


关于如何调和有什么想法吗?谢谢

这是您想要从英特尔获得的文档:。它解释了如何使用AES指令集。可惜ARM和POWER8没有提供相同的质量指导。
\u mm\u aeskeygenassist\u si128
的用法应该类似于Botan的用法。如果将单词中的字节反转,例如使用
0x16157e2b
而不是
0x2b7e1516
,会发生什么?请注意,英特尔处理器是little endian!请注意,输出单词的顺序也可能是“错误的”(对于little endian爱好者,请将“错误”放在引号内)。