CPU-функции RDRAND и RDSEED стали доступнее

    Всем привет!

    Сам я криптографией не занимаюсь, но кому то вполне может пригодится мое небольшое исследование. Решил разобраться со встроенными в процессор функциями RDRAND и RDSEED. Компилятор Delphi сказал Undeclared identifier. Хмм. Уже давно существует BMI, BMI2, AVX, AVX2 и даже AVX-512, а дельфийцы остановились на SSE4.2. Не беда. Скомпилируем код сами.

    Сначала сделал проверку на поддержку данных функций процессором. Конечно же CPUID. Использовать CPUID можно начиная с первых Pentium процессоров. Надеюсь никто не додумается запустить CPUID на 486 машине, ибо ее там еще не было. Кстати RDRAND и RDSEED до процессоров IvyBridge также не существует.

    function CPU_support_RDRAND: Boolean;
    asm
      mov rax, $01
      cpuid
      test ecx, 40000000h //тестируем 30-й бит
      setne al
    end;
    
    function CPU_support_RDSEED: Boolean;
    asm
      mov rcx, 0
      mov rax, $07 //страница №7
      cpuid
      test ebx, 40000h //тестируем 18-й бит
      setne al
    end;
    

    Оказалось, что мой Core i7 G6950X Extreme поддерживает данные функции. Поэтому дальше решил скомпилировать байт-код вручную. Для опытных приведу код REX и REX.W префиксов. Возможно вы захотите записать результат в другой регистр:

    const
      REX_RDRAND32: Byte = $F0; //(11b:REG, 110b:OPCODE, 000b:EAX) 
      REX_RDSEED32: Byte = $F8; //(11b:REG, 111b:OPCODE, 000b:EAX)
      REX_W_RDRAND64: Byte = $48; //(11b:REG, 110b:OPCODE, 000b:RAX)
      REX_W_RDSEED64: Byte = $48; //(11b:REG, 111b:OPCODE, 000b:RAX)
    

    Функции могут работать как в 32-х битном режиме, так и в 64-х битном. Поэтому сделал обе и даже в двух вариантах. В итоге получилось 4 функции:

    function RDRand32: DWord;
    asm
     @Retry:
      db $0F, $C7, $F0 //RDRAND EAX (CF = 1 говорит о корректности данных)
      jnc @Retry
    end;
    
    function RDSeed32: DWord;
    asm
     @Retry:
      db $0F, $C7, $F8 //RDSEED EAX (CF = 1 говорит о корректности данных)
      jnc @Retry
    end;
    
    function RDRand64: QWord;
    asm
      .NOFRAME
    
     @Retry:
      db $48, $0F, $C7, $F0  //RDRAND RAX (CF = 1 говорит о корректности данных)
      jnc @Retry
    end;
    
    function RDSeed64: QWord;
    asm
      .NOFRAME
    
     @Retry:
      db $48, $0F, $C7, $F8 //RDSEED RAX (CF = 1 говорит о корректности данных)
      jnc @Retry
    end;

    По скорости они медленней, чем библиотечная функция Random. RDRand примерно на 35%, а RDSeed процентов на 50% и даже более, но качество уникальности генерируемых значений значительно выше. На данном ресурсе есть неплохие статьи на эту тему, ну а моя миссия (сделать функции доступными в Delphi) завершена. В Lazarus не тестировал, но скорее всего будет работать без каких либо изменений. В конец объявления функции нужно лишь добавить резервное слово assembler.

    Здесь исходные тексты тестового консольного приложения. Там можно найти прототип функций Random32 и Random64 на основе встроенных в процессор. Возможно это то, что вы искали. Всем пока!
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 15

      +3
      Надеюсь никто не додумается запустить CPUID на 486 машине, ибо ее там еще не было.

      На каких-то не было, а на каких-то и была.
        +2
        качество уникальности генерируемых значений значительно выше

        Интересно, кто и как это определил?


        Вообще, как раз для криптографии очень нежелательно использовать один источник случайных чисел, особенно встроенный в процессор. Не знаю, как под виндой, но в линухе используется смесь из нескольких источников, чтобы возможные закладки в любом из них были нивелированы: вышеупомянутый RDRAND плюс события от клавы/мыши/диска/etc.

          +1
          Эти функции сертифицированы.
          RDRAND: Стандарт NIST SP 800-90A
          RDSEED: Стандарт NIST SP 800-90B and NIST SP800-90C.
          Стандарты конечно не наши, но все же.
            +1

            И как это отвечает на мой вопрос? Наличие сертификата говорит только о том, что кто-то вложил ресурсы в сертификацию. Сама по себе сертификация качество продукта не изменяет, и ничего не говорит о качестве этого продукта относительно других.

              0
              И как это отвечает на мой вопрос?

              Вы пишите: используется смесь из нескольких источников...
              В этой статье как раз описывается как устроены данные функции:
              habr.com/ru/post/128666
              Они тоже берут данные из нескольких источников.
                0

                Это не имеет значения, потому что работа RDRAND полностью контролируется одной компанией, и провести аудит как она на самом деле работает в конкретном куске кремния — крайне проблематично.

                  0
                  Я вас ни к чему не агитирую.
            0

            Была даже петиция на тему убрать rdrand из /dev/random :-) но Торвальдс заявляет что если там есть бэкдор то это никак не повляет т.к используются и другие способы как вы упомянули.

              0

              Я в курсе. И, на мой взгляд, он абсолютно прав. Что не отменяет возможности того, что RDRAND содержит бэкдор.

            0
            Первый раз вижу инструкцию, которая не возвращает сразу правильное значение. Прям асинхронный ассемблер какой-то получается: пока генерируется случайное число процессор может заняться чем-то еще.
              +1
              Видимо, вы не застали математический сопроцессор x87 в те времена, когда он был отдельным чипом.
              0
              Здраствуйте, увидел у Вас похожие штуки и решил спросить. Где почитать и найти таблицы с объяснениями всех команд, чисто чтоб подобное
              .text
              Filename: In[35]
              pushq %rbp
              movq %rsp, %rbp
              Source line: 1
              mulsd %xmm0, %xmm0
              popq %rbp
              retq
              nopw (%rax,%rax)

              не представлялось какой-то магией, чтоб можно было такую вещь окинуть взором и сделать вывод, де, тут сумма и цикл, можно сделать и лучше
                +1
                На сайте Intel . А как обычно все делают: опыт — сын ошибок трудных. В вашем случае вроде ассемблер AT&T.
              • НЛО прилетело и опубликовало эту надпись здесь
                  0
                  Проц Intel i7 G6950X Extreme 3.0ГГц (3.4 ГГц при работе). Разгон до 4 ГГц выключил.
                  Монитор откалиброван, а больше мне ничего калибровать не надо.

                  Генерация данных:
                  Заголовок спойлера
                  Всего итераций (x64): 100 000 000
                  
                  Функция: RDRand32
                  Время: 8,47 сек.
                  11 807 769,51 в сек.
                  
                  Функция: RDRand64
                  Время: 8,25 сек.
                  12 121 212,12 в сек.
                  
                  Функция: System.Random
                  Время: 0,23 сек.
                  427 350 427,35 в сек.
                  
                  Всего итераций (x64): 10 000 000
                  
                  Функция: RDSeed32
                  Время: 9,86 сек.
                  1 014 301,65 в сек.
                  
                  Функция: RDSeed64
                  Время: 9,86 сек.
                  1 014 198,78 в сек.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое