Одним из хороших (но, вероятно, не самых быстрых) вариантов, предлагающих очень высокое качество, было бы использование 32-битного блока . шифр в режиме CTR. По сути, ваше состояние RNG будет просто 32-битным счетчиком, который увеличивается на единицу при каждом вызове RNG, а результатом будет шифрование этого значения счетчика с использованием блочного шифра с некоторым произвольно выбранным фиксированным ключом. Для дополнительной случайности вы можете даже предоставить (нестандартную) функцию, позволяющую пользователю установить собственный ключ.
Существует не так много широко используемых 32-битных блочных шифров, поскольку такой короткий размер блока создает проблемы для криптографического использования. (По сути, парадокс дня рождения позволяет отличить вывод такого шифра от случайной функции с непренебрежимо малая вероятность после примерно 216 = 65536 выходов, а после 232 выходов неслучайность, очевидно, становится очевидной.) Однако некоторые шифры с регулируемым размером блока , например XXTEA или HPC позволит вам перейти на 32-битную версию и подойдет для ваших целей.
(Редактировать: Плохо, XXTEA использует только 64-разрядную версию. Однако, как предлагает CodesInChaos в комментариях, Skip32 может быть другим вариантом. Или вы можете создать свой собственный 32-разрядный шифр Фейстеля.)
Конструкция режима CTR гарантирует, что RNG будет иметь полный период из 232 выходов, в то время как стандартное требование безопасности (не взломанных) блочных шифров по существу состоит в том, что вычислительно невозможно различить их выходные данные. из случайной перестановки набора 32-битных целых чисел. (Конечно, как отмечалось выше, такую перестановку легко отличить от случайной функции принимает 32-битные значения.)
Использование режима CTR также предоставляет некоторые дополнительные функции, которые могут оказаться удобными (даже если они не являются частью официального API, для которого вы разрабатываете), такие как возможность быстрого поиска в любой точке выходного потока RNG, просто добавляя или вычитание из состояния.
С другой стороны, вы, вероятно, не хотите следовать общепринятой практике заполнения RNG, просто устанавливая внутреннее состояние в начальное значение, так как это приведет к тому, что выходные потоки, сгенерированные из ближайших начальных значений, быть очень похожими (в основном просто один и тот же поток, сдвинутый из-за разницы семян). Один из способов избежать этой проблемы — добавить дополнительный шаг шифрования в процесс заполнения, т. е. зашифровать начальное число с помощью шифра и установить значение внутреннего счетчика равным результату.
person
Ilmari Karonen
schedule
11.06.2013
malloc()
любого практичного размера? Или индекс в статическую таблицу указателей? - person sh1   schedule 11.06.2013unsigned int
. Однако преобразование выходных данных LCG или LFSR с картой масштаба 1:1 звучит более многообещающе. - person R.. GitHub STOP HELPING ICE   schedule 12.06.2013