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
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