C++ AES-NI, расшифровывающий 256-битный блок

Итак, вот моя проблема... Я пишу реализацию AES-NI для библиотеки, и я застрял в расшифровке 256-битного блока. Вот что я знаю.. 128-битный блок работает отлично. Шифрование 256 блоков соответствует проверенной реализации Rijndael. Расширенный ключ также выравнивается с другой реализацией Rijndael (учитывая порядок байтов с прямым порядком байтов). Подпрограмма использует маску наложения и сдвига, чтобы компенсировать тасование столбца смещения 256-битного блока, это инверсия маски, используемой для шифрования блока, это также проверено и, кажется, работает нормально. Вот функция шифрования:

    void Encrypt32(const std::vector<byte> &Input, const size_t InOffset, std::vector<byte> &Output, const size_t OutOffset)
{
    const size_t LRD = m_expKey.size() - 3;
    size_t keyCtr = 0;
    __m128i RIJNDAEL256_MASK = { 0,1,6,7,4,5,10,11,8,9,14,15,12,13,2,3 };
    __m128i BLEND_MASK = _mm_set_epi32(0x80000000, 0x80800000, 0x80800000, 0x80808000);
    __m128i block1 = _mm_loadu_si128((const __m128i*)(const void*)&Input[InOffset]);
    __m128i block2 = _mm_loadu_si128((const __m128i*)(const void*)&Input[InOffset + 16]);
    __m128i temp1, temp2;

    block1 = _mm_xor_si128(block1, m_expKey[keyCtr]);
    block2 = _mm_xor_si128(block2, m_expKey[++keyCtr]);

    while (keyCtr != LRD)
    {
        temp1 = _mm_blendv_epi8(block1, block2, BLEND_MASK);    // combine 2 blocks
        temp2 = _mm_blendv_epi8(block2, block1, BLEND_MASK);
        temp1 = _mm_shuffle_epi8(temp1, RIJNDAEL256_MASK);      // shuffle
        temp2 = _mm_shuffle_epi8(temp2, RIJNDAEL256_MASK);
        block1 = _mm_aesenc_si128(temp1, m_expKey[++keyCtr]);   // encrypt
        block2 = _mm_aesenc_si128(temp2, m_expKey[++keyCtr]);
    }

    temp1 = _mm_blendv_epi8(block1, block2, BLEND_MASK);
    temp2 = _mm_blendv_epi8(block2, block1, BLEND_MASK);
    temp1 = _mm_shuffle_epi8(temp1, RIJNDAEL256_MASK);
    temp2 = _mm_shuffle_epi8(temp2, RIJNDAEL256_MASK);
    block1 = _mm_aesenclast_si128(temp1, m_expKey[++keyCtr]);
    block2 = _mm_aesenclast_si128(temp2, m_expKey[++keyCtr]);

    _mm_storeu_si128((__m128i*)(void*)&Output[OutOffset], block1);
    _mm_storeu_si128((__m128i*)(void*)&Output[OutOffset + 16], block2);
}

Это обратное преобразование:

    void Decrypt32(const std::vector<byte> &Input, const size_t InOffset, std::vector<byte> &Output, const size_t OutOffset)
{
    const size_t LRD = m_expKey.size() - 3;
    __m128i RIJNDAELINV_MASK = { 0,1,14,15,4,5,2,3,8,9,6,7,12,13,10,11 };
    __m128i BLEND_MASK = _mm_set_epi32(0x80000000, 0x80800000, 0x80800000, 0x80808000);
    __m128i block1 = _mm_loadu_si128((const __m128i*)(const void*)&Input[InOffset]);
    __m128i block2 = _mm_loadu_si128((const __m128i*)(const void*)&Input[InOffset + 16]);
    __m128i temp1, temp2;
    size_t keyCtr = 0;

    block1 = _mm_xor_si128(block1, m_expKey[keyCtr]);
    block2 = _mm_xor_si128(block2, m_expKey[++keyCtr]);

    while (keyCtr != LRD)
    {
        temp1 = _mm_aesdec_si128(block1, m_expKey[++keyCtr]);   // decrypt
        temp2 = _mm_aesdec_si128(block2, m_expKey[++keyCtr]);
        temp1 = _mm_shuffle_epi8(temp1, RIJNDAELINV_MASK);      // shuffle
        temp2 = _mm_shuffle_epi8(temp2, RIJNDAELINV_MASK);
        block1 = _mm_blendv_epi8(temp1, temp2, BLEND_MASK);     // combine
        block2 = _mm_blendv_epi8(temp2, temp1, BLEND_MASK);
    }

    temp1 = _mm_aesdeclast_si128(block1, m_expKey[++keyCtr]);
    temp2 = _mm_aesdeclast_si128(block2, m_expKey[++keyCtr]);
    temp1 = _mm_shuffle_epi8(temp1, RIJNDAELINV_MASK);
    temp2 = _mm_shuffle_epi8(temp2, RIJNDAELINV_MASK);
    block1 = _mm_blendv_epi8(temp1, temp2, BLEND_MASK);
    block2 = _mm_blendv_epi8(temp2, temp1, BLEND_MASK);

    _mm_storeu_si128((__m128i*)(void*)&Output[OutOffset], block1);
    _mm_storeu_si128((__m128i*)(void*)&Output[OutOffset + 16], block2);
}

Я отлаживал это часами и просто не могу определить проблему, может кто-нибудь понять, почему это не сработает? Я могу опубликовать код для мерзавца, если это поможет.

0 ответов

Другие вопросы по тегам