]> git.proxmox.com Git - rustc.git/blob - src/stdsimd/crates/core_arch/src/x86/aes.rs
New upstream version 1.34.2+dfsg1
[rustc.git] / src / stdsimd / crates / core_arch / src / x86 / aes.rs
1 //! AES New Instructions (AES-NI)
2 //!
3 //! The intrinsics here correspond to those in the `wmmintrin.h` C header.
4 //!
5 //! The reference is [Intel 64 and IA-32 Architectures Software Developer's
6 //! Manual Volume 2: Instruction Set Reference, A-Z][intel64_ref].
7 //!
8 //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
9
10 use core_arch::x86::__m128i;
11
12 #[cfg(test)]
13 use stdsimd_test::assert_instr;
14
15 #[allow(improper_ctypes)]
16 extern "C" {
17 #[link_name = "llvm.x86.aesni.aesdec"]
18 fn aesdec(a: __m128i, round_key: __m128i) -> __m128i;
19 #[link_name = "llvm.x86.aesni.aesdeclast"]
20 fn aesdeclast(a: __m128i, round_key: __m128i) -> __m128i;
21 #[link_name = "llvm.x86.aesni.aesenc"]
22 fn aesenc(a: __m128i, round_key: __m128i) -> __m128i;
23 #[link_name = "llvm.x86.aesni.aesenclast"]
24 fn aesenclast(a: __m128i, round_key: __m128i) -> __m128i;
25 #[link_name = "llvm.x86.aesni.aesimc"]
26 fn aesimc(a: __m128i) -> __m128i;
27 #[link_name = "llvm.x86.aesni.aeskeygenassist"]
28 fn aeskeygenassist(a: __m128i, imm8: u8) -> __m128i;
29 }
30
31 /// Perform one round of an AES decryption flow on data (state) in `a`.
32 ///
33 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesdec_si128)
34 #[inline]
35 #[target_feature(enable = "aes")]
36 #[cfg_attr(test, assert_instr(aesdec))]
37 #[stable(feature = "simd_x86", since = "1.27.0")]
38 pub unsafe fn _mm_aesdec_si128(a: __m128i, round_key: __m128i) -> __m128i {
39 aesdec(a, round_key)
40 }
41
42 /// Perform the last round of an AES decryption flow on data (state) in `a`.
43 ///
44 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesdeclast_si128)
45 #[inline]
46 #[target_feature(enable = "aes")]
47 #[cfg_attr(test, assert_instr(aesdeclast))]
48 #[stable(feature = "simd_x86", since = "1.27.0")]
49 pub unsafe fn _mm_aesdeclast_si128(a: __m128i, round_key: __m128i) -> __m128i {
50 aesdeclast(a, round_key)
51 }
52
53 /// Perform one round of an AES encryption flow on data (state) in `a`.
54 ///
55 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesenc_si128)
56 #[inline]
57 #[target_feature(enable = "aes")]
58 #[cfg_attr(test, assert_instr(aesenc))]
59 #[stable(feature = "simd_x86", since = "1.27.0")]
60 pub unsafe fn _mm_aesenc_si128(a: __m128i, round_key: __m128i) -> __m128i {
61 aesenc(a, round_key)
62 }
63
64 /// Perform the last round of an AES encryption flow on data (state) in `a`.
65 ///
66 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesenclast_si128)
67 #[inline]
68 #[target_feature(enable = "aes")]
69 #[cfg_attr(test, assert_instr(aesenclast))]
70 #[stable(feature = "simd_x86", since = "1.27.0")]
71 pub unsafe fn _mm_aesenclast_si128(a: __m128i, round_key: __m128i) -> __m128i {
72 aesenclast(a, round_key)
73 }
74
75 /// Perform the `InvMixColumns` transformation on `a`.
76 ///
77 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesimc_si128)
78 #[inline]
79 #[target_feature(enable = "aes")]
80 #[cfg_attr(test, assert_instr(aesimc))]
81 #[stable(feature = "simd_x86", since = "1.27.0")]
82 pub unsafe fn _mm_aesimc_si128(a: __m128i) -> __m128i {
83 aesimc(a)
84 }
85
86 /// Assist in expanding the AES cipher key.
87 ///
88 /// Assist in expanding the AES cipher key by computing steps towards
89 /// generating a round key for encryption cipher using data from `a` and an
90 /// 8-bit round constant `imm8`.
91 ///
92 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aeskeygenassist_si128)
93 #[inline]
94 #[target_feature(enable = "aes")]
95 #[cfg_attr(test, assert_instr(aeskeygenassist, imm8 = 0))]
96 #[rustc_args_required_const(1)]
97 #[stable(feature = "simd_x86", since = "1.27.0")]
98 pub unsafe fn _mm_aeskeygenassist_si128(a: __m128i, imm8: i32) -> __m128i {
99 macro_rules! call {
100 ($imm8:expr) => {
101 aeskeygenassist(a, $imm8)
102 };
103 }
104 constify_imm8!(imm8, call)
105 }
106
107 #[cfg(test)]
108 mod tests {
109 // The constants in the tests below are just bit patterns. They should not
110 // be interpreted as integers; signedness does not make sense for them, but
111 // __m128i happens to be defined in terms of signed integers.
112 #![allow(overflowing_literals)]
113
114 use stdsimd_test::simd_test;
115
116 use core_arch::x86::*;
117
118 #[simd_test(enable = "aes")]
119 unsafe fn test_mm_aesdec_si128() {
120 // Constants taken from https://msdn.microsoft.com/en-us/library/cc664949.aspx.
121 let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
122 let k = _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
123 let e = _mm_set_epi64x(0x044e4f5176fec48f, 0xb57ecfa381da39ee);
124 let r = _mm_aesdec_si128(a, k);
125 assert_eq_m128i(r, e);
126 }
127
128 #[simd_test(enable = "aes")]
129 unsafe fn test_mm_aesdeclast_si128() {
130 // Constants taken from https://msdn.microsoft.com/en-us/library/cc714178.aspx.
131 let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
132 let k = _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
133 let e = _mm_set_epi64x(0x36cad57d9072bf9e, 0xf210dd981fa4a493);
134 let r = _mm_aesdeclast_si128(a, k);
135 assert_eq_m128i(r, e);
136 }
137
138 #[simd_test(enable = "aes")]
139 unsafe fn test_mm_aesenc_si128() {
140 // Constants taken from https://msdn.microsoft.com/en-us/library/cc664810.aspx.
141 let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
142 let k = _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
143 let e = _mm_set_epi64x(0x16ab0e57dfc442ed, 0x28e4ee1884504333);
144 let r = _mm_aesenc_si128(a, k);
145 assert_eq_m128i(r, e);
146 }
147
148 #[simd_test(enable = "aes")]
149 unsafe fn test_mm_aesenclast_si128() {
150 // Constants taken from https://msdn.microsoft.com/en-us/library/cc714136.aspx.
151 let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
152 let k = _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
153 let e = _mm_set_epi64x(0xb6dd7df25d7ab320, 0x4b04f98cf4c860f8);
154 let r = _mm_aesenclast_si128(a, k);
155 assert_eq_m128i(r, e);
156 }
157
158 #[simd_test(enable = "aes")]
159 unsafe fn test_mm_aesimc_si128() {
160 // Constants taken from https://msdn.microsoft.com/en-us/library/cc714195.aspx.
161 let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
162 let e = _mm_set_epi64x(0xc66c82284ee40aa0, 0x6633441122770055);
163 let r = _mm_aesimc_si128(a);
164 assert_eq_m128i(r, e);
165 }
166
167 #[simd_test(enable = "aes")]
168 unsafe fn test_mm_aeskeygenassist_si128() {
169 // Constants taken from https://msdn.microsoft.com/en-us/library/cc714138.aspx.
170 let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
171 let e = _mm_set_epi64x(0x857c266b7c266e85, 0xeac4eea9c4eeacea);
172 let r = _mm_aeskeygenassist_si128(a, 5);
173 assert_eq_m128i(r, e);
174 }
175 }