diff --git a/SM4-with-AESENCLAST.md b/SM4-with-AESENCLAST.md index e306482..78ab4b1 100644 --- a/SM4-with-AESENCLAST.md +++ b/SM4-with-AESENCLAST.md @@ -21,6 +21,75 @@ My question is how to generate all (M1, C1, M2, C2)? {(M1, C1, M2, C2) | SM4-S(x) = A2(AES-S(A1(x)), A1(x) = M1*x + C1, A2(x) = M2*x + C2} ``` +**Evolution path** + +sm4_box_aesenclast <-> sm4_box_aesbox_1 <-> sm4_box_aesbox_2 <-> sm4_box_aesbox_3 <-> sm4_box_aesbox_4 +``` +sm4_box_aesenclast + y := mm_and_si128(x, const_0f) + y = mm_shuffle_epi8(a1l, y) + x = mm_srli_epi64(x, 4) + x = mm_and_si128(x, const_0f) + x = xor(mm_shuffle_epi8(a1h, x), y) + + x = mm_shuffle_epi8(x, shift_row_inv) + x = mm_aesenclast_si128(x, const_0f) + + y = mm_andnot_si128(x, const_0f) + y = mm_shuffle_epi8(a2l, y) + x = mm_srli_epi64(x, 4) + x = mm_and_si128(x, const_0f) + x = xor(mm_shuffle_epi8(a2h, x), y) + +sm4_box_aesbox_1 + var y __m128i + for i := 0; i < 16; i++ { + y.bytes[i] = a1l.bytes[x.bytes[i]&0xf] ^ a1h.bytes[x.bytes[i]>>4] + } + x = y + + for i := 0; i < 16; i++ { + x.bytes[i] = aes_sbox[x.bytes[i]] ^ 0xf + } + + for i := 0; i < 16; i++ { + y.bytes[i] = a2l.bytes[(^x.bytes[i])&0xf] ^ a2h.bytes[x.bytes[i]>>4] + } + +sm4_box_aesbox_2 + for i := 0; i < 16; i++ { + v := x.bytes[i] + v = a1l.bytes[v&0xf] ^ a1h.bytes[v>>4] + v = aes_sbox[v] ^ 0xf + v = a2l.bytes[^v&0xf] ^ a2h.bytes[v>>4] + x.bytes[i] = v + } + +sm4_box_aesbox_3 + for i := 0; i < 16; i++ { + v := x.bytes[i] + v = a1l.bytes[v&0xf] ^ a1h.bytes[v>>4] + + v = aes_sbox[v] + + v = a2l.bytes[v&0xf] ^ a2h.bytes[v>>4] + + x.bytes[i] = v + } + +sm4_box_aesbox_4 + for i := 0; i < 16; i++ { + v := x.bytes[i] + v = a1_table[v] + + v = aes_sbox[v] + + v = a2_table[v] + + x.bytes[i] = v + } +``` + **How to calculate M, C from lookup table?** 1.The first element of the table, T[0] should be the C.