AVR随机数发生器


12

我已经阅读了TI(slaa338)的一份应用笔记,其中描述了一种用于生成“用于实数”(与“伪”数相对)的随机数的技术。它利用MSP430有点奇怪的时钟子系统来实现此目标。有谁知道可以在AVR(尤其是XMega的AVR)上实现的用于生成“真实”随机数的技术?


1
伪随机适用于骰子游戏。我认为他希望密码学安全。
科尔图克

2
您能否提示应用程序和/或所需的随机程度?如果是用于加密技术,则除了种子质量外,还有其他注意事项。根据您的要求,一些已经提出的建议(例如,对各种类型的环境投入进行采样)可能是适当的,也可能是不合适的。
温德尔·奥斯卡

Answers:


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,2010年

顺便说一句:如果您真的需要安全性,那么我介绍的简单,有效和快速的LCG方法就不是您想要的:许多LCG可以被破坏;只需连续获取2-3个值,然后将它们插入具有一组已知常量的LCG生成器中-这将包括Wikipedia页面上的所有内容。匹配模式将使攻击者可以预测下一个数字。也可能(但更难)从零开始找出常量。
凯文·维米尔

1
@reemrevnivek仅供参考,Atmel正在出售他们的SecureAVR产品线...如果您想要加密的东西,他们建议使用基于ARM的32位处理器,这对于AVR的开发环境而言是完全不同的。他们确实有一对带有True RNG的游戏,也许有一天我会和他们一起玩。
vicatcu,2010年

7

将ADC连接到硬件噪声源,并在需要时使用软件“加白”随机数。

这是一个基于AVR的项目,它可以完成此任务:Leon的迷你便携式随机数发生器(mPRNG)

根据所需的密码安全性,您可以使用接地模拟输入或“ 内部温度传感器 ” 的噪声作为随机性种子,而不是外部硬件。

更新:后来我为Arduino编写了一个程序,该程序使用芯片的计时器作为熵源(由于嘈杂的比特被截断了,所以ADC没用),这激发了熵库的创建。

在这两种情况下,随机性都不来自温度值本身,温度值本身变化缓慢,而是来自最低有效位最低有效位从一次读取到下一次随机变化。我多次读取该值,对于输出的每一位一次,与上一次读取进行位移和异或。 将真正的随机位与不相关的位进行XOR可以保留随机性,因此随机性会散布到所有位,从而变成真正的白噪声。但是,您的比特率不会很高,因为每个采集时间或定时器周期只能得到一位输出。使用计时器方法,我获得了约64位/秒的速度。


5
不幸的是,命名“ -PRNG”(或多或少是真实的)RNG。
尼克T 2010年

对于ADC +1,我想您可能正在寻找的是频率比温度传感器更高的东西。
章鱼

1
@Octopus好吧,您没有使用温度作为熵源,而是使用了噪声最低的有效位,即使温度恒定,每次读取ADC时,这些位都会随机变化。但是,当我在Arduino上测试时,这些位始终为0,因此这是不可行的,因此我不得不使用计时器变化。在我使用该方法的另一个MCU上,ADC的LSB嘈杂且可用。
endolith 2015年

3

生成随机种子的另一个技巧是计算直到发生外部事件为止的时钟周期数。例如,如果这是一个人要使用的设备,请计算时钟周期数直到他按下“开始”按钮,然后将其用作随机种子。


4
这可能不是很安全,因为它们可以通过确保对一台设备的控制来闯入,从而抵御旁道攻击,但是与所有加密技术一样,应用程序决定了可行性。
Kortuk

3

为了确保不会以相同的顺序重新启动,我在eeprom中使用了somme字节:

#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从当前的init看起来是随机的……等等……但是,如果我将randinit重置为ffff(或0000?),我将拥有相同的randinit序列!因此,这并不完美。我忘记了有关上载* .hex的保险丝会擦掉eeprom的警告;)
jojo l'abricot 2010年


2

您是否看过使用randomSeed()之类的东西?-在Arduino IDE中使用

您可以使用此函数对atmel AVR上的浮动(自由)模拟引脚进行采样,然后使用该值为随机数函数-random()创建任意起点。

random()创建的值可以是伪随机数-但是randomSeed()创建的任意起点应尽可能是真实的随机数/值。


2
诸如模拟引脚之类的采样几乎是随机的,但分布不均匀。但是,将种子随机运行几次,并且可以。
凯文·维米尔

....通过伪随机数生成器,一对夫妇... <-怎么丢失了?NTS:先动脑,然后动手指。
凯文·维米尔

确实-如果将其用于加密/保护等也不是最安全的方法,但它会为您提供诸如生成音乐或骰子游戏之类的不错的随机数。它也很容易实现:)
Jim

1

有一篇有关如何使用AVR硬件实现此目标的论文。它涉及依靠时钟抖动。基本上,您使用一个基于一个时钟源的定时器中断来采样另一个定时器的低位,而该定时器是由一个单独的独立时钟源提供时钟的。这两个时钟将具有一些与之相关的随机抖动,并且采样不会是完全周期性的。

我在STM32微控制器上做了一个小的概念证明,代码在github上。基于一组随机测试套件,它获得了一些良好的结果。

以我的观点,我认为这比用ADC采样浮动引脚更好,后者非常容易受到攻击(将引脚接地),并且您的数字不再那么随意了!)我敢肯定,有一种方法可以处理基于时钟抖动的RNG,但是我可以完全基于片上内部时钟源来执行此操作,这让我感觉更好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.