Сейчас на форуме: zds, UniSoft (+5 невидимых)

 eXeL@B —› Программирование —› Небольшой TrueRNG v2.0
Посл.ответ Сообщение

Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 29 января 2013 21:09
· Личное сообщение · #1

Продолжение топика https://ssl.exelab.ru/f/action=vthread&forum=6&topic=20695
Вторая версия алгоритма в которой решены почти все существующие проблемы. Проходит статтесты на виртуалках (кроме детерминированных эмуляторов вроде Bochs), проходит корреляционные тесты при одновременном запуске множества копий, работает надежно на всем доступном мне железе (в том числе на процессорах в которых TSC увеличивается кратно). Минусы - скорость генерации снижена, генерация может завершиться ошибкой.

Code:
  1. static void waitNextTick()
  2. {
  3.          unsigned long t1 = timeGetTime();
  4.          do {
  5.                  Sleep(1);
  6.          } while (t1 == timeGetTime());
  7. }
  8.  
  9. static unsigned char extractBit(unsigned long t)
  10. {
  11.          unsigned short t0 = t & 0xFFFF;
  12.          unsigned short t1 = (>> 16) & 0xFFFF;
  13.          unsigned long delta=0x9e3779b9, sum = 0;
  14.  
  15.          for (int i = 0; i < 64; i++) {
  16.                  sum += delta;
  17.                  t0 += (t1<<4) ^ (t1 + (sum & 0xFFFF)) ^ (t1>>5);
  18.                  t1 += (t0<<4) ^ (t0 + (sum & 0xFFFF)) ^ (t0>>5);
  19.          }
  20.          return t0 & 1;
  21. }
  22.  
  23. unsigned char randomBit()
  24. {
  25.          for (int i = 0; i < 128; i++)
  26.          {
  27.                  unsigned __int64 t0 = __rdtsc();
  28.                  waitNextTick();
  29.                  unsigned __int64 t1 = __rdtsc() - t0;
  30.                  waitNextTick();
  31.                  unsigned __int64 t2 = __rdtsc() - t0 - t1;
  32.  
  33.                  // отбрасываем тайминги больше 0xFFFFFFFF как заведомо неправдоподобные
  34.                  if (t1 > 0xFFFFFFFF || t2 > 0xFFFFFFFF) continue;
  35.                  // отбрасываем слишком похожие тайминги (отсеиваются очень редкие совпадения)
  36.                  if (_abs64(t1 - t2) < 64) continue;
  37.  
  38.                  // извлекаем из двух таймингов по одному биту используя псевдослучайный экстрактор
  39.                  unsigned char bit0 = extractBit(t1 & 0xFFFFFFFF);
  40.                  unsigned char bit1 = extractBit(t2 & 0xFFFFFFFF);
  41.                  
  42.                  // используем экстрактор фон Неймана
  43.                  // для устнанения значительных статистических отклонений на виртуалках
  44.                  if (bit0 ^ bit1) return bit0;
  45.          }
  46.          // если генерация не удалась за 128 попыток, мы находимся в полностью детерминистичном эмуляторе
  47.          // либо счетчик тактов процессора полностью непригоден для данного алгоритма
  48.          __debugbreak();
  49. }

З.Ы. перед генерацией не забываем вызвать timeBeginPeriod(1), иначе всё будет совсем медленно.

-----
PGP key <0x1B6A24550F33E44A>


| Сообщение посчитали полезным: 4kusNick, plutos, kioresk, Getorix, Gideon Vi


Ранг: 199.6 (ветеран), 12thx
Активность: 0.10
Статус: Участник
www.uinc.ru

Создано: 30 января 2013 05:23
· Личное сообщение · #2

Йа дебил - объясните мне, зачем это нужно? Производные XorShift'а по определению не криптостойкие генераторы, сколько бы туда не вмешивались rdtsc
Или это попытка детектирования виртуалок/гипервизоров? Тогда д0вай консольку, печатающую результат - проверим.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 30 января 2013 06:31
· Личное сообщение · #3

DrGolova пишет:
Йа дебил - объясните мне, зачем это нужно?

Просто для интереса. Попытка сделать как можно более простой "чистый" ГСЧ не требующий ввода внешних данных. Для практических задач малопригодно, ибо там рулят криптостойкие ГПСЧ с подмешиванием энтропии из многих источников.

DrGolova пишет:
Производные XorShift'а по определению не криптостойкие генераторы, сколько бы туда не вмешивались rdtsc

Так суть в том, что это ГСЧ а не ГПСЧ. Следующий генерируемый бит никак не зависит от предыдущих (у ГСЧ нет состояния). Вся магия функции extractBit нужна лишь для свертки 32 бит в 1 при неизвестном (и предположительно неслучайном) распределении исходных данных. Энтропию этот алгоритм берет из джиттера между системным таймером и тактовой частотой процессора (этот эффект есть как на железе так и в виртуалках, за одним единственным исключением - Bochs).

-----
PGP key <0x1B6A24550F33E44A>


| Сообщение посчитали полезным: Jupiter
 eXeL@B —› Программирование —› Небольшой TrueRNG v2.0
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати