Как выбрать версию шифрования AES из SynCrypto?

SynCrypto - это библиотека с открытым исходным кодом для шифрования данных, включенная в этот пакет.

В этом блоке (SynCrypto.pas) есть следующий комментарий в начале файла:

AES128 cypher 84 МБ / с uncypher 81 МБ / с asm версия
AES128 cypher 57 МБ / с uncypher 57 МБ / с версия на паскале
AES192 cypher 72 МБ / с uncypher 70 МБ / с asm версия
AES192 cypher 48 МБ / с uncypher 48 МБ / с pascal версия
AES256 cypher 62 МБ / с uncypher 61 МБ / с asm версия
AES256 cypher 42 МБ / с uncypher 42 МБ / с pascal версия

Из этого я понимаю, что есть две версии кода: pascal-slower и asm-fast. Но проблема в том, как я могу выбрать между этими двумя?

Изменить: И дополнительный вопрос, если вы позволите мне: как Candy я выбираю битовую ширину ключа: 128, 192 и 256?

Я использую этот код для шифрования и дешифрования:

  outp := TAESCFB.SimpleEncrypt(inp,'privatekey',true,true);
  inp := TAESCFB.SimpleEncrypt(outp,'privatekey',false,true);

... и Delphi 2009.

1 ответ

Решение

Краткий ответ: самый быстрый код всегда будет использоваться для вас, в зависимости от компилятора и компьютера.

Длинный ответ:

Существует только одна версия кода, скомпилированная за раз, либо паскаль, либо оптимизированная asm. Это зависит от условных определений при работе в модуле, устанавливается автоматически в зависимости от версии вашего компилятора (от Delphi 5 до последней версии Delphi или FPC) и платформы ЦП (если он имеет Intel или ARM). Затем во время выполнения на Intel можно обнаружить и использовать аппаратные коды операций AES-NI или, на VIA, аппаратные коды операций Padlock. Даже паскальская реализация может быть свернута или развернута.

{$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}

Подводя итог, можно сказать, что при работе с AES устройство имеет шесть различных версий алгоритма: паскаль прокручивается, паскаль разворачивается, x86/x64 asm без AES-NI, x86/x64 asm с AES-NI, x86 с замком, Windows API.

SimpleEncrypt:

Есть два перегруженных SimpleEncrypt методы. Один с фиксированным размером 256 бит (тот, который вы использовали), другой с KeySize параметр (128, 192 или 256):

class function TAESAbstract.SimpleEncrypt(const Input: RawByteString; const Key;
   KeySize: integer; Encrypt, IVAtBeginning: boolean): RawByteString;

Конечно, вы должны сначала хэшировать введенный пароль в секретный ключ THash128 или THash256 перед вызовом функции. Мы рекомендуем использовать PBKDF2_HMAC_SHA256 для этой цели (с большим круглым числом).

Некоторые цифры:

С современным процессором, включая AES-NI, вы получите потрясающую производительность. Это, безусловно, самая быстрая нативная реализация AES в Delphi/FPC (никто другой не использует AES-NI). Некоторые цифры запускают мой ноутбук, взятые из TTestCryptographicRoutines.Benchmark регрессионные тесты:

 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

Забудьте о Windows API, который по сравнению с этим слишком медленный. TAES...CRC Класс добавляет 128-битный crc32c к входу и выходу во время сжатия без потери скорости, для аутентификации и проверки содержимого. Я также включил шифрование SHAKE128/SHAKE256 (не совместимое с AES), которое сравнимо с HMAC-SHA-256 + AES-256 за один шаг и очень быстрое на всех процессорах без AES-NI.

Другие вопросы по тегам