aes.rs - source
Description: Source of the Rust file `library/core/src/../../stdarch/crates/core_arch/src/x86/aes.rs`.

#
core/stdarch/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]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
    9
    10use crate::core_arch::x86::__m128i;
    11
    12#[cfg(test)]
    13use stdarch_test::assert_instr;
    14
    15#[allow(improper_ctypes)]
    16unsafe 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/// Performs one round of an AES decryption flow on data (state) in `a`.
    32///
    33/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#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")]
    38pub fn _mm_aesdec_si128(a: __m128i, round_key: __m128i) -> __m128i {
    39    unsafe { aesdec(a, round_key) }
    40}
    41
    42/// Performs the last round of an AES decryption flow on data (state) in `a`.
    43///
    44/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#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")]
    49pub fn _mm_aesdeclast_si128(a: __m128i, round_key: __m128i) -> __m128i {
    50    unsafe { aesdeclast(a, round_key) }
    51}
    52
    53/// Performs one round of an AES encryption flow on data (state) in `a`.
    54///
    55/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#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")]
    60pub fn _mm_aesenc_si128(a: __m128i, round_key: __m128i) -> __m128i {
    61    unsafe { aesenc(a, round_key) }
    62}
    63
    64/// Performs the last round of an AES encryption flow on data (state) in `a`.
    65///
    66/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#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")]
    71pub fn _mm_aesenclast_si128(a: __m128i, round_key: __m128i) -> __m128i {
    72    unsafe { aesenclast(a, round_key) }
    73}
    74
    75/// Performs the `InvMixColumns` transformation on `a`.
    76///
    77/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#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")]
    82pub fn _mm_aesimc_si128(a: __m128i) -> __m128i {
    83    unsafe { 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://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aeskeygenassist_si128)
    93#[inline]
    94#[target_feature(enable = "aes")]
    95#[cfg_attr(test, assert_instr(aeskeygenassist, IMM8 = 0))]
    96#[rustc_legacy_const_generics(1)]
    97#[stable(feature = "simd_x86", since = "1.27.0")]
    98pub fn _mm_aeskeygenassist_si128<const IMM8: i32>(a: __m128i) -> __m128i {
    99    static_assert_uimm_bits!(IMM8, 8);
    100    unsafe { aeskeygenassist(a, IMM8 as u8) }
    101}
    102
    103#[cfg(test)]
    104mod tests {
    105    // The constants in the tests below are just bit patterns. They should not
    106    // be interpreted as integers; signedness does not make sense for them, but
    107    // __m128i happens to be defined in terms of signed integers.
    108    #![allow(overflowing_literals)]
    109
    110    use stdarch_test::simd_test;
    111
    112    use crate::core_arch::x86::*;
    113
    114    #[simd_test(enable = "aes")]
    115    fn test_mm_aesdec_si128() {
    116        // Constants taken from https://msdn.microsoft.com/en-us/library/cc664949.aspx.
    117        let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
    118        let k = _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
    119        let e = _mm_set_epi64x(0x044e4f5176fec48f, 0xb57ecfa381da39ee);
    120        let r = _mm_aesdec_si128(a, k);
    121        assert_eq_m128i(r, e);
    122    }
    123
    124    #[simd_test(enable = "aes")]
    125    fn test_mm_aesdeclast_si128() {
    126        // Constants taken from https://msdn.microsoft.com/en-us/library/cc714178.aspx.
    127        let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
    128        let k = _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
    129        let e = _mm_set_epi64x(0x36cad57d9072bf9e, 0xf210dd981fa4a493);
    130        let r = _mm_aesdeclast_si128(a, k);
    131        assert_eq_m128i(r, e);
    132    }
    133
    134    #[simd_test(enable = "aes")]
    135    fn test_mm_aesenc_si128() {
    136        // Constants taken from https://msdn.microsoft.com/en-us/library/cc664810.aspx.
    137        let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
    138        let k = _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
    139        let e = _mm_set_epi64x(0x16ab0e57dfc442ed, 0x28e4ee1884504333);
    140        let r = _mm_aesenc_si128(a, k);
    141        assert_eq_m128i(r, e);
    142    }
    143
    144    #[simd_test(enable = "aes")]
    145    fn test_mm_aesenclast_si128() {
    146        // Constants taken from https://msdn.microsoft.com/en-us/library/cc714136.aspx.
    147        let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
    148        let k = _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
    149        let e = _mm_set_epi64x(0xb6dd7df25d7ab320, 0x4b04f98cf4c860f8);
    150        let r = _mm_aesenclast_si128(a, k);
    151        assert_eq_m128i(r, e);
    152    }
    153
    154    #[simd_test(enable = "aes")]
    155    fn test_mm_aesimc_si128() {
    156        // Constants taken from https://msdn.microsoft.com/en-us/library/cc714195.aspx.
    157        let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
    158        let e = _mm_set_epi64x(0xc66c82284ee40aa0, 0x6633441122770055);
    159        let r = _mm_aesimc_si128(a);
    160        assert_eq_m128i(r, e);
    161    }
    162
    163    #[simd_test(enable = "aes")]
    164    fn test_mm_aeskeygenassist_si128() {
    165        // Constants taken from https://msdn.microsoft.com/en-us/library/cc714138.aspx.
    166        let a = _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
    167        let e = _mm_set_epi64x(0x857c266b7c266e85, 0xeac4eea9c4eeacea);
    168        let r = _mm_aeskeygenassist_si128::<5>(a);
    169        assert_eq_m128i(r, e);
    170    }
    171}