vsm4key4

SM4 Key Generation

VSM4KEY4 xmm1, xmm2

SM4 key generation.

Details

Performs key schedule expansion for SM4 block cipher, deriving round keys from a 128-bit key material input and producing expanded key words in the destination XMM register. This instruction is used during SM4 key setup to generate all required round keys and does not modify EFLAGS.

Pseudocode Operation

key ← xmm2[32*i..32*i+31] for i in 0 to 3
expanded_key ← SM4_KEY_SCHEDULE(key)
xmm1[128 bits] ← expanded_key[0..3]

Example

VSM4KEY4 xmm1, xmm2

Encoding

Binary Layout
DA
+0
 
Format VEX
Opcode VEX.128.F3.0F38.W0 DA /r
Extension SM4

Operands

  • dest
    128-bit XMM SIMD register
  • src
    128-bit XMM SIMD register

Reference (Intel® SDM)

Instruction Forms

Opcode Instruction Op/En 64/32-bit Mode CPUID Description
VEX.128.F3.0F38.W0 DA /r VSM4KEY4 xmm1, xmm2, xmm3/m128 A V/V AVX SM4 Performs four rounds of SM4 key expansion.
VEX.256.F3.0F38.W0 DA /r VSM4KEY4 ymm1, ymm2, ymm3/m256 A V/V AVX SM4 Performs four rounds of SM4 key expansion.

Instruction Operand Encoding

Op/En Tuple Type Operand 1 Operand 2 Operand 3 Operand 4
A N/A ModRM:reg (w) VEX.vvvv (r) ModRM:r/m (r) N/A

Description

The VSM4KEY4 instruction performs four rounds of SM4 key expansion. The instruction operates on independent 128-bit lanes. Additional details can be found at: https://tools.ietf.org/html/draft-ribose-cfrg-sm4-10. Both SM4 instructions use a common sbox table: BYTE sbox[256] = { 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48 }

Operation

define ROL32(dword, n):
count := n % 32
dest := (dword << count) | (dword >> (32-count))
return dest

define SBOX_BYTE(dword, i):
// sbox[] array defined in introduction
return sbox[dword.byte[i]]

define lower_t(dword):
tmp.byte[0] := SBOX_BYTE(dword, 0)


VSM4KEY4—Perform Four Rounds of SM4 Key Expansion                                                                                      Vol. 2C 5-761
tmp.byte[1] := SBOX_BYTE(dword, 1)
tmp.byte[2] := SBOX_BYTE(dword, 2)
tmp.byte[3] := SBOX_BYTE(dword, 3)
return tmp

define L_KEY(dword):
return dword ^ ROL32(dword, 13) ^ ROL32(dword, 23)

define T_KEY(dword):
return L_KEY(lower_t(dword))

define F_KEY(X0, X1, X2, X3, round_key):
return X0 ^ T_KEY(X1 ^ X2 ^ X3 ^ round_key)


VSM4KEY4 DEST, SRC1, SRC2
VL = (128, 256) // VEX versions
// or
VL = (128,256,512) // EVEX versions
KL := VL/128

for i in 0..KL-1:
P[0] := SRC1.xmm[i].dword[0]
P[1] := SRC1.xmm[i].dword[1]
P[2] := SRC1.xmm[i].dword[2]
P[3] := SRC1.xmm[i].dword[3]

C[0] := F_KEY(P[0], P[1], P[2], P[3], SRC2.xmm[i].dword[0])
C[1] := F_KEY(P[1], P[2], P[3], C[0], SRC2.xmm[i].dword[1])
C[2] := F_KEY(P[2], P[3], C[0], C[1], SRC2.xmm[i].dword[2])
C[3] := F_KEY(P[3], C[0], C[1], C[2], SRC2.xmm[i].dword[3])

DEST.xmm[i].dword[0] := C[0]
DEST.xmm[i].dword[1] := C[1]
DEST.xmm[i].dword[2] := C[2]
DEST.xmm[i].dword[3] := C[3]

DEST[MAXVL-1:VL] := 0

Intel C/C++ Compiler Intrinsic Equivalent

VSM4KEY4 __m128i _mm_sm4key4_epi32 (__m128i __A, __m128i __B);
VSM4KEY4 __m256i _mm256_sm4key4_epi32 (__m256i __A, __m256i __B);

Flags Affected

None.

Exceptions

SIMD Floating-Point Exceptions

None.

Other Exceptions

See Table 2-23, “Type 6 Class Exception Conditions.” VSM4KEY4—Perform Four Rounds of SM4 Key Expansion Vol. 2C 5-762