3、真随机数发生器(TRNG):TRNG原理、基于振荡器的TRNG设计、熵源评估与测试
3.1 真随机数到底“真”在哪?
做硬件安全这么多年,我经常被问到:“TRNG和PRNG到底有啥区别?”
说白了,PRNG(伪随机数发生器)是个数学算法。你给它一个种子,它就能吐出一长串看起来随机的数。但问题是——只要知道种子,序列就能完全复现。这在安全场景下,是个致命伤。
TRNG不一样。它不靠算法,而是靠物理世界的随机性。比如热噪声、抖动、放射性衰变。这些过程在物理上是不可预测的。你想想看,谁能精确预测一个电子的运动轨迹?没人。
所以,TRNG的核心价值在于:它的输出不可复现,不可预测。这是所有密码学安全的基石。
- PRNG:确定性算法 + 种子 → 伪随机序列
- TRNG:物理熵源 + 采样 → 真随机序列
3.2 基于振荡器的TRNG设计——我踩过的坑
在众多TRNG实现中,基于振荡器的方案是最常见的。为什么?因为它好做,成本低,适合集成到SoC里。
基本原理其实很简单:利用两个振荡器之间的相位抖动。一个慢速振荡器去采样一个快速振荡器。由于热噪声和1/f噪声的存在,每次采样的结果都会有一点点偏差。这个偏差,就是随机性的来源。
嗯,这里要注意。我当年第一次做这个设计时,天真地以为随便搭两个环振就能用。结果呢?测试出来的随机数质量惨不忍睹。后来才明白,振荡器的设计直接决定了熵源的质量。
3.2.1 经典结构:双环振TRNG
我习惯用这种结构:
慢环振(低频) → 分频器 → D触发器的时钟端
快环振(高频) → D触发器的数据端
D触发器的输出 → 后处理模块
慢环振的频率通常在几十MHz,快环振在几百MHz到GHz级别。每次慢环振的上升沿到来时,D触发器采样快环振的当前电平。由于相位抖动,采样结果会在0和1之间随机跳变。
3.2.2 设计中的“坑”与“避坑”
我曾经在一个项目里,TRNG的随机性测试死活过不了。查了三天,最后发现是电源噪声太大,导致振荡器的抖动被“淹没”了。你想想看,如果电源纹波是周期性的,那抖动就变成了确定性偏差,随机性自然就没了。
所以,我总结了几条避坑指南:
- 电源隔离:TRNG的振荡器一定要用独立的LDO供电。别和数字逻辑共用电源。
- 布局布线:振荡器要远离时钟树和高速I/O。我见过一个案例,TRNG被DDR的时钟串扰了,输出全是0x55。
- 温度补偿:振荡器的频率会随温度漂移。如果漂移太大,采样窗口会错位。建议加一个温度传感器做校准。
3.3 熵源评估——别被“看起来随机”骗了
设计完TRNG,怎么知道它好不好?光看波形是不够的。我见过太多“看起来随机”的序列,一上统计测试就原形毕露。
熵源评估,说白了就是回答三个问题:
- 输出是否均匀? 0和1的比例是不是接近50%?
- 是否有相关性? 相邻比特之间有没有依赖关系?
- 熵率够不够? 每比特携带了多少随机信息?
3.3.1 常用的统计测试套件
我个人最常用的是NIST SP 800-22测试套件。它包含15项测试,比如:
| 测试名称 | 检测目标 | 我的经验阈值 |
|---|---|---|
| 频率测试 | 0/1比例是否均匀 | P-value > 0.01 |
| 游程测试 | 连续相同比特的长度分布 | P-value > 0.01 |
| 块内频率测试 | 局部均匀性 | P-value > 0.01 |
| 离散傅里叶变换测试 | 周期性模式 | P-value > 0.01 |
注意,P-value大于0.01只是“通过”,不代表“优秀”。我一般要求所有测试的P-value都大于0.5,才敢说这个TRNG是可靠的。
3.3.2 在线监测——别等流片回来才后悔
我曾经吃过一次大亏。TRNG在实验室测试时一切正常,但到了客户现场,温度一高,随机性就下降了。为什么?因为振荡器的抖动随温度变化,熵源退化了。
从那以后,我坚持在TRNG里加一个在线熵源监测模块。它实时统计输出的0/1比例,如果偏离50%超过某个阈值(比如±5%),就触发告警,甚至直接切断输出。
这样做的好处是:你不需要等到系统出问题才去排查。TRNG一旦退化,安全机制就形同虚设。在线监测是最后一道防线。
3.4 后处理——把“毛坯”变成“精装”
原始熵源的输出往往有偏差。比如,由于工艺偏差,振荡器的占空比可能不是50%,导致输出中1的比例偏高。
这时候就需要后处理。我常用的方法有两种:
- 冯·诺依曼校正器:检测相邻比特对,如果是“01”输出0,“10”输出1,“00”和“11”丢弃。简单有效,但吞吐率会下降。
- 哈希提取:用SHA-256或类似算法对原始数据进行压缩。能有效去除偏差,但硬件开销大。
我个人习惯的做法是:先用冯·诺依曼校正器做一级处理,再用一个轻量级的LFSR做白化。这样既保证了随机性,又控制了面积和功耗。
3.5 测试与验证——实战中的“最后一公里”
TRNG的测试,不能只靠仿真。我建议在FPGA上做原型验证,采集真实数据跑NIST测试。FPGA的布局布线环境和ASIC不同,但至少能验证架构的正确性。
测试流程我一般这样安排:
- 常温测试:25°C,采集1000万比特,跑NIST全套。
- 高低温测试:-40°C和85°C,各采集500万比特,看温度漂移。
- 电压拉偏测试:核心电压±10%,看电源敏感度。
- 长期稳定性测试:连续运行72小时,每小时采集一次数据,看是否有退化趋势。
我记得有一次,TRNG在72小时测试中,第48小时突然出现了一组P-value低于0.01的数据。查了半天,发现是芯片温度升高后,一个旁路电容的ESR变化了,导致电源噪声增大。换了电容后问题解决。这种问题,不做长期测试根本发现不了。
好了,关于TRNG的原理、设计和测试,我就讲这么多。下一章我们聊聊物理不可克隆函数(PUF),那又是一个很有意思的话题。