Skip to content

[API Proposal]: Expose System.Runtime.Intrinsics.X86.Aes256 and Aes512 #86952

Open
@e4m2

Description

@e4m2

Background and motivation

On some newer x86 CPUs VAES provides wider variants of encoding/decoding included in the older AES instruction set.

The 256-bit VEX-encoded variant (effectively operating on 2 AES blocks in parallel using a single instruction) has a separate CPUID flag and is not dependent on AVX512 support. Additionally, if AVX512F is supported, a 512-bit EVEX-encoded variant is available. As expected, EVEX-encoded 128 and 256-bit variants are available if AVX512VL is supported.

API Proposal

namespace System.Runtime.Intrinsics.X86;

[Intrinsic]
[CLSCompliant(false)]
public abstract class Aes256 : Aes
{
    internal Aes256() { }

    // This would depend on the VAES CPUID bit for VEX encoding and VAES + AVX512VL for EVEX
    public static new bool IsSupported { get => IsSupported; }

    [Intrinsic]
    public new abstract class X64 : Aes.X64
    {
        internal X64() { }

        public static new bool IsSupported { get => IsSupported; }
    }

    /// <summary>
    /// __m256i _mm256_aesdec_epi128(__m256i a, __m256i RoundKey)
    ///   VAESDEC ymm1, ymm2, ymm3/m256
    /// </summary>
    public static Vector256<byte> Decrypt(Vector256<byte> value, Vector256<byte> roundKey);

    /// <summary>
    /// __m256i _mm256_aesdeclast_epi128(__m256i a, __m256i RoundKey)
    ///   VAESDECLAST ymm1, ymm2, ymm3/m256
    /// </summary>
    public static Vector256<byte> DecryptLast(Vector256<byte> value, Vector256<byte> roundKey);

    /// <summary>
    /// __m256i _mm256_aesenc_epi128(__m256i a, __m256i RoundKey)
    ///   VAESENC ymm1, ymm2, ymm3/m256
    /// </summary>
    public static Vector256<byte> Encrypt(Vector256<byte> value, Vector256<byte> roundKey);
    
    /// <summary>
    /// __m256i _mm256_aesenclast_epi128(__m256i a, __m256i RoundKey)
    ///   VAESENCLAST ymm1, ymm2, ymm3/m256
    /// </summary>
    public static Vector256<byte> EncryptLast(Vector256<byte> value, Vector256<byte> roundKey);
}

[Intrinsic]
[CLSCompliant(false)]
public abstract class Aes512 : Aes
{
    internal Aes512() { }

    // This would depend on the VAES + AVX512F CPUID bits
    public static new bool IsSupported { get => IsSupported; }

    [Intrinsic]
    public new abstract class X64 : Aes.X64
    {
        internal X64() { }

        public static new bool IsSupported { get => IsSupported; }
    }
    
    /// <summary>
    /// __m512i _mm512_aesdec_epi128(__m512i a, __m512i RoundKey)
    ///   VAESDEC zmm1, zmm2, zmm3/m512
    /// </summary>
    public static Vector512<byte> Decrypt(Vector512<byte> value, Vector512<byte> roundKey);
    
    /// <summary>
    /// __m512i _mm512_aesdeclast_epi128(__m512i a, __m512i RoundKey)
    ///   VAESDECLAST zmm1, zmm2, zmm3/m512
    /// </summary>
    public static Vector512<byte> DecryptLast(Vector512<byte> value, Vector512<byte> roundKey);

    /// <summary>
    /// __m512i _mm512_aesenc_epi128(__m512i a, __m512i RoundKey)
    ///   VAESENC zmm1, zmm2, zmm3/m512
    /// </summary>
    public static Vector512<byte> Encrypt(Vector512<byte> value, Vector512<byte> roundKey);

    /// <summary>
    /// __m512i _mm512_aesenclast_epi128(__m512i a, __m512i RoundKey)
    ///   VAESENCLAST zmm1, zmm2, zmm3/m512
    /// </summary>
    public static Vector512<byte> EncryptLast(Vector512<byte> value, Vector512<byte> roundKey);
}

Note VAES doesn't include round key assist or inverse mix columns instructions.

API Usage

Same as AES intrinsics, except using wider vector types.

Alternative Designs

No response

Risks

No response

References

https://en.wikichip.org/wiki/x86/vaes
https://en.wikipedia.org/wiki/AVX-512#VAES
https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#othertechs=VAES

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions