Генератор случайных чисел AVR


12

Я прочитал приложение от TI ( slaa338 ), в котором описана методика генерации «реальных» (в отличие от «псевдо») случайных чисел. Он использует несколько экзотическую подсистему часов MSP430 для достижения этой цели. Кто-нибудь знает метод, который может быть реализован на AVR (меня интересует, в частности, XMega) для генерации «реальных» случайных чисел?


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

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 существует, спасибо за указатель!
Викацу

Кстати: если вам ДЕЙСТВИТЕЛЬНО нужна безопасность, простой, эффективный и быстрый метод LCG, который я представил, не тот, который вам нужен: многие LCG могут быть повреждены; просто получите 2-3 значения подряд и подключите их к генератору LCG с набором известных констант - это будет включать все на странице Википедии. Соответствующий шаблон позволит злоумышленнику предсказать, каким будет следующее число. Также возможно (но сложнее) выяснить, что такое константы из ничего.
Кевин Вермеер

1
@reemrevnivek К вашему сведению, Atmel продает свою линию SecureAVR ... они рекомендуют свои 32-битные процессоры на основе ARM, если вы хотите криптографический материал, который является совершенно другой игрой с точки зрения среды разработки от AVR. Хотя у них есть пара с настоящими ГСЧ, возможно, я когда-нибудь поиграю с ними.
Викачу

7

Подключите АЦП к аппаратному источнику шума и используйте программное обеспечение для «отбеливания» случайных чисел, если это необходимо.

Вот проект на основе AVR, который делает это: мини портативный генератор случайных чисел Леона (mPRNG)

В зависимости от того, насколько криптографически он должен быть защищен, вы можете использовать шум заземленного аналогового входа или « внутреннего датчика температуры » в качестве начального числа случайности вместо внешнего оборудования.

Обновление : позже я написал программу для Arduino, которая использует таймеры чипа в качестве источника энтропии (АЦП оказался бесполезным, потому что биты с шумом усекаются), и это вдохновило на создание библиотеки Entropy .

В обоих случаях случайность связана, например, не с самим значением температуры, которое изменяется только медленно, а с младшими значащими битами , которые случайным образом меняются от одного чтения к следующему. Я прочитал значение несколько раз, один раз для каждого бита вывода, сдвига битов и XORing с предыдущим чтением. XOR по-настоящему случайного бита с некоррелированным битом сохраняет случайность , поэтому случайность распространяется на все биты и становится настоящим белым шумом. Тем не менее, ваша скорость передачи данных будет не очень высокой, поскольку вы получаете только один бит вывода за время захвата или цикл таймера. С помощью метода таймера я получил около 64 бит / с.


5
Называя (более или менее верным) ГСЧ, "-PRNG" вызывает сожаление.
Ник Т

+1 для АЦП, я думаю, вы, вероятно, ищете что-то, что меняется с большей частотой, чем датчик температуры.
Осьминог

1
@Octopus Ну, вы не используете температуру в качестве источника энтропии, вы используете наименьшие значащие биты, которые будут меняться случайным образом каждый раз, когда вы читаете АЦП, даже если температура постоянна. Когда я тестировал на Arduino, эти биты всегда были равны 0, поэтому это было невозможно, и вместо этого мне пришлось использовать вариацию таймера. На другом MCU, на котором я использовал этот метод, младшие биты АЦП были шумными и работоспособными.
эндолит

3

Еще одна хитрость для генерации случайного начального числа - подсчет количества тактов до появления внешнего события. Например, если это устройство будет использоваться человеком, посчитайте количество тактов, пока он не нажмет кнопку «идти», и используйте его в качестве случайного начального числа.


4
Это может быть не очень защищено от атак по побочным каналам, так как они могут быть взломаны путем обеспечения контроля над одним устройством, но, как и во всей криптографии, приложение определяет осуществимость.
Кортук

3

Чтобы не перезапускать с той же последовательностью, я использую somme byte в 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) будет случайным, потому что при каждом запуске я инициализирую генератор случайных чисел с его содержимым. ТОГДА я загружаю его с новым рандом (). Поэтому следующий init будет выглядеть случайным по сравнению с текущим ... и так далее ... Но если я сброслю randinit на ffff (или 0000?), У меня будет та же последовательность randinit! Так что это не идеально. Я забыл предупреждение о предохранителе, который стирает eeprom при загрузке * .hex;)
jojo l'abricot

3

Я создал библиотеку, которая в то время как оригинал, разработанный для Arduino, хорошо работает как класс в реализации C ++, использующей g ++ на avr, но в действительности она недавно была перенесена и на архитектуру ARM.

Он использует джиттер между сторожевым таймером и системными часами и был протестирован на ряде различных чипов (задокументировано на вики-странице).

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


2

Вы смотрели на использование чего-то вроде randomSeed () ? - используется в Arduino IDE

Вы можете использовать эту функцию для выборки плавающего (свободного) аналогового вывода на AVR Atmel, затем она использует значение для создания произвольной начальной точки для функции псевдослучайных чисел - random ().

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


2
Выборка таких вещей, как аналоговые выводы, близка к случайной, но не будет иметь равномерного распределения. Тем не менее, пропустите семя случайным образом пару раз, и это произойдет.
Кевин Вермеер

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

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

1

Есть документ о том, как этого добиться с помощью оборудования AVR. Это предполагает полагаться на джиттер часов. В основном, вы используете прерывание таймера, основанное на одном источнике синхронизации, для выборки младших бит отдельного таймера, который синхронизируется с отдельным независимым источником синхронизации. Эти два такта будут иметь некоторый случайный джиттер, связанный с ними, и выборка не будет идеально периодической.

Я сделал небольшое доказательство концепции этого на микроконтроллере STM32, код здесь на github . Он получил некоторые хорошие результаты, основанные на наборе тестов рандомизации.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.