Давайте пограємо в комп’ютерний покер, тільки ви, я та сервер, яким ми обоє довіряємо. Сервер використовує генератор псевдовипадкових чисел, який ініціалізується 32-бітним насінням безпосередньо перед відтворенням. Тож є близько чотирьох мільярдів можливих колод.
Я маю в руках п’ять карток - мабуть, ми не граємо в Texas Hold 'Em. Припустимо, картки роздаються одній мені, одній вам, одній мені, одній вам тощо. Тож у мене на палубі є перша, третя, п'ята, сьома та дев'ята карти.
Раніше я запускав псевдовипадковий генератор чисел чотири мільярди разів, один раз з кожним насінням, і записував першу карту, сформовану для кожного в базу даних. Припустимо, моя перша картка - пікова дама. Це відображається лише в якості першої картки в одній із 52 можливих колод, тому ми скоротили можливі колоди з чотирьох мільярдів до приблизно 80 мільйонів або близько того.
Припустимо, моя друга картка - це три серця. Зараз я запускаю свої RNG ще в 80 мільйонів разів, використовуючи 80 мільйонів насіння, які дають пікову королеву як перше число. Це займає у мене пару секунд. Я записую всі колоди, які виробляють три серця, як третю карту - другу карту в моїй руці. Це знову лише близько 2% колод, тож зараз ми знизилися до 2 мільйонів колод.
Припустимо, третьою картою в моїй руці є 7 клубів. У мене є база даних з 2 мільйонами насінин, які видають дві мої картки; Я запускаю свій RNG ще 2 мільйони разів, щоб знайти 2% тих колод, які видають 7 клубів як третю карту, і ми знизилися до лише 40 тисяч колод.
Ви бачите, як це йде. Я запускаю свій RNG ще 40000 разів, щоб знайти всі насіння, які дають мою четверту карту, і це зводить нас до 800 колод, а потім запускаю його ще 800 разів, щоб отримати ~ 20 насінин, які дають мою п'яту карту, і тепер я просто генеруйте ці двадцять колод карт, і я знаю, що у вас є одна з двадцяти можливих рук. Більше того, я дуже добре розумію, що я буду малювати далі.
Тепер ви бачите, чому важлива справжня випадковість? Як ви описуєте це, ви вважаєте, що розподіл важливий, але розподіл - це не те, що робить процес випадковим. Непередбачуваність - це те, що робить процес випадковим.
ОНОВЛЕННЯ
На підставі (зараз видалених через їх неконструктивний характер) коментарів принаймні 0,3% людей, які читали це, плутають мою думку. Коли люди сперечаються з пунктами, які я не робив, або, що ще гірше, сперечаються з пунктами, які я робив, припускаючи, що я їх не робив, то я знаю, що мені потрібно пояснити більш чітко і уважно.
Здається, існує певна плутанина навколо розповсюдження слів, тому я хочу ретельно закликати до звичаїв.
Питання:
- Як відрізняються псевдовипадкові числа та справді випадкові числа?
- Чому різниця важлива?
- Чи різниці мають щось спільне з розподілом випуску PRNG?
Почнемо з розгляду ідеального способу генерування випадкової колоди карт, за допомогою яких можна грати в покер. Тоді ми побачимо, чим відрізняються інші методи генерування колод, і чи можна скористатися цією різницею.
Почнемо з того, що ми маємо чарівну коробку з написом TRNG
. Як його вхід, ми даємо йому ціле число n, що більше або дорівнює одиниці, і як його вихід дає нам справді випадкове число між одиницею і n, включно. Вихід з поля абсолютно непередбачуваний (якщо йому задано число, відмінне від одного), і будь-яке число між одним і n є таким же ймовірним, як і інше; це означає, що розподіл є рівномірним . (Є й інші більш вдосконалені статистичні перевірки випадковості, які ми могли б виконати; я ігнорую цей момент, оскільки він не є звичним для мого аргументу. TRNG ідеально статистично випадковий за припущенням.)
Починаємо з нерозміщеної колоди карт. Попросимо поле для числа між одним і 52 - тобто TRNG(52)
. Незалежно від того, яке число воно дає, ми відраховуємо стільки карток з нашої відсортованої колоди та вилучаємо її. Це стає першою карткою на перетасованій колоді. Потім ми просимо TRNG(51)
і робимо те саме, щоб вибрати другу карту тощо.
Ще один спосіб поглянути на це: їх 52! = 52 x 51 x 50 ... x 2 x 1 можливі колоди, що приблизно становить 2 226 . Ми вибрали одну з них насправді навмання.
Тепер ми розбираємось з картками. Коли я дивлюся на свої картки, я поняття не маю, які картки у вас є. (Окрім очевидного факту, що у вас немає жодної з карток у мене.) Вони можуть бути будь-якими картками з однаковою ймовірністю.
Тож дозвольте мені переконатися, що я це чітко пояснюю. Ми маємо рівномірний розподіл кожного окремого випуску TRNG(n)
; кожен вибирає число між 1 і n з вірогідністю 1 / n. Також результат цього процесу полягає в тому, що ми обрали один із 52! можливі палуби з ймовірністю 1/52!, тому розподілом по безлічі можливих колод є також рівномірної.
Гаразд.
Тепер припустимо, що у нас є менш магічний ящик, позначений етикеткою PRNG
. Перш ніж ви зможете використовувати його, його потрібно посіяти 32-бітним безпідписаним номером.
АСІДА: Чому 32 ? Хіба це не може бути посіяне 64-або 256- або 10000-бітним числом? Звичайно. Але (1) на практиці більшість позачергових ПРНГ висівають з 32-розрядним числом, і (2) якщо у вас є 10000 біт випадковості, щоб зробити насіння, то чому ви взагалі використовуєте PRNG? У вас вже є джерело 10000 біт випадковості!
Так чи інакше, поверніться до того, як працює PRNG: після посіву ви можете використовувати його так само, як і ви TRNG
. Тобто ви передаєте це число, n, і воно повертає вам число між 1 і n включно. Більше того, розподіл цього випуску більш-менш рівномірний . Тобто, коли ми запитуємо PRNG
число від 1 до 6, ми отримуємо 1, 2, 3, 4, 5 або 6, приблизно, шосту частину часу, незалежно від того, яке насіння було.
Я хочу кілька разів наголосити на цьому, тому що він, мабуть, бентежить певних коментаторів. Розподіл PRNG є рівномірним щонайменше двома способами. По-перше, припустимо, ми обираємо будь-яке конкретне насіння. Ми очікували, що послідовність PRNG(6), PRNG(6), PRNG(6)...
в мільйон разів призведе до рівномірного розподілу чисел між 1 і 6. І по-друге, якби ми вибрали мільйон різних насінин і покликали PRNG(6)
один раз для кожного насіння, знову ми очікували б рівномірного розподілу чисел від 1 до 6. Рівномірність ПРНГ в будь-якій з цих операцій не стосується нападу, який я описую .
Цей процес, як кажуть, є псевдовипадковим, оскільки поведінка коробки насправді повністю детермінована; він вибирає один з 2 32 можливих способів поведінки на основі насіння. Тобто, після того, як вона висіяна, PRNG(6), PRNG(6), PRNG(6), ...
виробляється послідовність чисел з рівномірним розподілом, але ця послідовність повністю визначається насінням. Для заданої послідовності викликів, скажімо, PRNG (52), PRNG (51) ... і так далі, існує лише 2 32 можливі послідовності. Насіння по суті вибирає, який з них ми отримаємо.
Для генерування колоди тепер сервер генерує насіння. (Як? Ми повернемося до цього питання.) Потім вони дзвонять PRNG(52)
, PRNG(51)
і так далі , щоб створити палубу, подібну раніше.
Ця система сприйнятлива до атаки, яку я описав. Для нападу на сервер ми спочатку, заздалегідь, закладаємо власну копію коробки з 0 і запитуємо PRNG(52)
та записуємо це. Потім ми повторно засіваємо 1, запитуємо PRNG(52)
і записуємо це, аж до 2 32 -1.
Тепер сервер покеру, який використовує PRNG для генерації колод, повинен якось генерувати насіння. Не має значення, як вони це роблять. Вони могли закликати TRNG(2^32)
отримати справді випадкове насіння. Або вони могли сприймати поточний час як насіння, що навряд чи є випадковим; Я знаю, котрий час так само, як і ти. Сенс моєї атаки полягає в тому, що це не має значення, оскільки я маю свою базу даних . Коли я бачу свою першу карту, я можу усунути 98% можливих насінин. Коли я бачу свою другу карту, я можу ліквідувати на 98% більше тощо, поки в кінцевому підсумку я не можу зійти до жмені можливих насінин і з великою часткою ймовірності знати, що у вас в руці.
Тепер ще раз хочу підкреслити, що тут припущення полягає в тому, що якби ми зателефонували PRNG(6)
мільйон разів, ми отримали кожне число приблизно в шосту частину часу . Цей розподіл є (більш-менш) рівномірним , і якщо рівномірність цього розподілу - все, що вам цікаво , це добре. Суть питання в тому, чи є інші речі, про PRNG(6)
те, що нас цікавить? і відповідь - так . Ми дбаємо і про непередбачуваність .
Інший спосіб розглянути проблему полягає в тому, що, хоча розподіл мільйона дзвінків PRNG(6)
може бути нормальним, оскільки PRNG обирає лише 2 32 можливі поведінки, він не може генерувати всі можливі колоди. Він може генерувати лише 2 32 з 2 226 можливих колод; крихітна частка. Тож розподіл по набору всіх колод дуже поганий. Але знову ж таки, фундаментальна атака заснована на тому, що ми змогли успішно передбачити минуле та майбутнє поведінку PRNG
з невеликого зразка її результатів.
Дозвольте сказати це в третій-чотири рази, щоб переконатися, що це занурилося. Тут є три розподіли. По-перше, розподіл процесу, який виробляє випадкове 32-бітове насіння. Це може бути абсолютно випадковим, непередбачуваним та рівномірним, і атака все одно спрацює . По-друге, розподіл мільйона дзвінків до PRNG(6)
. Це може бути ідеально рівномірним, і атака все одно спрацює. По-третє, розподіл колод, обраний описаним мною псевдовипадковим процесом. Цей розподіл вкрай поганий; може бути обрана лише крихітна частка можливих колод IRL. Напад залежить від передбачуваності поведінки ПРНГ на основі часткових знань про її вихід .
ВІДПОВІДЬ: Ця атака вимагає, щоб зловмисник знав або міг відгадати, який саме алгоритм використовується PRNG. Чи реально це чи ні, це питання відкрите. Однак, розробляючи систему безпеки, ви повинні спроектувати її для захисту від атак, навіть якщо зловмисник знає всі алгоритми програми . По-іншому: частина системи безпеки, яка повинна залишатися таємною, щоб система була захищеною, називається "ключем". Якщо ваша система залежить від її безпеки від алгоритмів, які ви використовуєте як секрет, то ваш ключ містить ці алгоритми . Це надзвичайно слабка позиція!
Жити далі.
Тепер припустимо, що у нас є третя магічна коробочка з написом CPRNG
. Це криптовалютна версія PRNG
. Це займає 256-бітове насіння, а не 32-бітове насіння. Він ділиться з PRNG
властивістю того, що насіння обирає одну з 2 256 можливих поведінок. Як і у інших наших машин, властивість полягає в тому, що велика кількість дзвінків CPRNG(n)
виробляє рівномірний розподіл результатів між 1 і n: кожен відбувається 1 / n часу. Чи можемо ми здійснити нашу атаку проти цього?
Наша первісна атака вимагає від нас зберігати 2 32 відображення від насіння до PRNG(52)
. Але 2 256 - значно більша кількість; цілком нездійсненно запускати CPRNG(52)
це багато разів і зберігати результати.
Але припустимо, є якийсь інший спосіб прийняти значення CPRNG(52)
і з цього вивести факт про насіння? Ми були досить тупі до цих пір, просто грубо змушуючи всі можливі комбінації. Чи можемо ми заглянути всередину чарівної скриньки, зрозуміти, як вона працює, і на основі результатів вивести факти про насіння?
Ні. Деталі є занадто складними для пояснення, але CPRNG розроблені розумно, щоб неможливо було вивести будь-який корисний факт про насіння з першого виходу CPRNG(52)
або з будь-якого підмножини виходу, незалежно від того, наскільки великим .
Гаразд, тепер припустимо, що сервер використовує CPRNG
для генерації колод. Для цього потрібно 256-бітове насіння. Як він вибирає це насіння? Якщо він обирає будь-яке значення, яке може передбачити нападник, то раптом атака знову стає життєздатною . Якщо ми зможемо визначити, що з 2 256 можливих насінин, сервер, ймовірно, буде обраний лише чотири мільярди, тоді ми знову повернемося до справи . Ми можемо знову здійснити цю атаку, лише звертаючи увагу на малу кількість насіння, яке можливо може бути сформовано.
Тому сервер повинен зробити роботу над тим, щоб 256-бітове число було розподілено рівномірно - тобто кожне можливе насіння вибирається з вірогідністю 1/2 256 . В основному сервер повинен закликати TRNG(2^256)-1
генерувати насіння для CPRNG
.
Що робити, якщо я можу зламати сервер і зазирнути в нього, щоб побачити, яке насіння було обрано? У такому випадку зловмисник знає повне минуле і майбутнє CPRNG . Автору сервера потрібно захиститись від цієї атаки! (Звичайно, якщо я можу успішно влаштувати цю атаку, то, ймовірно, я можу також просто перерахувати гроші на свій банківський рахунок безпосередньо, тому, можливо, це не так цікаво. Сенс полягає в тому, що насіння має бути важко здогадатися таємницею, і воістину випадкове 256-бітове число досить важко здогадатися.)
Повернувшись до свого попереднього моменту про глибоку захист: 256-бітове насіння є ключем до цієї системи безпеки. Ідея CPRNG полягає в тому, що система захищена до тих пір, поки ключ захищений ; навіть якщо відомий кожен інший факт про алгоритм, доки ви можете зберігати ключовий секрет, карти противника непередбачувані.
Гаразд, тому насіння має бути одночасно таємним і рівномірно розподіленим, тому що якщо його немає, ми можемо здійснити атаку. Ми маємо припущення, що розподіл результатів CPRNG(n)
є рівномірним. А як щодо розподілу на наборі всіх можливих колод?
Можна сказати: є 2 256 можливих послідовностей, що виводяться CPRNG, але є лише 2 226 можливих колод. Тому є більше можливих послідовностей, ніж деки, тому ми добре; всі можливі колоди IRL зараз (з великою часткою ймовірності) можливі в цій системі. І це хороший аргумент, окрім ...
2 226 - це лише наближення 52 !. Розділіть його. 2 256/52 ! можливо, це не може бути цілим числом, бо, за одну річ, 52! ділиться на 3, але потужність двох не має! Оскільки це не ціла кількість, зараз у нас ситуація, коли всі колоди можливі , але деякі колоди швидше, ніж інші .
Якщо це не зрозуміло, розгляньте ситуацію з меншою кількістю. Припустимо, у нас є три карти, A, B і C. Припустимо, ми використовуємо PRNG з 8-бітним насінням, тому є 256 можливих насінин. Є 256 можливих виходів PRNG(3)
залежно від насіння; немає можливості, щоб одна третина з них була A, третина - B, а третина - C, оскільки 256 не поділяється на 3. Має бути невеликий ухил до одного з них.
Аналогічно, 52 не ділиться рівномірно на 2 256 , тому має бути деякий ухил по відношенню до деяких карток як обраної першої картки та відхилення від інших.
У нашій оригінальній системі з 32-бітним насінням було масове зміщення, і переважна більшість можливих колод ніколи не вироблялася. У цій системі можуть вироблятися всі колоди, але розподіл колод все ще є недоліком . Деякі колоди є дуже трохи більші, ніж інші.
Тепер питання полягає в тому: чи маємо ми атаку на основі цієї вади? і відповідь на практиці, мабуть, ні . CPRNG розроблені таким чином, що якщо насіння справді випадкове, то обчислити різницю між CPRNG
і таку обчислювально неможливо TRNG
.
Добре, так що давайте підведемо підсумки.
Як відрізняються псевдовипадкові числа та справді випадкові числа?
Вони відрізняються рівнем передбачуваності, який вони демонструють.
- Дійсно випадкові числа не передбачувані.
- Всі псевдовипадкові числа передбачувані, якщо насіння можна визначити чи здогадатися.
Чому різниця важлива?
Тому що є програми, де безпека системи спирається на непередбачуваність .
- Якщо для вибору кожної картки використовується TRNG, то система недоступна.
- Якщо CPRNG використовується для вибору кожної картки, система захищена, якщо насіння є непередбачуваним і невідомим.
- Якщо використовується звичайний PRNG з невеликим насіннєвим простором, система не захищена незалежно від того, насіння непередбачуване чи невідоме; достатньо невеликий насіннєвий простір чутливий до нападів, які я описав.
Чи різниця має щось спільне з розподілом випуску PRNG?
Рівномірність розподілу або їх з- за відсутності окремих викликів до RNG(n)
не відноситься до атак , які я описав.
Як ми бачили, і a, PRNG
і CPRNG
виробляють погані розподіли ймовірності вибору будь-якої окремої колоди з усіх можливих колод. Це PRNG
значно гірше, але в обох є проблеми.
Ще одне питання:
Якщо TRNG набагато кращий, ніж CPRNG, який, в свою чергу, набагато кращий, ніж PRNG, чому хтось використовує CPRNG або PRNG?
Дві причини.
Перший: витрати. TRNG коштує дорого . Генерувати справді випадкові числа важко. CPRNG дають хороші результати для довільно багатьох викликів із лише одним дзвінком на TRNG для насіння. З нижньої сторони, звичайно, ви повинні зберігати це насіння в секреті .
По-друге: іноді ми хочемо передбачити, і все, що нам важливо, - це хороший розподіл. Якщо ви генеруєте "випадкові" дані в якості програмних входів для тестового набору, і він виявляє помилку, тоді було б непогано, що запуск тестового набору знову видає помилку!
Я сподіваюся, що зараз це набагато зрозуміліше.
Нарешті, якщо вам сподобалося це, то вам може сподобатись подальше читання на тему випадковості та перестановки: