เครื่องมือสร้างตัวเลขสุ่มที่แท้จริงขนาดเล็กและไม่ขึ้นกับแพลตฟอร์มสำหรับ FPGA ใดๆ (และแม้แต่ ASIC)
neoTRNG มุ่งหวังที่จะเป็นเครื่องกำเนิดตัวเลขสุ่ม TRUE (TRNG) ขนาดเล็กและ ไม่เชื่อเรื่องพระเจ้าบนแพลตฟอร์ม ซึ่งสามารถสังเคราะห์สำหรับเทคโนโลยีเป้าหมาย ใดๆ (FPGA และแม้แต่ ASIC) มันขึ้นอยู่กับริงออสซิลเลเตอร์ที่ทำงานอย่างอิสระอย่างง่าย ซึ่งได้รับการปรับปรุงด้วย เทคนิคพิเศษ เพื่อให้สามารถสังเคราะห์ได้สำหรับแพลตฟอร์มใดๆ สัญญาณรบกวนเฟส ที่เกิดขึ้นเมื่อสุ่มตัวอย่างริงออสซิลเลเตอร์ที่ทำงานอย่างอิสระถูกใช้เป็นแหล่งเอนโทรปีทางกายภาพ
โปรเจ็กต์นี้เป็น "การแยกส่วน" จากโปรเซสเซอร์ NEORV32 RISC-V โดยที่ neoTRNG ถูกนำมาใช้เป็นโมดูล SoC เริ่มต้น
คุณสมบัติที่สำคัญ
คำเตือน
เป็นไปได้ว่า อย่าง น้อยอาจมีความสัมพันธ์ข้ามกันระหว่างสัญญาณ/เหตุการณ์ภายใน/ภายนอกกับตัวเลขสุ่มที่สร้างขึ้น ดังนั้นจึง ไม่มีการรับประกันเลยที่ 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
ทั่วไปสุดท้ายสามารถตั้งค่าเพื่อให้สามารถจำลอง TRNG ภายในการจำลอง RTL ธรรมดาได้
neoTRNG ขึ้นอยู่กับหมายเลขที่สามารถกำหนดค่าได้ ( NUM_CELLS
) ของเซลล์เอนโทรปี แต่ละเซลล์จะมีริงออสซิลเลเตอร์ ("RO") แบบธรรมดาที่สร้างขึ้นโดยใช้อินเวอร์เตอร์จำนวนคี่ ความถี่การสั่นของ RO ถูกกำหนดโดยการหน่วงเวลาการแพร่กระจายขององค์ประกอบภายในวงแหวน ความถี่นี้ไม่คงที่เนื่องจากมีความผันผวนน้อยที่สุดซึ่งเกิดจากเสียงรบกวนจากความร้อน เสียงช็อตอิเล็กทรอนิกส์ สถานะของอินเวอร์เตอร์ตัวสุดท้ายของ RO ถูกสุ่มตัวอย่างลงในฟลิปฟล็อปโดยใช้นาฬิกาคงที่ ( clk_i
) เนื่องจากความถี่ของ RO เปลี่ยนแปลงอย่างโกลาหลเมื่อเวลาผ่านไป สัญญาณ รบกวนเฟส โดยธรรมชาติของข้อมูลที่สุ่มตัวอย่างจึงถูกใช้เป็นแหล่งเอนโทรปีที่แท้จริง
เซลล์เอนโทรปีแต่ละเซลล์จะสร้างสตรีมข้อมูลสุ่มขนาด 1 บิต เอาต์พุตของเซลล์ทั้งหมดจะถูกผสมโดยใช้เกท XOR แบบกว้าง ก่อนที่สตรีมจะถูกลดอคติโดยเครื่องมือแยกแบบสุ่มอย่างง่าย บิตที่ไม่เอนเอียงหลายบิตจะถูกสุ่มตัวอย่าง / ดีซีเรียลไลซ์โดยหน่วยสุ่มตัวอย่างเพื่อให้เป็นตัวเลขสุ่มทั้งไบต์ หน่วยสุ่มตัวอย่างยังใช้กระบวนการหลังการประมวลผลแบบง่ายๆ เพื่อปรับปรุงการกระจายสเปกตรัมของตัวเลขสุ่ม
เซลล์เอนโทรปีแต่ละเซลล์ประกอบด้วยวงแหวนออสซิลเลเตอร์ที่สร้างขึ้นจาก สลักกลับด้าน จำนวนคี่ ความยาวของวงแหวนในเซลล์เอนโทรปีแรกถูกกำหนดโดยค่าทั่วไป NUM_INV_START
เซลล์เอนโทรปีเพิ่มเติมทุกเซลล์จะเพิ่มอินเวอร์เตอร์อีก 2 ตัวให้กับความยาวโซ่เริ่มต้นนี้ ดังนั้นเซลล์เอนโทรปีเพิ่มเติมแต่ละเซลล์จะแกว่งด้วยความถี่ที่ต่ำกว่าเซลล์ก่อนหน้า
องค์ประกอบแบบอะซิงโครนัส เช่น ริงออสซิลเลเตอร์นั้นยากที่จะนำไปใช้ในลักษณะที่ไม่ขึ้นกับแพลตฟอร์ม เนื่องจากโดยปกติแล้วพวกมันจำเป็นต้องใช้การตั้งค่าพื้นฐาน คุณลักษณะ หรือการสังเคราะห์เฉพาะแพลตฟอร์ม/เทคโนโลยี เพื่อให้มีสถาปัตยกรรมที่ไม่เชื่อเรื่องพระเจ้าเป้าหมายที่แท้จริง ซึ่งสามารถสังเคราะห์สำหรับเทคโนโลยีเป้าหมายใดๆ ได้ จึงมีการใช้เทคนิคพิเศษ: อินเวอร์เตอร์แต่ละตัวภายใน RO ตามด้วย สลัก ที่ให้การรีเซ็ตทั่วโลก และยังมีสลักแต่ละตัวที่สามารถเปิดใช้งานเพื่อสลับได้ สลักเป็นโหมดโปร่งใส
การเปิดใช้งานสลักแต่ละตัวจะถูกควบคุมโดยรีจิสเตอร์แบบกะยาวซึ่งมี FF ที่แตกต่างกันสำหรับทุกๆ สลักในห่วงโซ่ RO เมื่อเปิดใช้งาน TRNG การลงทะเบียนการเปลี่ยนแปลงนี้จะเริ่มเติมข้อมูลลงไป ดังนั้น แลตช์จะถูกเปิดใช้งานทีละตัว ซึ่งทำให้เครื่องมือสังเคราะห์ไม่สามารถตัดลอจิก/องค์ประกอบใดๆ จากห่วงโซ่ RO ได้ เนื่องจากสถานะการเริ่มต้นของสลักแต่ละตัว (ตามทฤษฎี) สามารถตรวจสอบได้โดยลอจิกภายนอก การเปิดใช้งาน shift register ของเซลล์เอนโทรปีทั้งหมดจะเชื่อมต่อแบบเดซี่เชนเพื่อดำเนินขั้นตอนการเริ่มต้นนี้ต่อไปในอาร์เรย์เอนโทรปีทั้งหมด
รูปภาพต่อไปนี้แสดงแผนผังอย่างง่ายของเซลล์เอนโทรปีแรกสุด ซึ่งประกอบด้วยองค์ประกอบสลักอินเวอร์เตอร์ 5 ชิ้นสำหรับริงออสซิลเลเตอร์ ฟลิปฟล็อป 5 ชิ้นสำหรับเปิดใช้งานกะรีจิสเตอร์ และฟลิปฟล็อปอีก 2 ชิ้นสำหรับซิงโครไนเซอร์
รูปภาพที่แสดง FPGA และผลลัพธ์การแมป (สร้างโดย Intel Quartus Prime) ของเซลล์เอนโทรปีแรกสุดสามารถดูได้ที่นี่ มันแสดงให้เห็นว่าองค์ประกอบแลตช์+อินเวอร์เตอร์ทั้งหมดของห่วงโซ่ริง-ออสซิลเลเตอร์ได้รับการแมปกับ LUT4 แต่ละตัวได้สำเร็จ
ทันทีที่บิตสุดท้ายของรีจิสเตอร์การเปิดใช้งานกะแบบเดซี่เชนของเซลล์เอนโทรปีถูกตั้งค่า หน่วยลดไบแอสก็จะเริ่มทำงาน หน่วยนี้ใช้ "John von Neumann Randomness Extractor" แบบง่ายๆ เพื่อลดอคติสตรีมข้อมูลสุ่มที่ได้รับ ตัวแยกใช้รีจิสเตอร์กะ 2 บิตที่สุ่มตัวอย่างบิตสุ่ม XOR-ed จากอาร์เรย์เซลล์เอนโทรปี ในทุก ๆ รอบวินาที ตัวแยกจะประเมินบิตตัวอย่างทั้งสองบิตเพื่อตรวจสอบคู่บิตที่ไม่ทับซ้อนกันเพื่อ หาขอบ
เมื่อใดก็ตามที่ตรวจพบขอบ สัญญาณ "ถูกต้อง" จะถูกส่งไปยังหน่วยเก็บตัวอย่างต่อไปนี้ Rising-edge ( 01
) ปล่อยบิตข้อมูล 1
บิต และ Falling-edge ( 10
) ปล่อยบิตข้อมูล 0
ดังนั้น หน่วยลดอคติต้องใช้รอบสัญญาณนาฬิกาอย่างน้อยสองรอบเพื่อสร้างบิตสุ่มบิตเดียว หากตรวจไม่พบขอบ ( 00
หรือ 11
) สัญญาณที่ถูกต้องจะยังคงต่ำและหน่วยสุ่มตัวอย่างจะหยุดทำงาน
หน่วยสุ่มตัวอย่างใช้ shift register 8 บิตเพื่อแปลงบิตสตรีมแบบ de-biased แบบอนุกรมให้เป็นตัวเลขสุ่มทั้งไบต์ นอกจากนี้ หน่วยตัวอย่างยังมีการประมวลผลภายหลังแบบง่ายๆ เพื่อปรับปรุงการกระจายสเปกตรัมของตัวอย่างสุ่มที่ได้รับ
เพื่อสร้างข้อมูลสุ่มหนึ่งไบต์ หน่วยสุ่มตัวอย่างจะรีเซ็ตรีจิสเตอร์กะภายในเป็นศูนย์ทั้งหมด และเริ่มใช้งานสตรีมสุ่มแบบดีไบอัสขนาด 64 บิต รีจิสเตอร์ shift ถูกนำมาใช้เป็น linear-feedback shift register (LFSR) ที่ XORs อินพุตสตรีมด้วยบิตสุดท้ายของรีจิสเตอร์เพื่อแย่งชิงเพิ่มเติมและผสมบิตสตรีมแบบสุ่ม
neoTRNG ได้รับการประเมินว่าเป็นส่วนหนึ่งของโปรเซสเซอร์ NEORV32 โดยที่ neoTRNG มีให้เป็นโมดูล SoC มาตรฐาน โปรเซสเซอร์ได้รับการสังเคราะห์สำหรับ Intel Cyclone IV EP4CE22F17C6N
FPGA ที่ทำงานที่ 100MHz สำหรับการประเมิน มีการใช้ การกำหนดค่าเริ่มต้น เพียงเล็กน้อย: เซลล์เอนโทรปีสามเซลล์ถูกนำมาใช้ โดยเซลล์แรกใช้อินเวอร์เตอร์ 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 เป็นชุดเครื่องมือที่ยอดเยี่ยมสำหรับการทดสอบความเครียดและกำหนดลักษณะเฉพาะของเครื่องกำเนิดตัวเลขสุ่ม
สำคัญ
- อยู่ระหว่างดำเนินการ ?
dieharder ต้องการตัวอย่างสุ่มชุดใหญ่ (ประมาณ 4GB) มิฉะนั้น ข้อมูลแบบสุ่มจะ ถูกย้อนกลับ ซึ่งจะช่วยลดเอนโทรปีโดยรวมอย่างเห็นได้ชัด ตอนนี้ฉันกำลังใช้การเชื่อมต่อ UART แบบธรรมดาเพื่อถ่ายโอนข้อมูลจาก FPGA ไปยังพีซี แต่แม้แต่อัตรารับส่งข้อมูลที่สูงกว่า ชุดข้อมูลขนาด 4GB ก็อาจใช้ เวลานาน ในการส่ง จนกว่าจะมีช่องทางการถ่ายทอดที่ดีขึ้น (หรือแค่มีเวลามาก) การประเมินนี้ "อยู่ระหว่างดำเนินการ" .
ผลลัพธ์การจับคู่สำหรับ neoTRNG ที่ใช้งานภายในโปรเซสเซอร์ NEORV32 RISC-V โดยใช้การกำหนดค่าเริ่มต้น ผลลัพธ์ที่สร้างขึ้นสำหรับ Intel Cyclone EP4CE22F17C6N
FPGA ที่ทำงานที่ 100MHz โดยใช้ Intel Quartus Prime
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 รอบสัญญาณนาฬิกา ดังนั้นการใช้งานที่ทำงานที่ 100 MHz จะสามารถสร้างข้อมูลสุ่มได้ประมาณ 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 ของโปรเจ็กต์