مولد أرقام عشوائي حقيقي صغير ومستقل عن النظام الأساسي لأي FPGA (وحتى ASICs).
يهدف neoTRNG إلى أن يكون مولدًا صغيرًا للأرقام العشوائية الحقيقية (TRNG) لا يعتمد على النظام الأساسي ويمكن تصنيعه لأي تقنية مستهدفة (FPGAs وحتى ASICs). وهو يعتمد على مذبذبات حلقية بسيطة تعمل بحرية، والتي يتم تعزيزها بتقنية خاصة للسماح بالتوليف لأي منصة. يتم استخدام ضجيج الطور الذي يحدث عند أخذ عينات من المذبذبات الحلقية الحرة كمصدر للإنتروبيا الفيزيائية.
هذا المشروع هو "عرضي" من معالج 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
العام. تضيف كل خلية إنتروبيا إضافية عاكسين آخرين إلى طول السلسلة الأولي هذا. ومن ثم، فإن كل خلية إنتروبيا إضافية تتأرجح بتردد أقل من سابقتها.
من الصعب تنفيذ العناصر غير المتزامنة مثل المذبذبات الحلقية بطريقة مستقلة عن النظام الأساسي لأنها تتطلب عادةً استخدام الأساسيات أو السمات أو إعدادات التوليف الخاصة بالمنصة/التقنية. من أجل توفير بنية حقيقية لا تستهدف الهدف، والتي يمكن تصنيعها لأي تقنية مستهدفة، يتم تطبيق تقنية خاصة: كل عاكس داخل RO يتبعه مزلاج يوفر إعادة ضبط شاملة وأيضًا مزلاج فردي يتيح التبديل المزلاج إلى الوضع الشفاف.
يتم التحكم في تمكينات المزلاج الفردية من خلال سجل التحول الطويل الذي يتميز بـ FF مميز لكل مزلاج فردي في سلسلة RO. عندما يتم تمكين TRNG، يبدأ سجل التحول هذا في الامتلاء بالوحدات. وبالتالي، يتم تمكين المزالج بشكل فردي واحدًا تلو الآخر مما يجعل من المستحيل على أداة التوليف قطع أي منطق/عناصر من سلسلة RO حيث يمكن (نظريًا) مراقبة حالات بدء كل مزلاج بواسطة منطق خارجي. يتم ربط سجل تمكين التحول لجميع خلايا الإنتروبيا بسلسلة تعاقبية لمواصلة إجراء بدء التشغيل عبر مصفوفة الإنتروبيا بأكملها.
تُظهر الصورة التالية مخططًا مبسطًا لخلية الإنتروبيا الأولى التي تتكون من 5 عناصر مزلاج عاكس لمذبذب الحلقات، و5 قلابات لسجل تمكين التحول، و2 قلابات أخرى للمزامن.
يمكن هنا رؤية صورة توضح لـ FPGA نتيجة التعيين (التي تم إنشاؤها بواسطة Intel Quartus Prime) لأول خلية إنتروبيا. إنه يوضح أن جميع عناصر المزلاج + العاكس لسلسلة المذبذب الحلقي قد تم تعيينها بنجاح إلى LUT4s الفردية.
بمجرد ضبط الجزء الأخير من سجل تمكين التحول المتسلسلة لخلية الإنتروبيا، تبدأ وحدة إزالة التحيز. تطبق هذه الوحدة طريقة "John von Neumann Randomness Extractor" البسيطة لإزالة انحياز تدفق البيانات العشوائية التي تم الحصول عليها. يطبق المستخرج سجل إزاحة 2 بت الذي يقوم بأخذ عينات من البت العشوائي XOR-ed من مصفوفة خلايا الإنتروبيا. في كل دورة ثانية، يقوم المستخرج بتقييم البتتين اللتين تم أخذ عينات منهما للتحقق من زوج البتات غير المتداخل من حيث الحواف .
كلما تم اكتشاف حافة، يتم إرسال إشارة "صالحة" إلى وحدة أخذ العينات التالية. تُصدر الحافة الصاعدة ( 01
) بتة بيانات 1
، وتُصدر الحافة الهابطة ( 10
) بتة بيانات 0
. ومن ثم، تتطلب وحدة إزالة الانحياز دورتين على مدار الساعة على الأقل لتوليد بتة عشوائية واحدة. إذا لم يتم اكتشاف أي حافة ( 00
أو 11
)، تظل الإشارة الصالحة منخفضة وتتوقف وحدة أخذ العينات.
تنفذ وحدة أخذ العينات سجل إزاحة 8 بت لتحويل تدفق البتات التسلسلي غير المتحيز إلى أرقام عشوائية على نطاق البايت. بالإضافة إلى ذلك، توفر وحدة العينة معالجة لاحقة بسيطة لتحسين التوزيع الطيفي للعينات العشوائية التي تم الحصول عليها.
من أجل توليد بايت واحد من البيانات العشوائية، تقوم وحدة أخذ العينات بإعادة ضبط سجل التحول الداخلي الخاص بها إلى الصفر الكامل وتبدأ في استهلاك 64 بت من التدفق العشوائي غير المتحيز. يتم تطبيق سجل الإزاحة على أنه سجل إزاحة التغذية المرتدة الخطية (LFSR) الذي يقوم XORs بتدفق الإدخال مع البت الأخير من السجل لمزيد من التدافع وخلط تدفق البتات العشوائي.
يتم تقييم neoTRNG كجزء من معالج NEORV32، حيث يتوفر neoTRNG كوحدة SoC قياسية. تم تصنيع المعالج لجهاز Intel Cyclone IV EP4CE22F17C6N
FPGA الذي يعمل بسرعة 100 ميجا هرتز. للتقييم، تم استخدام التكوين الافتراضي الصغير جدًا: تم تنفيذ ثلاث خلايا إنتروبيا حيث نفذت الأولى 5 عاكسات، والثانية نفذت 9 عاكسات والثالثة نفذت 11 عاكسًا. قد توفر التكوينات الأكثر تعقيدًا مع خلايا إنتروبيا أكبر/أكبر جودة عشوائية "أفضل".
NUM_CELLS = 3
NUM_INV_START = 5
SIM_MODE = false
ملحوظة
تم الحصول على إجمالي 4 ميغابايت من البيانات العشوائية للتقييمات. مجموعة البيانات هذه متاحة كملف ثنائي entropy.bin
في أصول الإصدار.
لتحليل الرسم البياني البسيط تم أخذ عينات من 4 ميغابايت من البايتات العشوائية من 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
تعتبر مجموعة اختبارات الأرقام العشوائية الأكثر تشددًا (ويكيبيديا، الصفحة الرئيسية) من تأليف روبرت ج. براون مجموعة أدوات رائعة لاختبار الإجهاد وتوصيف مولدات الأرقام العشوائية.
مهم
؟ العمل في التقدم؟
يحتاج المتشدد إلى مجموعة كبيرة من العينات العشوائية (حوالي 4 جيجابايت). وبخلاف ذلك، فمن الواضح أن البيانات العشوائية ستؤدي إلى تقليل الإنتروبيا الإجمالية. أستخدم حاليًا اتصال UART بسيطًا لنقل البيانات من FPGA إلى جهاز الكمبيوتر. ولكن حتى معدلات الباود الأعلى، فإن مجموعة البيانات التي يبلغ حجمها 4 جيجابايت قد تستغرق وقتًا طويلاً لإرسالها. حتى أحصل على قناة نقل أفضل (أو فقط الكثير من الوقت) فإن هذا التقييم "جاري العمل" .
نتائج التعيين لـ neoTRNG المطبقة داخل معالج NEORV32 RISC-V باستخدام التكوين الافتراضي. النتائج الناتجة عن Intel Cyclone EP4CE22F17C6N
FPGA الذي يعمل بسرعة 100 ميجاهرتز باستخدام 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 ميجاهرتز أن يولد حوالي 330 كيلو بايت من البيانات العشوائية في الثانية. يمكن تحقيق معدلات توليد أعلى عن طريق تشغيل العديد من مثيلات 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
يتم تنفيذ عملية محاكاة بسيطة من خلال سير عمل GitHub neoTRNG-sim
بالمشروع.