Странное поведение RDRAND на процессорах AMD
Во время работы над программой для визуализации данных в виде диаграмм с использованием инструкций rdrand и rdseed был обнаружен необычный баг, похоже, касающийся только процессоров AMD (возможно, ограничен только поколением Zen2): они не могут генерировать число 0 для запрошенного размера разрядности. При запуске того же кода на процессоре Intel нули генерируются без проблем.
Для проверки этого явления была подготовлена специальная программа-тестер. Автор просит всех желающих помочь выяснить суть проблемы, используя её для поиска сгенерированных нулей и опубликовать результаты в этой ветке форума.
О приложении для тестирования
Приложение демонстрирует глубокое владение техниками контроля и отрисовки данных на экран консоли в произвольных позициях — это может быть полезно для тех, кто раньше пытался добиться аналогичного эффекта в Linux CLI.
Прикреплённое тестовое приложение позволяет наблюдать проблему генератора на AMD. На процессоре AMD первый столбец диаграммы, показывающий количество нулей, вероятно, никогда не будет менять цвет с зелёного (это использует TSC-метод, разработанный для генерации случайных чисел), а базовая шкала диаграммы не будет масштабироваться выше нуля. На Intel проблемы нет — шкала нормально работает. Первый столбец отображает количество нулей, сгенерированных через rdrand (красный цвет), rdseed (синий) и пользовательским TSC-методом (зелёный), остальные столбцы показывают распределение остальных 65535 значений из 16-битного пространства.
Примечание: для компиляции потребуется набор макросов fastcall_v1.
Описание: Тестовое приложение. Для исправления измените строки rdrand и rdseed так, чтобы генерировать данные в 32-битные или 64-битные регистры, сохраняя при этом сбор 16-битных данных для отображения в графике (граф по-прежнему отображает 16-битные данные).
Обсуждение в сообществе
На уточняющий вопрос о том, генерируют ли 32/64-битные выходы нули в своих младших 16 битах, было подтверждено: да, при использовании 32-битных или 64-битных чисел младшие части могут выдавать ноль. Однако истинный ноль размером, соответствующим запросу, на AMD никогда не происходит.
В шутку было высказано предположение, что, возможно, какой-то руководитель AMD случайно выполнил RDRAND, получил ноль, объявил генератор неисправным и попросил инженеров это «исправить».
Обновления от разработчика
Согласно последним сообщениям, AMD ответила на запрос, однако ответ выглядел так, будто его либо неправильно интерпретировали, либо сгенерировали с помощью AI (он поразительно похож на ответ ChatGPT при проверке). Разработчик отправил уточняющий ответ с более подробным объяснением и фрагментом проблемного кода.
По состоянию на май 2026 года фидбека от AMD так и не поступило, но компания обещала эскалировать проблему внутри своей организации.
Технические исследования
Интересным наблюдением стало различие в производительности генераторов случайных чисел между разными моделями процессоров:
- Core i5 2012: 12,6 млн чисел в секунду (полностью зависит от тактовой частоты);
- Core i7 7700 (2017): 750 тыс. чисел в секунду;
- AMD Ryzen 7: около 2,6 млн чисел в секунду (инертен к изменению тактовой частоты).
Эти различия намекают, что схемы генераторов случайных чисел имеют серьёзные различия даже внутри одного производителя и одного поколения, вероятно, это разные версии или ревизии микросхем.
Разработчик отмечает, что подробной информации о том, как именно работает блок RNG в этих процессорах, найти не удалось.
Архитектура RDRAND в Intel
В обсуждении был упомянут исторический пример архитектуры Intel RDRAND. По литературе времени его введения, система содержала астабильный шумовой генератор (один бит), питающий синхронный дискретизатор, затем схему снятия смещения, питающую последовательный сдвиговый регистр. Это создавало внутреннее 128-битное семя. На основе семени работал высокоскоростной AESCSPRNG в режиме счётчика, выдающий биты для RDRAND и переинициализируемый периодически внутренним семенем по мере накопления битов. Инструкция RDSEED выдавала некоторые сырые биты внутреннего семени напрямую.
Современные реализации могли существенно измениться. RDRAND на тех процессорах мог генерировать выходные данные с полной тактовой частотой CPU, RDSEED был медленнее. Обсуждалась потенциальная проблема того, что это не является «собственно» случайным из-за PRNG в конвейере, но никто не мог продемонстрировать какую-либо измеримую проблему.
Есть много мест, где можно спрятать бэкдор в такой архитектуре, и его было бы чрезвычайно сложно обнаружить без обратного проектирования кремния.
Практическое значение
rdrand предполагается использовать как источник энтропии для ядра ОС, поэтому, хотя выбор AMD отмечать ноль как невалидный очень странен, инструкция не предназначена для использования как основной криптографический генератор случайных чисел. Для криптографических целей следует использовать криптографический генератор ОС. Для некриптографических применений данная особенность скорее всего не имеет значения.