1
$\begingroup$

I am trying to understand the SIMD implementation of TAU function of SM4 which is as follows:

#define SM4_TAU_L1 { \
    y = _mm_and_si128(x, c0f);              \
    y = _mm_shuffle_epi8(m1l, y);           \
    x = _mm_srli_epi64(x, 4);               \
    x = _mm_and_si128(x, c0f);              \
    x = _mm_shuffle_epi8(m1h, x) ^ y;       \
    x = _mm_shuffle_epi8(x, shr);           \
    x = _mm_aesenclast_si128(x, c0f);       \
    y = _mm_andnot_si128(x, c0f);           \
    y = _mm_shuffle_epi8(m2l, y);           \
    x = _mm_srli_epi64(x, 4);               \
    x = _mm_and_si128(x, c0f);              \
    x = _mm_shuffle_epi8(m2h, x) ^ y;       \
    y = x ^ _mm_shuffle_epi8(x, r08) ^      \
        _mm_shuffle_epi8(x, r16);           \
    y = _mm_slli_epi32(y, 2) ^              \
        _mm_srli_epi32(y, 30);              \
    x = x ^ y ^ _mm_shuffle_epi8(x, r24);   \
}

it looks as if the SM4 S-box is an affine equivalent of the Rijndael S-box using this formula:

$$SM4= B(raj(A(x\oplus a))\oplus b$$ where (using a search tool):

$$A=\begin{bmatrix} 1& 1& 1& 1& 1& 0& 0& 1\\ 1& 1& 1& 0& 1& 1& 0& 1\\ 1& 1& 1& 1& 1& 0& 1& 1\\ 1& 0& 0& 0& 1& 1& 1& 1\\ 1& 1& 0& 1& 0& 1& 0& 1\\ 1& 1& 1& 1& 1& 1& 0& 0\\ 1& 1& 1& 1& 0& 1& 1& 0\\ 0& 0& 0& 0& 0& 1& 0& 0 \end{bmatrix}$$

$$B=\begin{bmatrix} 0& 1& 0& 0& 1& 0& 0& 1\\ 0& 0& 0& 1& 1& 0& 1& 1\\ 1& 0& 0& 0& 1& 0& 0& 1\\ 1& 0& 0& 0& 1& 1& 0& 0\\ 1& 0& 0& 0& 0& 1& 1& 0\\ 0& 0& 0& 1& 0& 0& 1& 1\\ 0& 0& 1& 1& 0& 0& 1& 0\\ 0& 1& 0& 1& 1& 0& 0& 1 \end{bmatrix}$$

$$a=0x75 \space\space , \space\space b=0xfb$$

I applied the decomposition concept used in SCREAM Side-Channel Resistant Authenticated Encryption with Masking to obtain four 4-bit lookup tables of each matrix ( it worked); however, my values are different for m1l, m1h, m2l, m2h.

  // Affine transform 1 (low and high hibbles)
    const __m128i m1l __attribute__((aligned(0x10))) =
        { 0x9197E2E474720701, 0xC7C1B4B222245157 };
    const __m128i m1h __attribute__((aligned(0x10))) =
        { 0xE240AB09EB49A200, 0xF052B91BF95BB012 };

    // Affine transform 2 (low and high hibbles)
    const __m128i m2l __attribute__((aligned(0x10))) =
        { 0x5B67F2CEA19D0834, 0xEDD14478172BBE82 };
    const __m128i m2h __attribute__((aligned(0x10))) =
        { 0xAE7201DD73AFDC00, 0x11CDBE62CC1063BF };

In my understanding, the author used a 4-to-8 bit lookup table, and now my question:

How did the author derive the values of m1l, m1h, m2l, and m2h?

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.