brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.2 KiB · 47aeec4 Raw
270 lines · c
1/*===--------------- sm4intrin.h - SM4 intrinsics -----------------===2 *3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4 * See https://llvm.org/LICENSE.txt for license information.5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6 *7 *===-----------------------------------------------------------------------===8 */9 10#ifndef __IMMINTRIN_H11#error "Never use <sm4intrin.h> directly; include <immintrin.h> instead."12#endif // __IMMINTRIN_H13 14#ifndef __SM4INTRIN_H15#define __SM4INTRIN_H16 17/// This intrinsic performs four rounds of SM4 key expansion. The intrinsic18///    operates on independent 128-bit lanes. The calculated results are19///    stored in \a dst.20/// \headerfile <immintrin.h>21///22/// \code23/// __m128i _mm_sm4key4_epi32(__m128i __A, __m128i __B)24/// \endcode25///26/// This intrinsic corresponds to the \c VSM4KEY4 instruction.27///28/// \param __A29///    A 128-bit vector of [4 x int].30/// \param __B31///    A 128-bit vector of [4 x int].32/// \returns33///    A 128-bit vector of [4 x int].34///35/// \code{.operation}36/// DEFINE ROL32(dword, n) {37/// 	count := n % 3238/// 	dest := (dword << count) | (dword >> (32-count))39/// 	RETURN dest40/// }41/// DEFINE SBOX_BYTE(dword, i) {42/// 	RETURN sbox[dword.byte[i]]43/// }44/// DEFINE lower_t(dword) {45/// 	tmp.byte[0] := SBOX_BYTE(dword, 0)46/// 	tmp.byte[1] := SBOX_BYTE(dword, 1)47/// 	tmp.byte[2] := SBOX_BYTE(dword, 2)48/// 	tmp.byte[3] := SBOX_BYTE(dword, 3)49/// 	RETURN tmp50/// }51/// DEFINE L_KEY(dword) {52/// 	RETURN dword ^ ROL32(dword, 13) ^ ROL32(dword, 23)53/// }54/// DEFINE T_KEY(dword) {55/// 	RETURN L_KEY(lower_t(dword))56/// }57/// DEFINE F_KEY(X0, X1, X2, X3, round_key) {58/// 	RETURN X0 ^ T_KEY(X1 ^ X2 ^ X3 ^ round_key)59/// }60/// FOR i:= 0 to 061/// 	P[0] := __B.xmm[i].dword[0]62/// 	P[1] := __B.xmm[i].dword[1]63/// 	P[2] := __B.xmm[i].dword[2]64/// 	P[3] := __B.xmm[i].dword[3]65/// 	C[0] := F_KEY(P[0], P[1], P[2], P[3], __A.xmm[i].dword[0])66/// 	C[1] := F_KEY(P[1], P[2], P[3], C[0], __A.xmm[i].dword[1])67/// 	C[2] := F_KEY(P[2], P[3], C[0], C[1], __A.xmm[i].dword[2])68/// 	C[3] := F_KEY(P[3], C[0], C[1], C[2], __A.xmm[i].dword[3])69/// 	DEST.xmm[i].dword[0] := C[0]70/// 	DEST.xmm[i].dword[1] := C[1]71/// 	DEST.xmm[i].dword[2] := C[2]72/// 	DEST.xmm[i].dword[3] := C[3]73/// ENDFOR74/// DEST[MAX:128] := 075/// \endcode76#define _mm_sm4key4_epi32(A, B)                                                \77  (__m128i) __builtin_ia32_vsm4key4128((__v4su)A, (__v4su)B)78 79/// This intrinsic performs four rounds of SM4 key expansion. The intrinsic80///    operates on independent 128-bit lanes. The calculated results are81///    stored in \a dst.82/// \headerfile <immintrin.h>83///84/// \code85/// __m256i _mm256_sm4key4_epi32(__m256i __A, __m256i __B)86/// \endcode87///88/// This intrinsic corresponds to the \c VSM4KEY4 instruction.89///90/// \param __A91///    A 256-bit vector of [8 x int].92/// \param __B93///    A 256-bit vector of [8 x int].94/// \returns95///    A 256-bit vector of [8 x int].96///97/// \code{.operation}98/// DEFINE ROL32(dword, n) {99/// 	count := n % 32100/// 	dest := (dword << count) | (dword >> (32-count))101/// 	RETURN dest102/// }103/// DEFINE SBOX_BYTE(dword, i) {104/// 	RETURN sbox[dword.byte[i]]105/// }106/// DEFINE lower_t(dword) {107/// 	tmp.byte[0] := SBOX_BYTE(dword, 0)108/// 	tmp.byte[1] := SBOX_BYTE(dword, 1)109/// 	tmp.byte[2] := SBOX_BYTE(dword, 2)110/// 	tmp.byte[3] := SBOX_BYTE(dword, 3)111/// 	RETURN tmp112/// }113/// DEFINE L_KEY(dword) {114/// 	RETURN dword ^ ROL32(dword, 13) ^ ROL32(dword, 23)115/// }116/// DEFINE T_KEY(dword) {117/// 	RETURN L_KEY(lower_t(dword))118/// }119/// DEFINE F_KEY(X0, X1, X2, X3, round_key) {120/// 	RETURN X0 ^ T_KEY(X1 ^ X2 ^ X3 ^ round_key)121/// }122/// FOR i:= 0 to 1123/// 	P[0] := __B.xmm[i].dword[0]124/// 	P[1] := __B.xmm[i].dword[1]125/// 	P[2] := __B.xmm[i].dword[2]126/// 	P[3] := __B.xmm[i].dword[3]127/// 	C[0] := F_KEY(P[0], P[1], P[2], P[3], __A.xmm[i].dword[0])128/// 	C[1] := F_KEY(P[1], P[2], P[3], C[0], __A.xmm[i].dword[1])129/// 	C[2] := F_KEY(P[2], P[3], C[0], C[1], __A.xmm[i].dword[2])130/// 	C[3] := F_KEY(P[3], C[0], C[1], C[2], __A.xmm[i].dword[3])131/// 	DEST.xmm[i].dword[0] := C[0]132/// 	DEST.xmm[i].dword[1] := C[1]133/// 	DEST.xmm[i].dword[2] := C[2]134/// 	DEST.xmm[i].dword[3] := C[3]135/// ENDFOR136/// DEST[MAX:256] := 0137/// \endcode138#define _mm256_sm4key4_epi32(A, B)                                             \139  (__m256i) __builtin_ia32_vsm4key4256((__v8su)A, (__v8su)B)140 141/// This intrinisc performs four rounds of SM4 encryption. The intrinisc142///    operates on independent 128-bit lanes. The calculated results are143///    stored in \a dst.144/// \headerfile <immintrin.h>145///146/// \code147/// __m128i _mm_sm4rnds4_epi32(__m128i __A, __m128i __B)148/// \endcode149///150/// This intrinsic corresponds to the \c VSM4RNDS4 instruction.151///152/// \param __A153///    A 128-bit vector of [4 x int].154/// \param __B155///    A 128-bit vector of [4 x int].156/// \returns157///    A 128-bit vector of [4 x int].158///159/// \code{.operation}160/// DEFINE ROL32(dword, n) {161/// 	count := n % 32162/// 	dest := (dword << count) | (dword >> (32-count))163/// 	RETURN dest164/// }165/// DEFINE lower_t(dword) {166/// 	tmp.byte[0] := SBOX_BYTE(dword, 0)167/// 	tmp.byte[1] := SBOX_BYTE(dword, 1)168/// 	tmp.byte[2] := SBOX_BYTE(dword, 2)169/// 	tmp.byte[3] := SBOX_BYTE(dword, 3)170/// 	RETURN tmp171/// }172/// DEFINE L_RND(dword) {173/// 	tmp := dword174/// 	tmp := tmp ^ ROL32(dword, 2)175/// 	tmp := tmp ^ ROL32(dword, 10)176/// 	tmp := tmp ^ ROL32(dword, 18)177/// 	tmp := tmp ^ ROL32(dword, 24)178///   RETURN tmp179/// }180/// DEFINE T_RND(dword) {181/// 	RETURN L_RND(lower_t(dword))182/// }183/// DEFINE F_RND(X0, X1, X2, X3, round_key) {184/// 	RETURN X0 ^ T_RND(X1 ^ X2 ^ X3 ^ round_key)185/// }186/// FOR i:= 0 to 0187/// 	P[0] := __B.xmm[i].dword[0]188/// 	P[1] := __B.xmm[i].dword[1]189/// 	P[2] := __B.xmm[i].dword[2]190/// 	P[3] := __B.xmm[i].dword[3]191/// 	C[0] := F_RND(P[0], P[1], P[2], P[3], __A.xmm[i].dword[0])192/// 	C[1] := F_RND(P[1], P[2], P[3], C[0], __A.xmm[i].dword[1])193/// 	C[2] := F_RND(P[2], P[3], C[0], C[1], __A.xmm[i].dword[2])194/// 	C[3] := F_RND(P[3], C[0], C[1], C[2], __A.xmm[i].dword[3])195/// 	DEST.xmm[i].dword[0] := C[0]196/// 	DEST.xmm[i].dword[1] := C[1]197/// 	DEST.xmm[i].dword[2] := C[2]198/// 	DEST.xmm[i].dword[3] := C[3]199/// ENDFOR200/// DEST[MAX:128] := 0201/// \endcode202#define _mm_sm4rnds4_epi32(A, B)                                               \203  (__m128i) __builtin_ia32_vsm4rnds4128((__v4su)A, (__v4su)B)204 205/// This intrinisc performs four rounds of SM4 encryption. The intrinisc206///    operates on independent 128-bit lanes. The calculated results are207///    stored in \a dst.208/// \headerfile <immintrin.h>209///210/// \code211/// __m256i _mm256_sm4rnds4_epi32(__m256i __A, __m256i __B)212/// \endcode213///214/// This intrinsic corresponds to the \c VSM4RNDS4 instruction.215///216/// \param __A217///    A 256-bit vector of [8 x int].218/// \param __B219///    A 256-bit vector of [8 x int].220/// \returns221///    A 256-bit vector of [8 x int].222///223/// \code{.operation}224/// DEFINE ROL32(dword, n) {225/// 	count := n % 32226/// 	dest := (dword << count) | (dword >> (32-count))227/// 	RETURN dest228/// }229/// DEFINE lower_t(dword) {230/// 	tmp.byte[0] := SBOX_BYTE(dword, 0)231/// 	tmp.byte[1] := SBOX_BYTE(dword, 1)232/// 	tmp.byte[2] := SBOX_BYTE(dword, 2)233/// 	tmp.byte[3] := SBOX_BYTE(dword, 3)234/// 	RETURN tmp235/// }236/// DEFINE L_RND(dword) {237/// 	tmp := dword238/// 	tmp := tmp ^ ROL32(dword, 2)239/// 	tmp := tmp ^ ROL32(dword, 10)240/// 	tmp := tmp ^ ROL32(dword, 18)241/// 	tmp := tmp ^ ROL32(dword, 24)242///   RETURN tmp243/// }244/// DEFINE T_RND(dword) {245/// 	RETURN L_RND(lower_t(dword))246/// }247/// DEFINE F_RND(X0, X1, X2, X3, round_key) {248/// 	RETURN X0 ^ T_RND(X1 ^ X2 ^ X3 ^ round_key)249/// }250/// FOR i:= 0 to 0251/// 	P[0] := __B.xmm[i].dword[0]252/// 	P[1] := __B.xmm[i].dword[1]253/// 	P[2] := __B.xmm[i].dword[2]254/// 	P[3] := __B.xmm[i].dword[3]255/// 	C[0] := F_RND(P[0], P[1], P[2], P[3], __A.xmm[i].dword[0])256/// 	C[1] := F_RND(P[1], P[2], P[3], C[0], __A.xmm[i].dword[1])257/// 	C[2] := F_RND(P[2], P[3], C[0], C[1], __A.xmm[i].dword[2])258/// 	C[3] := F_RND(P[3], C[0], C[1], C[2], __A.xmm[i].dword[3])259/// 	DEST.xmm[i].dword[0] := C[0]260/// 	DEST.xmm[i].dword[1] := C[1]261/// 	DEST.xmm[i].dword[2] := C[2]262/// 	DEST.xmm[i].dword[3] := C[3]263/// ENDFOR264/// DEST[MAX:256] := 0265/// \endcode266#define _mm256_sm4rnds4_epi32(A, B)                                            \267  (__m256i) __builtin_ia32_vsm4rnds4256((__v8su)A, (__v8su)B)268 269#endif // __SM4INTRIN_H270