-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Open
Labels
Milestone
Description
Description
void Main() => BenchmarkRunner.Run<Bench>();
public class Bench
{
byte[] _key, _plaintext, _ciphertext;
[GlobalSetup]
public void Setup()
{
_key = RandomNumberGenerator.GetBytes(32);
_plaintext = Encoding.UTF8.GetBytes("This is a test. This is a test. ");
using var tempAes = Aes.Create();
tempAes.Key = _key;
_ciphertext = tempAes.EncryptEcb(_plaintext, PaddingMode.None);
}
[Benchmark(Baseline = true)]
public byte[] Old_Enc()
{
using Aes aes = Aes.Create();
aes.Padding = PaddingMode.None;
aes.Mode = CipherMode.ECB;
using var transform = aes.CreateEncryptor(_key, null);
return transform.TransformFinalBlock(_plaintext, 0, _plaintext.Length);
}
[Benchmark]
public byte[] Old_Dec()
{
using Aes aes = Aes.Create();
aes.Padding = PaddingMode.None;
aes.Mode = CipherMode.ECB;
using var transform = aes.CreateDecryptor(_key, null);
return transform.TransformFinalBlock(_ciphertext, 0, _ciphertext.Length);
}
[Benchmark]
public byte[] New_Enc()
{
using Aes aes = Aes.Create();
aes.Key = _key;
return aes.EncryptEcb((ReadOnlySpan<byte>)_plaintext, PaddingMode.None);
}
[Benchmark]
public byte[] New_Dec()
{
using Aes aes = Aes.Create();
aes.Key = _key;
return aes.DecryptEcb((ReadOnlySpan<byte>)_ciphertext, PaddingMode.None);
}
}Configuration
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19042.1202 (20H2/October2020Update)
Intel Core i7-10510U CPU 1.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=6.0.100-preview.7.21379.14
[Host] : .NET 6.0.0 (6.0.21.37719), X64 RyuJIT
Results
| Method | Mean | Error | StdDev | Ratio | RatioSD |
|---|---|---|---|---|---|
| Old_Enc | 725.8 ns | 7.82 ns | 6.53 ns | 1.00 | 0.00 |
| Old_Dec | 805.9 ns | 15.83 ns | 16.25 ns | 1.11 | 0.02 |
| New_Enc | 977.5 ns | 7.90 ns | 6.60 ns | 1.35 | 0.02 |
| New_Dec | 1,016.8 ns | 14.85 ns | 13.16 ns | 1.40 | 0.02 |
Analysis
EncryptEcb and DecryptEcb appear to be consistently 30~35% slower than the old approach of ICryptoTransform.TransformFinalBlock.
The bench code is a slightly modified version of @stephentoub example from his "Performance Improvements in .NET 6" post, which seems to suggest that these new one-shot methods are supposed to be faster - not slower.