Генератор випадкових чисел AVR


12

Я прочитав додаток від TI ( slaa338 ), який описує техніку для генерації "реальних" (на відміну від "псевдо") випадкових чисел. Він використовує дещо екзотичну тактову підсистему MSP430 для досягнення цієї мети. Хтось знає про техніку, яку можна реалізувати на AVR (мене цікавить зокрема XMega) для генерації "для реальних" випадкових чисел?


1
psuedo випадкових робіт для ігор з кубиками. Я думаю, що він хоче криптографічно захищений.
Кортук

2
Чи можете ви надати підказку щодо програми та / або ступеня випадковості, яка вам потрібна? Якщо це стосується криптографії, то крім якості насіння є додаткові міркування. Деякі із вже запропонованих пропозицій - наприклад, вибірки внесків до навколишнього середовища різних типів, можуть бути або не підходити на основі ваших вимог.
Вінделл Оскай

Відповіді:


6

Як погано вам користуватися XMega? Якщо генерація криптовалют та випадкових чисел є великою частиною вашого проекту, серія Atmel SecureAVR має вбудоване апаратне випадкове число і розраховане на криптографічні програми.

Незважаючи на це, я сумніваюся, що ви знайдете випадкове джерело насіння, яке має гарне поширення. Ви хочете кілька разів запустити його через генератор випадкових чисел псевдо. Поки щоразу починаєте з іншого насіння, це дасть вам гарний набір випадкових чисел. LGC - це швидкий і простий псевдовипадковий генератор:

static unsigned long Seed; 

/* Call before first use of NextVal */
unsigned long InitSeed()
{
   //Your code for random seed here

   // Correct distribution errors in seed
   NextVal();
   NextVal();
   NextVal();
   return NextVal();
}

 /* Linear Congruential Generator 
  * Constants from  
  * "Numerical Recipes in C" 
  * by way of 
   * <http://en.wikipedia.org/wiki/Linear_congruential_generator#LCGs_in_common_use>
   * Note: Secure implementations may want to get uncommon/new LCG values
  */
unsigned long NextVal()
{
  Seed=Seed*1664525L+1013904223L;
  return Seed;
} 

1
Це дивовижно, я не розумів, що існує лінія SecureAVR, дякую за вказівник!
vicatcu

BTW: Якщо вам дійсно потрібна безпека, простий, ефективний та швидкий метод LCG, який я представив, - це не те, що ви хочете: багато LCG можуть бути зламані; просто отримайте 2-3 значення підряд і підключіть їх до генератора LCG з набором відомих констант - це включатиме все на сторінці Вікіпедії. Відповідна схема дозволить зловмисникові передбачити, яким буде наступне число. Зрозуміти, які константи ні з чого, також можна (але складніше).
Кевін Вермер

1
@reemrevnivek FYI, Atmel продає свою лінійку SecureAVR ... вони рекомендують свої 32-бітні процесори на основі ARM, якщо ви хочете криптографічні матеріали, які є абсолютно різною кулькою гри з точки зору середовища розвитку від AVR. У них є пара з True RNG, хоча, можливо, я пограю з ними якийсь день.
vicatcu

7

Підключіть АЦП до апаратного джерела шуму і використовуйте програмне забезпечення для "відбілювання" випадкових чисел, якщо це необхідно.

Ось проект на основі AVR, який робить це: Міні-портативний генератор випадкових чисел Leon (mPRNG)

Залежно від того, наскільки криптографічно захищеним це потрібно, ви можете використовувати шум заземленого аналогового входу або " внутрішнього датчика температури " як насіння випадковості замість зовнішнього обладнання.

Оновлення : пізніше я написав програму для Arduino, яка використовує таймери мікросхем як джерело ентропії (АЦП виявився марним, оскільки шумні біти усічені), і це надихнуло на створення бібліотеки "Ентропія" .

В обох випадках випадковість відбувається не, наприклад, від самого значення температури, яке змінюється лише повільно, а від найменш значущих біт , які змінюються випадковим чином від одного зчитування до іншого. Я читаю значення кілька разів, один раз за кожен біт виводу, бітсіфтінг і XORing з попереднім прочитаним. XORing по-справжньому випадковий біт з некоррельованим бітом зберігає випадковість , тому випадковість поширюється навколо всіх біт і стає справжнім білим шумом. Однак швидкість передачі даних не буде дуже високою, оскільки ви отримуєте лише один біт виходу за час придбання або цикл таймера. Методом таймера я отримував близько 64 біт / с.


5
Назвати (більш-менш правдивий) RNG, "-PRNG" прикро.
Нік Т

+1 для ADC, я думаю, ви, напевно, шукаєте щось, що змінюється на більш високій частоті, ніж датчик температури.
Восьминіг

1
@ Октопод Ну, ви не використовуєте температуру як джерело ентропії, ви використовуєте найменш шумні біти, які змінюватимуться випадковим чином щоразу, коли ви читатимете АЦП, навіть якщо температура буде постійною. Однак, коли я тестував на Arduino, ці біти завжди були 0, тому це було неможливо, і мені довелося замість цього використовувати варіацію таймера. В іншому MCU, який я використовував цей метод, LSB-адреси АЦП були галасливими та зручними.
ендоліт

3

Ще одна хитрість для генерування випадкових насінин - підрахувати кількість тактових циклів до зовнішньої події. Наприклад, якщо це пристрій, яким користується людина, підраховуйте кількість циклів годин, поки він не натисне кнопку 'go', і використовуйте це як випадкове насіння.


4
Це може бути не дуже захищено від атак бічних каналів, оскільки вони можуть зламатись, забезпечивши контроль над одним пристроєм, але, як і у всіх криптовалютах, програма визначає можливість.
Кортук

3

Щоб не перезапустити ту саму послідовність, я використовую сом-байт в eeprom:

#include <avr/eeprom.h>
#include <stdlib.h> // rand

u16  EEMEM randinit; 

int main(void) {
        srand(eeprom_read_word(&randinit));
        eeprom_write_word(&randinit,rand());
        [...]
 }

Це дає досить непоганий випадковий характер і не коштує великих витрат на програму / пам'ять.


2
Це читає байт 0 кожного разу. Які докази у вас є, що цей байт є випадковим? Якщо це так, це чудова техніка!
Кевін Вермер

Це слово (насправді 0 і 1 байт) буде випадковим, тому що при кожному запуску я ініціалізую випадковий генератор з його вмістом. ЦЕ Я завантажую його з новим rand (). Отже, наступний init буде виглядати випадковим чином від поточного ... і так далі ... Але якщо я скину randinit до ffff (або 0000?), У мене буде та сама послідовність рандінітів! Тож це не ідеально. Я забув попередження про запобіжник, який стирає eeprom при завантаженні * .hex;)
jojo l'abricot

3

Я створив бібліотеку, яка, хоча оригінал, призначений для Arduino, добре працює як клас у реалізації C ++, використовуючи g ++ на avr, і справді недавно він був перенесений в архітектуру ARM.

Він використовує тремтіння між сторожовим таймером та системним годинником і був протестований на кількох різних мікросхемах (задокументовано на сторінці wiki)

http://code.google.com/p/avr-hardware-random-number-generation/wiki/WikiAVRentropy


2

Ви подивилися на використання чогось на кшталт randomSeed () ? - використовується в IDE Arduino

Ви можете скористатися цією функцією для вибірки плаваючого (вільного) аналогового штифта на AVR atmel, після чого воно використовує значення для створення довільної вихідної точки для функції псевдовипадкового числа - random ().

Значення, створене випадковим (), може бути псевдо випадковим числом, але довільна відправна точка, створена randomSeed (), повинна бути такою ж реальною випадковим числом / значенням, скільки ви можете отримати.


2
Вибірка проб, таких як аналогові штифти, близька до випадкових, але не матиме рівномірного розподілу. Пропустіть насіння через випадкові випадки пару разів, і це буде.
Кевін Вермер

.... через псевдогенератор випадкових чисел пару ... <- Як це пропало? NTS: Спочатку залучайте мозок, потім пальці.
Кевін Вермер

Точно так - це також не найбезпечніше, якщо використовувати його для шифрування / захисту тощо, але це дасть вам приємне випадкове число для чогось, наприклад, генеративної музики або ігор для кубиків. Це добре і легко здійснити :)
Джим

1

Існує документ про те, як цього досягти за допомогою апаратних засобів AVR. Він передбачає покладання на тремтіння годинника. В основному ви використовуєте переривання таймера на основі відключеного одного джерела тактової частоти для вибірки нижчих бітів окремого таймера, який вимикається окремим незалежним джерелом тактового сигналу. У двох годинників буде пов’язаний якийсь випадковий тремтіння, і вибірки не будуть ідеально періодичними.

Я зробив невеликий доказ концепції цього на мікроконтролері STM32, тут код на github . Це отримало хороші результати на основі набору тестових наборів рандомізації.

На мою думку, я вважаю, що це краще, ніж вибірки плаваючої шпильки з АЦП, яку надзвичайно легко атакувати (прив’язати шпильку до землі, і ваш номер вже не такий випадковий!). Я впевнений, що існує спосіб маніпулювати RNG, що базується на годинниковому тремтінні, але це робить мене трохи краще, що я можу це робити виключно на основі внутрішніх джерел тактових годин.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.