모든 FPGA(및 ASIC)를 위한 작고 플랫폼 독립적인 실제 난수 생성기입니다.
neoTRNG는 모든 대상 기술(FPGA 및 ASIC)에 대해 합성할 수 있는 작고 플랫폼에 구애받지 않는 TRUE 난수 생성기(TRNG)를 목표로 합니다. 이는 모든 플랫폼에 대한 합성을 허용하기 위해 특별한 기술 로 강화된 간단한 자유 실행 링 오실레이터를 기반으로 합니다. 자유 실행 링 오실레이터를 샘플링할 때 발생하는 위상 노이즈는 물리적 엔트로피 소스로 사용됩니다.
이 프로젝트는 neoTRNG가 기본 SoC 모듈로 구현되는 NEORV32 RISC-V 프로세서의 "파생"입니다.
주요 특징
주의
내부/외부 신호/이벤트와 생성된 난수 사이에 최소한 일부 교차 상관관계가 있을 수 있습니다. 따라서 neoTRNG가 완벽하거나 암호학적으로 안전한 난수를 제공한다는 보장은 전혀 없습니다 ! 제공된 평가 결과를 확인하거나 (더 나은 경우) 직접 테스트해 보세요. 또한 생성된 무작위 데이터의 무결성/품질을 확인할 수 있는 변조 감지 메커니즘이나 온라인 상태 모니터링이 아직 없습니다.
경고
neoTRNG를 영구적으로 활성화 하면 동적 전력 소비가 증가하고 칩의 국지적 가열이 발생할 수도 있습니다(매우 큰 구성을 사용하는 경우). 또한 설계로 인해 추가적인 전자기 간섭(EMI)이 방출될 수도 있습니다.
전체 디자인은 종속성이 전혀 없는 단일 VHDL 파일 rtl/neoTRNG.vhd
(예: 특수 라이브러리, 패키지 또는 하위 모듈)로 구현됩니다.
entity neoTRNG is
generic (
NUM_CELLS : natural range 1 to 99 := 3 ; -- number of ring-oscillator cells
NUM_INV_START : natural range 3 to 99 := 5 ; -- number of inverters in first cell, has to be odd
SIM_MODE : boolean := false -- enable simulation mode (no physical random if enabled!)
);
port (
clk_i : in std_ulogic ; -- module clock
rstn_i : in std_ulogic ; -- module reset, low-active, async, optional
enable_i : in std_ulogic ; -- module enable (high-active)
valid_o : out std_ulogic ; -- data_o is valid when set (high for one cycle)
data_o : out std_ulogic_vector ( 7 downto 0 ) -- random data byte output
);
end neoTRNG ;
neoTRNG는 clk_i
신호에 의해 구동되는 단일 클럭 도메인을 사용합니다. 모듈의 재설정 신호 rstn_i
선택 사항 입니다(사용하지 않는 경우 '1'
로 연결). 무작위 데이터는 간단한 데이터/유효 인터페이스를 사용하여 얻습니다. 새로운 유효한 무작위 바이트를 사용할 수 있을 때마다 valid_o
출력은 정확히 한 주기 동안 높으므로 data_o
출력은 사용자 논리에 의해 샘플링될 수 있습니다.
enable_i
신호는 TRNG를 초기화하고 시작하는 데 사용됩니다. TRNG를 사용하기 전에 이 신호는 내부 시프트 레지스터의 모든 비트가 다시 지워지도록 최소한 몇 100 클록 사이클(구성에 따라 다름) 동안 낮게 유지되어야 합니다. enable_i
가 설정되고 valid_o
처음으로 설정되면 TRNG가 작동됩니다. TRNG를 비활성화하려면 동일한 양의 클록 주기 동안 enable_i
낮아야 합니다. enable_i
낮아지면 모든 링 오실레이터가 중지되어 동적 스위칭 활동과 전력 소비를 줄입니다.
neoTRNG를 구성하기 위해 세 가지 일반이 제공됩니다. NUM_CELLS
총 엔트로피 셀 수를 정의합니다. NUM_INV_START
첫 번째 셀의 인버터 수(= 링 오실레이터의 길이)를 정의합니다. 이 두 가지 제네릭은 아래 아키텍처 섹션에서 자세히 설명합니다. 마지막 일반 SIM_MODE
일반 RTL 시뮬레이션 내에서 TRNG 시뮬레이션을 허용하도록 설정할 수 있습니다.
neoTRNG는 구성 가능한 엔트로피 셀 수( NUM_CELLS
)를 기반으로 합니다. 각 셀은 홀수 개의 인버터를 사용하여 구축된 간단한 링 발진기("RO")를 제공합니다. RO의 발진 주파수는 링 내 요소의 전파 지연에 의해 정의됩니다. 이 주파수는 열 잡음 전자 샷 잡음으로 인한 변동이 최소화되므로 정적이지 않습니다. RO의 마지막 인버터 상태는 정적 클럭( clk_i
)을 사용하여 플립플롭으로 샘플링됩니다. RO의 주파수는 시간이 지남에 따라 불규칙하게 변하기 때문에 샘플링된 데이터의 고유 위상 노이즈가 실제 엔트로피 소스로 사용됩니다.
각 엔트로피 셀은 1비트의 무작위 데이터 스트림을 생성합니다. 모든 셀의 출력은 스트림이 간단한 무작위성 추출기에 의해 편향되지 않기 전에 넓은 XOR 게이트를 사용하여 혼합됩니다. 바이어스되지 않은 여러 비트는 샘플링 단위에 의해 샘플링/역직렬화되어 바이트 전체의 난수를 제공합니다. 샘플링 유닛은 또한 난수의 스펙트럼 분포를 개선하기 위해 간단한 후처리를 적용합니다.
각 엔트로피 셀은 홀수 개의 반전 래치 로 구성된 링 발진기로 구성됩니다. 첫 번째 엔트로피 셀의 링 길이는 NUM_INV_START
제네릭에 의해 정의됩니다. 엔트로피 셀이 추가될 때마다 이 초기 체인 길이에 또 다른 2개의 인버터가 추가됩니다. 따라서 각각의 추가 엔트로피 셀은 이전 엔트로피 셀보다 낮은 주파수에서 진동합니다.
링 발진기와 같은 비동기 요소는 일반적으로 플랫폼/기술별 기본 요소, 속성 또는 합성 설정을 사용해야 하므로 플랫폼 독립적인 방식으로 구현하기가 어렵습니다. 모든 대상 기술에 대해 합성할 수 있는 실제 대상 독립적 아키텍처를 제공하기 위해 특수 기술이 적용됩니다. RO 내부의 각 인버터 뒤에는 글로벌 재설정을 제공하는 래치 와 스위치에 대한 개별 래치 활성화가 옵니다. 래치를 투명 모드로 전환합니다.
개별 래치 활성화는 RO 체인의 모든 단일 래치에 대해 고유한 FF를 제공하는 긴 시프트 레지스터에 의해 제어됩니다. TRNG가 활성화되면 이 시프트 레지스터는 1로 채워지기 시작합니다. 따라서 래치는 개별적으로 하나씩 활성화되므로 각 래치의 시작 상태는 (이론적으로) 외부 로직에 의해 모니터링될 수 있으므로 합성 도구가 RO 체인의 로직/요소를 트리밍하는 것이 불가능합니다. 모든 엔트로피 셀의 활성화 시프트 레지스터는 데이지 체인으로 연결되어 전체 엔트로피 배열에 걸쳐 이 시작 절차를 계속합니다.
다음 이미지는 링 오실레이터용 인버터 래치 요소 5개, 활성화 시프트 레지스터용 플립플롭 5개, 동기화 장치용 플립플롭 2개로 구성된 첫 번째 엔트로피 셀의 단순화된 회로도를 보여줍니다.
첫 번째 엔트로피 셀의 FPGA 매핑 결과(Intel Quartus Prime에서 생성)를 보여주는 이미지는 여기에서 볼 수 있습니다. 이는 링 오실레이터 체인의 모든 래치+인버터 요소가 개별 LUT4에 성공적으로 매핑되었음을 보여줍니다.
엔트로피 셀의 데이지 체인 활성화 시프트 레지스터의 마지막 비트가 설정되자마자 바이어스 제거 장치가 시작됩니다. 이 장치는 획득된 무작위 데이터 스트림의 편향을 제거하기 위해 간단한 "John von Neumann Randomness Extractor"를 구현합니다. 추출기는 엔트로피 셀 배열에서 XOR된 무작위 비트를 샘플링하는 2비트 시프트 레지스터를 구현합니다. 두 번째 주기마다 추출기는 샘플링된 두 비트를 평가하여 가장자리가 있는지 겹치지 않는 비트 쌍을 확인합니다.
가장자리가 감지될 때마다 "유효한" 신호가 다음 샘플링 단위로 전송됩니다. 상승 에지( 01
)는 1
데이터 비트를 방출하고 하강 에지( 10
)는 0
데이터 비트를 방출합니다. 따라서 디바이어스 장치는 단일 랜덤 비트를 생성하기 위해 최소 2개의 클록 사이클이 필요합니다. 에지가 감지되지 않으면( 00
또는 11
) 유효한 신호는 낮은 상태로 유지되고 샘플링 단위가 중단됩니다.
샘플링 장치는 8비트 시프트 레지스터를 구현하여 직렬 편향성 제거 비트스트림을 바이트 전체 난수로 변환합니다. 또한 샘플 유닛은 획득된 무작위 샘플의 스펙트럼 분포를 개선하기 위해 간단한 후처리를 제공합니다.
1바이트의 무작위 데이터를 생성하기 위해 샘플링 유닛은 내부 시프트 레지스터를 모두 0으로 재설정하고 편향되지 않은 무작위 스트림의 64비트를 소비하기 시작합니다. 시프트 레지스터는 입력 스트림을 레지스터의 마지막 비트와 XOR하여 무작위 비트스트림을 추가로 스크램블하고 혼합하는 LFSR( 선형 피드백 시프트 레지스터 )로 구현됩니다.
neoTRNG는 NEORV32 프로세서의 일부로 평가되며, 여기서 neoTRNG는 표준 SoC 모듈로 사용 가능합니다. 프로세서는 100MHz에서 실행되는 Intel Cyclone IV EP4CE22F17C6N
FPGA용으로 합성되었습니다. 평가를 위해 매우 작은 기본 구성이 사용되었습니다. 3개의 엔트로피 셀이 구현되어 첫 번째 셀은 5개의 인버터를 구현하고, 두 번째 셀은 9개의 인버터를 구현하고, 세 번째 셀은 11개의 인버터를 구현합니다. 더 많거나 더 큰 엔트로피 셀을 사용하는 더 복잡한 구성은 "더 나은" 무작위 품질을 제공할 수 있습니다.
NUM_CELLS = 3
NUM_INV_START = 5
SIM_MODE = false
메모
평가를 위해 총 4MB 의 무작위 데이터가 획득되었습니다. 이 데이터 세트는 릴리스 자산에서 entropy.bin
바이너리 파일로 제공됩니다.
간단한 히스토그램 분석을 위해 4MB의 무작위 바이트가 neoTRNG에서 샘플링되었습니다. 획득된 바이트는 발생에 따라 누적되었으며 각 빈이 하나의 특정 바이트 패턴(1바이트 = 8비트 = 256개의 다른 패턴)을 나타내는 빈으로 정렬되었습니다. 그런 다음 결과를 통계적 특성과 관련하여 분석했습니다.
[NOTE] integer numbers only
Number of samples: 4194304
Arithmetic mean: 127 (optimum would be 127)
Histogram occurrence
Average: 16384 (optimum would be 4194304/256 = 16384)
Min: 16051 = average - 333 (deviation) at bin 183 (optimum deviation would be 0)
Max: 16706 = average + 322 (deviation) at bin 144 (optimum deviation would be 0)
Average dev.: +/- 96 (optimum would be 0)
$ ent entropy.bin
Entropy = 7.994306 bits per byte.
Optimum compression would reduce the size
of this 4194304 byte file by 0 percent.
Chi square distribution for 4194304 samples is 16726.32, and randomly
would exceed this value less than 0.01 percent of the times.
Arithmetic mean value of data bytes is 127.9417 (127.5 = random).
Monte Carlo value for Pi is 3.132416851 (error 0.29 percent).
Serial correlation coefficient is 0.000496 (totally uncorrelated = 0.0).
$ rngtest < entropy.bin
rngtest 5
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
rngtest: starting FIPS tests...
rngtest: entropy source drained
rngtest: bits received from input: 33554432
rngtest: FIPS 140-2 successes: 1676
rngtest: FIPS 140-2 failures: 1
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 1
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=138.214; avg=1557.190; max=2119.276)Mibits/s
rngtest: FIPS tests speed: (min=32.660; avg=106.337; max=111.541)Mibits/s
rngtest: Program run time: 330110 microseconds
Robert G. Brown의 철저한 난수 테스트 모음(wikipedia, 홈페이지)은 난수 생성기의 스트레스 테스트 및 특성화를 위한 훌륭한 도구 세트입니다.
중요한
? 작업이 진행 중인가요?
dieharder에는 대규모 무작위 샘플 세트(약 4GB 정도)가 필요합니다. 그렇지 않으면 무작위 데이터가 되감기 되어 전체 엔트로피가 분명히 감소합니다. 지금은 간단한 UART 연결을 사용하여 FPGA에서 PC로 데이터를 전송하고 있습니다. 그러나 4GB의 데이터 세트를 전송 속도가 더 높이더라도 전송하는 데 시간이 오래 걸립니다. 더 나은 전송 채널(또는 많은 시간)이 확보될 때까지 이 평가는 "진행 중" 입니다.
기본 구성을 사용하여 NEORV32 RISC-V 프로세서 내에 구현된 neoTRNG에 대한 매핑 결과입니다. Intel Quartus Prime을 사용하여 100MHz에서 실행되는 Intel Cyclone EP4CE22F17C6N
FPGA에 대해 생성된 결과입니다.
Module Hierarchy Logic Cells Logic Registers
------------------------------------------------------------------------------------
neoTRNG:neoTRNG_inst 56 (27) 46 (19)
neoTRNG_cell:entropy_source:0:neoTRNG_cell_inst 8 (8) 7 (7)
neoTRNG_cell:entropy_source:1:neoTRNG_cell_inst 10 (10) 9 (9)
neoTRNG_cell:entropy_source:2:neoTRNG_cell_inst 14 (14) 11 (11)
메모
합성 도구는 래치 및 조합 루프가 감지되었다는 경고를 표시할 수 있습니다. 그러나 이것이 바로 우리가 원하는 것이기 때문에 이는 설계 결함이 아닙니다.
neoTRNG의 최대 생성 속도는 두 가지 요소로 정의됩니다.
따라서 neoTRNG는 하나의 랜덤 바이트를 방출하기 위해 최소한 A * B = 2 * 64 = 128
클럭 사이클이 필요합니다. FPGA 평가에 따르면 실제 샘플링 시간은 약 300 클럭 사이클인 것으로 나타났습니다. 따라서 100MHz로 실행되는 구현은 초당 약 330kB의 무작위 데이터를 생성할 수 있습니다. 여러 neoTRNG 인스턴스를 병렬로 실행하면 더 높은 생성 속도를 달성할 수 있습니다.
비동기 링 오실레이터는 (조합 루프로 인해) rtl 시뮬레이션이 불가능하므로 neoTRNG는 SIM_MODE
일반에 의해 활성화되는 전용 시뮬레이션 모드를 제공합니다. 활성화되면 간단한 플립플롭으로 구현된 "전파 지연"이 링 발진기의 인버터에 추가됩니다.
중요한
시뮬레이션 모드는 시뮬레이션/디버깅 전용입니다! SIM_MODE
가 활성화된 디자인은 합성될 수 있지만 실제/물리적 난수는 전혀 제공되지 않습니다 !
sim
폴더는 기본 구성을 사용하여 neoTRNG에 대한 간단한 테스트벤치를 제공합니다. 테스트벤치는 획득한 무작위 데이터 바이트를 십진수 값으로 시뮬레이터 콘솔에 출력합니다. 제공된 스크립트를 사용하여 GHDL로 테스트벤치를 시뮬레이션할 수 있습니다.
neoTRNG/sim$ sh ghdl.sh
../rtl/neoTRNG.vhd:105:3:@0ms:(assertion note): [neoTRNG] The neoTRNG (v3.2) - A Tiny and Platform-Independent True Random Number Generator, https://github.com/stnolting/neoTRNG
../rtl/neoTRNG.vhd:112:3:@0ms:(assertion warning): [neoTRNG] Simulation-mode enabled (NO TRUE/PHYSICAL RANDOM)!
18
210
147
5
79
94
70
100
185
246
203
220
ghdl:info: simulation stopped by --stop-time @100us
GHDL 파형 데이터는 sim/neoTRNG_tb.ghw
에 저장되며 gtkwave
사용하여 볼 수 있습니다.
neoTRNG/sim$ gtkwave neoTRNG_tb.ghw
간단한 시뮬레이션 실행은 프로젝트의 neoTRNG-sim
GitHub 작업 워크플로우에 의해 실행됩니다.