Short answer: the fastest code will always be used for you, depending on the compiler and computer.
Long answer:
There is only a single code version compiled at a time, either pascal or optimized asm. It depends on conditional defines when running in the unit, set automatically depending on your compiler version (from Delphi 5 up to latest Delphi or FPC revision), and CPU platform (if it has Intel or ARM). Then at runtime, on Intel, AES-NI hardware opcodes can be detected and used, or, on VIA, Padlock hardware opcodes. Even the pascal implementation may be rolled or unrolled.
{$define AES_ROLLED}
// if defined, use rolled version, which is faster (at least on my AMD CPU)
{$ifdef DELPHI5OROLDER}
{$define AES_PASCAL} // Delphi 5 internal asm is buggy :(
{$define SHA3_PASCAL}
{$else}
{$ifdef CPUINTEL} // AES-NI supported for x86 and x64
{$ifdef CPU64}
{$ifdef HASAESNI}
{$define USEAESNI}
{$define USEAESNI64}
{$else}
{$define AES_PASCAL} // Delphi XE2/XE3 do not have the AES-NI opcodes :(
{$endif}
{$define AESPASCAL_OR_CPU64}
{$else}
{$define USEAESNI}
{$define USEAESNI32}
{$endif}
{$else}
{$define AES_PASCAL} // AES128 unrolled pascal(Delphi7)=57MB/s rolled asm=84MB/s :)
{$define SHA3_PASCAL}
{$endif CPUINTEL}
{$endif}
To sumup, when working with AES, the unit has six diverse versions of the algorithm: pascal rolled, pascal unrolled, x86/x64 asm without AES-NI, x86/x64 asm with AES-NI, x86 with padlock, Windows API.
SimpleEncrypt:
There are two overloaded SimpleEncrypt
methods. One with fixed size of 256 bits (the one you used), another with a KeySize
parameter (either 128, 192 or 256):
class function TAESAbstract.SimpleEncrypt(const Input: RawByteString; const Key;
KeySize: integer; Encrypt, IVAtBeginning: boolean): RawByteString;
Of course, you should first hash the input password text into a THash128 or THash256 secret key, before calling the function. We recommend using PBKDF2_HMAC_SHA256
for this purpose (with a high round number).
Some numbers:
With a modern CPU, including AES-NI, you will have tremendous performance. This is the fastest native AES implementation in Delphi/FPC, for sure (no other uses AES-NI). Some numbers run my laptop, taken from TTestCryptographicRoutines.Benchmark
regression tests:
50000 AES128CFB in 229.60ms i.e. 217764/s or 463.4 MB/s
50000 AES128OFB in 183.66ms i.e. 272237/s or 579.3 MB/s
50000 AES128CFBCRC in 227.61ms i.e. 219674/s or 467.5 MB/s
50000 AES128OFBCRC in 181.18ms i.e. 275954/s or 587.2 MB/s
50000 AES256CFB in 288.57ms i.e. 173265/s or 368.7 MB/s
50000 AES256OFB in 243.96ms i.e. 204944/s or 436.1 MB/s
50000 AES256CFBCRC in 294.38ms i.e. 169844/s or 361.4 MB/s
50000 AES256OFBCRC in 244.49ms i.e. 204507/s or 435.2 MB/s
50000 SHAKE128 in 473.34ms i.e. 105631/s or 224.8 MB/s
50000 SHAKE256 in 596.74ms i.e. 83787/s or 178.3 MB/s
Forget about the Windows API, which are dead slow in comparison. The TAES...CRC
class adds a 128-bit crc32c to the input and output during compression with no speed penalty, to authentication and validate the content. I also included SHAKE128/SHAKE256 encryption (not AES compatible), which is comparable to HMAC-SHA-256 + AES-256 in a single step, and is very fast on all CPUs without AES-NI.