Description
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